From e9ddb0f9c30305a4d85266de04b26ed5e93a26a2 Mon Sep 17 00:00:00 2001 From: Gustavo Sampaio Date: Sun, 23 Feb 2020 11:37:58 -0300 Subject: [PATCH 001/137] Easy pick codelenses with keyboard shortcut Signed-off-by: Gustavo Sampaio --- .../contrib/codelens/codelensCommands.ts | 67 +++++++++++++++++++ .../contrib/codelens/codelensController.ts | 28 +++++--- .../editor/contrib/codelens/codelensWidget.ts | 4 ++ 3 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/vs/editor/contrib/codelens/codelensCommands.ts diff --git a/src/vs/editor/contrib/codelens/codelensCommands.ts b/src/vs/editor/contrib/codelens/codelensCommands.ts new file mode 100644 index 00000000000..ef9fdaa3143 --- /dev/null +++ b/src/vs/editor/contrib/codelens/codelensCommands.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Command } from 'vs/editor/browser/editorExtensions'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { CodeLensContribution } from 'vs/editor/contrib/codelens/codelensController'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { INotificationService } from 'vs/platform/notification/common/notification'; + +export class ShowLensesInCurrentLineCommand extends Command { + public runCommand(accessor: ServicesAccessor, args: any): void | Promise { + const quickInputService = accessor.get(IQuickInputService); + const commandService = accessor.get(ICommandService); + const notificationService = accessor.get(INotificationService); + + const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor(); + if (!focusedEditor?.getSelection()?.isEmpty()) { + return; + } + const lineNumber = focusedEditor.getSelection()?.positionLineNumber; + const codelensController = focusedEditor.getContribution(CodeLensContribution.ID) as CodeLensContribution; + + const activeLensesWidgets = codelensController.getLenses().filter(lens => lens.getLineNumber() === lineNumber); + + const commandArguments: Map = new Map(); + + const picker = quickInputService.createQuickPick(); + const items: (IQuickPickItem | IQuickPickSeparator)[] = []; + + activeLensesWidgets.forEach(widget => { + widget.getItems().forEach(codelens => { + const command = codelens.symbol.command; + if (!command) { + return; + } + items.push({ id: command.id, label: command.title }); + + commandArguments.set(command.id, command.arguments); + }); + }); + + + console.log(items); + picker.items = items; + picker.canSelectMany = false; + picker.onDidAccept(_ => { + const selectedItems = picker.selectedItems; + if (selectedItems.length === 1) { + const id = selectedItems[0].id!; + + if (!id) { + picker.hide(); + return; + } + + commandService.executeCommand(id, ...(commandArguments.get(id) || [])).catch(err => notificationService.error(err)); + } + picker.hide(); + }); + picker.show(); + } + +} diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 2b4865134c3..696dd680f76 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -3,23 +3,24 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancelablePromise, RunOnceScheduler, createCancelablePromise, disposableTimeout } from 'vs/base/common/async'; +import * as dom from 'vs/base/browser/dom'; +import { CancelablePromise, createCancelablePromise, disposableTimeout, RunOnceScheduler } from 'vs/base/common/async'; import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors'; -import { toDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; +import { hash } from 'vs/base/common/hash'; +import { DisposableStore, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { StableEditorScrollState } from 'vs/editor/browser/core/editorState'; -import { ICodeEditor, MouseTargetType, IViewZoneChangeAccessor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { IActiveCodeEditor, ICodeEditor, IViewZoneChangeAccessor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; +import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; -import { CodeLensProviderRegistry, CodeLens } from 'vs/editor/common/modes'; -import { CodeLensModel, getCodeLensData, CodeLensItem } from 'vs/editor/contrib/codelens/codelens'; -import { CodeLensWidget, CodeLensHelper } from 'vs/editor/contrib/codelens/codelensWidget'; +import { CodeLens, CodeLensProviderRegistry } from 'vs/editor/common/modes'; +import { CodeLensItem, CodeLensModel, getCodeLensData } from 'vs/editor/contrib/codelens/codelens'; +import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; +import { ShowLensesInCurrentLineCommand } from 'vs/editor/contrib/codelens/codelensCommands'; +import { CodeLensHelper, CodeLensWidget } from 'vs/editor/contrib/codelens/codelensWidget'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; -import { EditorOption } from 'vs/editor/common/config/editorOptions'; -import * as dom from 'vs/base/browser/dom'; -import { hash } from 'vs/base/common/hash'; export class CodeLensContribution implements IEditorContribution { @@ -402,6 +403,13 @@ export class CodeLensContribution implements IEditorContribution { } }); } + + public getLenses(): CodeLensWidget[] { + return this._lenses; + } } registerEditorContribution(CodeLensContribution.ID, CodeLensContribution); + +const showLensesInCurrentLineCommand = new ShowLensesInCurrentLineCommand({ id: 'codelens.showLensesInCurrentLine', precondition: undefined }); +showLensesInCurrentLineCommand.register(); diff --git a/src/vs/editor/contrib/codelens/codelensWidget.ts b/src/vs/editor/contrib/codelens/codelensWidget.ts index 622e7785aaf..273fcfb7ea1 100644 --- a/src/vs/editor/contrib/codelens/codelensWidget.ts +++ b/src/vs/editor/contrib/codelens/codelensWidget.ts @@ -336,6 +336,10 @@ export class CodeLensWidget { } } } + + getItems(): CodeLensItem[] { + return this._data; + } } registerThemingParticipant((theme, collector) => { From 1731aa3c347da0e6a9c4927fcc0fd4bfac88e2e4 Mon Sep 17 00:00:00 2001 From: Gustavo Sampaio Date: Sun, 23 Feb 2020 16:51:27 -0300 Subject: [PATCH 002/137] Fix tests and remove cyclic dependencies Signed-off-by: Gustavo Sampaio --- .../contrib/codelens/codelensCommands.ts | 67 ------------------- .../contrib/codelens/codelensController.ts | 59 +++++++++++++++- .../platform/quickinput/common/quickInput.ts | 2 +- 3 files changed, 58 insertions(+), 70 deletions(-) delete mode 100644 src/vs/editor/contrib/codelens/codelensCommands.ts diff --git a/src/vs/editor/contrib/codelens/codelensCommands.ts b/src/vs/editor/contrib/codelens/codelensCommands.ts deleted file mode 100644 index ef9fdaa3143..00000000000 --- a/src/vs/editor/contrib/codelens/codelensCommands.ts +++ /dev/null @@ -1,67 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Command } from 'vs/editor/browser/editorExtensions'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { CodeLensContribution } from 'vs/editor/contrib/codelens/codelensController'; -import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { INotificationService } from 'vs/platform/notification/common/notification'; - -export class ShowLensesInCurrentLineCommand extends Command { - public runCommand(accessor: ServicesAccessor, args: any): void | Promise { - const quickInputService = accessor.get(IQuickInputService); - const commandService = accessor.get(ICommandService); - const notificationService = accessor.get(INotificationService); - - const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor(); - if (!focusedEditor?.getSelection()?.isEmpty()) { - return; - } - const lineNumber = focusedEditor.getSelection()?.positionLineNumber; - const codelensController = focusedEditor.getContribution(CodeLensContribution.ID) as CodeLensContribution; - - const activeLensesWidgets = codelensController.getLenses().filter(lens => lens.getLineNumber() === lineNumber); - - const commandArguments: Map = new Map(); - - const picker = quickInputService.createQuickPick(); - const items: (IQuickPickItem | IQuickPickSeparator)[] = []; - - activeLensesWidgets.forEach(widget => { - widget.getItems().forEach(codelens => { - const command = codelens.symbol.command; - if (!command) { - return; - } - items.push({ id: command.id, label: command.title }); - - commandArguments.set(command.id, command.arguments); - }); - }); - - - console.log(items); - picker.items = items; - picker.canSelectMany = false; - picker.onDidAccept(_ => { - const selectedItems = picker.selectedItems; - if (selectedItems.length === 1) { - const id = selectedItems[0].id!; - - if (!id) { - picker.hide(); - return; - } - - commandService.executeCommand(id, ...(commandArguments.get(id) || [])).catch(err => notificationService.error(err)); - } - picker.hide(); - }); - picker.show(); - } - -} diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 696dd680f76..6bf5613c964 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + import * as dom from 'vs/base/browser/dom'; import { CancelablePromise, createCancelablePromise, disposableTimeout, RunOnceScheduler } from 'vs/base/common/async'; import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors'; @@ -10,17 +11,18 @@ import { hash } from 'vs/base/common/hash'; import { DisposableStore, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { StableEditorScrollState } from 'vs/editor/browser/core/editorState'; import { IActiveCodeEditor, ICodeEditor, IViewZoneChangeAccessor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; -import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; +import { Command, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; import { CodeLens, CodeLensProviderRegistry } from 'vs/editor/common/modes'; import { CodeLensItem, CodeLensModel, getCodeLensData } from 'vs/editor/contrib/codelens/codelens'; import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; -import { ShowLensesInCurrentLineCommand } from 'vs/editor/contrib/codelens/codelensCommands'; import { CodeLensHelper, CodeLensWidget } from 'vs/editor/contrib/codelens/codelensWidget'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; export class CodeLensContribution implements IEditorContribution { @@ -409,6 +411,59 @@ export class CodeLensContribution implements IEditorContribution { } } +export class ShowLensesInCurrentLineCommand extends Command { + public runCommand(accessor: ServicesAccessor, args: any): void | Promise { + const quickInputService = accessor.get(IQuickInputService); + const commandService = accessor.get(ICommandService); + const notificationService = accessor.get(INotificationService); + + const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor(); + if (!focusedEditor?.getSelection()?.isEmpty()) { + return; + } + const lineNumber = focusedEditor.getSelection()?.positionLineNumber; + const codelensController = focusedEditor.getContribution(CodeLensContribution.ID) as CodeLensContribution; + + const activeLensesWidgets = codelensController.getLenses().filter(lens => lens.getLineNumber() === lineNumber); + + const commandArguments: Map = new Map(); + + const picker = quickInputService.createQuickPick(); + const items: (IQuickPickItem | IQuickPickSeparator)[] = []; + + activeLensesWidgets.forEach(widget => { + widget.getItems().forEach(codelens => { + const command = codelens.symbol.command; + if (!command) { + return; + } + items.push({ id: command.id, label: command.title }); + + commandArguments.set(command.id, command.arguments); + }); + }); + + picker.items = items; + picker.canSelectMany = false; + picker.onDidAccept(_ => { + const selectedItems = picker.selectedItems; + if (selectedItems.length === 1) { + const id = selectedItems[0].id!; + + if (!id) { + picker.hide(); + return; + } + + commandService.executeCommand(id, ...(commandArguments.get(id) || [])).catch(err => notificationService.error(err)); + } + picker.hide(); + }); + picker.show(); + } + +} + registerEditorContribution(CodeLensContribution.ID, CodeLensContribution); const showLensesInCurrentLineCommand = new ShowLensesInCurrentLineCommand({ id: 'codelens.showLensesInCurrentLine', precondition: undefined }); diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 5827452f6e4..33e122679db 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -7,7 +7,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { CancellationToken } from 'vs/base/common/cancellation'; import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInputButton, IInputBox, QuickPickInput } from 'vs/base/parts/quickinput/common/quickInput'; -export { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods } from 'vs/base/parts/quickinput/common/quickInput'; +export * from 'vs/base/parts/quickinput/common/quickInput'; export const IQuickInputService = createDecorator('quickInputService'); From 6b745dace77c2756313ef9d310ff60847c73d77d Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 5 Mar 2020 11:24:32 -0800 Subject: [PATCH 003/137] Use codicons in scm --- extensions/git/package.json | 90 ++++--------------- extensions/git/resources/icons/dark/check.svg | 3 - extensions/git/resources/icons/dark/clean.svg | 3 - extensions/git/resources/icons/dark/git.svg | 3 - .../git/resources/icons/dark/open-change.svg | 3 - .../git/resources/icons/dark/open-file.svg | 3 - .../git/resources/icons/dark/refresh.svg | 4 - extensions/git/resources/icons/dark/stage.svg | 3 - .../git/resources/icons/dark/unstage.svg | 3 - .../git/resources/icons/light/check.svg | 3 - .../git/resources/icons/light/clean.svg | 3 - extensions/git/resources/icons/light/git.svg | 3 - .../git/resources/icons/light/open-change.svg | 3 - .../git/resources/icons/light/open-file.svg | 3 - .../git/resources/icons/light/refresh.svg | 4 - .../git/resources/icons/light/stage.svg | 3 - .../git/resources/icons/light/unstage.svg | 3 - .../base/browser/ui/actionbar/actionbar.css | 4 + 18 files changed, 22 insertions(+), 122 deletions(-) delete mode 100644 extensions/git/resources/icons/dark/check.svg delete mode 100644 extensions/git/resources/icons/dark/clean.svg delete mode 100644 extensions/git/resources/icons/dark/git.svg delete mode 100644 extensions/git/resources/icons/dark/open-change.svg delete mode 100644 extensions/git/resources/icons/dark/open-file.svg delete mode 100644 extensions/git/resources/icons/dark/refresh.svg delete mode 100644 extensions/git/resources/icons/dark/stage.svg delete mode 100644 extensions/git/resources/icons/dark/unstage.svg delete mode 100644 extensions/git/resources/icons/light/check.svg delete mode 100644 extensions/git/resources/icons/light/clean.svg delete mode 100644 extensions/git/resources/icons/light/git.svg delete mode 100644 extensions/git/resources/icons/light/open-change.svg delete mode 100644 extensions/git/resources/icons/light/open-file.svg delete mode 100644 extensions/git/resources/icons/light/refresh.svg delete mode 100644 extensions/git/resources/icons/light/stage.svg delete mode 100644 extensions/git/resources/icons/light/unstage.svg diff --git a/extensions/git/package.json b/extensions/git/package.json index 5246020c6c2..e299d60c118 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -40,10 +40,7 @@ "command": "git.init", "title": "%command.init%", "category": "Git", - "icon": { - "light": "resources/icons/light/git.svg", - "dark": "resources/icons/dark/git.svg" - } + "icon": "$(add)" }, { "command": "git.openRepository", @@ -59,37 +56,25 @@ "command": "git.refresh", "title": "%command.refresh%", "category": "Git", - "icon": { - "light": "resources/icons/light/refresh.svg", - "dark": "resources/icons/dark/refresh.svg" - } + "icon": "$(refresh)" }, { "command": "git.openChange", "title": "%command.openChange%", "category": "Git", - "icon": { - "light": "resources/icons/light/open-change.svg", - "dark": "resources/icons/dark/open-change.svg" - } + "icon": "$(compare-changes)" }, { "command": "git.openFile", "title": "%command.openFile%", "category": "Git", - "icon": { - "light": "resources/icons/light/open-file.svg", - "dark": "resources/icons/dark/open-file.svg" - } + "icon": "$(go-to-file)" }, { "command": "git.openFile2", "title": "%command.openFile%", "category": "Git", - "icon": { - "light": "resources/icons/light/open-file.svg", - "dark": "resources/icons/dark/open-file.svg" - } + "icon": "$(go-to-file)" }, { "command": "git.openHEADFile", @@ -100,37 +85,25 @@ "command": "git.stage", "title": "%command.stage%", "category": "Git", - "icon": { - "light": "resources/icons/light/stage.svg", - "dark": "resources/icons/dark/stage.svg" - } + "icon": "$(add)" }, { "command": "git.stageAll", "title": "%command.stageAll%", "category": "Git", - "icon": { - "light": "resources/icons/light/stage.svg", - "dark": "resources/icons/dark/stage.svg" - } + "icon": "$(add)" }, { "command": "git.stageAllTracked", "title": "%command.stageAllTracked%", "category": "Git", - "icon": { - "light": "resources/icons/light/stage.svg", - "dark": "resources/icons/dark/stage.svg" - } + "icon": "$(add)" }, { "command": "git.stageAllUntracked", "title": "%command.stageAllUntracked%", "category": "Git", - "icon": { - "light": "resources/icons/light/stage.svg", - "dark": "resources/icons/dark/stage.svg" - } + "icon": "$(add)" }, { "command": "git.stageSelectedRanges", @@ -146,37 +119,25 @@ "command": "git.stageChange", "title": "%command.stageChange%", "category": "Git", - "icon": { - "light": "resources/icons/light/stage.svg", - "dark": "resources/icons/dark/stage.svg" - } + "icon": "$(add)" }, { "command": "git.revertChange", "title": "%command.revertChange%", "category": "Git", - "icon": { - "light": "resources/icons/light/clean.svg", - "dark": "resources/icons/dark/clean.svg" - } + "icon": "$(discard)" }, { "command": "git.unstage", "title": "%command.unstage%", "category": "Git", - "icon": { - "light": "resources/icons/light/unstage.svg", - "dark": "resources/icons/dark/unstage.svg" - } + "icon": "$(remove)" }, { "command": "git.unstageAll", "title": "%command.unstageAll%", "category": "Git", - "icon": { - "light": "resources/icons/light/unstage.svg", - "dark": "resources/icons/dark/unstage.svg" - } + "icon": "$(remove)" }, { "command": "git.unstageSelectedRanges", @@ -187,46 +148,31 @@ "command": "git.clean", "title": "%command.clean%", "category": "Git", - "icon": { - "light": "resources/icons/light/clean.svg", - "dark": "resources/icons/dark/clean.svg" - } + "icon": "$(discard)" }, { "command": "git.cleanAll", "title": "%command.cleanAll%", "category": "Git", - "icon": { - "light": "resources/icons/light/clean.svg", - "dark": "resources/icons/dark/clean.svg" - } + "icon": "$(discard)" }, { "command": "git.cleanAllTracked", "title": "%command.cleanAllTracked%", "category": "Git", - "icon": { - "light": "resources/icons/light/clean.svg", - "dark": "resources/icons/dark/clean.svg" - } + "icon": "$(discard)" }, { "command": "git.cleanAllUntracked", "title": "%command.cleanAllUntracked%", "category": "Git", - "icon": { - "light": "resources/icons/light/clean.svg", - "dark": "resources/icons/dark/clean.svg" - } + "icon": "$(discard)" }, { "command": "git.commit", "title": "%command.commit%", "category": "Git", - "icon": { - "light": "resources/icons/light/check.svg", - "dark": "resources/icons/dark/check.svg" - } + "icon": "$(check)" }, { "command": "git.commitStaged", diff --git a/extensions/git/resources/icons/dark/check.svg b/extensions/git/resources/icons/dark/check.svg deleted file mode 100644 index 2d16f390078..00000000000 --- a/extensions/git/resources/icons/dark/check.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/dark/clean.svg b/extensions/git/resources/icons/dark/clean.svg deleted file mode 100644 index de85d6ba679..00000000000 --- a/extensions/git/resources/icons/dark/clean.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/dark/git.svg b/extensions/git/resources/icons/dark/git.svg deleted file mode 100644 index 4d9389336b9..00000000000 --- a/extensions/git/resources/icons/dark/git.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/dark/open-change.svg b/extensions/git/resources/icons/dark/open-change.svg deleted file mode 100644 index 41ebc85a8c8..00000000000 --- a/extensions/git/resources/icons/dark/open-change.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/dark/open-file.svg b/extensions/git/resources/icons/dark/open-file.svg deleted file mode 100644 index ed302ae1398..00000000000 --- a/extensions/git/resources/icons/dark/open-file.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/dark/refresh.svg b/extensions/git/resources/icons/dark/refresh.svg deleted file mode 100644 index e1f05aadeeb..00000000000 --- a/extensions/git/resources/icons/dark/refresh.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/extensions/git/resources/icons/dark/stage.svg b/extensions/git/resources/icons/dark/stage.svg deleted file mode 100644 index 4d9389336b9..00000000000 --- a/extensions/git/resources/icons/dark/stage.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/dark/unstage.svg b/extensions/git/resources/icons/dark/unstage.svg deleted file mode 100644 index 4c5a9c1e3a5..00000000000 --- a/extensions/git/resources/icons/dark/unstage.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/check.svg b/extensions/git/resources/icons/light/check.svg deleted file mode 100644 index a9f8aa131b5..00000000000 --- a/extensions/git/resources/icons/light/check.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/clean.svg b/extensions/git/resources/icons/light/clean.svg deleted file mode 100644 index b70626957d0..00000000000 --- a/extensions/git/resources/icons/light/clean.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/git.svg b/extensions/git/resources/icons/light/git.svg deleted file mode 100644 index 01a9de7d5ab..00000000000 --- a/extensions/git/resources/icons/light/git.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/open-change.svg b/extensions/git/resources/icons/light/open-change.svg deleted file mode 100644 index 772c3c198fc..00000000000 --- a/extensions/git/resources/icons/light/open-change.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/open-file.svg b/extensions/git/resources/icons/light/open-file.svg deleted file mode 100644 index 392a840c5ef..00000000000 --- a/extensions/git/resources/icons/light/open-file.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/refresh.svg b/extensions/git/resources/icons/light/refresh.svg deleted file mode 100644 index 9b1d9108409..00000000000 --- a/extensions/git/resources/icons/light/refresh.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/extensions/git/resources/icons/light/stage.svg b/extensions/git/resources/icons/light/stage.svg deleted file mode 100644 index 01a9de7d5ab..00000000000 --- a/extensions/git/resources/icons/light/stage.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/extensions/git/resources/icons/light/unstage.svg b/extensions/git/resources/icons/light/unstage.svg deleted file mode 100644 index d12a8ee3135..00000000000 --- a/extensions/git/resources/icons/light/unstage.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/base/browser/ui/actionbar/actionbar.css b/src/vs/base/browser/ui/actionbar/actionbar.css index 623ff4d7421..a8ab18355b9 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.css +++ b/src/vs/base/browser/ui/actionbar/actionbar.css @@ -45,6 +45,10 @@ display: inline-block; } +.monaco-action-bar .action-item .codicon { + vertical-align: middle; +} + .monaco-action-bar .action-label { font-size: 11px; margin-right: 4px; From a59fd7a5726933179a4d221f3e20010ca436f168 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 5 Mar 2020 22:18:27 +0100 Subject: [PATCH 004/137] product icons themes, first --- .../themes/browser/fileIconThemeData.ts | 17 +- .../themes/browser/productIconThemeData.ts | 236 +++++++++++++ .../themes/browser/workbenchThemeService.ts | 313 +++++++++++------- .../services/themes/common/colorThemeData.ts | 14 +- .../themes/common/productIconThemeSchema.ts | 91 +++++ .../themes/common/themeConfiguration.ts | 74 +++-- .../themes/common/themeExtensionPoints.ts | 31 +- .../themes/common/workbenchThemeService.ts | 20 +- 8 files changed, 646 insertions(+), 150 deletions(-) create mode 100644 src/vs/workbench/services/themes/browser/productIconThemeData.ts create mode 100644 src/vs/workbench/services/themes/common/productIconThemeSchema.ts diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index 0c028fe722f..3cd45716954 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -12,6 +12,9 @@ import { ExtensionData, IThemeExtensionPoint, IWorkbenchFileIconTheme } from 'vs import { IFileService } from 'vs/platform/files/common/files'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; import { asCSSUrl } from 'vs/base/browser/dom'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; + +const PERSISTED_FILE_ICON_THEME_STORAGE_KEY = 'iconThemeData'; export class FileIconThemeData implements IWorkbenchFileIconTheme { id: string; @@ -103,7 +106,12 @@ export class FileIconThemeData implements IWorkbenchFileIconTheme { return themeData; } - static fromStorageData(input: string): FileIconThemeData | null { + + static fromStorageData(storageService: IStorageService): FileIconThemeData | undefined { + const input = storageService.get(PERSISTED_FILE_ICON_THEME_STORAGE_KEY, StorageScope.GLOBAL); + if (!input) { + return undefined; + } try { let data = JSON.parse(input); const theme = new FileIconThemeData('', '', null); @@ -128,12 +136,12 @@ export class FileIconThemeData implements IWorkbenchFileIconTheme { } return theme; } catch (e) { - return null; + return undefined; } } - toStorageData() { - return JSON.stringify({ + toStorage(storageService: IStorageService) { + const data = JSON.stringify({ id: this.id, label: this.label, description: this.description, @@ -145,6 +153,7 @@ export class FileIconThemeData implements IWorkbenchFileIconTheme { hidesExplorerArrows: this.hidesExplorerArrows, watch: this.watch }); + storageService.store(PERSISTED_FILE_ICON_THEME_STORAGE_KEY, data, StorageScope.GLOBAL); } } diff --git a/src/vs/workbench/services/themes/browser/productIconThemeData.ts b/src/vs/workbench/services/themes/browser/productIconThemeData.ts new file mode 100644 index 00000000000..21d2a44033a --- /dev/null +++ b/src/vs/workbench/services/themes/browser/productIconThemeData.ts @@ -0,0 +1,236 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { URI } from 'vs/base/common/uri'; +import * as nls from 'vs/nls'; +import * as Paths from 'vs/base/common/path'; +import * as resources from 'vs/base/common/resources'; +import * as Json from 'vs/base/common/json'; +import { ExtensionData, IThemeExtensionPoint, IWorkbenchProductIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; +import { asCSSUrl } from 'vs/base/browser/dom'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE } from 'vs/workbench/services/themes/common/themeConfiguration'; + +const PERSISTED_PRODUCT_ICON_THEME_STORAGE_KEY = 'productIconThemeData'; + +export const DEFAULT_PRODUCT_ICON_THEME_ID = ''; // TODO + +export class ProductIconThemeData implements IWorkbenchProductIconTheme { + id: string; + label: string; + settingsId: string; + description?: string; + isLoaded: boolean; + location?: URI; + extensionData?: ExtensionData; + watch?: boolean; + + styleSheetContent?: string; + + private constructor(id: string, label: string, settingsId: string) { + this.id = id; + this.label = label; + this.settingsId = settingsId; + this.isLoaded = false; + } + + public ensureLoaded(fileService: IFileService): Promise { + return !this.isLoaded ? this.load(fileService) : Promise.resolve(this.styleSheetContent); + } + + public reload(fileService: IFileService): Promise { + return this.load(fileService); + } + + private load(fileService: IFileService): Promise { + if (!this.location) { + return Promise.resolve(this.styleSheetContent); + } + return _loadProductIconThemeDocument(fileService, this.location).then(iconThemeDocument => { + const result = _processIconThemeDocument(this.id, this.location!, iconThemeDocument); + this.styleSheetContent = result.content; + this.isLoaded = true; + return this.styleSheetContent; + }); + } + + static fromExtensionTheme(iconTheme: IThemeExtensionPoint, iconThemeLocation: URI, extensionData: ExtensionData): ProductIconThemeData { + const id = extensionData.extensionId + '-' + iconTheme.id; + const label = iconTheme.label || Paths.basename(iconTheme.path); + const settingsId = iconTheme.id; + + const themeData = new ProductIconThemeData(id, label, settingsId); + + themeData.description = iconTheme.description; + themeData.location = iconThemeLocation; + themeData.extensionData = extensionData; + themeData.watch = iconTheme._watch; + themeData.isLoaded = false; + return themeData; + } + + static createUnloadedTheme(id: string): ProductIconThemeData { + const themeData = new ProductIconThemeData(id, '', '__' + id); + themeData.isLoaded = false; + themeData.extensionData = undefined; + themeData.watch = false; + return themeData; + } + + private static _defaultProductIconTheme: ProductIconThemeData | null = null; + + static defaultTheme(): ProductIconThemeData { + let themeData = ProductIconThemeData._defaultProductIconTheme; + if (!themeData) { + themeData = ProductIconThemeData._defaultProductIconTheme = new ProductIconThemeData(DEFAULT_PRODUCT_ICON_THEME_ID, nls.localize('defaultTheme', 'Default theme'), DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE); + themeData.isLoaded = true; + themeData.extensionData = undefined; + themeData.watch = false; + } + return themeData; + } + + static fromStorageData(storageService: IStorageService): ProductIconThemeData | undefined { + const input = storageService.get(PERSISTED_PRODUCT_ICON_THEME_STORAGE_KEY, StorageScope.GLOBAL); + if (!input) { + return undefined; + } + try { + let data = JSON.parse(input); + const theme = new ProductIconThemeData('', '', ''); + for (let key in data) { + switch (key) { + case 'id': + case 'label': + case 'description': + case 'settingsId': + case 'extensionData': + case 'styleSheetContent': + case 'watch': + (theme as any)[key] = data[key]; + break; + case 'location': + theme.location = URI.revive(data.location); + break; + } + } + return theme; + } catch (e) { + return undefined; + } + } + + toStorage(storageService: IStorageService) { + const data = JSON.stringify({ + id: this.id, + label: this.label, + description: this.description, + settingsId: this.settingsId, + location: this.location, + styleSheetContent: this.styleSheetContent, + watch: this.watch + }); + storageService.store(PERSISTED_PRODUCT_ICON_THEME_STORAGE_KEY, data, StorageScope.GLOBAL); + } +} + +interface IconDefinition { + fontCharacter: string; + fontId: string; +} + +interface FontDefinition { + id: string; + weight: string; + style: string; + size: string; + src: { path: string; format: string; }[]; +} + +interface ProductIconThemeDocument { + iconDefinitions: { [key: string]: IconDefinition }; + fonts: FontDefinition[]; +} + +function _loadProductIconThemeDocument(fileService: IFileService, location: URI): Promise { + return fileService.readFile(location).then((content) => { + let errors: Json.ParseError[] = []; + let contentValue = Json.parse(content.value.toString(), errors); + if (errors.length > 0) { + return Promise.reject(new Error(nls.localize('error.cannotparseicontheme', "Problems parsing product icons file: {0}", errors.map(e => getParseErrorMessage(e.error)).join(', ')))); + } else if (Json.getNodeType(contentValue) !== 'object') { + return Promise.reject(new Error(nls.localize('error.invalidformat', "Invalid format for product icons theme file: Object expected."))); + } else if (!contentValue.iconDefinitions || !Array.isArray(contentValue.fonts) || !contentValue.fonts.length) { + return Promise.reject(new Error(nls.localize('error.missingProperties', "Invalid format for product icons theme file: Must contain iconDefinitions and fonts."))); + } + return Promise.resolve(contentValue); + }); +} + +function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, iconThemeDocument: ProductIconThemeDocument): { content: string; } { + + const result = { content: '' }; + + if (!iconThemeDocument.iconDefinitions || !Array.isArray(iconThemeDocument.fonts) || !iconThemeDocument.fonts.length) { + return result; + } + + const iconThemeDocumentLocationDirname = resources.dirname(iconThemeDocumentLocation); + function resolvePath(path: string) { + return resources.joinPath(iconThemeDocumentLocationDirname, path); + } + + let cssRules: string[] = []; + + let fonts = iconThemeDocument.fonts; + for (const font of fonts) { + const src = font.src.map(l => `${asCSSUrl(resolvePath(l.path))} format('${l.format}')`).join(', '); + cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; }`); + } + + let primaryFontId = fonts[0].id; + let iconDefinitions = iconThemeDocument.iconDefinitions; + for (const iconId in iconThemeDocument.iconDefinitions) { + const definition = iconDefinitions[iconId]; + if (definition && definition.fontCharacter) { + cssRules.push(`.codicon-${iconId}:before { content: '${definition.fontCharacter}' !important; font-family: ${definition.fontId || primaryFontId} !important; }`); + } + } + result.content = cssRules.join('\n'); + return result; +} + +/* +@font-face { + font-family: "codicon"; + src: url("./codicon.ttf?b5dd8f5aa953889dc1f4c9fa9b44d3dd") format("truetype"); +} + +.codicon[class*='codicon-'] { + font: normal normal normal 16px/1 codicon; + display: inline-block; + text-decoration: none; + text-rendering: auto; + text-align: center; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + + +.codicon-add:before { content: "\ea60" } +.codicon-plus:before { content: "\ea60" } +.codicon-gist-new:before { content: "\ea60" } +.codicon-repo-create:before { content: "\ea60" } +.codicon-lightbulb:before { content: "\ea61" } +.codicon-light-bulb:before { content: "\ea61" } +.codicon-repo:before { content: "\ea62" } +.codicon-repo-delete:before { content: "\ea62" } +.codicon-gist-fork:before { content: "\ea63" } +*/ diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 1742e39a855..9f5bb2c1ba2 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import * as types from 'vs/base/common/types'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IWorkbenchThemeService, IWorkbenchColorTheme, IWorkbenchFileIconTheme, ExtensionData, VS_LIGHT_THEME, VS_DARK_THEME, VS_HC_THEME, ThemeSettings } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IWorkbenchThemeService, IWorkbenchColorTheme, IWorkbenchFileIconTheme, ExtensionData, VS_LIGHT_THEME, VS_DARK_THEME, VS_HC_THEME, ThemeSettings, IWorkbenchProductIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -28,25 +28,26 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; -import { ThemeRegistry, registerColorThemeExtensionPoint, registerFileIconThemeExtensionPoint } from 'vs/workbench/services/themes/common/themeExtensionPoints'; -import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationSchemas, ThemeConfiguration } from 'vs/workbench/services/themes/common/themeConfiguration'; +import { ThemeRegistry, registerColorThemeExtensionPoint, registerFileIconThemeExtensionPoint, registerProductIconThemeExtensionPoint } from 'vs/workbench/services/themes/common/themeExtensionPoints'; +import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationSchemas, ThemeConfiguration, updateProductIconThemeConfigurationSchemas } from 'vs/workbench/services/themes/common/themeConfiguration'; +import { ProductIconThemeData, DEFAULT_PRODUCT_ICON_THEME_ID } from 'vs/workbench/services/themes/browser/productIconThemeData'; +import { registerProductIconThemeSchemas } from 'vs/workbench/services/themes/common/productIconThemeSchema'; // implementation -const DEFAULT_THEME_ID = 'vs-dark vscode-theme-defaults-themes-dark_plus-json'; +const DEFAULT_COLOR_THEME_ID = 'vs-dark vscode-theme-defaults-themes-dark_plus-json'; -const PERSISTED_THEME_STORAGE_KEY = 'colorThemeData'; -const PERSISTED_ICON_THEME_STORAGE_KEY = 'iconThemeData'; const PERSISTED_OS_COLOR_SCHEME = 'osColorScheme'; const defaultThemeExtensionId = 'vscode-theme-defaults'; const oldDefaultThemeExtensionId = 'vscode-theme-colorful-defaults'; -const DEFAULT_ICON_THEME_ID = 'vscode.vscode-theme-seti-vs-seti'; +const DEFAULT_FILE_ICON_THEME_ID = 'vscode.vscode-theme-seti-vs-seti'; const fileIconsEnabledClass = 'file-icons-enabled'; const colorThemeRulesClassName = 'contributedColorTheme'; -const iconThemeRulesClassName = 'contributedIconTheme'; +const fileIconThemeRulesClassName = 'contributedFileIconTheme'; +const productIconThemeRulesClassName = 'contributedProductIconTheme'; const themingRegistry = Registry.as(ThemingExtensions.ThemingContribution); @@ -64,13 +65,16 @@ function validateThemeId(theme: string): string { const colorThemesExtPoint = registerColorThemeExtensionPoint(); const fileIconThemesExtPoint = registerFileIconThemeExtensionPoint(); +const productIconThemesExtPoint = registerProductIconThemeExtensionPoint(); export class WorkbenchThemeService implements IWorkbenchThemeService { _serviceBrand: undefined; + private readonly container: HTMLElement; + private settings: ThemeConfiguration; + private readonly colorThemeRegistry: ThemeRegistry; private currentColorTheme: ColorThemeData; - private readonly container: HTMLElement; private readonly onColorThemeChange: Emitter; private readonly colorThemeWatcher: ThemeFileWatcher; private colorThemingParticipantChangeListener: IDisposable | undefined; @@ -80,7 +84,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { private readonly onFileIconThemeChange: Emitter; private readonly fileIconThemeWatcher: ThemeFileWatcher; - private settings: ThemeConfiguration; + private readonly productIconThemeRegistry: ThemeRegistry; + private currentProductIconTheme: ProductIconThemeData; + private readonly onProductIconThemeChange: Emitter; + private readonly productIconThemeWatcher: ThemeFileWatcher; constructor( @IExtensionService extensionService: IExtensionService, @@ -96,23 +103,24 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.settings = new ThemeConfiguration(configurationService); this.colorThemeRegistry = new ThemeRegistry(extensionService, colorThemesExtPoint, ColorThemeData.fromExtensionTheme); - this.colorThemeWatcher = new ThemeFileWatcher(fileService, environmentService, () => this.reloadCurrentColorTheme()); + this.colorThemeWatcher = new ThemeFileWatcher(fileService, environmentService, this.reloadCurrentColorTheme.bind(this)); this.onColorThemeChange = new Emitter({ leakWarningThreshold: 400 }); this.currentColorTheme = ColorThemeData.createUnloadedTheme(''); - this.fileIconThemeWatcher = new ThemeFileWatcher(fileService, environmentService, () => this.reloadCurrentFileIconTheme()); + this.fileIconThemeWatcher = new ThemeFileWatcher(fileService, environmentService, this.reloadCurrentFileIconTheme.bind(this)); this.fileIconThemeRegistry = new ThemeRegistry(extensionService, fileIconThemesExtPoint, FileIconThemeData.fromExtensionTheme, true); this.onFileIconThemeChange = new Emitter(); this.currentFileIconTheme = FileIconThemeData.createUnloadedTheme(''); + this.productIconThemeWatcher = new ThemeFileWatcher(fileService, environmentService, this.reloadCurrentProductIconTheme.bind(this)); + this.productIconThemeRegistry = new ThemeRegistry(extensionService, productIconThemesExtPoint, ProductIconThemeData.fromExtensionTheme, true); + this.onProductIconThemeChange = new Emitter(); + this.currentProductIconTheme = ProductIconThemeData.createUnloadedTheme(''); + // In order to avoid paint flashing for tokens, because // themes are loaded asynchronously, we need to initialize // a color theme document with good defaults until the theme is loaded - let themeData: ColorThemeData | undefined = undefined; - let persistedThemeData = this.storageService.get(PERSISTED_THEME_STORAGE_KEY, StorageScope.GLOBAL); - if (persistedThemeData) { - themeData = ColorThemeData.fromStorageData(persistedThemeData); - } + let themeData: ColorThemeData | undefined = ColorThemeData.fromStorageData(this.storageService); const containerBaseTheme = this.getBaseThemeFromContainer(); if (!themeData || themeData.baseTheme !== containerBaseTheme) { themeData = ColorThemeData.createUnloadedTheme(containerBaseTheme); @@ -123,15 +131,16 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.updateDynamicCSSRules(themeData); this.applyTheme(themeData, undefined, true); - const persistedIconThemeData = this.storageService.get(PERSISTED_ICON_THEME_STORAGE_KEY, StorageScope.GLOBAL); - if (persistedIconThemeData) { - const iconData = FileIconThemeData.fromStorageData(persistedIconThemeData); - if (iconData) { - _applyIconTheme(iconData, () => { - this.doSetFileIconTheme(iconData); - return Promise.resolve(iconData); - }); - } + const fileIconData = FileIconThemeData.fromStorageData(this.storageService); + if (fileIconData) { + _applyRules(fileIconData.styleSheetContent!, fileIconThemeRulesClassName); + this.doSetFileIconTheme(fileIconData); + } + + const productIconData = ProductIconThemeData.fromStorageData(this.storageService); + if (productIconData) { + _applyRules(productIconData.styleSheetContent!, productIconThemeRulesClassName); + this.doSetProductIconTheme(productIconData); } this.initialize().then(undefined, errors.onUnexpectedError).then(_ => { @@ -159,10 +168,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (!themeData) { // current theme is no longer available prevColorId = this.currentColorTheme.id; - this.setColorTheme(DEFAULT_THEME_ID, 'auto'); + this.setColorTheme(DEFAULT_COLOR_THEME_ID, 'auto'); } else { - if (this.currentColorTheme.id === DEFAULT_THEME_ID && !types.isUndefined(prevColorId) && await this.colorThemeRegistry.findThemeById(prevColorId)) { - // restore color + if (this.currentColorTheme.id === DEFAULT_COLOR_THEME_ID && !types.isUndefined(prevColorId) && await this.colorThemeRegistry.findThemeById(prevColorId)) { + // restore theme this.setColorTheme(prevColorId, 'auto'); prevColorId = undefined; } else { @@ -176,30 +185,37 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.fileIconThemeRegistry.onDidChange(async event => { updateFileIconThemeConfigurationSchemas(event.themes); - const iconThemeSetting = this.settings.fileIconTheme; - if (iconThemeSetting !== this.currentFileIconTheme.settingsId) { - const theme = await this.findFileIconThemeBySettingId(iconThemeSetting); - if (theme) { - this.setFileIconTheme(theme.id, undefined); - return; - } - } - - if (this.currentFileIconTheme.isLoaded) { - const theme = await this.findFileIconThemeById(this.currentFileIconTheme.id); - if (!theme) { - // current theme is no longer available - prevFileIconId = this.currentFileIconTheme.id; - this.setFileIconTheme(DEFAULT_ICON_THEME_ID, 'auto'); + if (!await this.restoreFileIconTheme()) { // checks if theme from settings exists and is set + // restore theme + if (this.currentFileIconTheme.id === DEFAULT_FILE_ICON_THEME_ID && !types.isUndefined(prevFileIconId) && await this.findFileIconThemeById(prevFileIconId)) { + this.setFileIconTheme(prevFileIconId, 'auto'); + prevFileIconId = undefined; } else { - // restore color - if (this.currentFileIconTheme.id === DEFAULT_ICON_THEME_ID && !types.isUndefined(prevFileIconId) && await this.findFileIconThemeById(prevFileIconId)) { - this.setFileIconTheme(prevFileIconId, 'auto'); - prevFileIconId = undefined; - } else { - this.reloadCurrentFileIconTheme(); - } + this.reloadCurrentFileIconTheme(); } + } else { + // current theme is no longer available + prevFileIconId = this.currentFileIconTheme.id; + this.setFileIconTheme(DEFAULT_FILE_ICON_THEME_ID, 'auto'); + } + }); + + let prevProductIconId: string | undefined = undefined; + this.productIconThemeRegistry.onDidChange(async event => { + updateProductIconThemeConfigurationSchemas(event.themes); + + if (await this.restoreProductIconTheme()) { // checks if theme from settings exists and is set + // restore theme + if (this.currentProductIconTheme.id === DEFAULT_PRODUCT_ICON_THEME_ID && !types.isUndefined(prevProductIconId) && await this.findProductIconThemeById(prevProductIconId)) { + this.setProductIconTheme(prevProductIconId, 'auto'); + prevProductIconId = undefined; + } else { + this.reloadCurrentProductIconTheme(); + } + } else { + // current theme is no longer available + prevProductIconId = this.currentProductIconTheme.id; + this.setProductIconTheme(DEFAULT_PRODUCT_ICON_THEME_ID, 'auto'); } }); } @@ -212,17 +228,20 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.onFileIconThemeChange.event; } - private initialize(): Promise<[IWorkbenchColorTheme | null, IWorkbenchFileIconTheme | null]> { + public get onDidProductIconThemeChange(): Event { + return this.onProductIconThemeChange.event; + } + + private initialize(): Promise<[IWorkbenchColorTheme | null, IWorkbenchFileIconTheme | null, IWorkbenchProductIconTheme | null]> { const extDevLocs = this.environmentService.extensionDevelopmentLocationURI; + const extDevLoc = extDevLocs && extDevLocs.length === 1 ? extDevLocs[0] : undefined; // in dev mode, switch to a theme provided by the extension under dev. const initializeColorTheme = async () => { - if (extDevLocs && extDevLocs.length === 1) { // in dev mode, switch to a theme provided by the extension under dev. - const devThemes = await this.colorThemeRegistry.findThemeByExtensionLocation(extDevLocs[0]); - if (devThemes.length) { - return this.setColorTheme(devThemes[0].id, ConfigurationTarget.MEMORY); - } + const devThemes = await this.colorThemeRegistry.findThemeByExtensionLocation(extDevLoc); + if (devThemes.length) { + return this.setColorTheme(devThemes[0].id, ConfigurationTarget.MEMORY); } - const theme = await this.colorThemeRegistry.findThemeBySettingsId(this.settings.colorTheme, DEFAULT_THEME_ID); + const theme = await this.colorThemeRegistry.findThemeBySettingsId(this.settings.colorTheme, DEFAULT_COLOR_THEME_ID); const persistedColorScheme = this.storageService.get(PERSISTED_OS_COLOR_SCHEME, StorageScope.GLOBAL); const preferredColorScheme = this.getPreferredColorScheme(); @@ -232,31 +251,31 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.setColorTheme(theme && theme.id, undefined); }; - const initializeIconTheme = async () => { - if (extDevLocs && extDevLocs.length === 1) { // in dev mode, switch to a theme provided by the extension under dev. - const devThemes = await this.fileIconThemeRegistry.findThemeByExtensionLocation(extDevLocs[0]); - if (devThemes.length) { - return this.setFileIconTheme(devThemes[0].id, ConfigurationTarget.MEMORY); - } + const initializeFileIconTheme = async () => { + const devThemes = await this.fileIconThemeRegistry.findThemeByExtensionLocation(extDevLoc); + if (devThemes.length) { + return this.setFileIconTheme(devThemes[0].id, ConfigurationTarget.MEMORY); } - const theme = await this.findFileIconThemeBySettingId(this.settings.fileIconTheme); - return this.setFileIconTheme(theme ? theme.id : DEFAULT_ICON_THEME_ID, undefined); + const theme = await this.findFileIconThemeBySettingsId(this.settings.fileIconTheme); + return this.setFileIconTheme(theme ? theme.id : DEFAULT_FILE_ICON_THEME_ID, undefined); }; - return Promise.all([initializeColorTheme(), initializeIconTheme()]); + const initializeProductIconTheme = async () => { + const devThemes = await this.productIconThemeRegistry.findThemeByExtensionLocation(extDevLoc); + if (devThemes.length) { + return this.setProductIconTheme(devThemes[0].id, ConfigurationTarget.MEMORY); + } + const theme = await this.findProductIconThemeBySettingsId(this.settings.productIconTheme); + return this.setProductIconTheme(theme ? theme.id : DEFAULT_PRODUCT_ICON_THEME_ID, undefined); + }; + + return Promise.all([initializeColorTheme(), initializeFileIconTheme(), initializeProductIconTheme()]); } private installConfigurationListener() { this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(ThemeSettings.COLOR_THEME)) { - const colorThemeSetting = this.settings.colorTheme; - if (colorThemeSetting !== this.currentColorTheme.settingsId) { - this.colorThemeRegistry.findThemeBySettingsId(colorThemeSetting, undefined).then(theme => { - if (theme) { - this.setColorTheme(theme.id, undefined); - } - }); - } + this.restoreColorTheme(); } if (e.affectsConfiguration(ThemeSettings.DETECT_COLOR_SCHEME)) { this.handlePreferredSchemeUpdated(); @@ -271,12 +290,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.applyPreferredColorTheme(HIGH_CONTRAST); } if (e.affectsConfiguration(ThemeSettings.ICON_THEME)) { - const iconThemeSetting = this.settings.fileIconTheme; - if (iconThemeSetting !== this.currentFileIconTheme.settingsId) { - this.findFileIconThemeBySettingId(iconThemeSetting).then(theme => { - this.setFileIconTheme(theme ? theme.id : DEFAULT_ICON_THEME_ID, undefined); - }); - } + this.restoreFileIconTheme(); + } + if (e.affectsConfiguration(ThemeSettings.PRODUCT_ICON_THEME)) { + this.restoreProductIconTheme(); } if (this.currentColorTheme) { let hasColorChanges = false; @@ -360,7 +377,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { themeId = validateThemeId(themeId); // migrate theme ids - return this.colorThemeRegistry.findThemeById(themeId, DEFAULT_THEME_ID).then(themeData => { + return this.colorThemeRegistry.findThemeById(themeId, DEFAULT_COLOR_THEME_ID).then(themeData => { if (!themeData) { return null; } @@ -444,7 +461,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { // remember theme data for a quick restore if (newTheme.isLoaded) { - this.storageService.store(PERSISTED_THEME_STORAGE_KEY, newTheme.toStorageData(), StorageScope.GLOBAL); + newTheme.toStorage(this.storageService); } return this.settings.setColorTheme(this.currentColorTheme, settingsTarget); @@ -490,55 +507,52 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.currentFileIconTheme; } - public setFileIconTheme(iconTheme: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { + public async setFileIconTheme(iconTheme: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { iconTheme = iconTheme || ''; if (iconTheme === this.currentFileIconTheme.id && this.currentFileIconTheme.isLoaded) { - return this.settings.setFileIconTheme(this.currentFileIconTheme, settingsTarget); + await this.settings.setFileIconTheme(this.currentFileIconTheme, settingsTarget); + return this.currentFileIconTheme; } - const onApply = (newIconTheme: FileIconThemeData) => { - this.doSetFileIconTheme(newIconTheme); - // remember theme data for a quick restore - if (newIconTheme.isLoaded && (!newIconTheme.location || !getRemoteAuthority(newIconTheme.location))) { - this.storageService.store(PERSISTED_ICON_THEME_STORAGE_KEY, newIconTheme.toStorageData(), StorageScope.GLOBAL); - } + const newThemeData = (await this.findFileIconThemeById(iconTheme)) || FileIconThemeData.noIconTheme(); + await newThemeData.ensureLoaded(this.fileService); + _applyRules(newThemeData.styleSheetContent!, fileIconThemeRulesClassName); - return this.settings.setFileIconTheme(this.currentFileIconTheme, settingsTarget); - }; + this.doSetFileIconTheme(newThemeData); - return this.findFileIconThemeById(iconTheme).then(data => { - const iconThemeData = data || FileIconThemeData.noIconTheme(); - return iconThemeData.ensureLoaded(this.fileService).then(_ => { - return _applyIconTheme(iconThemeData, onApply); - }); - }); + // remember theme data for a quick restore + if (newThemeData.isLoaded && (!newThemeData.location || !getRemoteAuthority(newThemeData.location))) { + newThemeData.toStorage(this.storageService); + } + await this.settings.setFileIconTheme(this.currentFileIconTheme, settingsTarget); + + return newThemeData; } private async findFileIconThemeById(id: string): Promise { return id.length === 0 ? FileIconThemeData.noIconTheme() : this.fileIconThemeRegistry.findThemeById(id); } - private async findFileIconThemeBySettingId(settingsId: string | null): Promise { + private async findFileIconThemeBySettingsId(settingsId: string | null): Promise { return !settingsId ? FileIconThemeData.noIconTheme() : this.fileIconThemeRegistry.findThemeBySettingsId(settingsId); } private async reloadCurrentFileIconTheme() { await this.currentFileIconTheme.reload(this.fileService); - _applyIconTheme(this.currentFileIconTheme, () => { - this.doSetFileIconTheme(this.currentFileIconTheme); - return Promise.resolve(this.currentFileIconTheme); - }); + _applyRules(this.currentFileIconTheme.styleSheetContent!, fileIconThemeRulesClassName); + this.doSetFileIconTheme(this.currentFileIconTheme); } - public restoreFileIconTheme() { - const fileIconThemeSetting = this.settings.fileIconTheme; - if (fileIconThemeSetting !== this.currentFileIconTheme.settingsId) { - this.fileIconThemeRegistry.findThemeBySettingsId(fileIconThemeSetting).then(theme => { - if (theme) { - this.setFileIconTheme(theme.id, undefined); - } - }); + public async restoreFileIconTheme(): Promise { + const settingId = this.settings.fileIconTheme; + const theme = await this.findFileIconThemeBySettingsId(settingId); + if (theme) { + if (settingId !== this.currentFileIconTheme.settingsId) { + await this.setFileIconTheme(theme.id, undefined); + } + return true; } + return false; } private doSetFileIconTheme(iconThemeData: FileIconThemeData): void { @@ -559,6 +573,74 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } + public getProductIconThemes(): Promise { + return this.productIconThemeRegistry.getThemes(); + } + + public getProductIconTheme() { + return this.currentProductIconTheme; + } + + public async setProductIconTheme(iconTheme: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { + iconTheme = iconTheme || ''; + if (iconTheme === this.currentProductIconTheme.id && this.currentProductIconTheme.isLoaded) { + await this.settings.setProductIconTheme(this.currentProductIconTheme, settingsTarget); + return this.currentProductIconTheme; + } + + const newThemeData = await this.findProductIconThemeById(iconTheme) || ProductIconThemeData.defaultTheme(); + await newThemeData.ensureLoaded(this.fileService); + _applyRules(newThemeData.styleSheetContent!, fileIconThemeRulesClassName); + + this.doSetProductIconTheme(newThemeData); + + // remember theme data for a quick restore + if (newThemeData.isLoaded && (!newThemeData.location || !getRemoteAuthority(newThemeData.location))) { + newThemeData.toStorage(this.storageService); + } + await this.settings.setProductIconTheme(this.currentProductIconTheme, settingsTarget); + + return newThemeData; + } + + private async findProductIconThemeById(id: string): Promise { + return id.length === 0 ? ProductIconThemeData.defaultTheme() : this.productIconThemeRegistry.findThemeById(id); + } + + private async findProductIconThemeBySettingsId(settingsId: string | null): Promise { + return !settingsId ? ProductIconThemeData.defaultTheme() : this.productIconThemeRegistry.findThemeBySettingsId(settingsId); + } + + private async reloadCurrentProductIconTheme() { + await this.currentProductIconTheme.reload(this.fileService); + _applyRules(this.currentProductIconTheme.styleSheetContent!, productIconThemeRulesClassName); + this.doSetProductIconTheme(this.currentProductIconTheme); + } + + public async restoreProductIconTheme(): Promise { + const settingId = this.settings.productIconTheme; + const theme = await this.findProductIconThemeBySettingsId(settingId); + if (theme) { + if (settingId !== this.currentProductIconTheme.settingsId) { + await this.setProductIconTheme(theme.id, undefined); + } + return true; + } + return false; + } + + private doSetProductIconTheme(iconThemeData: ProductIconThemeData): void { + this.currentProductIconTheme = iconThemeData; + + this.productIconThemeWatcher.update(iconThemeData); + + if (iconThemeData.id) { + this.sendTelemetry(iconThemeData.id, iconThemeData.extensionData, 'productIcon'); + } + this.onProductIconThemeChange.fire(this.currentProductIconTheme); + + } + private getBaseThemeFromContainer() { for (let i = this.container.classList.length - 1; i >= 0; i--) { const item = this.container.classList.item(i); @@ -603,11 +685,6 @@ class ThemeFileWatcher { } } -function _applyIconTheme(data: FileIconThemeData, onApply: (theme: FileIconThemeData) => Promise): Promise { - _applyRules(data.styleSheetContent!, iconThemeRulesClassName); - return onApply(data); -} - function _applyRules(styleSheetContent: string, rulesClassName: string) { const themeStyles = document.head.getElementsByClassName(rulesClassName); if (themeStyles.length === 0) { @@ -623,6 +700,6 @@ function _applyRules(styleSheetContent: string, rulesClassName: string) { registerColorThemeSchemas(); registerFileIconThemeSchemas(); - +registerProductIconThemeSchemas(); registerSingleton(IWorkbenchThemeService, WorkbenchThemeService); diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index 18bddfe27ba..18dcea74f29 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -23,6 +23,7 @@ import { TokenStyle, ProbeScope, TokenStylingRule, getTokenClassificationRegistr import { MatcherWithPriority, Matcher, createMatchers } from 'vs/workbench/services/themes/common/textMateScopeMatcher'; import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; import { CharCode } from 'vs/base/common/charCode'; +import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; let colorRegistry = Registry.as(ColorRegistryExtensions.ColorContribution); @@ -42,6 +43,8 @@ const tokenGroupToScopesMap = { export type TokenStyleDefinition = TokenStylingRule | ProbeScope[] | TokenStyleValue; export type TokenStyleDefinitions = { [P in keyof TokenStyleData]?: TokenStyleDefinition | undefined }; +const PERSISTED_THEME_STORAGE_KEY = 'colorThemeData'; + export class ColorThemeData implements IWorkbenchColorTheme { id: string; @@ -422,13 +425,13 @@ export class ColorThemeData implements IWorkbenchColorTheme { this.customTokenScopeMatchers = undefined; } - toStorageData() { + toStorage(storageService: IStorageService) { let colorMapData: { [key: string]: string } = {}; for (let key in this.colorMap) { colorMapData[key] = Color.Format.CSS.formatHexA(this.colorMap[key], true); } // no need to persist custom colors, they will be taken from the settings - return JSON.stringify({ + const value = JSON.stringify({ id: this.id, label: this.label, settingsId: this.settingsId, @@ -438,6 +441,7 @@ export class ColorThemeData implements IWorkbenchColorTheme { colorMap: colorMapData, watch: this.watch }); + storageService.store(PERSISTED_THEME_STORAGE_KEY, value, StorageScope.GLOBAL); } hasEqualData(other: ColorThemeData) { @@ -474,7 +478,11 @@ export class ColorThemeData implements IWorkbenchColorTheme { return themeData; } - static fromStorageData(input: string): ColorThemeData | undefined { + static fromStorageData(storageService: IStorageService): ColorThemeData | undefined { + const input = storageService.get(PERSISTED_THEME_STORAGE_KEY, StorageScope.GLOBAL); + if (!input) { + return undefined; + } try { let data = JSON.parse(input); let theme = new ColorThemeData('', '', ''); diff --git a/src/vs/workbench/services/themes/common/productIconThemeSchema.ts b/src/vs/workbench/services/themes/common/productIconThemeSchema.ts new file mode 100644 index 00000000000..29fe708a8e9 --- /dev/null +++ b/src/vs/workbench/services/themes/common/productIconThemeSchema.ts @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vs/nls'; + +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as JSONExtensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; +import { IJSONSchema } from 'vs/base/common/jsonSchema'; + +const schemaId = 'vscode://schemas/product-icon-theme'; +const schema: IJSONSchema = { + type: 'object', + allowComments: true, + allowTrailingCommas: true, + properties: { + fonts: { + type: 'array', + description: nls.localize('schema.fonts', 'Fonts that are used in the icon definitions.'), + items: { + type: 'object', + properties: { + id: { + type: 'string', + description: nls.localize('schema.id', 'The ID of the font.') + }, + src: { + type: 'array', + description: nls.localize('schema.src', 'The location of the font.'), + items: { + type: 'object', + properties: { + path: { + type: 'string', + description: nls.localize('schema.font-path', 'The font path, relative to the current workbench icon theme file.'), + }, + format: { + type: 'string', + description: nls.localize('schema.font-format', 'The format of the font.') + } + }, + required: [ + 'path', + 'format' + ] + } + }, + weight: { + type: 'string', + description: nls.localize('schema.font-weight', 'The weight of the font.') + }, + style: { + type: 'string', + description: nls.localize('schema.font-sstyle', 'The style of the font.') + }, + size: { + type: 'string', + description: nls.localize('schema.font-size', 'The default size of the font.') + } + }, + required: [ + 'id', + 'src' + ] + } + }, + iconDefinitions: { + type: 'object', + description: nls.localize('schema.iconDefinitions', 'Assocation of icon name to a font character.'), + additionalProperties: { + type: 'object', + description: nls.localize('schema.iconDefinition', 'An icon definition. The object key is the icon name.'), + properties: { + fontCharacter: { + type: 'string', + description: nls.localize('schema.fontCharacter', 'The character in the font to use.') + }, + fontId: { + type: 'string', + description: nls.localize('schema.fontId', 'When using a font: The id of the font. If not set, defaults to the first font definition.') + } + } + } + } + } +}; + +export function registerProductIconThemeSchemas() { + let schemaRegistry = Registry.as(JSONExtensions.JSONContribution); + schemaRegistry.registerSchema(schemaId, schema); +} diff --git a/src/vs/workbench/services/themes/common/themeConfiguration.ts b/src/vs/workbench/services/themes/common/themeConfiguration.ts index ea4b9edb36b..b45ebe90434 100644 --- a/src/vs/workbench/services/themes/common/themeConfiguration.ts +++ b/src/vs/workbench/services/themes/common/themeConfiguration.ts @@ -12,7 +12,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { textmateColorsSchemaId, textmateColorGroupSchemaId } from 'vs/workbench/services/themes/common/colorThemeSchema'; import { workbenchColorsSchemaId } from 'vs/platform/theme/common/colorRegistry'; import { tokenStylingSchemaId } from 'vs/platform/theme/common/tokenClassificationRegistry'; -import { ThemeSettings, IWorkbenchColorTheme, IWorkbenchFileIconTheme, IColorCustomizations, ITokenColorCustomizations, IExperimentalTokenStyleCustomizations } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { ThemeSettings, IWorkbenchColorTheme, IWorkbenchFileIconTheme, IColorCustomizations, ITokenColorCustomizations, IExperimentalTokenStyleCustomizations, IWorkbenchProductIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; const DEFAULT_THEME_SETTING_VALUE = 'Default Dark+'; @@ -20,7 +20,9 @@ const DEFAULT_THEME_DARK_SETTING_VALUE = 'Default Dark+'; const DEFAULT_THEME_LIGHT_SETTING_VALUE = 'Default Light+'; const DEFAULT_THEME_HC_SETTING_VALUE = 'Default High Contrast'; -const DEFAULT_ICON_THEME_SETTING_VALUE = 'vs-seti'; +const DEFAULT_FILE_ICON_THEME_SETTING_VALUE = 'vs-seti'; + +export const DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE = 'Default'; // Configuration: Themes const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -66,14 +68,6 @@ const detectColorSchemeSettingSchema: IConfigurationPropertySchema = { default: false }; -const iconThemeSettingSchema: IConfigurationPropertySchema = { - type: ['string', 'null'], - default: DEFAULT_ICON_THEME_SETTING_VALUE, - description: nls.localize('iconTheme', "Specifies the icon theme used in the workbench or 'null' to not show any file icons."), - enum: [null], - enumDescriptions: [nls.localize('noIconThemeDesc', 'No file icons')], - errorMessage: nls.localize('iconThemeError', "File icon theme is unknown or not installed.") -}; const colorCustomizationsSchema: IConfigurationPropertySchema = { type: 'object', description: nls.localize('workbenchColors', "Overrides colors from the currently selected color theme."), @@ -85,6 +79,23 @@ const colorCustomizationsSchema: IConfigurationPropertySchema = { }] }; +const fileIconThemeSettingSchema: IConfigurationPropertySchema = { + type: ['string', 'null'], + default: DEFAULT_FILE_ICON_THEME_SETTING_VALUE, + description: nls.localize('iconTheme', "Specifies the icon theme used in the workbench or 'null' to not show any file icons."), + enum: [null], + enumDescriptions: [nls.localize('noIconThemeDesc', 'No file icons')], + errorMessage: nls.localize('iconThemeError', "File icon theme is unknown or not installed.") +}; +const productIconThemeSettingSchema: IConfigurationPropertySchema = { + type: ['string', 'null'], + default: DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE, + description: nls.localize('workbenchIconTheme', "Specifies the workbench icon theme used."), + enum: [DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE], + enumDescriptions: [nls.localize('defaultWorkbenchIconThemeDesc', 'Default')], + errorMessage: nls.localize('workbenchIconThemeError', "Workbench icon theme is unknown or not installed.") +}; + const themeSettingsConfiguration: IConfigurationNode = { id: 'workbench', order: 7.1, @@ -95,8 +106,9 @@ const themeSettingsConfiguration: IConfigurationNode = { [ThemeSettings.PREFERRED_LIGHT_THEME]: preferredLightThemeSettingSchema, [ThemeSettings.PREFERRED_HC_THEME]: preferredHCThemeSettingSchema, [ThemeSettings.DETECT_COLOR_SCHEME]: detectColorSchemeSettingSchema, - [ThemeSettings.ICON_THEME]: iconThemeSettingSchema, - [ThemeSettings.COLOR_CUSTOMIZATIONS]: colorCustomizationsSchema + [ThemeSettings.ICON_THEME]: fileIconThemeSettingSchema, + [ThemeSettings.COLOR_CUSTOMIZATIONS]: colorCustomizationsSchema, + [ThemeSettings.PRODUCT_ICON_THEME]: productIconThemeSettingSchema } }; configurationRegistry.registerConfiguration(themeSettingsConfiguration); @@ -172,8 +184,15 @@ export function updateColorThemeConfigurationSchemas(themes: IWorkbenchColorThem } export function updateFileIconThemeConfigurationSchemas(themes: IWorkbenchFileIconTheme[]) { - iconThemeSettingSchema.enum = [null, ...themes.map(t => t.settingsId)]; - iconThemeSettingSchema.enumDescriptions = [iconThemeSettingSchema.enumDescriptions![0], ...themes.map(t => t.description || '')]; + fileIconThemeSettingSchema.enum!.splice(1, Number.MAX_VALUE, ...themes.map(t => t.settingsId)); + fileIconThemeSettingSchema.enumDescriptions!.splice(1, Number.MAX_VALUE, ...themes.map(t => t.description || '')); + + configurationRegistry.notifyConfigurationSchemaUpdated(themeSettingsConfiguration); +} + +export function updateProductIconThemeConfigurationSchemas(themes: IWorkbenchProductIconTheme[]) { + productIconThemeSettingSchema.enum!.splice(1, Number.MAX_VALUE, ...themes.map(t => t.settingsId)); + productIconThemeSettingSchema.enumDescriptions!.splice(1, Number.MAX_VALUE, ...themes.map(t => t.description || '')); configurationRegistry.notifyConfigurationSchemaUpdated(themeSettingsConfiguration); } @@ -191,6 +210,10 @@ export class ThemeConfiguration { return this.configurationService.getValue(ThemeSettings.ICON_THEME); } + public get productIconTheme(): string { + return this.configurationService.getValue(ThemeSettings.PRODUCT_ICON_THEME); + } + public get colorCustomizations(): IColorCustomizations { return this.configurationService.getValue(ThemeSettings.COLOR_CUSTOMIZATIONS) || {}; } @@ -203,21 +226,26 @@ export class ThemeConfiguration { return this.configurationService.getValue(ThemeSettings.TOKEN_COLOR_CUSTOMIZATIONS_EXPERIMENTAL) || {}; } - public async setColorTheme(theme: IWorkbenchColorTheme, settingsTarget: ConfigurationTarget | undefined | 'auto',): Promise { - if (!types.isUndefinedOrNull(settingsTarget)) { - await this.writeConfiguration(ThemeSettings.COLOR_THEME, theme.settingsId, settingsTarget); - } + public async setColorTheme(theme: IWorkbenchColorTheme, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { + await this.writeConfiguration(ThemeSettings.COLOR_THEME, theme.settingsId, settingsTarget); return theme; } - public async setFileIconTheme(theme: IWorkbenchFileIconTheme, settingsTarget: ConfigurationTarget | undefined | 'auto',): Promise { - if (!types.isUndefinedOrNull(settingsTarget)) { - await this.writeConfiguration(ThemeSettings.ICON_THEME, theme.settingsId, settingsTarget); - } + public async setFileIconTheme(theme: IWorkbenchFileIconTheme, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { + await this.writeConfiguration(ThemeSettings.ICON_THEME, theme.settingsId, settingsTarget); return theme; } - private writeConfiguration(key: string, value: any, settingsTarget: ConfigurationTarget | 'auto'): Promise { + public async setProductIconTheme(theme: IWorkbenchProductIconTheme, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { + await this.writeConfiguration(ThemeSettings.PRODUCT_ICON_THEME, theme.settingsId, settingsTarget); + return theme; + } + + private async writeConfiguration(key: string, value: any, settingsTarget: ConfigurationTarget | 'auto' | undefined): Promise { + if (settingsTarget === undefined) { + return; + } + let settings = this.configurationService.inspect(key); if (settingsTarget === 'auto') { if (!types.isUndefined(settings.workspaceFolderValue)) { diff --git a/src/vs/workbench/services/themes/common/themeExtensionPoints.ts b/src/vs/workbench/services/themes/common/themeExtensionPoints.ts index 18b0f092045..026b48b2547 100644 --- a/src/vs/workbench/services/themes/common/themeExtensionPoints.ts +++ b/src/vs/workbench/services/themes/common/themeExtensionPoints.ts @@ -65,7 +65,36 @@ export function registerFileIconThemeExtensionPoint() { type: 'string' }, path: { - description: nls.localize('vscode.extension.contributes.iconThemes.path', 'Path of the file icon theme definition file. The path is relative to the extension folder and is typically \'./iconthemes/awesome-icon-theme.json\'.'), + description: nls.localize('vscode.extension.contributes.iconThemes.path', 'Path of the file icon theme definition file. The path is relative to the extension folder and is typically \'./fileicons/awesome-icon-theme.json\'.'), + type: 'string' + } + }, + required: ['path', 'id'] + } + } + }); +} + +export function registerProductIconThemeExtensionPoint() { + return ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'productIconThemes', + jsonSchema: { + description: nls.localize('vscode.extension.contributes.productIconThemes', 'Contributes product icon themes.'), + type: 'array', + items: { + type: 'object', + defaultSnippets: [{ body: { id: '${1:id}', label: '${2:label}', path: './producticons/${3:id}-product-icon-theme.json' } }], + properties: { + id: { + description: nls.localize('vscode.extension.contributes.productIconThemes.id', 'Id of the product icon theme as used in the user settings.'), + type: 'string' + }, + label: { + description: nls.localize('vscode.extension.contributes.productIconThemes.label', 'Label of the product icon theme as shown in the UI.'), + type: 'string' + }, + path: { + description: nls.localize('vscode.extension.contributes.productIconThemes.path', 'Path of the product icon theme definition file. The path is relative to the extension folder and is typically \'./producticons/awesome-product-icon-theme.json\'.'), type: 'string' } }, diff --git a/src/vs/workbench/services/themes/common/workbenchThemeService.ts b/src/vs/workbench/services/themes/common/workbenchThemeService.ts index 1d4d91837fc..3e897cd371b 100644 --- a/src/vs/workbench/services/themes/common/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/common/workbenchThemeService.ts @@ -29,7 +29,9 @@ export enum ThemeSettings { PREFERRED_LIGHT_THEME = 'workbench.preferredLightColorTheme', PREFERRED_HC_THEME = 'workbench.preferredHighContrastColorTheme', DETECT_COLOR_SCHEME = 'window.autoDetectColorScheme', - DETECT_HC = 'window.autoDetectHighContrast' + DETECT_HC = 'window.autoDetectHighContrast', + + PRODUCT_ICON_THEME = 'workbench.productIconTheme' } export interface IWorkbenchColorTheme extends IColorTheme { @@ -59,6 +61,16 @@ export interface IWorkbenchFileIconTheme extends IFileIconTheme { readonly hidesExplorerArrows: boolean; } +export interface IWorkbenchProductIconTheme { + readonly id: string; + readonly label: string; + readonly settingsId: string; + readonly description?: string; + readonly extensionData?: ExtensionData; + + readonly isLoaded: boolean; +} + export interface IWorkbenchThemeService extends IThemeService { _serviceBrand: undefined; @@ -72,6 +84,12 @@ export interface IWorkbenchThemeService extends IThemeService { getFileIconTheme(): IWorkbenchFileIconTheme; getFileIconThemes(): Promise; onDidFileIconThemeChange: Event; + + setProductIconTheme(iconThemeId: string | undefined, settingsTarget: ConfigurationTarget | undefined): Promise; + getProductIconTheme(): IWorkbenchProductIconTheme; + getProductIconThemes(): Promise; + onDidProductIconThemeChange: Event; + } export interface IColorCustomizations { From 2075c45b675937089080a0433d48e6db9b831818 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 5 Mar 2020 23:34:47 +0100 Subject: [PATCH 005/137] Fixes #67739: Add support for long press IME + arrow keys --- .../browser/controller/textAreaHandler.ts | 4 +- .../browser/controller/textAreaInput.ts | 45 ++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index 79e69fdde44..043bd0eb018 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -252,9 +252,9 @@ export class TextAreaHandler extends ViewPart { this._viewController.setSelection('keyboard', modelSelection); })); - this._register(this._textAreaInput.onCompositionStart(() => { + this._register(this._textAreaInput.onCompositionStart((e) => { const lineNumber = this._selections[0].startLineNumber; - const column = this._selections[0].startColumn; + const column = this._selections[0].startColumn - (e.moveOneCharacterLeft ? 1 : 0); this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent( 'keyboard', diff --git a/src/vs/editor/browser/controller/textAreaInput.ts b/src/vs/editor/browser/controller/textAreaInput.ts index ba6a141c70a..225d9e73e8a 100644 --- a/src/vs/editor/browser/controller/textAreaInput.ts +++ b/src/vs/editor/browser/controller/textAreaInput.ts @@ -95,6 +95,10 @@ class InMemoryClipboardMetadataManager { } } +export interface ICompositionStartEvent { + moveOneCharacterLeft: boolean; +} + /** * Writes screen reader content to the textarea and is able to analyze its input events to generate: * - onCut @@ -126,8 +130,8 @@ export class TextAreaInput extends Disposable { private _onType = this._register(new Emitter()); public readonly onType: Event = this._onType.event; - private _onCompositionStart = this._register(new Emitter()); - public readonly onCompositionStart: Event = this._onCompositionStart.event; + private _onCompositionStart = this._register(new Emitter()); + public readonly onCompositionStart: Event = this._onCompositionStart.event; private _onCompositionUpdate = this._register(new Emitter()); public readonly onCompositionUpdate: Event = this._onCompositionUpdate.event; @@ -165,9 +169,11 @@ export class TextAreaInput extends Disposable { this._isDoingComposition = false; this._nextCommand = ReadFromTextArea.Type; + let lastKeyDown: IKeyboardEvent | null = null; + this._register(dom.addStandardDisposableListener(textArea.domNode, 'keydown', (e: IKeyboardEvent) => { - if (this._isDoingComposition && - (e.keyCode === KeyCode.KEY_IN_COMPOSITION || e.keyCode === KeyCode.Backspace)) { + if (e.keyCode === KeyCode.KEY_IN_COMPOSITION + || (this._isDoingComposition && e.keyCode === KeyCode.Backspace)) { // Stop propagation for keyDown events if the IME is processing key input e.stopPropagation(); } @@ -177,6 +183,8 @@ export class TextAreaInput extends Disposable { // See https://msdn.microsoft.com/en-us/library/ie/ms536939(v=vs.85).aspx e.preventDefault(); } + + lastKeyDown = e; this._onKeyDown.fire(e); })); @@ -190,12 +198,35 @@ export class TextAreaInput extends Disposable { } this._isDoingComposition = true; - // In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled. - if (!browser.isEdge) { + let moveOneCharacterLeft = false; + if ( + platform.isMacintosh + && lastKeyDown + && lastKeyDown.equals(KeyCode.KEY_IN_COMPOSITION) + && this._textAreaState.selectionStart === this._textAreaState.selectionEnd + && this._textAreaState.selectionStart > 0 + && this._textAreaState.value.substr(this._textAreaState.selectionStart - 1, 1) === e.data + ) { + // Handling long press case on macOS + arrow key => pretend the character was selected + if (lastKeyDown.code === 'ArrowRight' || lastKeyDown.code === 'ArrowLeft') { + moveOneCharacterLeft = true; + } + } + + if (moveOneCharacterLeft) { + this._textAreaState = new TextAreaState( + this._textAreaState.value, + this._textAreaState.selectionStart - 1, + this._textAreaState.selectionEnd, + this._textAreaState.selectionStartPosition ? new Position(this._textAreaState.selectionStartPosition.lineNumber, this._textAreaState.selectionStartPosition.column - 1) : null, + this._textAreaState.selectionEndPosition + ); + } else if (!browser.isEdge) { + // In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled. this._setAndWriteTextAreaState('compositionstart', TextAreaState.EMPTY); } - this._onCompositionStart.fire(); + this._onCompositionStart.fire({ moveOneCharacterLeft }); })); /** From 811c4b5552e4165262cb25eeb6480e04c295bd9a Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 00:17:06 +0100 Subject: [PATCH 006/137] Fixes #82958: Don't do anything for empty selections --- .../caretOperations/moveCaretCommand.ts | 63 ++++++------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts b/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts index 0ce4feb6174..81db0fd6217 100644 --- a/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts +++ b/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts @@ -13,66 +13,43 @@ export class MoveCaretCommand implements ICommand { private readonly _selection: Selection; private readonly _isMovingLeft: boolean; - private _cutStartIndex: number; - private _cutEndIndex: number; - private _moved: boolean; - - private _selectionId: string | null; - constructor(selection: Selection, isMovingLeft: boolean) { this._selection = selection; this._isMovingLeft = isMovingLeft; - this._cutStartIndex = -1; - this._cutEndIndex = -1; - this._moved = false; - this._selectionId = null; } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - let s = this._selection; - this._selectionId = builder.trackSelection(s); - if (s.startLineNumber !== s.endLineNumber) { + if (this._selection.startLineNumber !== this._selection.endLineNumber || this._selection.isEmpty()) { return; } - if (this._isMovingLeft && s.startColumn === 0) { - return; - } else if (!this._isMovingLeft && s.endColumn === model.getLineMaxColumn(s.startLineNumber)) { + const lineNumber = this._selection.startLineNumber; + const startColumn = this._selection.startColumn; + const endColumn = this._selection.endColumn; + if (this._isMovingLeft && startColumn === 1) { + return; + } + if (!this._isMovingLeft && endColumn === model.getLineMaxColumn(lineNumber)) { return; } - - let lineNumber = s.selectionStartLineNumber; - let lineContent = model.getLineContent(lineNumber); - - let left: string; - let middle: string; - let right: string; if (this._isMovingLeft) { - left = lineContent.substring(0, s.startColumn - 2); - middle = lineContent.substring(s.startColumn - 1, s.endColumn - 1); - right = lineContent.substring(s.startColumn - 2, s.startColumn - 1) + lineContent.substring(s.endColumn - 1); + const rangeBefore = new Range(lineNumber, startColumn - 1, lineNumber, startColumn); + const charBefore = model.getValueInRange(rangeBefore); + builder.addEditOperation(rangeBefore, null); + builder.addEditOperation(new Range(lineNumber, endColumn, lineNumber, endColumn), charBefore); } else { - left = lineContent.substring(0, s.startColumn - 1) + lineContent.substring(s.endColumn - 1, s.endColumn); - middle = lineContent.substring(s.startColumn - 1, s.endColumn - 1); - right = lineContent.substring(s.endColumn); + const rangeAfter = new Range(lineNumber, endColumn, lineNumber, endColumn + 1); + const charAfter = model.getValueInRange(rangeAfter); + builder.addEditOperation(rangeAfter, null); + builder.addEditOperation(new Range(lineNumber, startColumn, lineNumber, startColumn), charAfter); } - - let newLineContent = left + middle + right; - - builder.addEditOperation(new Range(lineNumber, 1, lineNumber, model.getLineMaxColumn(lineNumber)), null); - builder.addEditOperation(new Range(lineNumber, 1, lineNumber, 1), newLineContent); - - this._cutStartIndex = s.startColumn + (this._isMovingLeft ? -1 : 1); - this._cutEndIndex = this._cutStartIndex + s.endColumn - s.startColumn; - this._moved = true; } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - let result = helper.getTrackedSelection(this._selectionId!); - if (this._moved) { - result = result.setStartPosition(result.startLineNumber, this._cutStartIndex); - result = result.setEndPosition(result.startLineNumber, this._cutEndIndex); + if (this._isMovingLeft) { + return new Selection(this._selection.startLineNumber, this._selection.startColumn - 1, this._selection.endLineNumber, this._selection.endColumn - 1); + } else { + return new Selection(this._selection.startLineNumber, this._selection.startColumn + 1, this._selection.endLineNumber, this._selection.endColumn + 1); } - return result; } } From 1370ae0098c33e0909aff858fa9c8576660c6510 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 6 Mar 2020 09:25:31 +0100 Subject: [PATCH 007/137] quick input - lift workbench specific parts up --- .../standaloneQuickInputServiceImpl.ts | 7 +--- .../platform/quickinput/browser/quickInput.ts | 23 +++++----- .../quickinput/browser/quickInputService.ts | 42 +++++++++++++++++++ src/vs/workbench/workbench.common.main.ts | 4 +- 4 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 src/vs/workbench/services/quickinput/browser/quickInputService.ts diff --git a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts index 30d8373545c..f115d927976 100644 --- a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts +++ b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts @@ -10,10 +10,7 @@ import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IQuickInputService, IQuickInputButton, IQuickPickItem, IQuickPick, IInputBox, IQuickNavigateConfiguration, IPickOptions, QuickPickInput, IInputOptions } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; @@ -28,15 +25,13 @@ export class EditorScopedQuickInputServiceImpl extends QuickInputService { constructor( editor: ICodeEditor, - @IConfigurationService configurationService: IConfigurationService, @IInstantiationService instantiationService: IInstantiationService, - @IKeybindingService keybindingService: IKeybindingService, @IContextKeyService contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService, @IAccessibilityService accessibilityService: IAccessibilityService, @ILayoutService layoutService: ILayoutService ) { - super({ args: Object.create(null) } as IEnvironmentService, configurationService, instantiationService, keybindingService, contextKeyService, themeService, accessibilityService, layoutService); + super(instantiationService, contextKeyService, themeService, accessibilityService, layoutService); // Use the passed in code editor as host for the quick input widget const contribution = QuickInputEditorContribution.get(editor); diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index 1005f963acb..9882760eeb3 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -9,13 +9,10 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IThemeService, Themable } from 'vs/platform/theme/common/themeService'; import { inputBackground, inputForeground, inputBorder, inputValidationInfoBackground, inputValidationInfoForeground, inputValidationInfoBorder, inputValidationWarningBackground, inputValidationWarningForeground, inputValidationWarningBorder, inputValidationErrorBackground, inputValidationErrorForeground, inputValidationErrorBorder, badgeBackground, badgeForeground, contrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, progressBarBackground, widgetShadow, listFocusForeground, listFocusBackground, activeContrastBorder, pickerGroupBorder, pickerGroupForeground, quickInputForeground, quickInputBackground, quickInputTitleBackground } from 'vs/platform/theme/common/colorRegistry'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { computeStyles } from 'vs/platform/theme/common/styler'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; -import { QuickInputController, IQuickInputStyles } from 'vs/base/parts/quickinput/browser/quickInput'; +import { QuickInputController, IQuickInputStyles, IQuickInputOptions } from 'vs/base/parts/quickinput/browser/quickInput'; import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list'; @@ -43,25 +40,22 @@ export class QuickInputService extends Themable implements IQuickInputService { private readonly contexts = new Map>(); constructor( - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IConfigurationService private readonly configurationService: IConfigurationService, @IInstantiationService private readonly instantiationService: IInstantiationService, - @IKeybindingService private readonly keybindingService: IKeybindingService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService, - @ILayoutService private readonly layoutService: ILayoutService + @ILayoutService protected readonly layoutService: ILayoutService ) { super(themeService); } - protected createController(host: IQuickInputControllerHost = this.layoutService): QuickInputController { - const controller = this._register(new QuickInputController({ + protected createController(host: IQuickInputControllerHost = this.layoutService, options?: Partial): QuickInputController { + const defaultOptions: IQuickInputOptions = { idPrefix: 'quickInput_', // Constant since there is still only one. container: host.container, - ignoreFocusOut: () => this.environmentService.args['sticky-quickopen'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'), + ignoreFocusOut: () => false, isScreenReaderOptimized: () => this.accessibilityService.isScreenReaderOptimized(), - backKeybindingLabel: () => this.keybindingService.lookupKeybinding('workbench.action.quickInputBack')?.getLabel() || undefined, + backKeybindingLabel: () => undefined, setContextKey: (id?: string) => this.setContextKey(id), returnFocus: () => host.focus(), createList: ( @@ -72,6 +66,11 @@ export class QuickInputService extends Themable implements IQuickInputService { options: IListOptions, ) => this.instantiationService.createInstance(WorkbenchList, user, container, delegate, renderers, options) as List, styles: this.computeStyles() + }; + + const controller = this._register(new QuickInputController({ + ...defaultOptions, + ...options })); controller.layout(host.dimension, host.offset?.top ?? 0); diff --git a/src/vs/workbench/services/quickinput/browser/quickInputService.ts b/src/vs/workbench/services/quickinput/browser/quickInputService.ts new file mode 100644 index 00000000000..94d8ad01f04 --- /dev/null +++ b/src/vs/workbench/services/quickinput/browser/quickInputService.ts @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { QuickInputController } from 'vs/base/parts/quickinput/browser/quickInput'; +import { QuickInputService as BaseQuickInputService } from 'vs/platform/quickinput/browser/quickInput'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; + +export class QuickInputService extends BaseQuickInputService { + + constructor( + @IEnvironmentService private environmentService: IEnvironmentService, + @IConfigurationService private configurationService: IConfigurationService, + @IInstantiationService instantiationService: IInstantiationService, + @IKeybindingService private keybindingService: IKeybindingService, + @IContextKeyService contextKeyService: IContextKeyService, + @IThemeService themeService: IThemeService, + @IAccessibilityService accessibilityService: IAccessibilityService, + @ILayoutService protected layoutService: ILayoutService + ) { + super(instantiationService, contextKeyService, themeService, accessibilityService, layoutService); + } + + protected createController(): QuickInputController { + return super.createController(this.layoutService, { + ignoreFocusOut: () => this.environmentService.args['sticky-quickopen'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'), + backKeybindingLabel: () => this.keybindingService.lookupKeybinding('workbench.action.quickInputBack')?.getLabel() || undefined, + }); + } +} + +registerSingleton(IQuickInputService, QuickInputService, true); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 0aac4046cb5..402477b4e3f 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -84,6 +84,7 @@ import 'vs/workbench/services/workingCopy/common/workingCopyService'; import 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import 'vs/workbench/services/views/browser/viewDescriptorService'; +import 'vs/workbench/services/quickinput/browser/quickInputService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; @@ -112,8 +113,6 @@ import { OpenerService } from 'vs/editor/browser/services/openerService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; import { UserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSyncEnablementService'; -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; -import { QuickInputService } from 'vs/platform/quickinput/browser/quickInput'; registerSingleton(IUserDataSyncEnablementService, UserDataSyncEnablementService); registerSingleton(IGlobalExtensionEnablementService, GlobalExtensionEnablementService); @@ -129,7 +128,6 @@ registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationSe registerSingleton(IMenuService, MenuService, true); registerSingleton(IDownloadService, DownloadService, true); registerSingleton(IOpenerService, OpenerService, true); -registerSingleton(IQuickInputService, QuickInputService, true); //#endregion From 4857a9a74617758f1da94ff1c1dc19752e4fc8f7 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 6 Mar 2020 00:29:57 -0800 Subject: [PATCH 008/137] Revert "Fix integration test" This reverts commit 5a0ab960f04876886d500b02407734e14c92d1ff. --- extensions/emmet/src/test/index.ts | 2 +- extensions/git/src/test/index.ts | 2 +- extensions/markdown-language-features/src/test/index.ts | 2 +- extensions/typescript-language-features/src/test/index.ts | 2 +- extensions/vscode-api-tests/src/singlefolder-tests/index.ts | 2 +- extensions/vscode-api-tests/src/workspace-tests/index.ts | 2 +- extensions/vscode-colorize-tests/src/index.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/extensions/emmet/src/test/index.ts b/extensions/emmet/src/test/index.ts index f7b3e0de31c..c18e73555f1 100644 --- a/extensions/emmet/src/test/index.ts +++ b/extensions/emmet/src/test/index.ts @@ -45,7 +45,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } diff --git a/extensions/git/src/test/index.ts b/extensions/git/src/test/index.ts index 7b9af4c911c..87706c6bf53 100644 --- a/extensions/git/src/test/index.ts +++ b/extensions/git/src/test/index.ts @@ -45,7 +45,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } diff --git a/extensions/markdown-language-features/src/test/index.ts b/extensions/markdown-language-features/src/test/index.ts index 17fe84c7897..98717fcfb9f 100644 --- a/extensions/markdown-language-features/src/test/index.ts +++ b/extensions/markdown-language-features/src/test/index.ts @@ -45,7 +45,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } diff --git a/extensions/typescript-language-features/src/test/index.ts b/extensions/typescript-language-features/src/test/index.ts index 2a9b0603599..4095b0957be 100644 --- a/extensions/typescript-language-features/src/test/index.ts +++ b/extensions/typescript-language-features/src/test/index.ts @@ -25,7 +25,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/index.ts b/extensions/vscode-api-tests/src/singlefolder-tests/index.ts index 1de48efe3cb..85256b44b1a 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/index.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/index.ts @@ -45,7 +45,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '.'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } diff --git a/extensions/vscode-api-tests/src/workspace-tests/index.ts b/extensions/vscode-api-tests/src/workspace-tests/index.ts index 2512bd40f19..889f7f764e2 100644 --- a/extensions/vscode-api-tests/src/workspace-tests/index.ts +++ b/extensions/vscode-api-tests/src/workspace-tests/index.ts @@ -45,7 +45,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '.'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } diff --git a/extensions/vscode-colorize-tests/src/index.ts b/extensions/vscode-colorize-tests/src/index.ts index e30a08a4b08..9f853968e40 100644 --- a/extensions/vscode-colorize-tests/src/index.ts +++ b/extensions/vscode-colorize-tests/src/index.ts @@ -45,7 +45,7 @@ export function run(): Promise { const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } From a8ff40791d652263e9f08bce26123ebb68b5c671 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 6 Mar 2020 00:30:07 -0800 Subject: [PATCH 009/137] Revert "Fix failed integration tests" This reverts commit 0a36d4c82b5e4ae5523a6a776afa1f12cde96583. --- extensions/vscode-api-tests/src/singlefolder-tests/index.ts | 2 +- extensions/vscode-api-tests/src/workspace-tests/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/index.ts b/extensions/vscode-api-tests/src/singlefolder-tests/index.ts index 85256b44b1a..363358301d8 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/index.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/index.ts @@ -42,7 +42,7 @@ export function run(): Promise { mocha.useColors(true); } - const testsRoot = path.resolve(__dirname, '.'); + const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { diff --git a/extensions/vscode-api-tests/src/workspace-tests/index.ts b/extensions/vscode-api-tests/src/workspace-tests/index.ts index 889f7f764e2..69113f3cd41 100644 --- a/extensions/vscode-api-tests/src/workspace-tests/index.ts +++ b/extensions/vscode-api-tests/src/workspace-tests/index.ts @@ -42,7 +42,7 @@ export function run(): Promise { mocha.useColors(true); } - const testsRoot = path.resolve(__dirname, '.'); + const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { From 2362584a626621a80ec4af3bea52d2f0513e9383 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 6 Mar 2020 00:30:14 -0800 Subject: [PATCH 010/137] Revert "Fix #73803" This reverts commit 67e6aef0c85ed17ef673950ecc24c12df7f2d7a8. --- extensions/emmet/package.json | 3 +- extensions/emmet/src/test/index.ts | 80 +- extensions/emmet/yarn.lock | 2383 ++++++++++++++++- extensions/git/package.json | 3 +- extensions/git/src/test/index.ts | 80 +- extensions/git/yarn.lock | 494 +++- .../markdown-language-features/package.json | 1 + .../src/test/index.ts | 80 +- .../markdown-language-features/yarn.lock | 1416 +++++++++- .../typescript-language-features/package.json | 3 +- .../src/test/index.ts | 62 +- .../typescript-language-features/yarn.lock | 528 +++- extensions/vscode-api-tests/package.json | 4 +- .../src/singlefolder-tests/index.ts | 80 +- .../src/workspace-tests/index.ts | 80 +- extensions/vscode-api-tests/yarn.lock | 1911 ++++++++++++- extensions/vscode-colorize-tests/package.json | 7 +- extensions/vscode-colorize-tests/src/index.ts | 80 +- extensions/vscode-colorize-tests/yarn.lock | 1911 ++++++++++++- extensions/vscode-test-resolver/package.json | 9 +- extensions/vscode-test-resolver/yarn.lock | 1871 +++++++++++++ package.json | 1 - yarn.lock | 19 - 23 files changed, 10625 insertions(+), 481 deletions(-) diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 3fb82100d32..fc149b28e54 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -445,7 +445,8 @@ "devDependencies": { "@types/node": "^12.11.7", "mocha-junit-reporter": "^1.17.0", - "mocha-multi-reporters": "^1.1.7" + "mocha-multi-reporters": "^1.1.7", + "vscode": "1.0.1" }, "dependencies": { "@emmetio/css-parser": "ramya-rao-a/css-parser#vscode", diff --git a/extensions/emmet/src/test/index.ts b/extensions/emmet/src/test/index.ts index c18e73555f1..f3aeb0fefc1 100644 --- a/extensions/emmet/src/test/index.ts +++ b/extensions/emmet/src/test/index.ts @@ -3,68 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); const suite = 'Integration Emmet Tests'; -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - reporter?: string; - reporterOptions?: any; - } = { - ui: 'tdd', - timeout: 60000, - reporter: undefined, - reporterOptions: undefined +const options: any = { + ui: 'tdd', + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } }; - - if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { - options.reporter = 'mocha-multi-reporters'; - options.reporterOptions = { - reporterEnabled: 'spec, mocha-junit-reporter', - mochaJunitReporterReporterOptions: { - testsuitesTitle: `${suite} ${process.platform}`, - mochaFile: path.join( - process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, - `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml` - ) - } - }; - } - - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); } + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/emmet/yarn.lock b/extensions/emmet/yarn.lock index 48c9ea21aad..37e06ecb522 100644 --- a/extensions/emmet/yarn.lock +++ b/extensions/emmet/yarn.lock @@ -45,21 +45,376 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a" integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA== +ajv@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" + integrity sha1-RBT/dKUIecII7l/cgm4ywwNUnto= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-regex@^0.2.0, ansi-regex@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" + integrity sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-styles@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" + integrity sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y= + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.2.1, aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + integrity sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40= + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= + dependencies: + hoek "2.x.x" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + integrity sha1-T4owBctKfjiJ90kDD9JbluAdLjE= + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw== + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI= + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" + integrity sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ= + dependencies: + ansi-styles "^1.1.0" + escape-string-regexp "^1.0.0" + has-ansi "^0.1.0" + strip-ansi "^0.3.0" + supports-color "^0.2.0" + +chalk@^1.0.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^0.0.1, clone-stats@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + integrity sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8= + +cloneable-readable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" + integrity sha1-pikNQT8hemEjL5XkWP84QYz7ARc= + dependencies: + inherits "^2.0.1" + process-nextick-args "^1.0.6" + through2 "^2.0.1" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + integrity sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk= + dependencies: + delayed-stream "~1.0.0" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY= + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= + +commander@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + integrity sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= + dependencies: + boom "2.x.x" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + integrity sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4= + dependencies: + boom "5.x.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +dateformat@^1.0.7-1.2.3: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + integrity sha1-+HBX6ZWxofauaklgZkE3vFbwOdo= + dependencies: + ms "0.7.1" + debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -74,26 +429,1107 @@ debug@^3.1.0: dependencies: ms "2.0.0" +decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +deep-assign@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-1.0.0.tgz#b092743be8427dc621ea0067cdec7e70dd19f37b" + integrity sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s= + dependencies: + is-obj "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + integrity sha1-fyjS657nsVqX79ic5j3P2qPMur8= + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" + integrity sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + integrity sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU= + dependencies: + jsbn "~0.1.0" + +end-of-stream@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + integrity sha1-epDYM+/abPpurA9JSduw+tOmMgY= + dependencies: + once "^1.4.0" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + integrity sha1-+FWobOYa3E6GIcPNoh56dhLDqNw= + dependencies: + is-arrayish "^0.2.1" + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + integrity sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE= + +escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +event-stream@^3.3.1, event-stream@~3.3.4: + version "3.3.4" + resolved "https://registry.npmjs.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +event-stream@~3.1.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.1.7.tgz#b4c540012d0fe1498420f3d8946008db6393c37a" + integrity sha1-tMVAAS0P4UmEIPPYlGAI22OTw3o= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.2" + stream-combiner "~0.0.4" + through "~2.3.1" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0, extsprintf@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +fancy-log@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" + integrity sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg= + dependencies: + chalk "^1.1.1" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + integrity sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + integrity sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fstream@~0.1.28: + version "0.1.31" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-0.1.31.tgz#7337f058fbbbbefa8c9f561a28cab0849202c988" + integrity sha1-czfwWPu7vvqMn1YaKMqwhJICyYg= + dependencies: + graceful-fs "~3.0.2" + inherits "~2.0.0" + mkdirp "0.5" + rimraf "2" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + integrity sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ= + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + integrity sha1-pVZlqajM3EGRWofHAeMtTgFvrSI= + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob@3.2.11: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= + dependencies: + inherits "2" + minimatch "0.3" + +glob@^5.0.15, glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.5: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glogg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" + integrity sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U= + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + +graceful-fs@~3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + integrity sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg= + dependencies: + natives "^1.1.0" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +gulp-chmod@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/gulp-chmod/-/gulp-chmod-1.3.0.tgz#8bb6e8c11895dcbf9b42520c874347a5022bcb0d" + integrity sha1-i7bowRiV3L+bQlIMh0NHpQIryw0= + dependencies: + deep-assign "^1.0.0" + stat-mode "^0.2.0" + through2 "^2.0.0" + +gulp-filter@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-4.0.0.tgz#395f58a256c559cdb9e0d157f1caaf5248a38dcb" + integrity sha1-OV9YolbFWc254NFX8cqvUkijjcs= + dependencies: + gulp-util "^3.0.6" + multimatch "^2.0.0" + streamfilter "^1.0.5" + +gulp-gunzip@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/gulp-gunzip/-/gulp-gunzip-0.0.3.tgz#7b6e07b0f58fd3d42515c48ead5a63df0572f62f" + integrity sha1-e24HsPWP09QlFcSOrVpj3wVy9i8= + dependencies: + through2 "~0.6.5" + vinyl "~0.4.6" + +gulp-remote-src@^0.4.0: + version "0.4.3" + resolved "https://registry.yarnpkg.com/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz#5728cfd643433dd4845ddef0969f0f971a2ab4a1" + integrity sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE= + dependencies: + event-stream "~3.3.4" + node.extend "~1.1.2" + request "~2.79.0" + through2 "~2.0.3" + vinyl "~2.0.1" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + integrity sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw= + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +gulp-symdest@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gulp-symdest/-/gulp-symdest-1.1.0.tgz#c165320732d192ce56fd94271ffa123234bf2ae0" + integrity sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA= + dependencies: + event-stream "^3.3.1" + mkdirp "^0.5.1" + queue "^3.1.0" + vinyl-fs "^2.4.3" + +gulp-untar@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/gulp-untar/-/gulp-untar-0.0.4.tgz#635cc7d67d3d48aec0dbc69822623fc7c33f7d37" + integrity sha1-Y1zH1n09SK7A28aYImI/x8M/fTc= + dependencies: + event-stream "~3.1.5" + gulp-util "~2.2.14" + streamifier "~0.1.0" + tar "~0.1.19" + through2 "~0.4.1" + +gulp-util@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-util@~2.2.14: + version "2.2.20" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-2.2.20.tgz#d7146e5728910bd8f047a6b0b1e549bc22dbd64c" + integrity sha1-1xRuVyiRC9jwR6awseVJvCLb1kw= + dependencies: + chalk "^0.5.0" + dateformat "^1.0.7-1.2.3" + lodash._reinterpolate "^2.4.1" + lodash.template "^2.4.1" + minimist "^0.2.0" + multipipe "^0.1.0" + through2 "^0.5.0" + vinyl "^0.2.1" + +gulp-vinyl-zip@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-vinyl-zip/-/gulp-vinyl-zip-1.4.0.tgz#56382f2ccb57231bb0478c78737ccd572973bee1" + integrity sha1-VjgvLMtXIxuwR4x4c3zNVylzvuE= + dependencies: + event-stream "^3.3.1" + queue "^3.0.10" + through2 "^0.6.3" + vinyl "^0.4.6" + vinyl-fs "^2.0.0" + yauzl "^2.2.1" + yazl "^2.2.1" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" + integrity sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4= + dependencies: + ansi-regex "^0.2.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + integrity sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ== + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ== + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + integrity sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg== + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + image-size@^0.5.2: version "0.5.5" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= -is-buffer@~1.1.1: +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-my-json-valid@^2.12.4: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + integrity sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4= + +is@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" + integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + integrity sha1-jxDXl32NefL2/4YqgbBRPMslaGw= + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + jsonc-parser@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272" integrity sha1-3cyGSucI5gp6bdNtrqABcvqNknI= +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._escapehtmlchar@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" + integrity sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0= + dependencies: + lodash._htmlescapes "~2.4.1" + +lodash._escapestringchar@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz#ecfe22618a2ade50bfeea43937e51df66f0edb72" + integrity sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._htmlescapes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz#32d14bf0844b6de6f8b62a051b4f67c228b624cb" + integrity sha1-MtFL8IRLbeb4tioFG09nwii2JMs= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._isnative@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" + integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw= + +lodash._objecttypes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" + integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^2.4.1, lodash._reinterpolate@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz#4f1227aa5a8711fc632f5b07a1f4607aab8b3222" + integrity sha1-TxInqlqHEfxjL1sHofRgequLMiI= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._reunescapedhtml@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz#747c4fc40103eb3bb8a0976e571f7a2659e93ba7" + integrity sha1-dHxPxAED6zu4oJduVx96JlnpO6c= + dependencies: + lodash._htmlescapes "~2.4.1" + lodash.keys "~2.4.1" + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash._shimkeys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" + integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.defaults@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.4.1.tgz#a7e8885f05e68851144b6e12a8f3678026bc4c54" + integrity sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ= + dependencies: + lodash._objecttypes "~2.4.1" + lodash.keys "~2.4.1" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.escape@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-2.4.1.tgz#2ce12c5e084db0a57dda5e5d1eeeb9f5d175a3b4" + integrity sha1-LOEsXghNsKV92l5dHu659dF1o7Q= + dependencies: + lodash._escapehtmlchar "~2.4.1" + lodash._reunescapedhtml "~2.4.1" + lodash.keys "~2.4.1" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isobject@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" + integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.keys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" + integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc= + dependencies: + lodash._isnative "~2.4.1" + lodash._shimkeys "~2.4.1" + lodash.isobject "~2.4.1" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.template@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-2.4.1.tgz#9e611007edf629129a974ab3c48b817b3e1cf20d" + integrity sha1-nmEQB+32KRKal0qzxIuBez4c8g0= + dependencies: + lodash._escapestringchar "~2.4.1" + lodash._reinterpolate "~2.4.1" + lodash.defaults "~2.4.1" + lodash.escape "~2.4.1" + lodash.keys "~2.4.1" + lodash.templatesettings "~2.4.1" + lodash.values "~2.4.1" + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +lodash.templatesettings@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz#ea76c75d11eb86d4dbe89a83893bb861929ac699" + integrity sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk= + dependencies: + lodash._reinterpolate "~2.4.1" + lodash.escape "~2.4.1" + +lodash.values@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" + integrity sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ= + dependencies: + lodash.keys "~2.4.1" + lodash@^4.16.4: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" @@ -103,12 +1539,96 @@ md5@^2.1.0: crypt "~0.0.1" is-buffer "~1.1.1" +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo= + dependencies: + mime-db "~1.30.0" + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -mkdirp@~0.5.1: +minimist@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" + integrity sha1-Tf/lJdriuGTGbC4jxicdev3s784= + +minimist@^1.1.0, minimist@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= + +mkdirp@0.5, mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -134,11 +1654,560 @@ mocha-multi-reporters@^1.1.7: debug "^3.1.0" lodash "^4.16.4" +mocha@^2.3.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" + integrity sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg= + dependencies: + commander "2.3.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.2" + glob "3.2.11" + growl "1.9.2" + jade "0.26.3" + mkdirp "0.5.1" + supports-color "1.2.0" + to-iso-string "0.0.2" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + integrity sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg= + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.0, multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +natives@^1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.4.tgz#2f0f224fc9a7dd53407c7667c84cf8dbe773de58" + integrity sha512-Q29yeg9aFKwhLVdkTAejM/HvYG0Y1Am1+HUkFQGn5k2j8GS+v60TVmZh6nujpEAj/qql+wGUrlryO8bF+b1jEg== + +node.extend@~1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.6.tgz#a7b882c82d6c93a4863a5504bd5de8ec86258b96" + integrity sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y= + dependencies: + is "^3.1.0" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-assign@^4.0.0, object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + integrity sha1-cTfmmzKYuzQiR6G77jiByA4v14s= + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +process-nextick-args@^1.0.6, process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + integrity sha1-51vV9uJoEioqDgvaYwslUMFmUCw= + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A== + +queue@^3.0.10, queue@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/queue/-/queue-3.1.0.tgz#6c49d01f009e2256788789f2bffac6b8b9990585" + integrity sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU= + dependencies: + inherits "~2.0.0" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + integrity sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.67.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + integrity sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw== + dependencies: + aws-sign2 "~0.7.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.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +request@~2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + integrity sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +rimraf@2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + +"semver@2 || 3 || 4 || 5", semver@^5.1.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= + dependencies: + hoek "2.x.x" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + integrity sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg== + dependencies: + hoek "4.x.x" + +source-map-support@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f" + integrity sha1-NJAJd9W6PwfHdX7nLnO7GptTdU8= + dependencies: + source-map "0.1.32" + +source-map@0.1.32: + version "0.1.32" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" + integrity sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY= + dependencies: + amdefine ">=0.0.4" + +sparkles@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + integrity sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM= + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + integrity sha1-SzBz2TP/UfORLwOsVRlJikFQ20A= + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + integrity sha1-m98vIOH0DtRH++JzJmGR/O1RYmw= + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + integrity sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc= + +split@0.2: + version "0.2.10" + resolved "https://registry.yarnpkg.com/split/-/split-0.2.10.tgz#67097c601d697ce1368f418f06cd201cf0521a57" + integrity sha1-Zwl8YB1pfOE2j0GPBs0gHPBSGlc= + dependencies: + through "2" + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + integrity sha1-US322mKHFEMW3EwY/hzx2UBzm+M= + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stat-mode@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamfilter@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.5.tgz#87507111beb8e298451717b511cfed8f002abf53" + integrity sha1-h1BxEb644phFFxe1Ec/tjwAqv1M= + dependencies: + readable-stream "^2.0.2" + +streamifier@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f" + integrity sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8= + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4, stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= + +strip-ansi@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" + integrity sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA= + dependencies: + ansi-regex "^0.2.1" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -146,6 +2215,260 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + integrity sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4= + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +supports-color@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" + integrity sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4= + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + integrity sha1-2S3iaU6z9nMjlz1649i1W0wiGQo= + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +tar@~0.1.19: + version "0.1.20" + resolved "https://registry.yarnpkg.com/tar/-/tar-0.1.20.tgz#42940bae5b5f22c74483699126f9f3f27449cb13" + integrity sha1-QpQLrltfIsdEg2mRJvnz8nRJyxM= + dependencies: + block-stream "*" + fstream "~0.1.28" + inherits "2" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + integrity sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw= + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" + integrity sha1-390BLrnHAOIyP9M084rGIqs3Lac= + dependencies: + readable-stream "~1.0.17" + xtend "~3.0.0" + +through2@^0.6.0, through2@^0.6.1, through2@^0.6.3, through2@~0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@~2.0.0, through2@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through2@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + integrity sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s= + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +through@2, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + integrity sha1-HN+kcqnvUMI57maZm2YsoOs5k38= + dependencies: + extend-shallow "^2.0.1" + +to-iso-string@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" + integrity sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE= + +tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + integrity sha1-C2GKVWW23qkL80JdBNVe3EdadWE= + dependencies: + punycode "^1.4.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +unique-stream@^2.0.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + integrity sha1-WqADz76Uxf+GbE59ZouxxNuts2k= + dependencies: + json-stable-stringify "^1.0.0" + through2-filter "^2.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^3.0.0, uuid@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== + +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + integrity sha1-KAS6vnEq0zeUWaz74kdGqywwP7w= + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^2.0.0, vinyl-fs@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + integrity sha1-vm/zJwy1Xf19MGNkDegfJddTIjk= + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl-source-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz#44cbe5108205279deb0c5653c094a2887938b1ab" + integrity sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas= + dependencies: + through2 "^0.6.1" + vinyl "^0.4.3" + +vinyl@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.2.3.tgz#bca938209582ec5a49ad538a00fa1f125e513252" + integrity sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI= + dependencies: + clone-stats "~0.0.1" + +vinyl@^0.4.3, vinyl@^0.4.6, vinyl@~0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" + integrity sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw= + dependencies: + clone "^1.0.0" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + is-stream "^1.1.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + vscode-emmet-helper@^1.2.17: version "1.2.17" resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.2.17.tgz#f0c6bfcebc4285d081fb2618e6e5b9a08c567afa" @@ -184,7 +2507,63 @@ vscode-uri@^2.0.3: resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543" integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw== +vscode@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.0.1.tgz#3d161200615fe2af1d92ddc650751159411a513b" + integrity sha1-PRYSAGFf4q8dkt3GUHURWUEaUTs= + dependencies: + glob "^5.0.15" + gulp-chmod "^1.3.0" + gulp-filter "^4.0.0" + gulp-gunzip "0.0.3" + gulp-remote-src "^0.4.0" + gulp-symdest "^1.0.0" + gulp-untar "0.0.4" + gulp-vinyl-zip "^1.1.2" + mocha "^2.3.3" + request "^2.67.0" + semver "^5.1.0" + source-map-support "^0.3.2" + vinyl-source-stream "^1.1.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + xml@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= + dependencies: + object-keys "~0.4.0" + +xtend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" + integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= + +yauzl@^2.2.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" + integrity sha1-qBmB6nCleUYTOIPwKcWCGok1mn8= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.0.1" + +yazl@^2.2.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071" + integrity sha1-7CblzIfVYBud+EMtvdPNLlFzoHE= + dependencies: + buffer-crc32 "~0.2.3" diff --git a/extensions/git/package.json b/extensions/git/package.json index 7bfa07f9968..5246020c6c2 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1879,6 +1879,7 @@ "@types/which": "^1.0.28", "mocha": "^3.2.0", "mocha-junit-reporter": "^1.23.3", - "mocha-multi-reporters": "^1.1.7" + "mocha-multi-reporters": "^1.1.7", + "vscode": "^1.1.36" } } diff --git a/extensions/git/src/test/index.ts b/extensions/git/src/test/index.ts index 87706c6bf53..747c4562e8a 100644 --- a/extensions/git/src/test/index.ts +++ b/extensions/git/src/test/index.ts @@ -3,68 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); const suite = 'Integration Git Tests'; -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - reporter?: string; - reporterOptions?: any; - } = { - ui: 'tdd', - timeout: 60000, - reporter: undefined, - reporterOptions: undefined +const options: any = { + ui: 'tdd', + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } }; - - if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { - options.reporter = 'mocha-multi-reporters'; - options.reporterOptions = { - reporterEnabled: 'spec, mocha-junit-reporter', - mochaJunitReporterReporterOptions: { - testsuitesTitle: `${suite} ${process.platform}`, - mochaFile: path.join( - process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, - `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml` - ) - } - }; - } - - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); } + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index eda97acfe49..ac135e43a80 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -36,6 +36,23 @@ resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6" integrity sha1-AW44dim4gXvtZT/jLqtdESecjfY= +agent-base@4, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +ajv@^6.5.5: + version "6.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9" + integrity sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" @@ -50,11 +67,45 @@ applicationinsights@1.0.8: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -68,16 +119,43 @@ browser-stdout@1.3.0: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -90,11 +168,23 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + dayjs@1.8.19: version "1.8.19" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe" @@ -107,6 +197,13 @@ debug@2.6.8: dependencies: ms "2.0.0" +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -121,6 +218,11 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + diagnostic-channel-publishers@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" @@ -138,21 +240,92 @@ diff@3.2.0: resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + escape-string-regexp@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + file-type@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74" integrity sha1-ETz+1S4daVmrgCSJBuLyWozcy3Q= +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" @@ -165,26 +338,98 @@ glob@7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.2: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + growl@1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -210,21 +455,61 @@ is-buffer@~1.1.1: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + jschardet@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184" integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q== +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + json3@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -295,7 +580,19 @@ md5@^2.1.0: crypt "~0.0.1" is-buffer "~1.1.1" -minimatch@^3.0.2: +mime-db@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -351,6 +648,23 @@ mocha@^3.2.0: mkdirp "0.5.1" supports-color "3.1.2" +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -361,6 +675,11 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -373,7 +692,68 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -"safer-buffer@>= 2.1.2 < 3": +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +psl@^1.1.28: + version "1.7.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" + integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -383,6 +763,39 @@ semver@^5.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== +semver@^5.4.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +source-map-support@^0.5.0: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -397,6 +810,62 @@ supports-color@3.1.2: dependencies: has-flag "^1.0.0" +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +url-parse@^1.4.4: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vscode-extension-telemetry@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b" @@ -409,11 +878,32 @@ vscode-nls@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002" integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw== +vscode-test@^0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8" + integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w== + dependencies: + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + vscode-uri@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542" integrity sha512-lWXWofDSYD8r/TIyu64MdwB4FaSirQ608PP/TzUyslyOeHGwQ0eTHUZeJrK1ILOmwUHaJtV693m2JoUYroUDpw== +vscode@^1.1.36: + version "1.1.36" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.36.tgz#5e1a0d1bf4977d0c7bc5159a9a13d5b104d4b1b6" + integrity sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ== + dependencies: + glob "^7.1.2" + mocha "^5.2.0" + request "^2.88.0" + semver "^5.4.1" + source-map-support "^0.5.0" + url-parse "^1.4.4" + vscode-test "^0.4.1" + which@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 5304d683496..dbc8746c913 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -346,6 +346,7 @@ "mocha-multi-reporters": "^1.1.7", "ts-loader": "^6.2.1", "typescript": "^3.7.3", + "vscode": "^1.1.10", "webpack": "^4.41.2", "webpack-cli": "^3.3.0" } diff --git a/extensions/markdown-language-features/src/test/index.ts b/extensions/markdown-language-features/src/test/index.ts index 98717fcfb9f..77019228745 100644 --- a/extensions/markdown-language-features/src/test/index.ts +++ b/extensions/markdown-language-features/src/test/index.ts @@ -3,68 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); const suite = 'Integration Markdown Tests'; -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - reporter?: string; - reporterOptions?: any; - } = { - ui: 'tdd', - timeout: 60000, - reporter: undefined, - reporterOptions: undefined +const options: any = { + ui: 'tdd', + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } }; - - if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { - options.reporter = 'mocha-multi-reporters'; - options.reporterOptions = { - reporterEnabled: 'spec, mocha-junit-reporter', - mochaJunitReporterReporterOptions: { - testsuitesTitle: `${suite} ${process.platform}`, - mochaFile: path.join( - process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, - `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml` - ) - } - }; - } - - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); } + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index a5499196d91..5c7a22c74f0 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -218,6 +218,16 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + ajv@^6.1.0: version "6.2.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.1.tgz#28a6abc493a2abe0fb4c8507acaedb43fa550671" @@ -237,6 +247,27 @@ ajv@^6.10.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= + dependencies: + ansi-wrap "0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= + dependencies: + ansi-wrap "0.1.0" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -252,6 +283,11 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -259,6 +295,11 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -296,26 +337,78 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.1.0: +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= + arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -372,7 +465,12 @@ aws-sign2@~0.6.0: resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= -aws4@^1.2.1: +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4= @@ -407,6 +505,11 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" @@ -446,6 +549,20 @@ boom@2.x.x: dependencies: hoek "2.x.x" +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + integrity sha1-T4owBctKfjiJ90kDD9JbluAdLjE= + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw== + dependencies: + hoek "4.x.x" + brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -454,6 +571,15 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + braces@^2.3.0, braces@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" @@ -484,6 +610,11 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.1.1" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" @@ -542,6 +673,11 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -607,6 +743,11 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -621,6 +762,17 @@ chalk@2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^1.0.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + chalk@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" @@ -693,6 +845,45 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + integrity sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8= + +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + integrity sha1-0hfR6WERjjrJpLi7oyhVU79kfNs= + +cloneable-readable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" + integrity sha1-pikNQT8hemEjL5XkWP84QYz7ARc= + dependencies: + inherits "^2.0.1" + process-nextick-args "^1.0.6" + through2 "^2.0.1" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -723,6 +914,11 @@ color-name@^1.1.1: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -730,11 +926,21 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^2.9.0: + version "2.14.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" + integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -776,6 +982,11 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +convert-source-map@^1.1.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + integrity sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU= + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -851,6 +1062,13 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + integrity sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4= + dependencies: + boom "5.x.x" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -885,6 +1103,18 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug@3.1.0, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -892,13 +1122,6 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -909,6 +1132,13 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +deep-assign@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-1.0.0.tgz#b092743be8427dc621ea0067cdec7e70dd19f37b" + integrity sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s= + dependencies: + is-obj "^1.0.0" + deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -976,6 +1206,11 @@ diagnostic-channel@0.2.0: dependencies: semver "^5.3.0" +diff@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" + integrity sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww== + diffie-hellman@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" @@ -990,6 +1225,28 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" + integrity sha512-g8ID9OroF9hKt2POf8YLayy+9594PzmM3scI00/uBXocX3TWNgoB67hjzkFe9ITAbQOne/lLdBxHXvYUM4ZgGA== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + duplexify@^3.4.2, duplexify@^3.5.3: version "3.5.4" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" @@ -1076,7 +1333,7 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -1101,6 +1358,19 @@ estraverse@^4.1.0, estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +event-stream@^3.3.1, event-stream@~3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + events@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" @@ -1127,6 +1397,13 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1140,6 +1417,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -1147,6 +1431,13 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= + dependencies: + kind-of "^1.1.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -1162,11 +1453,18 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.0: +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -1191,6 +1489,15 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= +fancy-log@^1.1.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1" + integrity sha1-9BEl49hPLn2JpD0G2VjI94vha+E= + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + time-stamp "^1.0.0" + fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" @@ -1206,11 +1513,34 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -1254,6 +1584,11 @@ findup-sync@3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + flush-write-stream@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" @@ -1262,11 +1597,18 @@ flush-write-stream@^1.0.0: inherits "^2.0.1" readable-stream "^2.0.4" -for-in@^1.0.2: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -1281,6 +1623,15 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + integrity sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -1296,6 +1647,11 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -1352,6 +1708,18 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + integrity sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ= + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1376,7 +1744,22 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^3.1.0: +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0, glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= @@ -1384,7 +1767,21 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.5: +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + integrity sha1-pVZlqajM3EGRWofHAeMtTgFvrSI= + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob@7.1.2, glob@^7.0.5, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== @@ -1396,6 +1793,17 @@ glob@^7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.3, glob@^7.1.4: version "7.1.5" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" @@ -1444,21 +1852,161 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +glogg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810" + integrity sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw== + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + graceful-fs@^4.1.15: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== -graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= +growl@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + integrity sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q== + +gulp-chmod@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-chmod/-/gulp-chmod-2.0.0.tgz#00c390b928a0799b251accf631aa09e01cc6299c" + integrity sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw= + dependencies: + deep-assign "^1.0.0" + stat-mode "^0.2.0" + through2 "^2.0.0" + +gulp-filter@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.1.0.tgz#a05e11affb07cf7dcf41a7de1cb7b63ac3783e73" + integrity sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM= + dependencies: + multimatch "^2.0.0" + plugin-error "^0.1.2" + streamfilter "^1.0.5" + +gulp-gunzip@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulp-gunzip/-/gulp-gunzip-1.0.0.tgz#15b741145e83a9c6f50886241b57cc5871f151a9" + integrity sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak= + dependencies: + through2 "~0.6.5" + vinyl "~0.4.6" + +gulp-remote-src@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz#5728cfd643433dd4845ddef0969f0f971a2ab4a1" + integrity sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE= + dependencies: + event-stream "~3.3.4" + node.extend "~1.1.2" + request "~2.79.0" + through2 "~2.0.3" + vinyl "~2.0.1" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + integrity sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw= + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +gulp-symdest@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gulp-symdest/-/gulp-symdest-1.1.0.tgz#c165320732d192ce56fd94271ffa123234bf2ae0" + integrity sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA= + dependencies: + event-stream "^3.3.1" + mkdirp "^0.5.1" + queue "^3.1.0" + vinyl-fs "^2.4.3" + +gulp-untar@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/gulp-untar/-/gulp-untar-0.0.6.tgz#d6bdefde7e9a8e054c9f162385a0782c4be74000" + integrity sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA= + dependencies: + event-stream "~3.3.4" + gulp-util "~3.0.8" + streamifier "~0.1.1" + tar "^2.2.1" + through2 "~2.0.3" + +gulp-util@~3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-vinyl-zip@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.0.tgz#24e40685dc05b7149995245099e0590263be8dad" + integrity sha1-JOQGhdwFtxSZlSRQmeBZAmO+ja0= + dependencies: + event-stream "^3.3.1" + queue "^4.2.1" + through2 "^2.0.3" + vinyl "^2.0.2" + vinyl-fs "^2.0.0" + yauzl "^2.2.1" + yazl "^2.2.1" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" integrity sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4= +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + har-validator@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" @@ -1467,11 +2015,38 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -1541,6 +2116,21 @@ hawk@3.1.3, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + integrity sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ== + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + highlight.js@9.15.10: version "9.15.10" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2" @@ -1560,6 +2150,11 @@ hoek@2.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ== + homedir-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" @@ -1576,6 +2171,15 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -1700,6 +2304,18 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -1712,6 +2328,11 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1729,6 +2350,13 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -1743,6 +2371,23 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +is-my-json-valid@^2.12.4: + version "2.17.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471" + integrity sha512-Q2khNw+oBlWuaYvEEHtKSw/pCxD2L5Rc1C+UQme9X6JdRDh7m5D7HkozA0qa3DUkQ6VzCnEm8mVIQPyIRkI5sQ== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -1760,6 +2405,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + is-odd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" @@ -1774,7 +2424,22 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-stream@^1.1.0: +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -1784,6 +2449,16 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4= + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -1794,6 +2469,16 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +is@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" + integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1846,7 +2531,7 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= -json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= @@ -1875,6 +2560,11 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -1885,6 +2575,11 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" + integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -1916,6 +2611,13 @@ lazy-cache@^2.0.2: dependencies: set-getter "^0.1.0" +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -1961,6 +2663,110 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" @@ -2003,6 +2809,11 @@ map-cache@^0.2.2: resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -2073,6 +2884,32 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + micromatch@^3.0.4, micromatch@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -2132,7 +2969,7 @@ mime-db@~1.30.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= -mime-types@^2.1.12, mime-types@~2.1.7: +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo= @@ -2154,7 +2991,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -2166,7 +3003,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.2.0: +minimist@^1.1.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -2195,7 +3032,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -"mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -2221,6 +3058,22 @@ mocha-multi-reporters@^1.1.7: debug "^3.1.0" lodash "^4.16.4" +mocha@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" + integrity sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA== + dependencies: + browser-stdout "1.3.0" + commander "2.11.0" + debug "3.1.0" + diff "3.3.1" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + mkdirp "0.5.1" + supports-color "4.4.0" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -2238,6 +3091,23 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + nan@^2.3.0: version "2.9.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" @@ -2322,6 +3192,13 @@ node-pre-gyp@^0.6.39: tar "^2.2.1" tar-pack "^3.4.0" +node.extend@~1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.6.tgz#a7b882c82d6c93a4863a5504bd5de8ec86258b96" + integrity sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y= + dependencies: + is "^3.1.0" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -2330,7 +3207,7 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-path@^2.1.1: +normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -2359,12 +3236,17 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -oauth-sign@~0.8.1: +oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= -object-assign@^4.1.0: +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-assign@^4.0.0, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -2385,6 +3267,14 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -2399,6 +3289,14 @@ once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: dependencies: wrappy "1" +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + integrity sha1-cTfmmzKYuzQiR6G77jiByA4v14s= + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -2490,6 +3388,16 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -2525,6 +3433,13 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + pbkdf2@^3.0.3: version "3.0.14" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" @@ -2536,11 +3451,21 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + picomatch@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177" @@ -2551,6 +3476,18 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -2558,12 +3495,28 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -process-nextick-args@~1.0.6: +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +process-nextick-args@^1.0.6, process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= @@ -2639,11 +3592,21 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + integrity sha1-51vV9uJoEioqDgvaYwslUMFmUCw= + qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" integrity sha1-E+JtKK1rD/qpExLNO/cI7TUecjM= +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A== + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -2654,6 +3617,33 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= +querystringify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" + integrity sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs= + +queue@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/queue/-/queue-3.1.0.tgz#6c49d01f009e2256788789f2bffac6b8b9990585" + integrity sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU= + dependencies: + inherits "~2.0.0" + +queue@^4.2.1: + version "4.4.2" + resolved "https://registry.yarnpkg.com/queue/-/queue-4.4.2.tgz#5a9733d9a8b8bd1b36e934bc9c55ab89b28e29c7" + integrity sha512-fSMRXbwhMwipcDZ08enW2vl+YDmAmhcNcr43sCJL8DIg+CFOsoRLG23ctxA+fwNk1w55SePSiS7oqQQSgQoVJQ== + dependencies: + inherits "~2.0.0" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + integrity sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" @@ -2692,7 +3682,17 @@ rc@^1.1.7: string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.1.5: +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== @@ -2705,6 +3705,16 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -2715,6 +3725,13 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -2733,11 +3750,21 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= -repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -2766,6 +3793,60 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" +request@^2.83.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + integrity sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw== + dependencies: + aws-sign2 "~0.7.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.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +request@~2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + integrity sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -2776,6 +3857,11 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requires-port@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -2856,7 +3942,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -semver@^5.3.0, semver@^5.5.0: +semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== @@ -2980,6 +4066,13 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + integrity sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg== + dependencies: + hoek "4.x.x" + source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" @@ -2996,6 +4089,13 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.3.tgz#2b3d5fff298cfa4d1afd7d4352d569e9a0158e76" + integrity sha512-eKkTgWYeBOQqFGXRfKabMFdnWepo51vWqEdoeikaEPFiJC7MCU5j2h4+6Q8npkZTeLGbSyecZvRxiSoWl3rh+w== + dependencies: + source-map "^0.6.0" + source-map-support@~0.5.12: version "0.5.16" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" @@ -3019,6 +4119,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sparkles@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + integrity sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM= + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -3026,6 +4131,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -3053,6 +4165,11 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +stat-mode@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3069,6 +4186,13 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + stream-each@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" @@ -3093,6 +4217,18 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= +streamfilter@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.7.tgz#ae3e64522aa5a35c061fd17f67620c7653c643c9" + integrity sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ== + dependencies: + readable-stream "^2.0.2" + +streamifier@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f" + integrity sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8= + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -3118,7 +4254,12 @@ string_decoder@^1.0.0, string_decoder@~1.0.3: dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4: +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= @@ -3144,6 +4285,21 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + integrity sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4= + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -3154,6 +4310,13 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +supports-color@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + integrity sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ== + dependencies: + has-flag "^2.0.0" + supports-color@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" @@ -3161,6 +4324,11 @@ supports-color@6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + supports-color@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" @@ -3225,7 +4393,23 @@ terser@^4.1.2: source-map "~0.6.1" source-map-support "~0.5.12" -through2@^2.0.0: +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + integrity sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw= + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.6.0, through2@~0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@^2.0.3, through2@~2.0.0, through2@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= @@ -3233,6 +4417,16 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" +through@2, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + timers-browserify@^2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae" @@ -3240,6 +4434,13 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + integrity sha1-HN+kcqnvUMI57maZm2YsoOs5k38= + dependencies: + extend-shallow "^2.0.1" + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -3277,7 +4478,7 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@~2.3.0: +tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" integrity sha1-C2GKVWW23qkL80JdBNVe3EdadWE= @@ -3312,6 +4513,11 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -3366,6 +4572,14 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-stream@^2.0.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + integrity sha1-WqADz76Uxf+GbE59ZouxxNuts2k= + dependencies: + json-stable-stringify "^1.0.0" + through2-filter "^2.0.0" + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -3391,6 +4605,14 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" + integrity sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw== + dependencies: + querystringify "~1.0.0" + requires-port "~1.0.0" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -3427,7 +4649,7 @@ util@^0.11.0: dependencies: inherits "2.0.3" -uuid@^3.0.0: +uuid@^3.0.0, uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" integrity sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA== @@ -3437,6 +4659,11 @@ v8-compile-cache@2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -3446,6 +4673,88 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vinyl-fs@^2.0.0, vinyl-fs@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + integrity sha1-vm/zJwy1Xf19MGNkDegfJddTIjk= + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl-source-stream@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-1.1.2.tgz#62b53a135610a896e98ca96bee3a87f008a8e780" + integrity sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A= + dependencies: + through2 "^2.0.3" + vinyl "^0.4.3" + +vinyl@^0.4.3, vinyl@~0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" + integrity sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw= + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vinyl@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" + integrity sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw= + dependencies: + clone "^1.0.0" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + is-stream "^1.1.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + vm-browserify@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" @@ -3463,6 +4772,26 @@ vscode-nls@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002" integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw== +vscode@^1.1.10: + version "1.1.10" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.10.tgz#d1cba378ab24f1d3ddf9cd470d242ee1472dd35b" + integrity sha512-MvFXXSGuhw0Q6GC6dQrnRc0ES+63wpttGIoYGBMQnoS9JFCCNC/rWfX0lBCHJyuKL2Q8CYg0ROsMEHbHVwEtVw== + dependencies: + glob "^7.1.2" + gulp-chmod "^2.0.0" + gulp-filter "^5.0.1" + gulp-gunzip "1.0.0" + gulp-remote-src "^0.4.3" + gulp-symdest "^1.1.0" + gulp-untar "^0.0.6" + gulp-vinyl-zip "^2.1.0" + mocha "^4.0.1" + request "^2.83.0" + semver "^5.4.1" + source-map-support "^0.5.0" + url-parse "^1.1.9" + vinyl-source-stream "^1.1.0" + watchpack@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" @@ -3578,7 +4907,7 @@ xml@^1.0.0: resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= -xtend@^4.0.0, xtend@~4.0.1: +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= @@ -3618,6 +4947,21 @@ yargs@13.2.4: y18n "^4.0.0" yargs-parser "^13.1.0" +yauzl@^2.2.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" + integrity sha1-qBmB6nCleUYTOIPwKcWCGok1mn8= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.0.1" + +yazl@^2.2.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071" + integrity sha1-7CblzIfVYBud+EMtvdPNLlFzoHE= + dependencies: + buffer-crc32 "~0.2.3" + zone.js@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009" diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 35f9eda5cad..b3f12439bc8 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -26,7 +26,8 @@ "devDependencies": { "@types/node": "^12.11.7", "@types/rimraf": "2.0.2", - "@types/semver": "^5.5.0" + "@types/semver": "^5.5.0", + "vscode": "^1.1.36" }, "scripts": { "vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:typescript ./tsconfig.json" diff --git a/extensions/typescript-language-features/src/test/index.ts b/extensions/typescript-language-features/src/test/index.ts index 4095b0957be..1a5f7419059 100644 --- a/extensions/typescript-language-features/src/test/index.ts +++ b/extensions/typescript-language-features/src/test/index.ts @@ -3,48 +3,26 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +// +// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING +// +// This file is providing the test runner to use when running extension tests. +// By default the test runner in use is Mocha based. +// +// You can provide your own test runner if you want to override it by exporting +// a function run(testRoot: string, clb: (error:Error) => void) that the extension +// host can call to run the tests. The test runner is expected to use console.log +// to report the results back to the caller. When the tests are finished, return +// a possible error to the callback or null if none. -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - } = { - ui: 'tdd', - timeout: 60000 - }; +const testRunner = require('vscode/lib/testrunner'); - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } +// You can directly control Mocha options by uncommenting the following lines +// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info +testRunner.configure({ + ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), // colored output from test results (only windows cannot handle) + timeout: 60000, +}); - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); -} +export = testRunner; diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index 4175fbbfd42..82daf1829dd 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -44,6 +44,23 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== +agent-base@4, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +ajv@^6.5.5: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + applicationinsights@1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5" @@ -53,11 +70,45 @@ applicationinsights@1.0.8: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" + integrity "sha1-JDkOatYThrCnRyZXVNKhchnehiw= sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -66,11 +117,69 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + diagnostic-channel-publishers@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" @@ -83,12 +192,100 @@ diagnostic-channel@0.2.0: dependencies: semver "^5.3.0" +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +escape-string-regexp@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -glob@^7.1.3: +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.2, glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -100,6 +297,59 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -113,18 +363,114 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + jsonc-parser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== -minimatch@^3.0.4: +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +mime-db@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity "sha1-ChLgUCZQ5HPXNVNQUOfI9OtPrlg= sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity "sha1-nJIfwJt+FJpl39wNpNIJlyALCgY= sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==" + dependencies: + mime-db "1.43.0" + +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -137,6 +483,67 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +psl@^1.1.24: + version "1.7.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" + integrity "sha1-8cTEeo75cWfepda79IFtc26ISjw= sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -144,21 +551,115 @@ rimraf@^2.6.3: dependencies: glob "^7.1.3" +safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + semver@5.5.1: version "5.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== -semver@^5.3.0: +semver@^5.3.0, semver@^5.4.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +source-map-support@^0.5.0: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + typescript-vscode-sh-plugin@^0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/typescript-vscode-sh-plugin/-/typescript-vscode-sh-plugin-0.6.8.tgz#60d5025f2ab814496824ee997b5e9fc12c5b7f1a" integrity sha512-XEh/GwBRsZKWQjPTODqWWiW8o8DyF7Yzfp/xvq1vyK5Z9JykFKAkx95BEmALv9x9dpc2RcLZHgVsKFXrtDABCw== +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +url-parse@^1.4.4: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +uuid@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vscode-extension-telemetry@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b" @@ -171,6 +672,27 @@ vscode-nls@^4.1.1: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== +vscode-test@^0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8" + integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w== + dependencies: + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + +vscode@^1.1.36: + version "1.1.36" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.36.tgz#5e1a0d1bf4977d0c7bc5159a9a13d5b104d4b1b6" + integrity sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ== + dependencies: + glob "^7.1.2" + mocha "^5.2.0" + request "^2.88.0" + semver "^5.4.1" + source-map-support "^0.5.0" + url-parse "^1.4.4" + vscode-test "^0.4.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index 512b5373ebe..8ac6b2806ca 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -76,6 +76,7 @@ "languages": [ "markdown" ], + "configurationAttributes": { "launch": { "required": [ @@ -120,6 +121,7 @@ "@types/node": "^12.11.7", "mocha-junit-reporter": "^1.17.0", "mocha-multi-reporters": "^1.1.7", - "typescript": "^1.6.2" + "typescript": "^1.6.2", + "vscode": "1.1.5" } } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/index.ts b/extensions/vscode-api-tests/src/singlefolder-tests/index.ts index 363358301d8..8379f9b1ab7 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/index.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/index.ts @@ -3,68 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); const suite = 'Integration Single Folder Tests'; -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - reporter?: string; - reporterOptions?: any; - } = { - ui: 'tdd', - timeout: 60000, - reporter: undefined, - reporterOptions: undefined +const options: any = { + ui: 'tdd', + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } }; - - if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { - options.reporter = 'mocha-multi-reporters'; - options.reporterOptions = { - reporterEnabled: 'spec, mocha-junit-reporter', - mochaJunitReporterReporterOptions: { - testsuitesTitle: `${suite} ${process.platform}`, - mochaFile: path.join( - process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, - `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml` - ) - } - }; - } - - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); } + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/vscode-api-tests/src/workspace-tests/index.ts b/extensions/vscode-api-tests/src/workspace-tests/index.ts index 69113f3cd41..dfef493b2ab 100644 --- a/extensions/vscode-api-tests/src/workspace-tests/index.ts +++ b/extensions/vscode-api-tests/src/workspace-tests/index.ts @@ -3,68 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); const suite = 'Integration Workspace Tests'; -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - reporter?: string; - reporterOptions?: any; - } = { - ui: 'tdd', - timeout: 60000, - reporter: undefined, - reporterOptions: undefined +const options: any = { + ui: 'tdd', + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } }; - - if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { - options.reporter = 'mocha-multi-reporters'; - options.reporterOptions = { - reporterEnabled: 'spec, mocha-junit-reporter', - mochaJunitReporterReporterOptions: { - testsuitesTitle: `${suite} ${process.platform}`, - mochaFile: path.join( - process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, - `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml` - ) - } - }; - } - - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); } + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/vscode-api-tests/yarn.lock b/extensions/vscode-api-tests/yarn.lock index cae8848e493..2d8b725ff2d 100644 --- a/extensions/vscode-api-tests/yarn.lock +++ b/extensions/vscode-api-tests/yarn.lock @@ -12,21 +12,314 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a" integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA== +ajv@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" + integrity sha1-RBT/dKUIecII7l/cgm4ywwNUnto= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y= + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.2.1, aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + integrity sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40= + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= + dependencies: + hoek "2.x.x" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + integrity sha1-T4owBctKfjiJ90kDD9JbluAdLjE= + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw== + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI= + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.0.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + integrity sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8= + +cloneable-readable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" + integrity sha1-pikNQT8hemEjL5XkWP84QYz7ARc= + dependencies: + inherits "^2.0.1" + process-nextick-args "^1.0.6" + through2 "^2.0.1" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + integrity sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk= + dependencies: + delayed-stream "~1.0.0" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + integrity sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= + dependencies: + boom "2.x.x" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + integrity sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4= + dependencies: + boom "5.x.x" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= + dependencies: + ms "2.0.0" + debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -41,16 +334,896 @@ debug@^3.1.0: dependencies: ms "2.0.0" -is-buffer@~1.1.1: +deep-assign@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-1.0.0.tgz#b092743be8427dc621ea0067cdec7e70dd19f37b" + integrity sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s= + dependencies: + is-obj "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" + integrity sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + integrity sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU= + dependencies: + jsbn "~0.1.0" + +end-of-stream@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + integrity sha1-epDYM+/abPpurA9JSduw+tOmMgY= + dependencies: + once "^1.4.0" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +event-stream@^3.3.1, event-stream@~3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0, extsprintf@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +fancy-log@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" + integrity sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg= + dependencies: + chalk "^1.1.1" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + integrity sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + integrity sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + integrity sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ= + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + integrity sha1-pVZlqajM3EGRWofHAeMtTgFvrSI= + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.5, glob@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glogg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" + integrity sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U= + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +gulp-chmod@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-chmod/-/gulp-chmod-2.0.0.tgz#00c390b928a0799b251accf631aa09e01cc6299c" + integrity sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw= + dependencies: + deep-assign "^1.0.0" + stat-mode "^0.2.0" + through2 "^2.0.0" + +gulp-filter@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.0.1.tgz#5d87f662e317e5839ef7650e620e6c9008ff92d0" + integrity sha512-5olRzAhFdXB2klCu1lnazP65aO9YdA/5WfC9VdInIc8PrUeDIoZfaA3Edb0yUBGhVdHv4eHKL9Fg5tUoEJ9z5A== + dependencies: + gulp-util "^3.0.6" + multimatch "^2.0.0" + streamfilter "^1.0.5" + +gulp-gunzip@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/gulp-gunzip/-/gulp-gunzip-0.0.3.tgz#7b6e07b0f58fd3d42515c48ead5a63df0572f62f" + integrity sha1-e24HsPWP09QlFcSOrVpj3wVy9i8= + dependencies: + through2 "~0.6.5" + vinyl "~0.4.6" + +gulp-remote-src@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz#5728cfd643433dd4845ddef0969f0f971a2ab4a1" + integrity sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE= + dependencies: + event-stream "~3.3.4" + node.extend "~1.1.2" + request "~2.79.0" + through2 "~2.0.3" + vinyl "~2.0.1" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + integrity sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw= + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +gulp-symdest@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gulp-symdest/-/gulp-symdest-1.1.0.tgz#c165320732d192ce56fd94271ffa123234bf2ae0" + integrity sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA= + dependencies: + event-stream "^3.3.1" + mkdirp "^0.5.1" + queue "^3.1.0" + vinyl-fs "^2.4.3" + +gulp-untar@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/gulp-untar/-/gulp-untar-0.0.6.tgz#d6bdefde7e9a8e054c9f162385a0782c4be74000" + integrity sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA= + dependencies: + event-stream "~3.3.4" + gulp-util "~3.0.8" + streamifier "~0.1.1" + tar "^2.2.1" + through2 "~2.0.3" + +gulp-util@^3.0.6, gulp-util@~3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-vinyl-zip@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-vinyl-zip/-/gulp-vinyl-zip-1.4.0.tgz#56382f2ccb57231bb0478c78737ccd572973bee1" + integrity sha1-VjgvLMtXIxuwR4x4c3zNVylzvuE= + dependencies: + event-stream "^3.3.1" + queue "^3.0.10" + through2 "^0.6.3" + vinyl "^0.4.6" + vinyl-fs "^2.0.0" + yauzl "^2.2.1" + yazl "^2.2.1" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + integrity sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ== + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ== + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-my-json-valid@^2.12.4: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + integrity sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4= + +is@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" + integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c= + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash@^4.16.4: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" @@ -60,12 +1233,62 @@ md5@^2.1.0: crypt "~0.0.1" is-buffer "~1.1.1" +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo= + dependencies: + mime-db "~1.30.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -mkdirp@~0.5.1: +minimist@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -91,11 +1314,439 @@ mocha-multi-reporters@^1.1.7: debug "^3.1.0" lodash "^4.16.4" +mocha@^3.2.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +node.extend@~1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.6.tgz#a7b882c82d6c93a4863a5504bd5de8ec86258b96" + integrity sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y= + dependencies: + is "^3.1.0" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-assign@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + integrity sha1-cTfmmzKYuzQiR6G77jiByA4v14s= + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +process-nextick-args@^1.0.6, process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + integrity sha1-51vV9uJoEioqDgvaYwslUMFmUCw= + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A== + +querystringify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" + integrity sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs= + +queue@^3.0.10, queue@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/queue/-/queue-3.1.0.tgz#6c49d01f009e2256788789f2bffac6b8b9990585" + integrity sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU= + dependencies: + inherits "~2.0.0" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + integrity sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.79.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + integrity sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw== + dependencies: + aws-sign2 "~0.7.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.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +request@~2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + integrity sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +requires-port@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +rimraf@2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + +semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= + dependencies: + hoek "2.x.x" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + integrity sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg== + dependencies: + hoek "4.x.x" + +source-map-support@^0.4.11: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +sparkles@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + integrity sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM= + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + integrity sha1-US322mKHFEMW3EwY/hzx2UBzm+M= + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stat-mode@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamfilter@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.5.tgz#87507111beb8e298451717b511cfed8f002abf53" + integrity sha1-h1BxEb644phFFxe1Ec/tjwAqv1M= + dependencies: + readable-stream "^2.0.2" + +streamifier@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f" + integrity sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8= + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4, stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -103,12 +1754,268 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + integrity sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4= + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU= + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + integrity sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw= + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.6.0, through2@^0.6.1, through2@^0.6.3, through2@~0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@~2.0.0, through2@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + integrity sha1-HN+kcqnvUMI57maZm2YsoOs5k38= + dependencies: + extend-shallow "^2.0.1" + +tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + integrity sha1-C2GKVWW23qkL80JdBNVe3EdadWE= + dependencies: + punycode "^1.4.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + typescript@^1.6.2: version "1.8.10" resolved "https://registry.yarnpkg.com/typescript/-/typescript-1.8.10.tgz#b475d6e0dff0bf50f296e5ca6ef9fbb5c7320f1e" integrity sha1-tHXW4N/wv1DyluXKbvn7tccyDx4= +unique-stream@^2.0.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + integrity sha1-WqADz76Uxf+GbE59ZouxxNuts2k= + dependencies: + json-stable-stringify "^1.0.0" + through2-filter "^2.0.0" + +url-parse@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" + integrity sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw== + dependencies: + querystringify "~1.0.0" + requires-port "~1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^3.0.0, uuid@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== + +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^2.0.0, vinyl-fs@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + integrity sha1-vm/zJwy1Xf19MGNkDegfJddTIjk= + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl-source-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz#44cbe5108205279deb0c5653c094a2887938b1ab" + integrity sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas= + dependencies: + through2 "^0.6.1" + vinyl "^0.4.3" + +vinyl@^0.4.3, vinyl@^0.4.6, vinyl@~0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" + integrity sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw= + dependencies: + clone "^1.0.0" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + is-stream "^1.1.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vscode@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.5.tgz#10eb104001840c3dd0813815fd4a05f8fc882d14" + integrity sha1-EOsQQAGEDD3QgTgV/UoF+PyILRQ= + dependencies: + glob "^7.1.1" + gulp-chmod "^2.0.0" + gulp-filter "^5.0.0" + gulp-gunzip "0.0.3" + gulp-remote-src "^0.4.2" + gulp-symdest "^1.1.0" + gulp-untar "^0.0.6" + gulp-vinyl-zip "^1.4.0" + mocha "^3.2.0" + request "^2.79.0" + semver "^5.3.0" + source-map-support "^0.4.11" + url-parse "^1.1.9" + vinyl-source-stream "^1.1.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + xml@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +yauzl@^2.2.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" + integrity sha1-qBmB6nCleUYTOIPwKcWCGok1mn8= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.0.1" + +yazl@^2.2.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071" + integrity sha1-7CblzIfVYBud+EMtvdPNLlFzoHE= + dependencies: + buffer-crc32 "~0.2.3" diff --git a/extensions/vscode-colorize-tests/package.json b/extensions/vscode-colorize-tests/package.json index 9ba9c999fd7..d99e050d302 100644 --- a/extensions/vscode-colorize-tests/package.json +++ b/extensions/vscode-colorize-tests/package.json @@ -22,7 +22,8 @@ "devDependencies": { "@types/node": "^12.11.7", "mocha-junit-reporter": "^1.17.0", - "mocha-multi-reporters": "^1.1.7" + "mocha-multi-reporters": "^1.1.7", + "vscode": "1.1.5" }, "contributes": { "semanticTokenTypes": [ @@ -40,9 +41,7 @@ "semanticTokenStyleDefaults": [ { "selector": "testToken", - "scope": [ - "entity.name.function.special" - ] + "scope": [ "entity.name.function.special" ] }, { "selector": "*.testModifier", diff --git a/extensions/vscode-colorize-tests/src/index.ts b/extensions/vscode-colorize-tests/src/index.ts index 9f853968e40..a315ee36112 100644 --- a/extensions/vscode-colorize-tests/src/index.ts +++ b/extensions/vscode-colorize-tests/src/index.ts @@ -3,68 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); const suite = 'Integration Colorize Tests'; -export function run(): Promise { - // Create the mocha test - const options: { - ui?: string; - timeout?: number; - reporter?: string; - reporterOptions?: any; - } = { - ui: 'tdd', - timeout: 60000, - reporter: undefined, - reporterOptions: undefined +const options: any = { + ui: 'tdd', + useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } }; - - if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { - options.reporter = 'mocha-multi-reporters'; - options.reporterOptions = { - reporterEnabled: 'spec, mocha-junit-reporter', - mochaJunitReporterReporterOptions: { - testsuitesTitle: `${suite} ${process.platform}`, - mochaFile: path.join( - process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, - `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml` - ) - } - }; - } - - const mocha = new Mocha(options); - if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') { - mocha.useColors(true); - } - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - e(err); - } - }); - }); } + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/vscode-colorize-tests/yarn.lock b/extensions/vscode-colorize-tests/yarn.lock index f2e574c18c5..b8a66d65eff 100644 --- a/extensions/vscode-colorize-tests/yarn.lock +++ b/extensions/vscode-colorize-tests/yarn.lock @@ -7,21 +7,314 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a" integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA== +ajv@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" + integrity sha1-RBT/dKUIecII7l/cgm4ywwNUnto= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y= + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.2.1, aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + integrity sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40= + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= + dependencies: + hoek "2.x.x" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + integrity sha1-T4owBctKfjiJ90kDD9JbluAdLjE= + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw== + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI= + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.0.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + integrity sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8= + +cloneable-readable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" + integrity sha1-pikNQT8hemEjL5XkWP84QYz7ARc= + dependencies: + inherits "^2.0.1" + process-nextick-args "^1.0.6" + through2 "^2.0.1" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + integrity sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk= + dependencies: + delayed-stream "~1.0.0" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + integrity sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= + dependencies: + boom "2.x.x" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + integrity sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4= + dependencies: + boom "5.x.x" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= + dependencies: + ms "2.0.0" + debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -36,21 +329,901 @@ debug@^3.1.0: dependencies: ms "2.0.0" -is-buffer@~1.1.1: +deep-assign@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-1.0.0.tgz#b092743be8427dc621ea0067cdec7e70dd19f37b" + integrity sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s= + dependencies: + is-obj "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" + integrity sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + integrity sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU= + dependencies: + jsbn "~0.1.0" + +end-of-stream@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + integrity sha1-epDYM+/abPpurA9JSduw+tOmMgY= + dependencies: + once "^1.4.0" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +event-stream@^3.3.1, event-stream@~3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0, extsprintf@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +fancy-log@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" + integrity sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg= + dependencies: + chalk "^1.1.1" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + integrity sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + integrity sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + integrity sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ= + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + integrity sha1-pVZlqajM3EGRWofHAeMtTgFvrSI= + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.5, glob@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glogg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" + integrity sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U= + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +gulp-chmod@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-chmod/-/gulp-chmod-2.0.0.tgz#00c390b928a0799b251accf631aa09e01cc6299c" + integrity sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw= + dependencies: + deep-assign "^1.0.0" + stat-mode "^0.2.0" + through2 "^2.0.0" + +gulp-filter@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.0.1.tgz#5d87f662e317e5839ef7650e620e6c9008ff92d0" + integrity sha512-5olRzAhFdXB2klCu1lnazP65aO9YdA/5WfC9VdInIc8PrUeDIoZfaA3Edb0yUBGhVdHv4eHKL9Fg5tUoEJ9z5A== + dependencies: + gulp-util "^3.0.6" + multimatch "^2.0.0" + streamfilter "^1.0.5" + +gulp-gunzip@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/gulp-gunzip/-/gulp-gunzip-0.0.3.tgz#7b6e07b0f58fd3d42515c48ead5a63df0572f62f" + integrity sha1-e24HsPWP09QlFcSOrVpj3wVy9i8= + dependencies: + through2 "~0.6.5" + vinyl "~0.4.6" + +gulp-remote-src@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz#5728cfd643433dd4845ddef0969f0f971a2ab4a1" + integrity sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE= + dependencies: + event-stream "~3.3.4" + node.extend "~1.1.2" + request "~2.79.0" + through2 "~2.0.3" + vinyl "~2.0.1" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + integrity sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw= + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +gulp-symdest@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gulp-symdest/-/gulp-symdest-1.1.0.tgz#c165320732d192ce56fd94271ffa123234bf2ae0" + integrity sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA= + dependencies: + event-stream "^3.3.1" + mkdirp "^0.5.1" + queue "^3.1.0" + vinyl-fs "^2.4.3" + +gulp-untar@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/gulp-untar/-/gulp-untar-0.0.6.tgz#d6bdefde7e9a8e054c9f162385a0782c4be74000" + integrity sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA= + dependencies: + event-stream "~3.3.4" + gulp-util "~3.0.8" + streamifier "~0.1.1" + tar "^2.2.1" + through2 "~2.0.3" + +gulp-util@^3.0.6, gulp-util@~3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-vinyl-zip@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-vinyl-zip/-/gulp-vinyl-zip-1.4.0.tgz#56382f2ccb57231bb0478c78737ccd572973bee1" + integrity sha1-VjgvLMtXIxuwR4x4c3zNVylzvuE= + dependencies: + event-stream "^3.3.1" + queue "^3.0.10" + through2 "^0.6.3" + vinyl "^0.4.6" + vinyl-fs "^2.0.0" + yauzl "^2.2.1" + yazl "^2.2.1" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + integrity sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ== + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ== + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-my-json-valid@^2.12.4: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + integrity sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4= + +is@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" + integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + jsonc-parser@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c= + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash@^4.16.4: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" @@ -60,12 +1233,62 @@ md5@^2.1.0: crypt "~0.0.1" is-buffer "~1.1.1" +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo= + dependencies: + mime-db "~1.30.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -mkdirp@~0.5.1: +minimist@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -91,11 +1314,439 @@ mocha-multi-reporters@^1.1.7: debug "^3.1.0" lodash "^4.16.4" +mocha@^3.2.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +node.extend@~1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.6.tgz#a7b882c82d6c93a4863a5504bd5de8ec86258b96" + integrity sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y= + dependencies: + is "^3.1.0" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-assign@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + integrity sha1-cTfmmzKYuzQiR6G77jiByA4v14s= + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +process-nextick-args@^1.0.6, process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + integrity sha1-51vV9uJoEioqDgvaYwslUMFmUCw= + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A== + +querystringify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" + integrity sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs= + +queue@^3.0.10, queue@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/queue/-/queue-3.1.0.tgz#6c49d01f009e2256788789f2bffac6b8b9990585" + integrity sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU= + dependencies: + inherits "~2.0.0" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + integrity sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.79.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + integrity sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw== + dependencies: + aws-sign2 "~0.7.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.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +request@~2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + integrity sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +requires-port@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +rimraf@2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + +semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= + dependencies: + hoek "2.x.x" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + integrity sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg== + dependencies: + hoek "4.x.x" + +source-map-support@^0.4.11: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +sparkles@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + integrity sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM= + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + integrity sha1-US322mKHFEMW3EwY/hzx2UBzm+M= + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stat-mode@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamfilter@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.5.tgz#87507111beb8e298451717b511cfed8f002abf53" + integrity sha1-h1BxEb644phFFxe1Ec/tjwAqv1M= + dependencies: + readable-stream "^2.0.2" + +streamifier@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f" + integrity sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8= + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4, stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -103,7 +1754,263 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + integrity sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4= + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU= + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + integrity sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw= + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.6.0, through2@^0.6.1, through2@^0.6.3, through2@~0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@~2.0.0, through2@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + integrity sha1-HN+kcqnvUMI57maZm2YsoOs5k38= + dependencies: + extend-shallow "^2.0.1" + +tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + integrity sha1-C2GKVWW23qkL80JdBNVe3EdadWE= + dependencies: + punycode "^1.4.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +unique-stream@^2.0.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + integrity sha1-WqADz76Uxf+GbE59ZouxxNuts2k= + dependencies: + json-stable-stringify "^1.0.0" + through2-filter "^2.0.0" + +url-parse@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" + integrity sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw== + dependencies: + querystringify "~1.0.0" + requires-port "~1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^3.0.0, uuid@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== + +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^2.0.0, vinyl-fs@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + integrity sha1-vm/zJwy1Xf19MGNkDegfJddTIjk= + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl-source-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz#44cbe5108205279deb0c5653c094a2887938b1ab" + integrity sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas= + dependencies: + through2 "^0.6.1" + vinyl "^0.4.3" + +vinyl@^0.4.3, vinyl@^0.4.6, vinyl@~0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" + integrity sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw= + dependencies: + clone "^1.0.0" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + is-stream "^1.1.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vscode@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.5.tgz#10eb104001840c3dd0813815fd4a05f8fc882d14" + integrity sha1-EOsQQAGEDD3QgTgV/UoF+PyILRQ= + dependencies: + glob "^7.1.1" + gulp-chmod "^2.0.0" + gulp-filter "^5.0.0" + gulp-gunzip "0.0.3" + gulp-remote-src "^0.4.2" + gulp-symdest "^1.1.0" + gulp-untar "^0.0.6" + gulp-vinyl-zip "^1.4.0" + mocha "^3.2.0" + request "^2.79.0" + semver "^5.3.0" + source-map-support "^0.4.11" + url-parse "^1.1.9" + vinyl-source-stream "^1.1.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + xml@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +yauzl@^2.2.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" + integrity sha1-qBmB6nCleUYTOIPwKcWCGok1mn8= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.0.1" + +yazl@^2.2.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071" + integrity sha1-7CblzIfVYBud+EMtvdPNLlFzoHE= + dependencies: + buffer-crc32 "~0.2.3" diff --git a/extensions/vscode-test-resolver/package.json b/extensions/vscode-test-resolver/package.json index 5583c0da84c..90e3e0e87ee 100644 --- a/extensions/vscode-test-resolver/package.json +++ b/extensions/vscode-test-resolver/package.json @@ -8,9 +8,7 @@ "engines": { "vscode": "^1.25.0" }, - "extensionKind": [ - "ui" - ], + "extensionKind": [ "ui" ], "scripts": { "compile": "node ./node_modules/vscode/bin/compile -watch -p ./", "vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:vscode-test-resolver ./tsconfig.json" @@ -23,7 +21,8 @@ ], "main": "./out/extension", "devDependencies": { - "@types/node": "^12.11.7" + "@types/node": "^12.11.7", + "vscode": "1.1.5" }, "contributes": { "resourceLabelFormatters": [ @@ -89,4 +88,6 @@ } } } + + } diff --git a/extensions/vscode-test-resolver/yarn.lock b/extensions/vscode-test-resolver/yarn.lock index 40784952b89..4bc1451096e 100644 --- a/extensions/vscode-test-resolver/yarn.lock +++ b/extensions/vscode-test-resolver/yarn.lock @@ -6,3 +6,1874 @@ version "12.11.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a" integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA== + +ajv@^6.5.5: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= + dependencies: + ansi-wrap "0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + integrity sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.1.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= + dependencies: + ms "2.0.0" + +deep-assign@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-1.0.0.tgz#b092743be8427dc621ea0067cdec7e70dd19f37b" + integrity sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s= + dependencies: + is-obj "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +end-of-stream@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +event-stream@3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +event-stream@^3.3.1, event-stream@~3.3.4: + version "3.3.5" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.5.tgz#e5dd8989543630d94c6cf4d657120341fa31636b" + integrity sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g== + dependencies: + duplexer "^0.1.1" + from "^0.1.7" + map-stream "0.0.7" + pause-stream "^0.0.11" + split "^1.0.1" + stream-combiner "^0.2.2" + through "^2.3.8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= + dependencies: + kind-of "^1.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fancy-log@^1.1.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +from@^0.1.7, from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^5.3.2: + version "5.3.5" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + integrity sha1-pVZlqajM3EGRWofHAeMtTgFvrSI= + dependencies: + extend "^3.0.0" + glob "^5.0.3" + glob-parent "^3.0.0" + micromatch "^2.3.7" + ordered-read-streams "^0.3.0" + through2 "^0.6.0" + to-absolute-glob "^0.1.1" + unique-stream "^2.0.2" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.1, glob@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.2: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +gulp-chmod@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-chmod/-/gulp-chmod-2.0.0.tgz#00c390b928a0799b251accf631aa09e01cc6299c" + integrity sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw= + dependencies: + deep-assign "^1.0.0" + stat-mode "^0.2.0" + through2 "^2.0.0" + +gulp-filter@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.1.0.tgz#a05e11affb07cf7dcf41a7de1cb7b63ac3783e73" + integrity sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM= + dependencies: + multimatch "^2.0.0" + plugin-error "^0.1.2" + streamfilter "^1.0.5" + +gulp-gunzip@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/gulp-gunzip/-/gulp-gunzip-0.0.3.tgz#7b6e07b0f58fd3d42515c48ead5a63df0572f62f" + integrity sha1-e24HsPWP09QlFcSOrVpj3wVy9i8= + dependencies: + through2 "~0.6.5" + vinyl "~0.4.6" + +gulp-remote-src@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/gulp-remote-src/-/gulp-remote-src-0.4.4.tgz#4a4d18fac0ffedde94a7855953de90db00a1d1b1" + integrity sha512-mo7lGgZmNXyTbcUzfjSnUVkx1pnqqiwv/pPaIrYdTO77hq0WNTxXLAzQdoYOnyJ0mfVLNmNl9AGqWLiAzTPMMA== + dependencies: + event-stream "3.3.4" + node.extend "~1.1.2" + request "^2.88.0" + through2 "~2.0.3" + vinyl "~2.0.1" + +gulp-sourcemaps@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + integrity sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw= + dependencies: + convert-source-map "^1.1.1" + graceful-fs "^4.1.2" + strip-bom "^2.0.0" + through2 "^2.0.0" + vinyl "^1.0.0" + +gulp-symdest@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/gulp-symdest/-/gulp-symdest-1.1.1.tgz#b0a6df3d43a0537165946ab8e38c1b7080a66fac" + integrity sha512-UHd3MokfIN7SrFdsbV5uZTwzBpL0ZSTu7iq98fuDqBGZ0dlHxgbQBJwfd6qjCW83snkQ3Hz9IY4sMRMz2iTq7w== + dependencies: + event-stream "3.3.4" + mkdirp "^0.5.1" + queue "^3.1.0" + vinyl-fs "^2.4.3" + +gulp-untar@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/gulp-untar/-/gulp-untar-0.0.6.tgz#d6bdefde7e9a8e054c9f162385a0782c4be74000" + integrity sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA= + dependencies: + event-stream "~3.3.4" + gulp-util "~3.0.8" + streamifier "~0.1.1" + tar "^2.2.1" + through2 "~2.0.3" + +gulp-util@~3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-vinyl-zip@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-vinyl-zip/-/gulp-vinyl-zip-1.4.0.tgz#56382f2ccb57231bb0478c78737ccd572973bee1" + integrity sha1-VjgvLMtXIxuwR4x4c3zNVylzvuE= + dependencies: + event-stream "^3.3.1" + queue "^3.0.10" + through2 "^0.6.3" + vinyl "^0.4.6" + vinyl-fs "^2.0.0" + yauzl "^2.2.1" + yazl "^2.2.1" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + integrity sha1-1LVcafUYhvm2XHDWwmItN+KfSP4= + +is@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/is/-/is-3.3.0.tgz#61cff6dd3c4193db94a3d62582072b44e5645d79" + integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" + integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c= + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +map-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= + +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.38.0: + version "1.38.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" + integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.22" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" + integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== + dependencies: + mime-db "~1.38.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@^3.2.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +node.extend@~1.1.2: + version "1.1.8" + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.8.tgz#0aab3e63789f4e6d68b42bc00073ad1881243cf0" + integrity sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA== + dependencies: + has "^1.0.3" + is "^3.2.1" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-assign@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +ordered-read-streams@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + integrity sha1-cTfmmzKYuzQiR6G77jiByA4v14s= + dependencies: + is-stream "^1.0.1" + readable-stream "^2.0.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +pause-stream@0.0.11, pause-stream@^0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +psl@^1.1.24: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" + integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== + +queue@^3.0.10, queue@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/queue/-/queue-3.1.0.tgz#6c49d01f009e2256788789f2bffac6b8b9990585" + integrity sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU= + dependencies: + inherits "~2.0.0" + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.3.5, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.79.0, request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +rimraf@2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +source-map-support@^0.4.11: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + +split@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stat-mode@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" + integrity sha1-5sgLYjEj19gM8TLOU480YokHJQI= + +stream-combiner@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + integrity sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg= + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamfilter@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.7.tgz#ae3e64522aa5a35c061fd17f67620c7653c643c9" + integrity sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ== + dependencies: + readable-stream "^2.0.2" + +streamifier@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f" + integrity sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8= + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-bom-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + integrity sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4= + dependencies: + first-chunk-stream "^1.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU= + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + integrity sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw= + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.6.0, through2@^0.6.3, through2@~0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.3, through2@~2.0.0, through2@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@2, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +to-absolute-glob@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + integrity sha1-HN+kcqnvUMI57maZm2YsoOs5k38= + dependencies: + extend-shallow "^2.0.1" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +url-parse@^1.1.9: + version "1.4.4" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" + integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== + dependencies: + querystringify "^2.0.0" + requires-port "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^2.0.0, vinyl-fs@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + integrity sha1-vm/zJwy1Xf19MGNkDegfJddTIjk= + dependencies: + duplexify "^3.2.0" + glob-stream "^5.3.2" + graceful-fs "^4.0.0" + gulp-sourcemaps "1.6.0" + is-valid-glob "^0.3.0" + lazystream "^1.0.0" + lodash.isequal "^4.0.0" + merge-stream "^1.0.0" + mkdirp "^0.5.0" + object-assign "^4.0.0" + readable-stream "^2.0.4" + strip-bom "^2.0.0" + strip-bom-stream "^1.0.0" + through2 "^2.0.0" + through2-filter "^2.0.0" + vali-date "^1.0.0" + vinyl "^1.0.0" + +vinyl-source-stream@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-1.1.2.tgz#62b53a135610a896e98ca96bee3a87f008a8e780" + integrity sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A= + dependencies: + through2 "^2.0.3" + vinyl "^0.4.3" + +vinyl@^0.4.3, vinyl@^0.4.6, vinyl@~0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" + integrity sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw= + dependencies: + clone "^1.0.0" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + is-stream "^1.1.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vscode@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.5.tgz#10eb104001840c3dd0813815fd4a05f8fc882d14" + integrity sha1-EOsQQAGEDD3QgTgV/UoF+PyILRQ= + dependencies: + glob "^7.1.1" + gulp-chmod "^2.0.0" + gulp-filter "^5.0.0" + gulp-gunzip "0.0.3" + gulp-remote-src "^0.4.2" + gulp-symdest "^1.1.0" + gulp-untar "^0.0.6" + gulp-vinyl-zip "^1.4.0" + mocha "^3.2.0" + request "^2.79.0" + semver "^5.3.0" + source-map-support "^0.4.11" + url-parse "^1.1.9" + vinyl-source-stream "^1.1.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +"xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +yauzl@^2.2.1: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yazl@^2.2.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" diff --git a/package.json b/package.json index 7bcf69e406d..ae6bcde9491 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "@types/chokidar": "2.1.3", "@types/cookie": "^0.3.3", "@types/debug": "^4.1.5", - "@types/glob": "5.0.36", "@types/graceful-fs": "4.1.2", "@types/http-proxy-agent": "^2.0.1", "@types/iconv-lite": "0.0.1", diff --git a/yarn.lock b/yarn.lock index 0c44266ede5..c2f11789a2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -208,20 +208,6 @@ resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== - -"@types/glob@5.0.36": - version "5.0.36" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.36.tgz#0c80a9c8664fc7d19781de229f287077fd622cb2" - integrity sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg== - dependencies: - "@types/events" "*" - "@types/minimatch" "*" - "@types/node" "*" - "@types/graceful-fs@4.1.2": version "4.1.2" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.2.tgz#fbc9575dbcc6d1d91dd768d30c5fc0c19f6c50bd" @@ -253,11 +239,6 @@ resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.4.0.tgz#ca24e6ee6d0df10c003aafe26e93113b8faf0d8e" integrity sha512-cq/NkUUy6rpWD8n7PweNQQBpw2o0cf5v6fbkUVEpOB9VzzIvyPvSEId1/goIj+MciW2v1Lw5mRimKO01XgE9EA== -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - "@types/mocha@2.2.39": version "2.2.39" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.39.tgz#f68d63db8b69c38e9558b4073525cf96c4f7a829" From 3e1afd6999b463407b1eccc244bed360f4a3e32e Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 10:16:37 +0100 Subject: [PATCH 011/137] Fixes #82540: Only execute a click link gesture if the mouse down occurs on the same line number --- src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts b/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts index bc3e6cad236..202d1e0d294 100644 --- a/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts +++ b/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts @@ -110,6 +110,7 @@ export class ClickLinkGesture extends Disposable { private lastMouseMoveEvent: ClickLinkMouseEvent | null; private hasTriggerKeyOnMouseDown: boolean; + private lineNumberOnMouseDown: number; constructor(editor: ICodeEditor) { super(); @@ -119,6 +120,7 @@ export class ClickLinkGesture extends Disposable { this.lastMouseMoveEvent = null; this.hasTriggerKeyOnMouseDown = false; + this.lineNumberOnMouseDown = 0; this._register(this._editor.onDidChangeConfiguration((e) => { if (e.hasChanged(EditorOption.multiCursorModifier)) { @@ -129,6 +131,7 @@ export class ClickLinkGesture extends Disposable { this._opts = newOpts; this.lastMouseMoveEvent = null; this.hasTriggerKeyOnMouseDown = false; + this.lineNumberOnMouseDown = 0; this._onCancel.fire(); } })); @@ -167,10 +170,12 @@ export class ClickLinkGesture extends Disposable { // release the mouse button without wanting to do the navigation. // With this flag we prevent goto definition if the mouse was down before the trigger key was pressed. this.hasTriggerKeyOnMouseDown = mouseEvent.hasTriggerModifier; + this.lineNumberOnMouseDown = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; } private onEditorMouseUp(mouseEvent: ClickLinkMouseEvent): void { - if (this.hasTriggerKeyOnMouseDown) { + const currentLineNumber = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; + if (this.hasTriggerKeyOnMouseDown && this.lineNumberOnMouseDown && this.lineNumberOnMouseDown === currentLineNumber) { this._onExecute.fire(mouseEvent); } } From b5804ac1b14c0fc66526b262d14317070ba9fc72 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 10:19:48 +0100 Subject: [PATCH 012/137] :lipstick: --- .../gotoSymbol/link/clickLinkGesture.ts | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts b/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts index 202d1e0d294..19f2de625f8 100644 --- a/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts +++ b/src/vs/editor/contrib/gotoSymbol/link/clickLinkGesture.ts @@ -108,9 +108,9 @@ export class ClickLinkGesture extends Disposable { private readonly _editor: ICodeEditor; private _opts: ClickLinkOptions; - private lastMouseMoveEvent: ClickLinkMouseEvent | null; - private hasTriggerKeyOnMouseDown: boolean; - private lineNumberOnMouseDown: number; + private _lastMouseMoveEvent: ClickLinkMouseEvent | null; + private _hasTriggerKeyOnMouseDown: boolean; + private _lineNumberOnMouseDown: number; constructor(editor: ICodeEditor) { super(); @@ -118,9 +118,9 @@ export class ClickLinkGesture extends Disposable { this._editor = editor; this._opts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier)); - this.lastMouseMoveEvent = null; - this.hasTriggerKeyOnMouseDown = false; - this.lineNumberOnMouseDown = 0; + this._lastMouseMoveEvent = null; + this._hasTriggerKeyOnMouseDown = false; + this._lineNumberOnMouseDown = 0; this._register(this._editor.onDidChangeConfiguration((e) => { if (e.hasChanged(EditorOption.multiCursorModifier)) { @@ -129,80 +129,80 @@ export class ClickLinkGesture extends Disposable { return; } this._opts = newOpts; - this.lastMouseMoveEvent = null; - this.hasTriggerKeyOnMouseDown = false; - this.lineNumberOnMouseDown = 0; + this._lastMouseMoveEvent = null; + this._hasTriggerKeyOnMouseDown = false; + this._lineNumberOnMouseDown = 0; this._onCancel.fire(); } })); - this._register(this._editor.onMouseMove((e: IEditorMouseEvent) => this.onEditorMouseMove(new ClickLinkMouseEvent(e, this._opts)))); - this._register(this._editor.onMouseDown((e: IEditorMouseEvent) => this.onEditorMouseDown(new ClickLinkMouseEvent(e, this._opts)))); - this._register(this._editor.onMouseUp((e: IEditorMouseEvent) => this.onEditorMouseUp(new ClickLinkMouseEvent(e, this._opts)))); - this._register(this._editor.onKeyDown((e: IKeyboardEvent) => this.onEditorKeyDown(new ClickLinkKeyboardEvent(e, this._opts)))); - this._register(this._editor.onKeyUp((e: IKeyboardEvent) => this.onEditorKeyUp(new ClickLinkKeyboardEvent(e, this._opts)))); - this._register(this._editor.onMouseDrag(() => this.resetHandler())); + this._register(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(new ClickLinkMouseEvent(e, this._opts)))); + this._register(this._editor.onMouseDown((e: IEditorMouseEvent) => this._onEditorMouseDown(new ClickLinkMouseEvent(e, this._opts)))); + this._register(this._editor.onMouseUp((e: IEditorMouseEvent) => this._onEditorMouseUp(new ClickLinkMouseEvent(e, this._opts)))); + this._register(this._editor.onKeyDown((e: IKeyboardEvent) => this._onEditorKeyDown(new ClickLinkKeyboardEvent(e, this._opts)))); + this._register(this._editor.onKeyUp((e: IKeyboardEvent) => this._onEditorKeyUp(new ClickLinkKeyboardEvent(e, this._opts)))); + this._register(this._editor.onMouseDrag(() => this._resetHandler())); - this._register(this._editor.onDidChangeCursorSelection((e) => this.onDidChangeCursorSelection(e))); - this._register(this._editor.onDidChangeModel((e) => this.resetHandler())); - this._register(this._editor.onDidChangeModelContent(() => this.resetHandler())); + this._register(this._editor.onDidChangeCursorSelection((e) => this._onDidChangeCursorSelection(e))); + this._register(this._editor.onDidChangeModel((e) => this._resetHandler())); + this._register(this._editor.onDidChangeModelContent(() => this._resetHandler())); this._register(this._editor.onDidScrollChange((e) => { if (e.scrollTopChanged || e.scrollLeftChanged) { - this.resetHandler(); + this._resetHandler(); } })); } - private onDidChangeCursorSelection(e: ICursorSelectionChangedEvent): void { + private _onDidChangeCursorSelection(e: ICursorSelectionChangedEvent): void { if (e.selection && e.selection.startColumn !== e.selection.endColumn) { - this.resetHandler(); // immediately stop this feature if the user starts to select (https://github.com/Microsoft/vscode/issues/7827) + this._resetHandler(); // immediately stop this feature if the user starts to select (https://github.com/Microsoft/vscode/issues/7827) } } - private onEditorMouseMove(mouseEvent: ClickLinkMouseEvent): void { - this.lastMouseMoveEvent = mouseEvent; + private _onEditorMouseMove(mouseEvent: ClickLinkMouseEvent): void { + this._lastMouseMoveEvent = mouseEvent; this._onMouseMoveOrRelevantKeyDown.fire([mouseEvent, null]); } - private onEditorMouseDown(mouseEvent: ClickLinkMouseEvent): void { + private _onEditorMouseDown(mouseEvent: ClickLinkMouseEvent): void { // We need to record if we had the trigger key on mouse down because someone might select something in the editor // holding the mouse down and then while mouse is down start to press Ctrl/Cmd to start a copy operation and then // release the mouse button without wanting to do the navigation. // With this flag we prevent goto definition if the mouse was down before the trigger key was pressed. - this.hasTriggerKeyOnMouseDown = mouseEvent.hasTriggerModifier; - this.lineNumberOnMouseDown = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; + this._hasTriggerKeyOnMouseDown = mouseEvent.hasTriggerModifier; + this._lineNumberOnMouseDown = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; } - private onEditorMouseUp(mouseEvent: ClickLinkMouseEvent): void { + private _onEditorMouseUp(mouseEvent: ClickLinkMouseEvent): void { const currentLineNumber = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0; - if (this.hasTriggerKeyOnMouseDown && this.lineNumberOnMouseDown && this.lineNumberOnMouseDown === currentLineNumber) { + if (this._hasTriggerKeyOnMouseDown && this._lineNumberOnMouseDown && this._lineNumberOnMouseDown === currentLineNumber) { this._onExecute.fire(mouseEvent); } } - private onEditorKeyDown(e: ClickLinkKeyboardEvent): void { + private _onEditorKeyDown(e: ClickLinkKeyboardEvent): void { if ( - this.lastMouseMoveEvent + this._lastMouseMoveEvent && ( e.keyCodeIsTriggerKey // User just pressed Ctrl/Cmd (normal goto definition) || (e.keyCodeIsSideBySideKey && e.hasTriggerModifier) // User pressed Ctrl/Cmd+Alt (goto definition to the side) ) ) { - this._onMouseMoveOrRelevantKeyDown.fire([this.lastMouseMoveEvent, e]); + this._onMouseMoveOrRelevantKeyDown.fire([this._lastMouseMoveEvent, e]); } else if (e.hasTriggerModifier) { this._onCancel.fire(); // remove decorations if user holds another key with ctrl/cmd to prevent accident goto declaration } } - private onEditorKeyUp(e: ClickLinkKeyboardEvent): void { + private _onEditorKeyUp(e: ClickLinkKeyboardEvent): void { if (e.keyCodeIsTriggerKey) { this._onCancel.fire(); } } - private resetHandler(): void { - this.lastMouseMoveEvent = null; - this.hasTriggerKeyOnMouseDown = false; + private _resetHandler(): void { + this._lastMouseMoveEvent = null; + this._hasTriggerKeyOnMouseDown = false; this._onCancel.fire(); } } From 91f1eef2727e3161fc6132fdc63a99ef2e4a7198 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 6 Mar 2020 10:42:22 +0100 Subject: [PATCH 013/137] Run smoke test as part of product build (#92145) * tests - run smoketest as part of product build (without failing it) * fix smoke * add quotes * uncomment --- .../darwin/product-build-darwin.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 795bc78556e..aae3ccb7297 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -135,6 +135,23 @@ steps: displayName: Run integration tests (Browser) condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +- script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-darwin + APP_NAME="`ls $APP_ROOT | head -n 1`" + yarn smoketest --build "$APP_ROOT/$APP_NAME" + continueOnError: true + displayName: Run smoke tests (Electron) + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + +- script: | + set -e + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin" \ + yarn smoketest --web --headless + continueOnError: true + displayName: Run smoke tests (Browser) + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | set -e security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain From c7be212f89064dd6584a24b2afaa2c94af2e95f1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 10:43:13 +0100 Subject: [PATCH 014/137] Fix #92144 --- .../sharedProcess/sharedProcessMain.ts | 4 +- .../common/abstractSynchronizer.ts | 67 ++++------------ .../userDataSync/common/extensionsSync.ts | 9 +-- .../userDataSync/common/globalStateSync.ts | 10 +-- .../userDataSync/common/keybindingsSync.ts | 13 +-- .../userDataSync/common/settingsSync.ts | 13 ++- .../userDataSync/common/userDataSync.ts | 6 ++ .../common/userDataSyncBackupStoreService.ts | 80 +++++++++++++++++++ src/vs/workbench/workbench.web.main.ts | 4 +- 9 files changed, 131 insertions(+), 75 deletions(-) create mode 100644 src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index ac772deb3cf..79e8473bcc6 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -49,7 +49,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider'; import { Schemas } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/productService'; -import { IUserDataSyncService, IUserDataSyncStoreService, registerConfiguration, IUserDataSyncLogService, IUserDataSyncUtilService, ISettingsSyncService, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncService, IUserDataSyncStoreService, registerConfiguration, IUserDataSyncLogService, IUserDataSyncUtilService, ISettingsSyncService, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService'; import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; import { UserDataSyncChannel, UserDataSyncUtilServiceClient, SettingsSyncChannel, UserDataAutoSyncChannel, UserDataSyncStoreServiceChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc'; @@ -67,6 +67,7 @@ import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagemen import { UserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSyncEnablementService'; import { IAuthenticationTokenService, AuthenticationTokenService } from 'vs/platform/authentication/common/authentication'; import { AuthenticationTokenServiceChannel } from 'vs/platform/authentication/common/authenticationIpc'; +import { UserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSyncBackupStoreService'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -194,6 +195,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat services.set(IUserDataSyncUtilService, new UserDataSyncUtilServiceClient(server.getChannel('userDataSyncUtil', client => client.ctx !== 'main'))); services.set(IGlobalExtensionEnablementService, new SyncDescriptor(GlobalExtensionEnablementService)); services.set(IUserDataSyncStoreService, new SyncDescriptor(UserDataSyncStoreService)); + services.set(IUserDataSyncBackupStoreService, new SyncDescriptor(UserDataSyncBackupStoreService)); services.set(IUserDataSyncEnablementService, new SyncDescriptor(UserDataSyncEnablementService)); services.set(ISettingsSyncService, new SyncDescriptor(SettingsSynchroniser)); services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService)); diff --git a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts index 03edf498efd..938f0bc8ac9 100644 --- a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts +++ b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts @@ -7,11 +7,10 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IFileService, IFileContent, FileChangesEvent, FileSystemProviderError, FileSystemProviderErrorCode, FileOperationResult, FileOperationError } from 'vs/platform/files/common/files'; import { VSBuffer } from 'vs/base/common/buffer'; import { URI } from 'vs/base/common/uri'; -import { SyncSource, SyncStatus, IUserData, IUserDataSyncStoreService, UserDataSyncErrorCode, UserDataSyncError, IUserDataSyncLogService, IUserDataSyncUtilService, ResourceKey, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncSource, SyncStatus, IUserData, IUserDataSyncStoreService, UserDataSyncErrorCode, UserDataSyncError, IUserDataSyncLogService, IUserDataSyncUtilService, ResourceKey, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { joinPath, dirname } from 'vs/base/common/resources'; -import { toLocalISOString } from 'vs/base/common/date'; -import { ThrottledDelayer, CancelablePromise } from 'vs/base/common/async'; +import { CancelablePromise } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ParseError, parse } from 'vs/base/common/json'; @@ -44,7 +43,6 @@ function isSyncData(thing: any): thing is ISyncData { export abstract class AbstractSynchroniser extends Disposable { protected readonly syncFolder: URI; - private cleanUpDelayer: ThrottledDelayer; private _status: SyncStatus = SyncStatus.Idle; get status(): SyncStatus { return this._status; } @@ -58,9 +56,11 @@ export abstract class AbstractSynchroniser extends Disposable { constructor( readonly source: SyncSource, + readonly resourceKey: ResourceKey, @IFileService protected readonly fileService: IFileService, @IEnvironmentService environmentService: IEnvironmentService, @IUserDataSyncStoreService protected readonly userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService protected readonly userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IUserDataSyncEnablementService protected readonly userDataSyncEnablementService: IUserDataSyncEnablementService, @ITelemetryService private readonly telemetryService: ITelemetryService, @IUserDataSyncLogService protected readonly logService: IUserDataSyncLogService, @@ -68,9 +68,7 @@ export abstract class AbstractSynchroniser extends Disposable { ) { super(); this.syncFolder = joinPath(environmentService.userDataSyncHome, source); - this.lastSyncResource = joinPath(this.syncFolder, `lastSync${source}.json`); - this.cleanUpDelayer = new ThrottledDelayer(50); - this.cleanUpBackup(); + this.lastSyncResource = joinPath(this.syncFolder, `lastSync${this.resourceKey}.json`); } protected setStatus(status: SyncStatus): void { @@ -217,51 +215,11 @@ export abstract class AbstractSynchroniser extends Disposable { return { ref, syncData }; } - protected async backupLocal(content: VSBuffer): Promise { - const resource = joinPath(this.syncFolder, `${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}.json`); - try { - await this.fileService.writeFile(resource, content); - } catch (e) { - this.logService.error(e); - } - this.cleanUpDelayer.trigger(() => this.cleanUpBackup()); + protected async backupLocal(content: string): Promise { + const syncData: ISyncData = { version: this.version, content }; + return this.userDataSyncBackupStoreService.backup(this.resourceKey, JSON.stringify(syncData)); } - private async cleanUpBackup(): Promise { - try { - if (!(await this.fileService.exists(this.syncFolder))) { - return; - } - const stat = await this.fileService.resolve(this.syncFolder); - if (stat.children) { - const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}(\.json)?$/.test(stat.name)).sort(); - const backUpMaxAge = 1000 * 60 * 60 * 24 * (this.configurationService.getValue('sync.localBackupDuration') || 30 /* Default 30 days */); - let toDelete = all.filter(stat => { - const ctime = stat.ctime || new Date( - parseInt(stat.name.substring(0, 4)), - parseInt(stat.name.substring(4, 6)) - 1, - parseInt(stat.name.substring(6, 8)), - parseInt(stat.name.substring(9, 11)), - parseInt(stat.name.substring(11, 13)), - parseInt(stat.name.substring(13, 15)) - ).getTime(); - return Date.now() - ctime > backUpMaxAge; - }); - const remaining = all.length - toDelete.length; - if (remaining < 10) { - toDelete = toDelete.slice(10 - remaining); - } - await Promise.all(toDelete.map(stat => { - this.logService.info('Deleting from backup', stat.resource.path); - this.fileService.del(stat.resource); - })); - } - } catch (e) { - this.logService.error(e); - } - } - - abstract readonly resourceKey: ResourceKey; protected abstract readonly version: number; protected abstract performSync(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null): Promise; } @@ -283,15 +241,17 @@ export abstract class AbstractFileSynchroniser extends AbstractSynchroniser { constructor( protected readonly file: URI, source: SyncSource, + resourceKey: ResourceKey, @IFileService fileService: IFileService, @IEnvironmentService environmentService: IEnvironmentService, @IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService, @ITelemetryService telemetryService: ITelemetryService, @IUserDataSyncLogService logService: IUserDataSyncLogService, @IConfigurationService configurationService: IConfigurationService, ) { - super(source, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); + super(source, resourceKey, fileService, environmentService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); this._register(this.fileService.watch(dirname(file))); this._register(this.fileService.onDidFilesChange(e => this.onFileChanges(e))); } @@ -327,7 +287,6 @@ export abstract class AbstractFileSynchroniser extends AbstractSynchroniser { try { if (oldContent) { // file exists already - await this.backupLocal(oldContent.value); await this.fileService.writeFile(this.file, VSBuffer.fromString(newContent), oldContent); } else { // file does not exist @@ -382,16 +341,18 @@ export abstract class AbstractJsonFileSynchroniser extends AbstractFileSynchroni constructor( file: URI, source: SyncSource, + resourceKey: ResourceKey, @IFileService fileService: IFileService, @IEnvironmentService environmentService: IEnvironmentService, @IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService, @ITelemetryService telemetryService: ITelemetryService, @IUserDataSyncLogService logService: IUserDataSyncLogService, @IUserDataSyncUtilService protected readonly userDataSyncUtilService: IUserDataSyncUtilService, @IConfigurationService configurationService: IConfigurationService, ) { - super(file, source, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); + super(file, source, resourceKey, fileService, environmentService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); } protected hasErrors(content: string): boolean { diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index 1e9c81523e0..d953a8c7d93 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SyncStatus, IUserDataSyncStoreService, ISyncExtension, IUserDataSyncLogService, IUserDataSynchroniser, SyncSource, ResourceKey, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncStatus, IUserDataSyncStoreService, ISyncExtension, IUserDataSyncLogService, IUserDataSynchroniser, SyncSource, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { Event } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IExtensionManagementService, IExtensionGalleryService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -16,7 +16,6 @@ import { merge } from 'vs/platform/userDataSync/common/extensionsMerge'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { AbstractSynchroniser, IRemoteUserData, ISyncData } from 'vs/platform/userDataSync/common/abstractSynchronizer'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { VSBuffer } from 'vs/base/common/buffer'; interface ISyncPreviewResult { readonly localExtensions: ISyncExtension[]; @@ -35,7 +34,6 @@ interface ILastSyncUserData extends IRemoteUserData { export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUserDataSynchroniser { - readonly resourceKey: ResourceKey = 'extensions'; protected readonly version: number = 2; protected isEnabled(): boolean { return super.isEnabled() && this.extensionGalleryService.isEnabled(); } @@ -43,6 +41,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, @IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, @IGlobalExtensionEnablementService private readonly extensionEnablementService: IGlobalExtensionEnablementService, @IUserDataSyncLogService logService: IUserDataSyncLogService, @@ -51,7 +50,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse @IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService, @ITelemetryService telemetryService: ITelemetryService, ) { - super(SyncSource.Extensions, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); + super(SyncSource.Extensions, 'extensions', fileService, environmentService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); this._register( Event.debounce( Event.any( @@ -180,7 +179,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse if (added.length || removed.length || updated.length) { // back up all disabled or market place extensions const backUpExtensions = localExtensions.filter(e => e.disabled || !!e.identifier.uuid); - await this.backupLocal(VSBuffer.fromString(JSON.stringify(backUpExtensions, null, '\t'))); + await this.backupLocal(JSON.stringify(backUpExtensions)); skippedExtensions = await this.updateLocalExtensions(added, removed, updated, skippedExtensions); } diff --git a/src/vs/platform/userDataSync/common/globalStateSync.ts b/src/vs/platform/userDataSync/common/globalStateSync.ts index ff9dc75d808..cef7d798ab5 100644 --- a/src/vs/platform/userDataSync/common/globalStateSync.ts +++ b/src/vs/platform/userDataSync/common/globalStateSync.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IGlobalState, SyncSource, IUserDataSynchroniser, ResourceKey, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IGlobalState, SyncSource, IUserDataSynchroniser, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { VSBuffer } from 'vs/base/common/buffer'; import { Event } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -29,19 +29,19 @@ interface ISyncPreviewResult { export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUserDataSynchroniser { - readonly resourceKey: ResourceKey = 'globalState'; protected readonly version: number = 1; constructor( @IFileService fileService: IFileService, @IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IUserDataSyncLogService logService: IUserDataSyncLogService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService, @ITelemetryService telemetryService: ITelemetryService, @IConfigurationService configurationService: IConfigurationService, ) { - super(SyncSource.GlobalState, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); + super(SyncSource.GlobalState, 'globalState', fileService, environmentService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService); this._register(this.fileService.watch(dirname(this.environmentService.argvResource))); this._register(Event.filter(this.fileService.onDidFilesChange, e => e.contains(this.environmentService.argvResource))(() => this._onDidChangeLocal.fire())); } @@ -130,7 +130,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs return SyncStatus.Idle; } - private async getPreview(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null,): Promise { + private async getPreview(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null): Promise { const remoteGlobalState: IGlobalState = remoteUserData.syncData ? JSON.parse(remoteUserData.syncData.content) : null; const lastSyncGlobalState = lastSyncUserData && lastSyncUserData.syncData ? JSON.parse(lastSyncUserData.syncData.content) : null; @@ -158,7 +158,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs if (local) { // update local this.logService.trace('UI State: Updating local ui state...'); - await this.backupLocal(VSBuffer.fromString(JSON.stringify(localUserData, null, '\t'))); + await this.backupLocal(JSON.stringify(localUserData)); await this.writeLocalGlobalState(local); this.logService.info('UI State: Updated local ui state'); } diff --git a/src/vs/platform/userDataSync/common/keybindingsSync.ts b/src/vs/platform/userDataSync/common/keybindingsSync.ts index e6e7e2931da..773be441b2f 100644 --- a/src/vs/platform/userDataSync/common/keybindingsSync.ts +++ b/src/vs/platform/userDataSync/common/keybindingsSync.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IFileService, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; -import { UserDataSyncError, UserDataSyncErrorCode, SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IUserDataSyncUtilService, SyncSource, IUserDataSynchroniser, ResourceKey, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; +import { UserDataSyncError, UserDataSyncErrorCode, SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IUserDataSyncUtilService, SyncSource, IUserDataSynchroniser, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { merge } from 'vs/platform/userDataSync/common/keybindingsMerge'; import { VSBuffer } from 'vs/base/common/buffer'; import { parse } from 'vs/base/common/json'; @@ -29,12 +29,12 @@ interface ISyncContent { export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implements IUserDataSynchroniser { - readonly resourceKey: ResourceKey = 'keybindings'; protected get conflictsPreviewResource(): URI { return this.environmentService.keybindingsSyncPreviewResource; } protected readonly version: number = 1; constructor( @IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IUserDataSyncLogService logService: IUserDataSyncLogService, @IConfigurationService configurationService: IConfigurationService, @IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService, @@ -43,7 +43,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem @IUserDataSyncUtilService userDataSyncUtilService: IUserDataSyncUtilService, @ITelemetryService telemetryService: ITelemetryService, ) { - super(environmentService.keybindingsResource, SyncSource.Keybindings, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService); + super(environmentService.keybindingsResource, SyncSource.Keybindings, 'keybindings', fileService, environmentService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService); } async pull(): Promise { @@ -197,13 +197,14 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem if (hasLocalChanged) { this.logService.trace('Keybindings: Updating local keybindings...'); + await this.backupLocal(this.toSyncContent(content, null)); await this.updateLocalFileContent(content, fileContent); this.logService.info('Keybindings: Updated local keybindings'); } if (hasRemoteChanged) { this.logService.trace('Keybindings: Updating remote keybindings...'); - const remoteContents = this.updateSyncContent(content, remoteUserData.syncData ? remoteUserData.syncData.content : null); + const remoteContents = this.toSyncContent(content, remoteUserData.syncData ? remoteUserData.syncData.content : null); remoteUserData = await this.updateRemoteUserData(remoteContents, forcePush ? null : remoteUserData.ref); this.logService.info('Keybindings: Updated remote keybindings'); } @@ -218,7 +219,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem if (lastSyncUserData?.ref !== remoteUserData.ref && (content !== null || fileContent !== null)) { this.logService.trace('Keybindings: Updating last synchronized keybindings...'); - const lastSyncContent = this.updateSyncContent(content !== null ? content : fileContent!.value.toString(), null); + const lastSyncContent = this.toSyncContent(content !== null ? content : fileContent!.value.toString(), null); await this.updateLastSyncUserData({ ref: remoteUserData.ref, syncData: { version: remoteUserData.syncData!.version, content: lastSyncContent } }); this.logService.info('Keybindings: Updated last synchronized keybindings'); } @@ -301,7 +302,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem } } - private updateSyncContent(keybindingsContent: string, syncContent: string | null): string { + private toSyncContent(keybindingsContent: string, syncContent: string | null): string { let parsed: ISyncContent = {}; try { parsed = JSON.parse(syncContent || '{}'); diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index 1c75533e750..fa85bc9a3ac 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IFileService, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; -import { UserDataSyncError, UserDataSyncErrorCode, SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IUserDataSyncUtilService, IConflictSetting, ISettingsSyncService, CONFIGURATION_SYNC_STORE_KEY, SyncSource, ResourceKey, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; +import { UserDataSyncError, UserDataSyncErrorCode, SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IUserDataSyncUtilService, IConflictSetting, ISettingsSyncService, CONFIGURATION_SYNC_STORE_KEY, SyncSource, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { VSBuffer } from 'vs/base/common/buffer'; import { parse } from 'vs/base/common/json'; import { localize } from 'vs/nls'; @@ -37,7 +37,6 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement _serviceBrand: any; - readonly resourceKey: ResourceKey = 'settings'; protected readonly version: number = 1; protected get conflictsPreviewResource(): URI { return this.environmentService.settingsSyncPreviewResource; } @@ -50,6 +49,7 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement @IFileService fileService: IFileService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, @IUserDataSyncLogService logService: IUserDataSyncLogService, @IUserDataSyncUtilService userDataSyncUtilService: IUserDataSyncUtilService, @IConfigurationService configurationService: IConfigurationService, @@ -57,7 +57,7 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement @ITelemetryService telemetryService: ITelemetryService, @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, ) { - super(environmentService.settingsResource, SyncSource.Settings, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService); + super(environmentService.settingsResource, SyncSource.Settings, 'settings', fileService, environmentService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService); } protected setStatus(status: SyncStatus): void { @@ -259,6 +259,7 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement if (hasLocalChanged) { this.logService.trace('Settings: Updating local settings...'); + await this.backupLocal(JSON.stringify(this.toSettingsSyncContent(content))); await this.updateLocalFileContent(content, fileContent); this.logService.info('Settings: Updated local settings'); } @@ -269,7 +270,7 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement const ignoredSettings = await this.getIgnoredSettings(content); content = updateIgnoredSettings(content, remoteSettingsSyncContent ? remoteSettingsSyncContent.settings : '{}', ignoredSettings, formatUtils); this.logService.trace('Settings: Updating remote settings...'); - remoteUserData = await this.updateRemoteUserData(JSON.stringify({ settings: content }), forcePush ? null : remoteUserData.ref); + remoteUserData = await this.updateRemoteUserData(JSON.stringify(this.toSettingsSyncContent(content)), forcePush ? null : remoteUserData.ref); this.logService.info('Settings: Updated remote settings'); } @@ -354,6 +355,10 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement return null; } + private toSettingsSyncContent(settings: string): ISettingsSyncContent { + return { settings }; + } + private _defaultIgnoredSettings: Promise | undefined = undefined; protected async getIgnoredSettings(content?: string): Promise { if (!this._defaultIgnoredSettings) { diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 315eeb93e3d..f45f10187df 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -156,6 +156,12 @@ export interface IUserDataSyncStoreService { delete(key: ResourceKey): Promise; } +export const IUserDataSyncBackupStoreService = createDecorator('IUserDataSyncBackupStoreService'); +export interface IUserDataSyncBackupStoreService { + _serviceBrand: undefined; + backup(resourceKey: ResourceKey, content: string): Promise; +} + //#endregion // #region User Data Sync Error diff --git a/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts new file mode 100644 index 00000000000..8875ec93336 --- /dev/null +++ b/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable, } from 'vs/base/common/lifecycle'; +import { IUserDataSyncLogService, ResourceKey, ALL_RESOURCE_KEYS, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; +import { joinPath } from 'vs/base/common/resources'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { toLocalISOString } from 'vs/base/common/date'; +import { VSBuffer } from 'vs/base/common/buffer'; + +export class UserDataSyncBackupStoreService extends Disposable implements IUserDataSyncBackupStoreService { + + _serviceBrand: any; + + constructor( + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IFileService private readonly fileService: IFileService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IUserDataSyncLogService private readonly logService: IUserDataSyncLogService, + ) { + super(); + ALL_RESOURCE_KEYS.forEach(resourceKey => this.cleanUpBackup(resourceKey)); + } + + async backup(resourceKey: ResourceKey, content: string): Promise { + const folder = joinPath(this.environmentService.userDataSyncHome, resourceKey); + const resource = joinPath(folder, `${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}.json`); + try { + await this.fileService.writeFile(resource, VSBuffer.fromString(content)); + } catch (e) { + this.logService.error(e); + } + try { + this.cleanUpBackup(resourceKey); + } catch (e) { /* Ignore */ } + } + + private async cleanUpBackup(resourceKey: ResourceKey): Promise { + const folder = joinPath(this.environmentService.userDataSyncHome, resourceKey); + try { + try { + if (!(await this.fileService.exists(folder))) { + return; + } + } catch (e) { + return; + } + const stat = await this.fileService.resolve(folder); + if (stat.children) { + const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}(\.json)?$/.test(stat.name)).sort(); + const backUpMaxAge = 1000 * 60 * 60 * 24 * (this.configurationService.getValue('sync.localBackupDuration') || 30 /* Default 30 days */); + let toDelete = all.filter(stat => { + const ctime = stat.ctime || new Date( + parseInt(stat.name.substring(0, 4)), + parseInt(stat.name.substring(4, 6)) - 1, + parseInt(stat.name.substring(6, 8)), + parseInt(stat.name.substring(9, 11)), + parseInt(stat.name.substring(11, 13)), + parseInt(stat.name.substring(13, 15)) + ).getTime(); + return Date.now() - ctime > backUpMaxAge; + }); + const remaining = all.length - toDelete.length; + if (remaining < 10) { + toDelete = toDelete.slice(10 - remaining); + } + await Promise.all(toDelete.map(stat => { + this.logService.info('Deleting from backup', stat.resource.path); + this.fileService.del(stat.resource); + })); + } + } catch (e) { + this.logService.error(e); + } + } +} diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index da7a13e906d..df598774a44 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -62,10 +62,11 @@ import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { TunnelService } from 'vs/workbench/services/remote/common/tunnelService'; import { ILoggerService } from 'vs/platform/log/common/log'; import { FileLoggerService } from 'vs/platform/log/common/fileLogService'; -import { IUserDataSyncStoreService, IUserDataSyncService, IUserDataSyncLogService, ISettingsSyncService, IUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncStoreService, IUserDataSyncService, IUserDataSyncLogService, ISettingsSyncService, IUserDataAutoSyncService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { AuthenticationService, IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService'; import { UserDataSyncLogService } from 'vs/platform/userDataSync/common/userDataSyncLog'; import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; +import { UserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSyncBackupStoreService'; import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService'; import { SettingsSynchroniser } from 'vs/platform/userDataSync/common/settingsSync'; import { IAuthenticationTokenService, AuthenticationTokenService } from 'vs/platform/authentication/common/authentication'; @@ -83,6 +84,7 @@ registerSingleton(ILoggerService, FileLoggerService); registerSingleton(IAuthenticationService, AuthenticationService); registerSingleton(IUserDataSyncLogService, UserDataSyncLogService); registerSingleton(IUserDataSyncStoreService, UserDataSyncStoreService); +registerSingleton(IUserDataSyncBackupStoreService, UserDataSyncBackupStoreService); registerSingleton(IAuthenticationTokenService, AuthenticationTokenService); registerSingleton(IUserDataAutoSyncService, UserDataAutoSyncService); registerSingleton(ISettingsSyncService, SettingsSynchroniser); From 85dda6d7f5537fe18582df442319727bfbce9286 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 6 Mar 2020 10:47:58 +0100 Subject: [PATCH 015/137] Allow welcome content in custom views Fixes #92143 --- src/vs/workbench/browser/parts/views/customView.ts | 11 +++++++++++ src/vs/workbench/common/views.ts | 2 ++ .../welcome/common/viewsWelcomeExtensionPoint.ts | 1 - 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 3e31d2a53ae..e538874807c 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -67,6 +67,7 @@ export class CustomTreeViewPane extends ViewPane { this._register(this.treeView.onDidChangeTitle((newTitle) => this.updateTitle(newTitle))); this._register(toDisposable(() => this.treeView.setVisibility(false))); this._register(this.onDidChangeBodyVisibility(() => this.updateTreeVisibility())); + this._register(this.treeView.onDidChangeWelcomeState(() => this._onDidChangeViewWelcomeState.fire())); this.updateTreeVisibility(); } @@ -83,6 +84,10 @@ export class CustomTreeViewPane extends ViewPane { } } + shouldShowWelcome(): boolean { + return (this.treeView.dataProvider === undefined) && (this.treeView.message === undefined); + } + layoutBody(height: number, width: number): void { this.treeView.layout(height, width); } @@ -151,6 +156,9 @@ export class CustomTreeView extends Disposable implements ITreeView { private readonly _onDidChangeActions: Emitter = this._register(new Emitter()); readonly onDidChangeActions: Event = this._onDidChangeActions.event; + private readonly _onDidChangeWelcomeState: Emitter = this._register(new Emitter()); + readonly onDidChangeWelcomeState: Event = this._onDidChangeWelcomeState.event; + private readonly _onDidChangeTitle: Emitter = this._register(new Emitter()); readonly onDidChangeTitle: Event = this._onDidChangeTitle.event; @@ -223,6 +231,8 @@ export class CustomTreeView extends Disposable implements ITreeView { this._dataProvider = undefined; this.updateMessage(); } + + this._onDidChangeWelcomeState.fire(); } private _message: string | undefined; @@ -233,6 +243,7 @@ export class CustomTreeView extends Disposable implements ITreeView { set message(message: string | undefined) { this._message = message; this.updateMessage(); + this._onDidChangeWelcomeState.fire(); } get title(): string { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index a85e346bd98..1cc7f5b050f 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -488,6 +488,8 @@ export interface ITreeView extends IDisposable { readonly onDidChangeTitle: Event; + readonly onDidChangeWelcomeState: Event; + refresh(treeItems?: ITreeItem[]): Promise; setVisibility(visible: boolean): void; diff --git a/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts b/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts index 9a1fdbe078e..a16e6d6b37b 100644 --- a/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts +++ b/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts @@ -40,7 +40,6 @@ const viewsWelcomeExtensionPointSchema = Object.freeze Date: Fri, 6 Mar 2020 10:58:13 +0100 Subject: [PATCH 016/137] Fixes #90016: Allow quotes to surround selection when using the mac US Intl keyboard layout --- src/vs/editor/common/controller/cursor.ts | 4 ++-- .../common/controller/cursorTypeOperations.ts | 18 ++++++++------- .../test/browser/controller/cursor.test.ts | 22 +++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index a7dcdf9040c..07a39961aa6 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -779,7 +779,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { } private _type(source: string, text: string): void { - if (!this._isDoingComposition && source === 'keyboard') { + if (source === 'keyboard') { // If this event is coming straight from the keyboard, look for electric characters and enter const len = text.length; @@ -790,7 +790,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { // Here we must interpret each typed character individually const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions); - this._executeEditOperation(TypeOperations.typeWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr)); + this._executeEditOperation(TypeOperations.typeWithInterceptors(this._isDoingComposition, this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr)); offset += charLength; } diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 64db6112da9..9ae8b986bce 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -796,9 +796,9 @@ export class TypeOperations { return null; } - public static typeWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { + public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { - if (ch === '\n') { + if (!isDoingComposition && ch === '\n') { let commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { commands[i] = TypeOperations._enter(config, model, false, selections[i]); @@ -809,7 +809,7 @@ export class TypeOperations { }); } - if (this._isAutoIndentType(config, model, selections)) { + if (!isDoingComposition && this._isAutoIndentType(config, model, selections)) { let commands: Array = []; let autoIndentFails = false; for (let i = 0, len = selections.length; i < len; i++) { @@ -827,13 +827,15 @@ export class TypeOperations { } } - if (this._isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) { + if (!isDoingComposition && this._isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) { return this._runAutoClosingOvertype(prevEditOperationType, config, model, selections, ch); } - const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, true); - if (autoClosingPairOpenCharType) { - return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch, true, autoClosingPairOpenCharType); + if (!isDoingComposition) { + const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, true); + if (autoClosingPairOpenCharType) { + return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch, true, autoClosingPairOpenCharType); + } } if (this._isSurroundSelectionType(config, model, selections, ch)) { @@ -842,7 +844,7 @@ export class TypeOperations { // Electric characters make sense only when dealing with a single cursor, // as multiple cursors typing brackets for example would interfer with bracket matching - if (this._isTypeInterceptorElectricChar(config, model, selections)) { + if (!isDoingComposition && this._isTypeInterceptorElectricChar(config, model, selections)) { const r = this._typeInterceptorElectricChar(prevEditOperationType, config, model, selections[0], ch); if (r) { return r; diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index b6984401643..42c4dff0db2 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -5044,6 +5044,28 @@ suite('autoClosingPairs', () => { mode.dispose(); }); + test('issue #90016: allow accents on mac US intl keyboard to surround selection', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'test' + ], + languageIdentifier: mode.getLanguageIdentifier() + }, (model, cursor) => { + cursor.setSelections('test', [new Selection(1, 1, 1, 5)]); + + // Typing ` + e on the mac US intl kb layout + cursorCommand(cursor, H.CompositionStart, null, 'keyboard'); + cursorCommand(cursor, H.Type, { text: '\'' }, 'keyboard'); + cursorCommand(cursor, H.ReplacePreviousChar, { replaceCharCnt: 1, text: '\'' }, 'keyboard'); + cursorCommand(cursor, H.ReplacePreviousChar, { replaceCharCnt: 1, text: '\'' }, 'keyboard'); + cursorCommand(cursor, H.CompositionEnd, null, 'keyboard'); + + assert.equal(model.getValue(), '\'test\''); + }); + mode.dispose(); + }); + test('issue #53357: Over typing ignores characters after backslash', () => { let mode = new AutoClosingMode(); usingCursor({ From 09be616d397242a1d5cd430cb5123067f9083347 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 6 Mar 2020 11:03:25 +0100 Subject: [PATCH 017/137] quick omni - very basic first registry --- .../parts/quickinput/browser/quickInput.ts | 15 +-- .../standaloneQuickInputServiceImpl.ts | 3 + .../platform/quickinput/browser/quickInput.ts | 11 ++ .../platform/quickinput/browser/quickOmni.ts | 24 +++++ .../platform/quickinput/common/quickInput.ts | 46 +++++++- .../platform/quickinput/common/quickOmni.ts | 100 ++++++++++++++++++ .../browser/parts/quickopen/quickopen.ts | 2 + .../configurationResolverService.test.ts | 2 + 8 files changed, 188 insertions(+), 15 deletions(-) create mode 100644 src/vs/platform/quickinput/browser/quickOmni.ts create mode 100644 src/vs/platform/quickinput/common/quickOmni.ts diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 212810233e4..322fa757457 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -298,9 +298,8 @@ class QuickInput extends Disposable implements IQuickInput { this.ui.leftActionBar.clear(); const leftButtons = this.buttons.filter(button => button === backButton); this.ui.leftActionBar.push(leftButtons.map((button, index) => { - const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => { + const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, async () => { this.onDidTriggerButtonEmitter.fire(button); - return Promise.resolve(null); }); action.tooltip = button.tooltip || ''; return action; @@ -308,9 +307,8 @@ class QuickInput extends Disposable implements IQuickInput { this.ui.rightActionBar.clear(); const rightButtons = this.buttons.filter(button => button !== backButton); this.ui.rightActionBar.push(rightButtons.map((button, index) => { - const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => { + const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, async () => { this.onDidTriggerButtonEmitter.fire(button); - return Promise.resolve(null); }); action.tooltip = button.tooltip || ''; return action; @@ -1472,19 +1470,16 @@ export class QuickInputController extends Disposable { } } - accept() { + async accept() { this.onDidAcceptEmitter.fire(); - return Promise.resolve(undefined); } - back() { + async back() { this.onDidTriggerButtonEmitter.fire(this.backButton); - return Promise.resolve(undefined); } - cancel() { + async cancel() { this.hide(); - return Promise.resolve(undefined); } layout(dimension: dom.IDimension, titleBarOffset: number): void { diff --git a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts index f115d927976..babc23fba6b 100644 --- a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts +++ b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts @@ -18,6 +18,7 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService import { QuickInputController } from 'vs/base/parts/quickinput/browser/quickInput'; import { QuickInputService, IQuickInputControllerHost } from 'vs/platform/quickinput/browser/quickInput'; import { once } from 'vs/base/common/functional'; +import { IQuickOmniController } from 'vs/platform/quickinput/common/quickOmni'; export class EditorScopedQuickInputServiceImpl extends QuickInputService { @@ -76,6 +77,8 @@ export class StandaloneQuickInputServiceImpl implements IQuickInputService { return quickInputService; } + get quickOmni(): IQuickOmniController { return this.activeService.quickOmni; } + get backButton(): IQuickInputButton { return this.activeService.backButton; } get onShow() { return this.activeService.onShow; } diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index 9882760eeb3..a11b314cfe3 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -16,6 +16,8 @@ import { QuickInputController, IQuickInputStyles, IQuickInputOptions } from 'vs/ import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list'; +import { IQuickOmniController } from 'vs/platform/quickinput/common/quickOmni'; +import { QuickOmniController } from 'vs/platform/quickinput/browser/quickOmni'; export interface IQuickInputControllerHost extends ILayoutService { } @@ -37,6 +39,15 @@ export class QuickInputService extends Themable implements IQuickInputService { return this._controller; } + private _quickOmni: IQuickOmniController | undefined; + get quickOmni(): IQuickOmniController { + if (!this._quickOmni) { + this._quickOmni = this._register(this.instantiationService.createInstance(QuickOmniController)); + } + + return this._quickOmni; + } + private readonly contexts = new Map>(); constructor( diff --git a/src/vs/platform/quickinput/browser/quickOmni.ts b/src/vs/platform/quickinput/browser/quickOmni.ts new file mode 100644 index 00000000000..0d82b9adb80 --- /dev/null +++ b/src/vs/platform/quickinput/browser/quickOmni.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { Disposable } from 'vs/base/common/lifecycle'; + +export class QuickOmniController extends Disposable { + + constructor( + @IQuickInputService private readonly quickInputService: IQuickInputService + ) { + super(); + } + + async show(prefix?: string): Promise { + this.quickInputService.pick([ + { label: '1' }, + { label: '2' }, + { label: '3' } + ]); + } +} diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index a21044f67e5..68677753058 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -7,6 +7,7 @@ import { Event } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInputButton, IInputBox, QuickPickInput } from 'vs/base/parts/quickinput/common/quickInput'; +import { IQuickOmniController } from 'vs/platform/quickinput/common/quickOmni'; export { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods } from 'vs/base/parts/quickinput/common/quickInput'; @@ -18,20 +19,29 @@ export interface IQuickInputService { _serviceBrand: undefined; + /** + * Provides access to the back button in quick input. + */ readonly backButton: IQuickInputButton; /** - * Allows to register on the event that quick input is showing + * Provides access to the quick omni providers. + */ + readonly quickOmni: IQuickOmniController; + + /** + * Allows to register on the event that quick input is showing. */ readonly onShow: Event; /** - * Allows to register on the event that quick input is hiding + * Allows to register on the event that quick input is hiding. */ readonly onHide: Event; /** - * Opens the quick input box for selecting items and returns a promise with the user selected item(s) if any. + * Opens the quick input box for selecting items and returns a promise + * with the user selected item(s) if any. */ pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): Promise; pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): Promise; @@ -42,20 +52,46 @@ export interface IQuickInputService { */ input(options?: IInputOptions, token?: CancellationToken): Promise; + /** + * Provides raw access to the quick pick controller. + */ createQuickPick(): IQuickPick; + + /** + * Provides raw access to the quick input controller. + */ createInputBox(): IInputBox; + /** + * Moves focus into quick input. + */ focus(): void; + /** + * Toggle the checked state of the selected item. + */ toggle(): void; + /** + * Navigate inside the opened quick input list. + */ navigate(next: boolean, quickNavigate?: IQuickNavigateConfiguration): void; - accept(): Promise; - + /** + * Navigate back in a multi-step quick input. + */ back(): Promise; + /** + * Accept the selected item. + */ + accept(): Promise; + + /** + * Cancels quick input and closes it. + */ cancel(): Promise; + // TODO@Ben remove once quick open is gone hide(focusLost?: boolean): void; } diff --git a/src/vs/platform/quickinput/common/quickOmni.ts b/src/vs/platform/quickinput/common/quickOmni.ts new file mode 100644 index 00000000000..5765d91d56c --- /dev/null +++ b/src/vs/platform/quickinput/common/quickOmni.ts @@ -0,0 +1,100 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { first } from 'vs/base/common/arrays'; +import { startsWith } from 'vs/base/common/strings'; + +export interface IQuickOmniController { + + /** + * Open the quick omni picker with the optional prefix. + */ + show(prefix?: string): Promise; +} + +export interface IQuickOmniProvider { + + /** + * Called whenever a prefix was typed into quick pick that matches the provider. + * + * @param service the service to use to drive the quick input widget + * @param token cancellation support + */ + provide(service: IQuickInputService, token: CancellationToken): Promise; +} + +export interface QuickOmniProviderHelp { + + /** + * The prefix to show for the help entry. If not provided, + * the prefix used for registration will be taken. + */ + prefix?: string; + + /** + * A description text to help understand the intent of the provider. + */ + description: string; + + /** + * Separation between provider for editors and global ones. + */ + needsEditor: boolean; +} + +export interface IQuickOmniProviderDescriptor { + readonly ctor: IConstructorSignature0; + readonly prefix: string; + readonly contextKey: string | undefined; + readonly helpEntries: QuickOmniProviderHelp[]; +} + +export const Extensions = { + Quickomni: 'workbench.contributions.quickomni' +}; + +export interface IQuickOmniRegistry { + + /** + * Registers a quick omni provider to the platform. + */ + registerQuickOmniProvider(provider: IQuickOmniProviderDescriptor): void; + + /** + * Get all registered quick omni providers. + */ + getQuickOmniProviders(): IQuickOmniProviderDescriptor[]; + + /** + * Get a specific quick omni provider for a given prefix. + */ + getQuickOmniProvider(prefix: string): IQuickOmniProviderDescriptor | undefined; +} + +class QuickOmniRegistry implements IQuickOmniRegistry { + private providers: IQuickOmniProviderDescriptor[] = []; + + registerQuickOmniProvider(provider: IQuickOmniProviderDescriptor): void { + this.providers.push(provider); + + // sort the providers by decreasing prefix length, such that longer + // prefixes take priority: 'ext' vs 'ext install' - the latter should win + this.providers.sort((providerA, providerB) => providerB.prefix.length - providerA.prefix.length); + } + + getQuickOmniProviders(): IQuickOmniProviderDescriptor[] { + return this.providers.slice(0); + } + + getQuickOmniProvider(text: string): IQuickOmniProviderDescriptor | undefined { + return text ? (first(this.providers, provider => startsWith(text, provider.prefix)) || undefined) : undefined; + } +} + +Registry.add(Extensions.Quickomni, new QuickOmniRegistry()); diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index 5f7373c0d3f..d2ed77f70b2 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -165,6 +165,8 @@ export class LegacyQuickInputQuickOpenController extends Disposable { super(); this.registerListeners(); + + setTimeout(() => { this.quickInputService.quickOmni.show(); }, 0); } private registerListeners(): void { diff --git a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts index d8bda093b41..64da9b3eed0 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts @@ -534,6 +534,8 @@ class MockQuickInputService implements IQuickInputService { readonly onShow = Event.None; readonly onHide = Event.None; + readonly quickOmni = undefined!; + public pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): Promise; public pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): Promise; public pick(picks: Promise[]> | QuickPickInput[], options?: Omit, 'canPickMany'>, token?: CancellationToken): Promise { From db28209bf2315ceb27790fc9c440d5abe78d74a6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 11:06:14 +0100 Subject: [PATCH 018/137] fix tests --- .../platform/userDataSync/test/common/userDataSyncClient.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts index b94d21ce4ed..181df5ae44f 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts @@ -6,7 +6,7 @@ import { IRequestService } from 'vs/platform/request/common/request'; import { IRequestOptions, IRequestContext, IHeaders } from 'vs/base/parts/request/common/request'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IUserData, ResourceKey, IUserDataManifest, ALL_RESOURCE_KEYS, IUserDataSyncLogService, IUserDataSyncStoreService, IUserDataSyncUtilService, IUserDataSyncEnablementService, ISettingsSyncService, IUserDataSyncService, getDefaultIgnoredSettings } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserData, ResourceKey, IUserDataManifest, ALL_RESOURCE_KEYS, IUserDataSyncLogService, IUserDataSyncStoreService, IUserDataSyncUtilService, IUserDataSyncEnablementService, ISettingsSyncService, IUserDataSyncService, getDefaultIgnoredSettings, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { bufferToStream, VSBuffer } from 'vs/base/common/buffer'; import { generateUuid } from 'vs/base/common/uuid'; import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService'; @@ -36,6 +36,7 @@ import { Emitter } from 'vs/base/common/event'; import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication'; import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; +import { UserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSyncBackupStoreService'; export class UserDataSyncClient extends Disposable { @@ -89,6 +90,7 @@ export class UserDataSyncClient extends Disposable { this.instantiationService.stub(IUserDataSyncLogService, logService); this.instantiationService.stub(ITelemetryService, NullTelemetryService); this.instantiationService.stub(IUserDataSyncStoreService, this.instantiationService.createInstance(UserDataSyncStoreService)); + this.instantiationService.stub(IUserDataSyncBackupStoreService, this.instantiationService.createInstance(UserDataSyncBackupStoreService)); this.instantiationService.stub(IUserDataSyncUtilService, new TestUserDataSyncUtilService()); this.instantiationService.stub(IUserDataSyncEnablementService, this.instantiationService.createInstance(UserDataSyncEnablementService)); From 1f720ae43a339cc16f61701da0405891aeb7f126 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 6 Mar 2020 11:34:06 +0100 Subject: [PATCH 019/137] Revert "Only write config file during postinstall if process env variables are present (#91793)" This reverts commit b2b488fa438e953e7d304ffc7d37b90d2362a4c8. --- extensions/github-authentication/build/postinstall.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/github-authentication/build/postinstall.js b/extensions/github-authentication/build/postinstall.js index 16e51347559..e12fd05f191 100644 --- a/extensions/github-authentication/build/postinstall.js +++ b/extensions/github-authentication/build/postinstall.js @@ -20,9 +20,7 @@ function main() { } } - if (Object.keys(content).length > 0) { - fs.writeFileSync(path.join(__dirname, '../src/common/config.json'), JSON.stringify(content)); - } + fs.writeFileSync(path.join(__dirname, '../src/common/config.json'), JSON.stringify(content)); } main(); From 4a8dc15b9511154fedc572c930df0a072762caa1 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 6 Mar 2020 11:58:53 +0100 Subject: [PATCH 020/137] Enable inputs in user tasks Fixes #91660 --- .../workbench/api/browser/mainThreadTask.ts | 5 +++-- .../tasks/browser/terminalTaskSystem.ts | 6 +++--- .../contrib/tasks/common/taskSystem.ts | 3 ++- .../workbench/contrib/tasks/common/tasks.ts | 9 +++++++++ .../browser/configurationResolverService.ts | 20 +++++++++++-------- .../common/configurationResolver.ts | 5 +++-- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index ede1ae5c393..30fd88fcb13 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -33,6 +33,7 @@ import { RunOptionsDTO } from 'vs/workbench/api/common/shared/tasks'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; namespace TaskExecutionDTO { export function from(value: TaskExecution): TaskExecutionDTO { @@ -604,7 +605,7 @@ export class MainThreadTask implements MainThreadTaskShape { return URI.parse(`${info.scheme}://${info.authority}${path}`); }, context: this._extHostContext, - resolveVariables: (workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet): Promise => { + resolveVariables: (workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise => { const vars: string[] = []; toResolve.variables.forEach(item => vars.push(item)); return Promise.resolve(this._proxy.$resolveVariables(workspaceFolder.uri, { process: toResolve.process, variables: vars })).then(values => { @@ -613,7 +614,7 @@ export class MainThreadTask implements MainThreadTaskShape { partiallyResolvedVars.push(entry.value); }); return new Promise((resolve, reject) => { - this._configurationResolverService.resolveWithInteraction(workspaceFolder, partiallyResolvedVars, 'tasks').then(resolvedVars => { + this._configurationResolverService.resolveWithInteraction(workspaceFolder, partiallyResolvedVars, 'tasks', undefined, target).then(resolvedVars => { const result: ResolvedVariables = { process: undefined, variables: new Map() diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index bf6617e3b90..99c961b924a 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -33,7 +33,7 @@ import { IOutputService } from 'vs/workbench/contrib/output/common/output'; import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEventKind, ProblemHandlingStrategy } from 'vs/workbench/contrib/tasks/common/problemCollectors'; import { Task, CustomTask, ContributedTask, RevealKind, CommandOptions, ShellConfiguration, RuntimeType, PanelKind, - TaskEvent, TaskEventKind, ShellQuotingOptions, ShellQuoting, CommandString, CommandConfiguration, ExtensionTaskSource, TaskScope, RevealProblemKind, DependsOrder + TaskEvent, TaskEventKind, ShellQuotingOptions, ShellQuoting, CommandString, CommandConfiguration, ExtensionTaskSource, TaskScope, RevealProblemKind, DependsOrder, TaskSourceKind } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, ITaskResolver, @@ -545,7 +545,7 @@ export class TerminalTaskSystem implements ITaskSystem { resolveSet.process.path = envPath; } } - resolvedVariables = taskSystemInfo.resolveVariables(workspaceFolder, resolveSet).then(async (resolved) => { + resolvedVariables = taskSystemInfo.resolveVariables(workspaceFolder, resolveSet, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolved) => { this.mergeMaps(alreadyResolved, resolved.variables); resolved.variables = new Map(alreadyResolved); if (isProcess) { @@ -563,7 +563,7 @@ export class TerminalTaskSystem implements ITaskSystem { unresolved.forEach(variable => variablesArray.push(variable)); return new Promise((resolve, reject) => { - this.configurationResolverService.resolveWithInteraction(workspaceFolder, variablesArray, 'tasks').then(async (resolvedVariablesMap: Map | undefined) => { + this.configurationResolverService.resolveWithInteraction(workspaceFolder, variablesArray, 'tasks', undefined, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolvedVariablesMap: Map | undefined) => { if (resolvedVariablesMap) { this.mergeMaps(alreadyResolved, resolvedVariablesMap); resolvedVariablesMap = new Map(alreadyResolved); diff --git a/src/vs/workbench/contrib/tasks/common/taskSystem.ts b/src/vs/workbench/contrib/tasks/common/taskSystem.ts index 0ac0d5799a6..8784de163b4 100644 --- a/src/vs/workbench/contrib/tasks/common/taskSystem.ts +++ b/src/vs/workbench/contrib/tasks/common/taskSystem.ts @@ -10,6 +10,7 @@ import { Event } from 'vs/base/common/event'; import { Platform } from 'vs/base/common/platform'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Task, TaskEvent, KeyedTaskIdentifier } from './tasks'; +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export const enum TaskErrors { NotConfigured, @@ -118,7 +119,7 @@ export interface TaskSystemInfo { platform: Platform; context: any; uriProvider: (this: void, path: string) => URI; - resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet): Promise; + resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise; getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>; } diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 2fcd3f90195..f8eff3b1d4b 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -15,6 +15,7 @@ import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/works import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export const TASK_RUNNING_STATE = new RawContextKey('taskRunning', false); @@ -377,6 +378,14 @@ export namespace TaskSourceKind { export const InMemory: 'inMemory' = 'inMemory'; export const WorkspaceFile: 'workspaceFile' = 'workspaceFile'; export const User: 'user' = 'user'; + + export function toConfigurationTarget(kind: string): ConfigurationTarget { + switch (kind) { + case TaskSourceKind.User: return ConfigurationTarget.USER; + case TaskSourceKind.WorkspaceFile: return ConfigurationTarget.WORKSPACE; + default: return ConfigurationTarget.WORKSPACE_FOLDER; + } + } } export interface TaskSourceConfigElement { diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index 9402493cd86..f53c82c5d26 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -11,7 +11,7 @@ import { Schemas } from 'vs/base/common/network'; import { toResource } from 'vs/workbench/common/editor'; import { IStringDictionary, forEach, fromMap } from 'vs/base/common/collections'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IWorkspaceFolder, IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -86,12 +86,12 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR }, envVariables); } - public async resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise { + public async resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary, target?: ConfigurationTarget): Promise { // resolve any non-interactive variables and any contributed variables config = this.resolveAny(folder, config); // resolve input variables in the order in which they are encountered - return this.resolveWithInteraction(folder, config, section, variables).then(mapping => { + return this.resolveWithInteraction(folder, config, section, variables, target).then(mapping => { // finally substitute evaluated command variables (if there are any) if (!mapping) { return null; @@ -103,14 +103,14 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR }); } - public async resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise | undefined> { + public async resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary, target?: ConfigurationTarget): Promise | undefined> { // resolve any non-interactive variables and any contributed variables const resolved = await this.resolveAnyMap(folder, config); config = resolved.newConfig; const allVariableMapping: Map = resolved.resolvedVariables; // resolve input and command variables in the order in which they are encountered - return this.resolveWithInputAndCommands(folder, config, variables, section).then(inputOrCommandMapping => { + return this.resolveWithInputAndCommands(folder, config, variables, section, target).then(inputOrCommandMapping => { if (this.updateMapping(inputOrCommandMapping, allVariableMapping)) { return allVariableMapping; } @@ -139,7 +139,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR * * @param variableToCommandMap Aliases for commands */ - private async resolveWithInputAndCommands(folder: IWorkspaceFolder | undefined, configuration: any, variableToCommandMap?: IStringDictionary, section?: string): Promise | undefined> { + private async resolveWithInputAndCommands(folder: IWorkspaceFolder | undefined, configuration: any, variableToCommandMap?: IStringDictionary, section?: string, target?: ConfigurationTarget): Promise | undefined> { if (!configuration) { return Promise.resolve(undefined); @@ -148,9 +148,13 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR // get all "inputs" let inputs: ConfiguredInput[] = []; if (folder && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && section) { - let result = this.configurationService.getValue(section, { resource: folder.uri }); + let result = this.configurationService.inspect(section, { resource: folder.uri }); if (result) { - inputs = result.inputs; + switch (target) { + case ConfigurationTarget.USER: inputs = (result.userValue)?.inputs; break; + case ConfigurationTarget.WORKSPACE: inputs = (result.workspaceValue)?.inputs; break; + default: inputs = (result.workspaceFolderValue)?.inputs; + } } } diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts index 8c3a5694be0..33a6c5d05da 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts @@ -6,6 +6,7 @@ import { IStringDictionary } from 'vs/base/common/collections'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export const IConfigurationResolverService = createDecorator('configurationResolverService'); @@ -29,13 +30,13 @@ export interface IConfigurationResolverService { * @param section For example, 'tasks' or 'debug'. Used for resolving inputs. * @param variables Aliases for commands. */ - resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise; + resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary, target?: ConfigurationTarget): Promise; /** * Similar to resolveWithInteractionReplace, except without the replace. Returns a map of variables and their resolution. * Keys in the map will be of the format input:variableName or command:variableName. */ - resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise | undefined>; + resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary, target?: ConfigurationTarget): Promise | undefined>; /** * Contributes a variable that can be resolved later. Consumers that use resolveAny, resolveWithInteraction, From a732c7fcfe86883610852aa3f3c4a5e5037d525c Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 6 Mar 2020 12:38:05 +0100 Subject: [PATCH 021/137] Fix broken test --- .../browser/configurationResolverService.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index f53c82c5d26..290c68e8bde 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -149,12 +149,17 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR let inputs: ConfiguredInput[] = []; if (folder && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && section) { let result = this.configurationService.inspect(section, { resource: folder.uri }); - if (result) { + if (result && (result.userValue || result.workspaceValue || result.workspaceFolderValue)) { switch (target) { case ConfigurationTarget.USER: inputs = (result.userValue)?.inputs; break; case ConfigurationTarget.WORKSPACE: inputs = (result.workspaceValue)?.inputs; break; default: inputs = (result.workspaceFolderValue)?.inputs; } + } else { + const valueResult = this.configurationService.getValue(section, { resource: folder.uri }); + if (valueResult) { + inputs = valueResult.inputs; + } } } From e3f23dc97ba64b1fefecb68708ba9a34a218f4ea Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 6 Mar 2020 13:01:23 +0100 Subject: [PATCH 022/137] quick omni => quick access --- .../standaloneQuickInputServiceImpl.ts | 4 +- .../browser/{quickOmni.ts => quickAccess.ts} | 2 +- .../platform/quickinput/browser/quickInput.ts | 14 +++---- .../common/{quickOmni.ts => quickAccess.ts} | 42 +++++++++---------- .../platform/quickinput/common/quickInput.ts | 6 +-- .../browser/parts/quickopen/quickopen.ts | 2 +- .../configurationResolverService.test.ts | 2 +- 7 files changed, 36 insertions(+), 36 deletions(-) rename src/vs/platform/quickinput/browser/{quickOmni.ts => quickAccess.ts} (93%) rename src/vs/platform/quickinput/common/{quickOmni.ts => quickAccess.ts} (61%) diff --git a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts index babc23fba6b..20342263dc2 100644 --- a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts +++ b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts @@ -18,7 +18,7 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService import { QuickInputController } from 'vs/base/parts/quickinput/browser/quickInput'; import { QuickInputService, IQuickInputControllerHost } from 'vs/platform/quickinput/browser/quickInput'; import { once } from 'vs/base/common/functional'; -import { IQuickOmniController } from 'vs/platform/quickinput/common/quickOmni'; +import { IQuickAccessController } from 'vs/platform/quickinput/common/quickAccess'; export class EditorScopedQuickInputServiceImpl extends QuickInputService { @@ -77,7 +77,7 @@ export class StandaloneQuickInputServiceImpl implements IQuickInputService { return quickInputService; } - get quickOmni(): IQuickOmniController { return this.activeService.quickOmni; } + get quickAccess(): IQuickAccessController { return this.activeService.quickAccess; } get backButton(): IQuickInputButton { return this.activeService.backButton; } diff --git a/src/vs/platform/quickinput/browser/quickOmni.ts b/src/vs/platform/quickinput/browser/quickAccess.ts similarity index 93% rename from src/vs/platform/quickinput/browser/quickOmni.ts rename to src/vs/platform/quickinput/browser/quickAccess.ts index 0d82b9adb80..fe0188fbe98 100644 --- a/src/vs/platform/quickinput/browser/quickOmni.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -6,7 +6,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { Disposable } from 'vs/base/common/lifecycle'; -export class QuickOmniController extends Disposable { +export class QuickAccessController extends Disposable { constructor( @IQuickInputService private readonly quickInputService: IQuickInputService diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index a11b314cfe3..1e3a7b5ec0f 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -16,8 +16,8 @@ import { QuickInputController, IQuickInputStyles, IQuickInputOptions } from 'vs/ import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list'; -import { IQuickOmniController } from 'vs/platform/quickinput/common/quickOmni'; -import { QuickOmniController } from 'vs/platform/quickinput/browser/quickOmni'; +import { IQuickAccessController } from 'vs/platform/quickinput/common/quickAccess'; +import { QuickAccessController } from 'vs/platform/quickinput/browser/quickAccess'; export interface IQuickInputControllerHost extends ILayoutService { } @@ -39,13 +39,13 @@ export class QuickInputService extends Themable implements IQuickInputService { return this._controller; } - private _quickOmni: IQuickOmniController | undefined; - get quickOmni(): IQuickOmniController { - if (!this._quickOmni) { - this._quickOmni = this._register(this.instantiationService.createInstance(QuickOmniController)); + private _quickAccess: IQuickAccessController | undefined; + get quickAccess(): IQuickAccessController { + if (!this._quickAccess) { + this._quickAccess = this._register(this.instantiationService.createInstance(QuickAccessController)); } - return this._quickOmni; + return this._quickAccess; } private readonly contexts = new Map>(); diff --git a/src/vs/platform/quickinput/common/quickOmni.ts b/src/vs/platform/quickinput/common/quickAccess.ts similarity index 61% rename from src/vs/platform/quickinput/common/quickOmni.ts rename to src/vs/platform/quickinput/common/quickAccess.ts index 5765d91d56c..7b06b76a31f 100644 --- a/src/vs/platform/quickinput/common/quickOmni.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -10,15 +10,15 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { first } from 'vs/base/common/arrays'; import { startsWith } from 'vs/base/common/strings'; -export interface IQuickOmniController { +export interface IQuickAccessController { /** - * Open the quick omni picker with the optional prefix. + * Open the quick access picker with the optional prefix. */ show(prefix?: string): Promise; } -export interface IQuickOmniProvider { +export interface IQuickAccessProvider { /** * Called whenever a prefix was typed into quick pick that matches the provider. @@ -29,7 +29,7 @@ export interface IQuickOmniProvider { provide(service: IQuickInputService, token: CancellationToken): Promise; } -export interface QuickOmniProviderHelp { +export interface QuickAccessProviderHelp { /** * The prefix to show for the help entry. If not provided, @@ -48,39 +48,39 @@ export interface QuickOmniProviderHelp { needsEditor: boolean; } -export interface IQuickOmniProviderDescriptor { - readonly ctor: IConstructorSignature0; +export interface IQuickAccessProviderDescriptor { + readonly ctor: IConstructorSignature0; readonly prefix: string; readonly contextKey: string | undefined; - readonly helpEntries: QuickOmniProviderHelp[]; + readonly helpEntries: QuickAccessProviderHelp[]; } export const Extensions = { - Quickomni: 'workbench.contributions.quickomni' + Quickaccess: 'workbench.contributions.quickaccess' }; -export interface IQuickOmniRegistry { +export interface IQuickAccessRegistry { /** - * Registers a quick omni provider to the platform. + * Registers a quick access provider to the platform. */ - registerQuickOmniProvider(provider: IQuickOmniProviderDescriptor): void; + registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): void; /** - * Get all registered quick omni providers. + * Get all registered quick access providers. */ - getQuickOmniProviders(): IQuickOmniProviderDescriptor[]; + getQuickAccessProviders(): IQuickAccessProviderDescriptor[]; /** - * Get a specific quick omni provider for a given prefix. + * Get a specific quick access provider for a given prefix. */ - getQuickOmniProvider(prefix: string): IQuickOmniProviderDescriptor | undefined; + getQuickAccessProvider(prefix: string): IQuickAccessProviderDescriptor | undefined; } -class QuickOmniRegistry implements IQuickOmniRegistry { - private providers: IQuickOmniProviderDescriptor[] = []; +class QuickAccessRegistry implements IQuickAccessRegistry { + private providers: IQuickAccessProviderDescriptor[] = []; - registerQuickOmniProvider(provider: IQuickOmniProviderDescriptor): void { + registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): void { this.providers.push(provider); // sort the providers by decreasing prefix length, such that longer @@ -88,13 +88,13 @@ class QuickOmniRegistry implements IQuickOmniRegistry { this.providers.sort((providerA, providerB) => providerB.prefix.length - providerA.prefix.length); } - getQuickOmniProviders(): IQuickOmniProviderDescriptor[] { + getQuickAccessProviders(): IQuickAccessProviderDescriptor[] { return this.providers.slice(0); } - getQuickOmniProvider(text: string): IQuickOmniProviderDescriptor | undefined { + getQuickAccessProvider(text: string): IQuickAccessProviderDescriptor | undefined { return text ? (first(this.providers, provider => startsWith(text, provider.prefix)) || undefined) : undefined; } } -Registry.add(Extensions.Quickomni, new QuickOmniRegistry()); +Registry.add(Extensions.Quickaccess, new QuickAccessRegistry()); diff --git a/src/vs/platform/quickinput/common/quickInput.ts b/src/vs/platform/quickinput/common/quickInput.ts index 68677753058..a2628686255 100644 --- a/src/vs/platform/quickinput/common/quickInput.ts +++ b/src/vs/platform/quickinput/common/quickInput.ts @@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInputButton, IInputBox, QuickPickInput } from 'vs/base/parts/quickinput/common/quickInput'; -import { IQuickOmniController } from 'vs/platform/quickinput/common/quickOmni'; +import { IQuickAccessController } from 'vs/platform/quickinput/common/quickAccess'; export { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods } from 'vs/base/parts/quickinput/common/quickInput'; @@ -25,9 +25,9 @@ export interface IQuickInputService { readonly backButton: IQuickInputButton; /** - * Provides access to the quick omni providers. + * Provides access to the quick access providers. */ - readonly quickOmni: IQuickOmniController; + readonly quickAccess: IQuickAccessController; /** * Allows to register on the event that quick input is showing. diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index d2ed77f70b2..da6fdd87829 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -166,7 +166,7 @@ export class LegacyQuickInputQuickOpenController extends Disposable { this.registerListeners(); - setTimeout(() => { this.quickInputService.quickOmni.show(); }, 0); + setTimeout(() => { this.quickInputService.quickAccess.show(); }, 0); } private registerListeners(): void { diff --git a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts index 64da9b3eed0..d8844b3636b 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts @@ -534,7 +534,7 @@ class MockQuickInputService implements IQuickInputService { readonly onShow = Event.None; readonly onHide = Event.None; - readonly quickOmni = undefined!; + readonly quickAccess = undefined!; public pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): Promise; public pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): Promise; From c05e980bed35afaeef535ef469cf9097b96feb90 Mon Sep 17 00:00:00 2001 From: Ilia Pozdnyakov Date: Thu, 13 Feb 2020 18:23:15 +0700 Subject: [PATCH 023/137] Add error code getter to FileSystemError #90517 --- src/vs/vscode.proposed.d.ts | 14 ++++++++++++++ src/vs/workbench/api/common/extHostFileSystem.ts | 11 ++++++++++- src/vs/workbench/api/common/extHostTypes.ts | 4 ++++ .../services/log/common/keyValueLogProvider.ts | 10 +++++----- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 083c74124bd..706ebf4325d 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1745,4 +1745,18 @@ declare module 'vscode' { } //#endregion + + //#region https://github.com/microsoft/vscode/issues/90517 + + export interface FileSystemError { + /** + * A code that identifies this error. + * + * Possible values are names of errors, like [`FileNotFound`](#FileSystemError.FileNotFound), + * or `undefined` for an unspecified error. + */ + readonly code?: string; + } + + ////#endregion } diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index a721785d28c..ca30ef0d660 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -148,7 +148,16 @@ class ConsumerFileSystem implements vscode.FileSystem { } // file system error - throw new FileSystemError(err.message, err.name as files.FileSystemProviderErrorCode); + switch (err.name) { + case files.FileSystemProviderErrorCode.FileExists: throw FileSystemError.FileExists(err.message); + case files.FileSystemProviderErrorCode.FileNotFound: throw FileSystemError.FileNotFound(err.message); + case files.FileSystemProviderErrorCode.FileNotADirectory: throw FileSystemError.FileNotADirectory(err.message); + case files.FileSystemProviderErrorCode.FileIsADirectory: throw FileSystemError.FileIsADirectory(err.message); + case files.FileSystemProviderErrorCode.NoPermissions: throw FileSystemError.NoPermissions(err.message); + case files.FileSystemProviderErrorCode.Unavailable: throw FileSystemError.Unavailable(err.message); + + default: throw new FileSystemError(err.message, err.name as files.FileSystemProviderErrorCode); + } } } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index e7810d7b6a3..0c62c89ad01 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2333,9 +2333,13 @@ export class FileSystemError extends Error { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.Unavailable, FileSystemError.Unavailable); } + readonly code?: string; + constructor(uriOrMessage?: string | URI, code: FileSystemProviderErrorCode = FileSystemProviderErrorCode.Unknown, terminator?: Function) { super(URI.isUri(uriOrMessage) ? uriOrMessage.toString(true) : uriOrMessage); + this.code = terminator?.name; + // mark the error as file system provider error so that // we can extract the error code on the receiving side markAsFileSystemProviderError(this, code); diff --git a/src/vs/workbench/services/log/common/keyValueLogProvider.ts b/src/vs/workbench/services/log/common/keyValueLogProvider.ts index 0db6b00da32..9180d49303e 100644 --- a/src/vs/workbench/services/log/common/keyValueLogProvider.ts +++ b/src/vs/workbench/services/log/common/keyValueLogProvider.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { IFileSystemProviderWithFileReadWriteCapability, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileDeleteOptions, FileWriteOptions, FileChangeType, FileSystemProviderErrorCode } from 'vs/platform/files/common/files'; +import { IFileSystemProviderWithFileReadWriteCapability, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileDeleteOptions, FileWriteOptions, FileChangeType } from 'vs/platform/files/common/files'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -53,13 +53,13 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys size: 0 }; } - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileNotFound)); + return Promise.reject(FileSystemError.FileNotFound(resource)); } async readdir(resource: URI): Promise<[string, FileType][]> { const hasKey = await this.hasKey(resource.path); if (hasKey) { - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileNotADirectory)); + return Promise.reject(FileSystemError.FileNotADirectory(resource)); } const keys = await this.getAllKeys(); const files: Map = new Map(); @@ -79,7 +79,7 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys async readFile(resource: URI): Promise { const hasKey = await this.hasKey(resource.path); if (!hasKey) { - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileNotFound)); + return Promise.reject(FileSystemError.FileNotFound(resource)); } const value = await this.getValue(resource.path); return VSBuffer.fromString(value).buffer; @@ -90,7 +90,7 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys if (!hasKey) { const files = await this.readdir(resource); if (files.length) { - return Promise.reject(new FileSystemError(resource, FileSystemProviderErrorCode.FileIsADirectory)); + return Promise.reject(FileSystemError.FileIsADirectory(resource)); } } await this.setValue(resource.path, VSBuffer.wrap(content).toString()); From 56fcba98e9f42e67711ab26a2da8ce2cd300b658 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 13:32:46 +0100 Subject: [PATCH 024/137] Fixes #87614: Ignore composition that doesn't do anything --- .../editor/common/controller/cursorTypeOperations.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 9ae8b986bce..0155bf76b6e 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -269,9 +269,15 @@ export class TypeOperations { commands[i] = null; continue; } - let pos = selection.getPosition(); - let startColumn = Math.max(1, pos.column - replaceCharCnt); - let range = new Range(pos.lineNumber, startColumn, pos.lineNumber, pos.column); + const pos = selection.getPosition(); + const startColumn = Math.max(1, pos.column - replaceCharCnt); + const range = new Range(pos.lineNumber, startColumn, pos.lineNumber, pos.column); + const oldText = model.getValueInRange(range); + if (oldText === txt) { + // => ignore composition that doesn't do anything + commands[i] = null; + continue; + } commands[i] = new ReplaceCommand(range, txt); } return new EditOperationResult(EditOperationType.Typing, commands, { From dc8a2bf6ac8371827811ba2662cf57b6aa841247 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 6 Mar 2020 13:33:53 +0100 Subject: [PATCH 025/137] debug: rename welcome view to just run fixes #91567 --- src/vs/workbench/contrib/debug/browser/startView.ts | 4 ++-- .../contrib/welcome/common/viewsWelcomeExtensionPoint.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/startView.ts b/src/vs/workbench/contrib/debug/browser/startView.ts index c69b7c228fd..2f56399c605 100644 --- a/src/vs/workbench/contrib/debug/browser/startView.ts +++ b/src/vs/workbench/contrib/debug/browser/startView.ts @@ -31,8 +31,8 @@ const CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR = new RawContextKey( export class StartView extends ViewPane { - static ID = 'workbench.debug.startView'; - static LABEL = localize('start', "Start"); + static ID = 'workbench.debug.welcome'; + static LABEL = localize('run', "Run"); private debugStartLanguageContext: IContextKey; private debuggerInterestedContext: IContextKey; diff --git a/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts b/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts index a16e6d6b37b..513eba9642f 100644 --- a/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts +++ b/src/vs/workbench/contrib/welcome/common/viewsWelcomeExtensionPoint.ts @@ -22,7 +22,7 @@ export type ViewsWelcomeExtensionPoint = ViewWelcome[]; export const ViewIdentifierMap: { [key: string]: string } = { 'explorer': 'workbench.explorer.emptyView', - 'debug': 'workbench.debug.startView', + 'debug': 'workbench.debug.welcome', 'scm': 'workbench.scm', }; From f41df243c5a140394dcee5d7c23dae567de8d66a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 6 Mar 2020 13:35:32 +0100 Subject: [PATCH 026/137] quick access - very basic first help entries --- .../quickinput/browser/quickAccess.ts | 36 ++++++++++++++----- .../quickinput/browser/quickAccessHelp.ts | 36 +++++++++++++++++++ .../platform/quickinput/common/quickAccess.ts | 16 +++++++-- .../browser/parts/quickopen/quickopen.ts | 29 ++++++++++++++- 4 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 src/vs/platform/quickinput/browser/quickAccessHelp.ts diff --git a/src/vs/platform/quickinput/browser/quickAccess.ts b/src/vs/platform/quickinput/browser/quickAccess.ts index fe0188fbe98..f733bc8ecbf 100644 --- a/src/vs/platform/quickinput/browser/quickAccess.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -3,22 +3,42 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import 'vs/platform/quickinput/browser/quickAccessHelp'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { Disposable } from 'vs/base/common/lifecycle'; +import { IQuickAccessController, IQuickAccessProvider, IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -export class QuickAccessController extends Disposable { +export class QuickAccessController extends Disposable implements IQuickAccessController { + + private readonly registry = Registry.as(Extensions.Quickaccess); constructor( - @IQuickInputService private readonly quickInputService: IQuickInputService + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IInstantiationService private readonly instantiationService: IInstantiationService ) { super(); } - async show(prefix?: string): Promise { - this.quickInputService.pick([ - { label: '1' }, - { label: '2' }, - { label: '3' } - ]); + async show(prefix = ''): Promise { + const provider = this.getOrInstantiateProvider(prefix); + + provider.provide(this.quickInputService, CancellationToken.None); + } + + private mapProviderToDescriptor = new Map(); + + private getOrInstantiateProvider(prefix: string): IQuickAccessProvider { + const providerDescriptor = this.registry.getQuickAccessProvider(prefix) || this.registry.defaultProvider; + + let provider = this.mapProviderToDescriptor.get(providerDescriptor); + if (!provider) { + provider = this.instantiationService.createInstance(providerDescriptor.ctor); + this.mapProviderToDescriptor.set(providerDescriptor, provider); + } + + return provider; } } diff --git a/src/vs/platform/quickinput/browser/quickAccessHelp.ts b/src/vs/platform/quickinput/browser/quickAccessHelp.ts new file mode 100644 index 00000000000..ffdb95d4865 --- /dev/null +++ b/src/vs/platform/quickinput/browser/quickAccessHelp.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickAccessProvider, IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { localize } from 'vs/nls'; + +class HelpQuickAccessProvider implements IQuickAccessProvider { + + private readonly registry = Registry.as(Extensions.Quickaccess); + + async provide(service: IQuickInputService, token: CancellationToken): Promise { + const picks: QuickPickInput[] = []; + + for (const provider of this.registry.getQuickAccessProviders()) { + for (const helpEntries of provider.helpEntries) { + picks.push({ + label: helpEntries.prefix || provider.prefix, + description: helpEntries.description + }); + } + } + + await service.pick(picks); + } +} + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ + ctor: HelpQuickAccessProvider, + prefix: '?', + helpEntries: [{ description: localize('quickAccessHelp', "Show all Quick Access Providers"), needsEditor: false }] +}); diff --git a/src/vs/platform/quickinput/common/quickAccess.ts b/src/vs/platform/quickinput/common/quickAccess.ts index 7b06b76a31f..eaa37e0b957 100644 --- a/src/vs/platform/quickinput/common/quickAccess.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -9,6 +9,7 @@ import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instant import { Registry } from 'vs/platform/registry/common/platform'; import { first } from 'vs/base/common/arrays'; import { startsWith } from 'vs/base/common/strings'; +import { assertIsDefined } from 'vs/base/common/types'; export interface IQuickAccessController { @@ -51,8 +52,8 @@ export interface QuickAccessProviderHelp { export interface IQuickAccessProviderDescriptor { readonly ctor: IConstructorSignature0; readonly prefix: string; - readonly contextKey: string | undefined; readonly helpEntries: QuickAccessProviderHelp[]; + readonly contextKey?: string; } export const Extensions = { @@ -61,6 +62,11 @@ export const Extensions = { export interface IQuickAccessRegistry { + /** + * The default provider to use when no other provider matches. + */ + defaultProvider: IQuickAccessProviderDescriptor; + /** * Registers a quick access provider to the platform. */ @@ -80,6 +86,10 @@ export interface IQuickAccessRegistry { class QuickAccessRegistry implements IQuickAccessRegistry { private providers: IQuickAccessProviderDescriptor[] = []; + private _defaultProvider: IQuickAccessProviderDescriptor | undefined = undefined; + get defaultProvider(): IQuickAccessProviderDescriptor { return assertIsDefined(this._defaultProvider); } + set defaultProvider(provider: IQuickAccessProviderDescriptor) { this._defaultProvider = provider; } + registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): void { this.providers.push(provider); @@ -92,8 +102,8 @@ class QuickAccessRegistry implements IQuickAccessRegistry { return this.providers.slice(0); } - getQuickAccessProvider(text: string): IQuickAccessProviderDescriptor | undefined { - return text ? (first(this.providers, provider => startsWith(text, provider.prefix)) || undefined) : undefined; + getQuickAccessProvider(prefix: string): IQuickAccessProviderDescriptor | undefined { + return prefix ? (first(this.providers, provider => startsWith(prefix, provider.prefix)) || undefined) : undefined; } } diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index da6fdd87829..49a6ef401fc 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -15,6 +15,8 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; +import { IQuickAccessRegistry, Extensions as QuickinputExtensions, IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; +import { CancellationToken } from 'vs/base/common/cancellation'; const inQuickOpenKey = 'inQuickOpen'; export const InQuickOpenContextKey = new RawContextKey(inQuickOpenKey, false); @@ -166,7 +168,7 @@ export class LegacyQuickInputQuickOpenController extends Disposable { this.registerListeners(); - setTimeout(() => { this.quickInputService.quickAccess.show(); }, 0); + setTimeout(() => this.quickInputService.quickAccess.show('?'), 0); } private registerListeners(): void { @@ -205,3 +207,28 @@ export class LegacyQuickInputQuickOpenController extends Disposable { } Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); + +class SampleQuickAccessProvider implements IQuickAccessProvider { + async provide(service: IQuickInputService, token: CancellationToken): Promise { + service.pick([ + { label: '1' }, + { label: '2' }, + { label: '3' } + ]); + } +} + +const quickAccessRegistry = Registry.as(QuickinputExtensions.Quickaccess); +['', '>', '@'].forEach(prefix => { + const provider = { + ctor: SampleQuickAccessProvider, + prefix, + helpEntries: [{ description: `Sample Provider with prefix ${prefix}`, needsEditor: false }] + }; + + if (!prefix) { + quickAccessRegistry.defaultProvider = provider; + } else { + quickAccessRegistry.registerQuickAccessProvider(provider); + } +}); From 03d5e98a0121be050c6925f16e57f0d3b32118c5 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 6 Mar 2020 13:47:44 +0100 Subject: [PATCH 027/137] rename debug start to debug welcome --- .../contrib/debug/browser/debug.contribution.ts | 4 ++-- .../workbench/contrib/debug/browser/debugViewlet.ts | 4 ++-- .../debug/browser/{startView.ts => welcomeView.ts} | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) rename src/vs/workbench/contrib/debug/browser/{startView.ts => welcomeView.ts} (91%) diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 4dcff55440e..3cc92cc0715 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -44,7 +44,7 @@ import { WatchExpressionsView } from 'vs/workbench/contrib/debug/browser/watchEx import { VariablesView } from 'vs/workbench/contrib/debug/browser/variablesView'; import { ClearReplAction, Repl } from 'vs/workbench/contrib/debug/browser/repl'; import { DebugContentProvider } from 'vs/workbench/contrib/debug/common/debugContentProvider'; -import { StartView } from 'vs/workbench/contrib/debug/browser/startView'; +import { WelcomeView } from 'vs/workbench/contrib/debug/browser/welcomeView'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { DebugViewPaneContainer, OpenDebugPanelAction } from 'vs/workbench/contrib/debug/browser/debugViewlet'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; @@ -108,7 +108,7 @@ viewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variab viewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctorDescriptor: new SyncDescriptor(WatchExpressionsView), order: 20, weight: 10, canToggleVisibility: true, canMoveView: true, focusCommand: { id: 'workbench.debug.action.focusWatchView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], viewContainer); viewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctorDescriptor: new SyncDescriptor(CallStackView), order: 30, weight: 30, canToggleVisibility: true, canMoveView: true, focusCommand: { id: 'workbench.debug.action.focusCallStackView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], viewContainer); viewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctorDescriptor: new SyncDescriptor(BreakpointsView), order: 40, weight: 20, canToggleVisibility: true, canMoveView: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' }, when: ContextKeyExpr.or(CONTEXT_BREAKPOINTS_EXIST, CONTEXT_DEBUG_UX.isEqualTo('default')) }], viewContainer); -viewsRegistry.registerViews([{ id: StartView.ID, name: StartView.LABEL, ctorDescriptor: new SyncDescriptor(StartView), order: 10, weight: 40, canToggleVisibility: true, when: CONTEXT_DEBUG_UX.isEqualTo('simple') }], viewContainer); +viewsRegistry.registerViews([{ id: WelcomeView.ID, name: WelcomeView.LABEL, ctorDescriptor: new SyncDescriptor(WelcomeView), order: 10, weight: 40, canToggleVisibility: true, when: CONTEXT_DEBUG_UX.isEqualTo('simple') }], viewContainer); viewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctorDescriptor: new SyncDescriptor(LoadedScriptsView), order: 35, weight: 5, canToggleVisibility: true, canMoveView: true, collapsed: true, when: ContextKeyExpr.and(CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_DEBUG_UX.isEqualTo('default')) }], viewContainer); registerCommands(); diff --git a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts index 7011327d8da..2c59ca9f209 100644 --- a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts @@ -32,8 +32,8 @@ import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryAc import { INotificationService } from 'vs/platform/notification/common/notification'; import { TogglePanelAction } from 'vs/workbench/browser/panel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { StartView } from 'vs/workbench/contrib/debug/browser/startView'; import { IViewDescriptorService } from 'vs/workbench/common/views'; +import { WelcomeView } from 'vs/workbench/contrib/debug/browser/welcomeView'; export class DebugViewPaneContainer extends ViewPaneContainer { @@ -92,7 +92,7 @@ export class DebugViewPaneContainer extends ViewPaneContainer { if (this.startDebugActionViewItem) { this.startDebugActionViewItem.focus(); } else { - this.focusView(StartView.ID); + this.focusView(WelcomeView.ID); } } diff --git a/src/vs/workbench/contrib/debug/browser/startView.ts b/src/vs/workbench/contrib/debug/browser/welcomeView.ts similarity index 91% rename from src/vs/workbench/contrib/debug/browser/startView.ts rename to src/vs/workbench/contrib/debug/browser/welcomeView.ts index 2f56399c605..eb23cb4cd14 100644 --- a/src/vs/workbench/contrib/debug/browser/startView.ts +++ b/src/vs/workbench/contrib/debug/browser/welcomeView.ts @@ -29,7 +29,7 @@ const debugStartLanguageKey = 'debugStartLanguage'; const CONTEXT_DEBUG_START_LANGUAGE = new RawContextKey(debugStartLanguageKey, undefined); const CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR = new RawContextKey('debuggerInterestedInActiveEditor', false); -export class StartView extends ViewPane { +export class WelcomeView extends ViewPane { static ID = 'workbench.debug.welcome'; static LABEL = localize('run', "Run"); @@ -52,7 +52,7 @@ export class StartView extends ViewPane { @IStorageService storageSevice: IStorageService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Start Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Welcome Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.debugStartLanguageContext = CONTEXT_DEBUG_START_LANGUAGE.bindTo(contextKeyService); this.debuggerInterestedContext = CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR.bindTo(contextKeyService); @@ -87,23 +87,23 @@ export class StartView extends ViewPane { } const viewsRegistry = Registry.as(Extensions.ViewsRegistry); -viewsRegistry.registerViewWelcomeContent(StartView.ID, { +viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, { content: localize('openAFileWhichCanBeDebugged', "[Open a file](command:{0}) which can be debugged or run.", isMacintosh ? OpenFileFolderAction.ID : OpenFileAction.ID), when: CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR.toNegated() }); let debugKeybindingLabel = ''; -viewsRegistry.registerViewWelcomeContent(StartView.ID, { +viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, { content: localize('runAndDebugAction', "[Run and Debug{0}](command:{1})", debugKeybindingLabel, StartAction.ID), preconditions: [CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR] }); -viewsRegistry.registerViewWelcomeContent(StartView.ID, { +viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, { content: localize('customizeRunAndDebug', "To customize Run and Debug [create a launch.json file](command:{0}).", ConfigureAction.ID), when: WorkbenchStateContext.notEqualsTo('empty') }); -viewsRegistry.registerViewWelcomeContent(StartView.ID, { +viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, { content: localize('customizeRunAndDebugOpenFolder', "To customize Run and Debug, [open a folder](command:{0}) and create a launch.json file.", isMacintosh ? OpenFileFolderAction.ID : OpenFolderAction.ID), when: WorkbenchStateContext.isEqualTo('empty') }); From 9933dff169920e770201609cfd45d769420346bb Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 13:58:56 +0100 Subject: [PATCH 028/137] Fixes #86696: Tweak hit testing on Firefox for pseudo elements --- src/vs/editor/browser/controller/mouseTarget.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index f83ff9bfd94..f0ad0cf79dc 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -925,6 +925,23 @@ export class MouseTargetFactory { } } + // For inline decorations, Gecko returns the `` of the line and the offset is the `` with the inline decoration + if (hitResult.offsetNode.nodeType === hitResult.offsetNode.ELEMENT_NODE) { + const parent1 = hitResult.offsetNode.parentNode; // expected to be the view line div + const parent1ClassName = parent1 && parent1.nodeType === parent1.ELEMENT_NODE ? (parent1).className : null; + + if (parent1ClassName === ViewLine.CLASS_NAME) { + const tokenSpan = hitResult.offsetNode.childNodes[Math.min(hitResult.offset, hitResult.offsetNode.childNodes.length - 1)]; + if (tokenSpan) { + const p = ctx.getPositionFromDOMInfo(tokenSpan, 0); + return { + position: p, + hitTarget: null + }; + } + } + } + return { position: null, hitTarget: hitResult.offsetNode From 329be45e5a2ee39f23625a74399f3600daf21b91 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 15:06:25 +0100 Subject: [PATCH 029/137] Fixes #81733 --- .../workbench/api/common/extHostExtensionActivator.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/extHostExtensionActivator.ts b/src/vs/workbench/api/common/extHostExtensionActivator.ts index 3a076946edd..7e86c340c1d 100644 --- a/src/vs/workbench/api/common/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/common/extHostExtensionActivator.ts @@ -252,7 +252,15 @@ export class ExtensionsActivator { return; } - const currentExtension = this._registry.getExtensionDescription(currentActivation.id)!; + const currentExtension = this._registry.getExtensionDescription(currentActivation.id); + if (!currentExtension) { + // Error condition 0: unknown extension + this._host.onExtensionActivationError(currentActivation.id, new MissingDependencyError(currentActivation.id.value)); + const error = new Error(`Unknown dependency '${currentActivation.id.value}'`); + this._activatedExtensions.set(ExtensionIdentifier.toKey(currentActivation.id), new FailedExtension(error)); + return; + } + const depIds = (typeof currentExtension.extensionDependencies === 'undefined' ? [] : currentExtension.extensionDependencies); let currentExtensionGetsGreenLight = true; From 435048ba3590aa22b5af48f5d0ba438d5c82509e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 6 Mar 2020 15:24:42 +0100 Subject: [PATCH 030/137] add search for pre-es6 util --- .vscode/searches/es6.code-search | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .vscode/searches/es6.code-search diff --git a/.vscode/searches/es6.code-search b/.vscode/searches/es6.code-search new file mode 100644 index 00000000000..09a841dc699 --- /dev/null +++ b/.vscode/searches/es6.code-search @@ -0,0 +1,74 @@ +# Query: @deprecated ES6 +# Flags: CaseSensitive WordMatch +# ContextLines: 2 + +11 results - 3 files + +src/vs/base/common/arrays.ts: + 401 + 402 /** + 403: * @deprecated ES6: use `Array.findIndex` + 404 */ + 405 export function firstIndex(array: ReadonlyArray, fn: (item: T) => boolean): number { + + 417 + 418 /** + 419: * @deprecated ES6: use `Array.find` + 420 */ + 421 export function first(array: ReadonlyArray, fn: (item: T) => boolean, notFoundValue: T): T; + + 474 + 475 /** + 476: * @deprecated ES6: use `Array.fill` + 477 */ + 478 export function fill(num: number, value: T, arr: T[] = []): T[] { + + 571 + 572 /** + 573: * @deprecated ES6: use `Array.find` + 574 */ + 575 export function find(arr: ArrayLike, predicate: (value: T, index: number, arr: ArrayLike) => any): T | undefined { + +src/vs/base/common/map.ts: + 9 + 10 /** + 11: * @deprecated ES6: use `[...SetOrMap.values()]` + 12 */ + 13 export function values(set: Set): V[]; + + 20 + 21 /** + 22: * @deprecated ES6: use `[...map.keys()]` + 23 */ + 24 export function keys(map: Map): K[] { + + 58 + 59 /** + 60: * @deprecated ES6: use `...Map.entries()` + 61 */ + 62 export function mapToSerializable(map: Map): [string, string][] { + + 71 + 72 /** + 73: * @deprecated ES6: use `new Map([[key1, value1],[key2, value2]])` + 74 */ + 75 export function serializableToMap(serializable: [string, string][]): Map { + +src/vs/base/common/strings.ts: + 16 + 17 /** + 18: * @deprecated ES6: use `String.padStart` + 19 */ + 20 export function pad(n: number, l: number, char: string = '0'): string { + + 147 + 148 /** + 149: * @deprecated ES6: use `String.startsWith` + 150 */ + 151 export function startsWith(haystack: string, needle: string): boolean { + + 168 + 169 /** + 170: * @deprecated ES6: use `String.endsWith` + 171 */ + 172 export function endsWith(haystack: string, needle: string): boolean { From 55c2dc54e296c2b5e2d297b7f3df2329a19b5794 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 6 Mar 2020 15:44:21 +0100 Subject: [PATCH 031/137] list: only aria-selected on selected items #91061 --- src/vs/base/browser/ui/list/listWidget.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 8ab511f551b..b2ee2f104f8 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -180,16 +180,16 @@ class Trait implements ISpliceable, IDisposable { } } -class FocusTrait extends Trait { +class SelectionTrait extends Trait { - constructor(private isAriaSelected: (index: number) => boolean) { - super('focused'); + constructor() { + super('selected'); } renderIndex(index: number, container: HTMLElement): void { super.renderIndex(index, container); - if (this.contains(index) || this.isAriaSelected(index)) { + if (this.contains(index)) { container.setAttribute('aria-selected', 'true'); } else { container.setAttribute('aria-selected', 'false'); @@ -1198,8 +1198,8 @@ export class List implements ISpliceable, IDisposable { renderers: IListRenderer[], private _options: IListOptions = DefaultOptions ) { - this.selection = new Trait('selected'); - this.focus = new FocusTrait(this.selection.contains); + this.selection = new SelectionTrait(); + this.focus = new Trait('focused'); mixin(_options, defaultStyles, false); From 18f3bee3e999d696b61b40eea7491f55b6e8160e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 6 Mar 2020 15:49:08 +0100 Subject: [PATCH 032/137] jsonValidation takes an array for fileMatch --- .../client/src/jsonMain.ts | 47 ++++++++++--------- .../server/src/jsonServerMain.ts | 25 ++++++---- .../platform/extensions/common/extensions.ts | 2 +- .../common/jsonValidationExtensionPoint.ts | 16 ++++--- .../extensions/browser/extensionEditor.ts | 2 +- 5 files changed, 54 insertions(+), 38 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts index 7b307332241..5d41458931c 100644 --- a/extensions/json-language-features/client/src/jsonMain.ts +++ b/extensions/json-language-features/client/src/jsonMain.ts @@ -40,8 +40,13 @@ export interface ISchemaAssociations { [pattern: string]: string[]; } +export interface ISchemaAssociation { + fileMatch: string[]; + uri: string; +} + namespace SchemaAssociationNotification { - export const type: NotificationType = new NotificationType('json/schemaAssociations'); + export const type: NotificationType = new NotificationType('json/schemaAssociations'); } namespace ResultLimitReachedNotification { @@ -264,10 +269,10 @@ export function activate(context: ExtensionContext) { toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand)); - client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context)); + client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); extensions.onDidChange(_ => { - client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context)); + client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); }); // manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652. @@ -324,8 +329,8 @@ export function deactivate(): Promise { return telemetryReporter ? telemetryReporter.dispose() : Promise.resolve(null); } -function getSchemaAssociation(_context: ExtensionContext): ISchemaAssociations { - const associations: ISchemaAssociations = {}; +function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] { + const associations: ISchemaAssociation[] = []; extensions.all.forEach(extension => { const packageJSON = extension.packageJSON; if (packageJSON && packageJSON.contributes && packageJSON.contributes.jsonValidation) { @@ -333,23 +338,21 @@ function getSchemaAssociation(_context: ExtensionContext): ISchemaAssociations { if (Array.isArray(jsonValidation)) { jsonValidation.forEach(jv => { let { fileMatch, url } = jv; - if (fileMatch && url) { - if (url[0] === '.' && url[1] === '/') { - url = Uri.file(path.join(extension.extensionPath, url)).toString(); - } - if (fileMatch[0] === '%') { - fileMatch = fileMatch.replace(/%APP_SETTINGS_HOME%/, '/User'); - fileMatch = fileMatch.replace(/%MACHINE_SETTINGS_HOME%/, '/Machine'); - fileMatch = fileMatch.replace(/%APP_WORKSPACES_HOME%/, '/Workspaces'); - } else if (fileMatch.charAt(0) !== '/' && !fileMatch.match(/\w+:\/\//)) { - fileMatch = '/' + fileMatch; - } - let association = associations[fileMatch]; - if (!association) { - association = []; - associations[fileMatch] = association; - } - association.push(url); + if (typeof fileMatch === 'string') { + fileMatch = [fileMatch]; + } + if (Array.isArray(fileMatch) && url) { + fileMatch = fileMatch.map(fm => { + if (fm[0] === '%') { + fm = fm.replace(/%APP_SETTINGS_HOME%/, '/User'); + fm = fm.replace(/%MACHINE_SETTINGS_HOME%/, '/Machine'); + fm = fm.replace(/%APP_WORKSPACES_HOME%/, '/Workspaces'); + } else if (!fm.match(/^(\w+:\/\/|\/|!)/)) { + fm = '/' + fm; + } + return fm; + }); + associations.push({ fileMatch, uri: url }); } }); } diff --git a/extensions/json-language-features/server/src/jsonServerMain.ts b/extensions/json-language-features/server/src/jsonServerMain.ts index 182eef7e9ee..e339620d1e1 100644 --- a/extensions/json-language-features/server/src/jsonServerMain.ts +++ b/extensions/json-language-features/server/src/jsonServerMain.ts @@ -23,8 +23,13 @@ interface ISchemaAssociations { [pattern: string]: string[]; } +interface ISchemaAssociation { + fileMatch: string[]; + uri: string; +} + namespace SchemaAssociationNotification { - export const type: NotificationType = new NotificationType('json/schemaAssociations'); + export const type: NotificationType = new NotificationType('json/schemaAssociations'); } namespace VSCodeContentRequest { @@ -230,7 +235,7 @@ namespace LimitExceededWarnings { } let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined; -let schemaAssociations: ISchemaAssociations | undefined = undefined; +let schemaAssociations: ISchemaAssociations | ISchemaAssociation[] | undefined = undefined; let formatterRegistration: Thenable | null = null; // The settings have changed. Is send on server activation as well. @@ -291,12 +296,16 @@ function updateConfiguration() { schemas: new Array() }; if (schemaAssociations) { - for (const pattern in schemaAssociations) { - const association = schemaAssociations[pattern]; - if (Array.isArray(association)) { - association.forEach(uri => { - languageSettings.schemas.push({ uri, fileMatch: [pattern] }); - }); + if (Array.isArray(schemaAssociations)) { + Array.prototype.push.apply(languageSettings.schemas, schemaAssociations); + } else { + for (const pattern in schemaAssociations) { + const association = schemaAssociations[pattern]; + if (Array.isArray(association)) { + association.forEach(uri => { + languageSettings.schemas.push({ uri, fileMatch: [pattern] }); + }); + } } } } diff --git a/src/vs/platform/extensions/common/extensions.ts b/src/vs/platform/extensions/common/extensions.ts index 87d90b14746..ac6ec196a03 100644 --- a/src/vs/platform/extensions/common/extensions.ts +++ b/src/vs/platform/extensions/common/extensions.ts @@ -38,7 +38,7 @@ export interface IGrammar { } export interface IJSONValidation { - fileMatch: string; + fileMatch: string | string[]; url: string; } diff --git a/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts b/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts index c3f09c4cdb1..dd2ad38b467 100644 --- a/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts +++ b/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts @@ -7,9 +7,10 @@ import * as nls from 'vs/nls'; import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import * as strings from 'vs/base/common/strings'; import * as resources from 'vs/base/common/resources'; +import { isString } from 'vs/base/common/types'; interface IJSONValidationExtensionPoint { - fileMatch: string; + fileMatch: string | string[]; url: string; } @@ -25,8 +26,11 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint { - if (typeof extension.fileMatch !== 'string') { - collector.error(nls.localize('invalid.fileMatch', "'configuration.jsonValidation.fileMatch' must be defined")); + if (!isString(extension.fileMatch) && !(Array.isArray(extension.fileMatch) && extension.fileMatch.every(isString))) { + collector.error(nls.localize('invalid.fileMatch', "'configuration.jsonValidation.fileMatch' must be defined as a string or an array of strings.")); return; } let uri = extension.url; - if (typeof extension.url !== 'string') { + if (!isString(uri)) { collector.error(nls.localize('invalid.url', "'configuration.jsonValidation.url' must be a URL or relative path")); return; } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 733bff5f29a..b68c1e206e8 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -1208,7 +1208,7 @@ export class ExtensionEditor extends BaseEditor { $('th', undefined, localize('schema', "Schema")) ), ...contrib.map(v => $('tr', undefined, - $('td', undefined, $('code', undefined, v.fileMatch)), + $('td', undefined, $('code', undefined, Array.isArray(v.fileMatch) ? v.fileMatch.join(', ') : v.fileMatch)), $('td', undefined, v.url) )))); From f91c7ded03bbf0bb3617bac4f4b9f9331add5b6f Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 6 Mar 2020 16:26:59 +0100 Subject: [PATCH 033/137] product icons more --- extensions/extension-editing/package.json | 6 +- extensions/vscode-colorize-tests/package.json | 7 + .../producticons/ElegantIcons.woff | Bin 0 -> 63664 bytes .../producticons/index.html | 3049 +++++++++++++++++ .../producticons/mit_license.txt | 21 + .../producticons/test-product-icon-theme.json | 36 + .../themes/browser/fileIconThemeData.ts | 2 +- .../themes/browser/productIconThemeData.ts | 2 +- .../themes/browser/workbenchThemeService.ts | 38 +- .../themes/common/themeExtensionPoints.ts | 55 +- 10 files changed, 3161 insertions(+), 55 deletions(-) create mode 100644 extensions/vscode-colorize-tests/producticons/ElegantIcons.woff create mode 100644 extensions/vscode-colorize-tests/producticons/index.html create mode 100644 extensions/vscode-colorize-tests/producticons/mit_license.txt create mode 100644 extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json diff --git a/extensions/extension-editing/package.json b/extensions/extension-editing/package.json index fe4a7b44d2a..75d77925b0d 100644 --- a/extensions/extension-editing/package.json +++ b/extensions/extension-editing/package.json @@ -35,9 +35,13 @@ "url": "vscode://schemas/language-configuration" }, { - "fileMatch": "*icon-theme.json", + "fileMatch": ["*icon-theme.json", "!*product-icon-theme.json"], "url": "vscode://schemas/icon-theme" }, + { + "fileMatch": "*product-icon-theme.json", + "url": "vscode://schemas/product-icon-theme" + }, { "fileMatch": "*color-theme.json", "url": "vscode://schemas/color-theme" diff --git a/extensions/vscode-colorize-tests/package.json b/extensions/vscode-colorize-tests/package.json index d99e050d302..e2c15b2f67b 100644 --- a/extensions/vscode-colorize-tests/package.json +++ b/extensions/vscode-colorize-tests/package.json @@ -55,6 +55,13 @@ "fontStyle": "bold" } } + ], + "productIconThemes": [ + { + "id": "Test Product Icons", + "label": "The Test Product Icon Theme", + "path": "./producticons/test-product-icon-theme.json" + } ] } } diff --git a/extensions/vscode-colorize-tests/producticons/ElegantIcons.woff b/extensions/vscode-colorize-tests/producticons/ElegantIcons.woff new file mode 100644 index 0000000000000000000000000000000000000000..393305253e5fc01d3369b4cf2735b08929432f96 GIT binary patch literal 63664 zcmaf(b9Cllv%qWH_SSZ{-g0Z(wr#uJVvDV9+qU1@erwykz4!0?oi8VIGV?o=OeT3w zp2;Nc^5Ww1Dk}0IAkVcR@E{-{U~~o`px@j7XAuz>CjkKgg#iJ%O#uNTb#mbTm=G6N zkp%&{%l&r8`xXK-hs7`nQ8Dpv*7V}Teb`fv6c+ZsB6 zfZWr62UP|E0k^v=Y?rh!H8cSMc?|gWVg44*PpA?Ui*NYNYQJrgZ=rxd`P#Rzb@BLS zv)}gS_x@`*(^%-Xh92L?d-`8LsQ(pED+LfcLtE2t*7|Lqf1i85ZLh4VgT1rMcfN(+ z4B=ZyK)^vjJTeb_VSQA@mh2a0?I}n@(&7T*Niu|1>T9n;#A1S|_en^|SQ#M{Sy-bG zq5{@2TyibQBY99LVnCwJmP({bX?&iZ9YxEjqp(vk`}f$*Cr@>$cD6pO~u497uZH7 z zv46}_7MNsK(wvQ3o4~JXxh3M>{^SutN^F_vIPhiF7NE@eJ2Q@bAbpG2CdrsgJTY^i z?i9R1=AY;dtYMYUP6!QS&J>T?<+Q?oh%FY60!$xU-E-P8L*a?UpbmEpgAZ@VMh>g& zdm1<2l(TGmEI;>Z82T7ivN^?E3^VRy??*V!ahqdEd|yX#l|QAZ2^awCd{0p?(UAxu zR9|wtm}l$3+K3*pm^cq=BcH*-2y-$s(N3HjufcUxX)=MRXZOMM2z&DGKhG?CM-d{Z zBV=+C9^`+g3@fanTXan;%&m>AO|7lZjLu9uw%i(QYcG)2`J3Nt_iesvW$XSmYc{Lf z*so%(r>qLp`P#j$H3OQbn&+FhA2TjOs(KF_@E>U(HQtgRMZHD5*}T)cg1b6Cw7mV_ z7#`Qp$uBe?>mDU8T8JURVBD~_>a;JB% zbgFdqIa)bg*KK(PP`m1rtf9+V%_94gZRo?rfq~mj5po}eol0y# z8gQ+|-id+8^j}rg0qMnSC5}!NM5h0$$__}+U(d03vLiD6S5eqtgYE>A$Hp zO<~Jg1J+f$O-t8W)*e+HolAIn)`+k2)6+(*`42cNY*}u=x@5O${(8;QcU_mS+pRq|IXW-#^xP3^{sRsVTNW8O z%iDdJz4o&3;Aih7!qY=Wtoi>jlgPlt>@_QUCj#PsRclJZmX!z2%611=Lye> zI_9*4FRH9hsybGsxw=#BH0>+oHtV+91G`+oz0Y<}io&Z~h*I^i_&#*)KeUWTky|lnri|Mh|;|kD!2{0g_lG^k$ z67KXE@)X|*ns5cF4+9= zQ51eLCP0QqkF}V-W7a6fax{Jf@;Q?o2Kb=to*7HLN5A%<{t$^{1rB`}ioZt&4y9e{ z42t|yCOh!XDLs?X9L1kYc{;HHNWi1sE!nv>af|sO>xJ_s z;A(W}R`(_Qy+r5N`_7xwzjq-&>aQPyWLpkx@1oW5IpfK<+k;fqi8&KY2UagdIwE}g zS}#pHR6Pl2z?MNlKPs+qg0|mwDck5wZK`%j>p)~y^-oD3AX1z1Wnu@A=!NYj?d`zt zC7O=}d0b@Bo+zbfjQrN!Q-z3p>#miLRDRsYQ!1NM;J%VR{^-E-BtcJ;I=WCEYXa>g zHR@T}5=T75knKDy*h4i{aVUa4KgObf_NHnvMx&q|)m+DL5FI(gK*w@{*$S^IrXnJz z%9sN0x47=URRPgWGh$4bIQc$aK^-9EdBddOA7I16u#sI0btc2A5cfpfx*!&i^1S^h z4qZ?H7(2FcA=PWm0Bjx`n&9xq>J4H)u~c)s;w|I;8-5rhe`0&Z=fVSz$%x5_)c=fj zjJ{Dfj(4nJN%J_$8@3&0-gh%@b%eeFxZ{z>_TakXy5m2g$n%envWnwB;Tp%hMfUj3 z;#l*UnBXJh??){A4SFo#*z=jmFnmKt6v!0C1xUu#7%-5_P$Wtk#dV3ne3$ zHnBnHH;>X25v_R>s}ae6Ld=(U1w4@go?rp)&8>1#XO~#ZwpjmWA|{u`4u2+iYUmI% zyiTEU9Y$p6?j3#@?Q9wu)ICpV@1?j8>Z?ZzKSlT14(((N?)(|tnKH6)b<_^SajU`E zl8$NBi}4VOIj8!3tZg-~!P%6EY5Tn)sLpqcvHCXH+7lts65)@4h8`X@f*nP*jjlW# zQL;A}Q)OhP&r%VW)}%QZiOy7w%~XZSbQG;lxVIQS)M<0`ig9!3cC(~VM@US)AK2L z-K9j`jdcRs?}O*T!#<;ld82hUBkk^$YBCH-iGNc?ViA(gJ9;&!S zOwX*L8^gUpPDfgi%$HQ|4p|I(tfS(HyMd6FIO+{jAN%M;)c$S#QaL5|BnqtY;Y2J= zQCmxU(u=IZkDr$Mq!;UjAFVD2l1B`4o?1WQi>&J^=Tybj5)#Nw4>)lbHN_cH0X?H> zJ)>5D`n5mxYmS=y;(Dm$=))6qIVl`ONlgfzi`cj2_9ho#|1{(|BN7n>lb89JGGr2D ztw)PJSv_-XQb;qd5~gM*)S65x+*pCX|2fGN$EH?UPjFtCW*nJxEY^PrnvPi2E4#0r z=&o9Zo@df@&?oCIjWHgXJQdZyrLyi5{;QLIjQPv2pWMYYX5BF=liKOmbdF8>=9>5+ zF`h9!8ultI&2c}^<$;1&j%Lr&tjBq9z=cF1RP1I!oSBzd1@_ndf1zdW3 zEQ)=OMgDE7m~GQGjEtSPm^>o=)1@aSVi*}3?I{_Pz?+chN!*_qA9);$R0baS@Nmcr z_$moBC`Xy)nBQbxBXX{C2lONSA&b*7u^ltI_q1x@FGtEn~?V;Vxp*-Cq zHBC&5o%t7DFe%zI@i#H# z>&OpH>2)ZDTI<(FIeVXGv}Wdo6x@LqsTZRqAU^Ki3U|8$fvd?Vb>yWEO}`SXQuJs^ ziC-e4ptp+m3d~g4e~OE3Dc_&9FaM3;W=*#{vRCQnJcU)>ru(YpyuUt&D^kI;5^{d; zKvPg>)aBotOir~y<~)N$kF8Q~zA*JxoLNZSP`fNf<4RTQ}EO+*c>=~6+?zJ1aXn$gk|Q)dgCTjWOujAU1NasD0m9~k_2N{hfycgp5p zsf6}KdxE06=`&y=Iv|$u9kX5Z9cs07sY}I8C87N>d_bL$^A(n1m?2l*8{r>gC(cjQ z+Rv4yZ1u|5{*#?K0G^mbVtzzRvY%Vz0ukf5`JpmdylL(*#rg!kNWBP#CHSh!@(4_q z`6BO-6N8rG#w8<=WmLz$2Snw~9b6|9o6Zd-%oqQQray@ja zo-&D!ZEXE7o3%p46!YbFJPyUO#LhCxRK|IBT=a`pPd;g9hY@gp-yc82HAB*Sv86vNFhM(05!ZpA4hD}O;` zJ0qBjAz=6a2=}k>N#c}fg(!lHqgRHqC)CKKQf(?ao~z1(djCKMLw^>eOlM=n*@u28 z(TN;e%^-I2C#4n}l-RPlROIYGR7~?;% z#lrM}4taQc)eqP(bl+cFi`B%Rx!B(y25gn?4GaW(i=Fj;23nPI;l%ykAfE>o1ePD? zI=N5wRx({FwA<@6zUT)zLDVujcM;_!r-&*lW|hAHT;eJja1Ll6KY_rrQbVz z@O}dlW@yan%$OQ0tj_`>ifmq$H&h3$bCo>-^m2CkoY1)%BvY3=1UhzwfFlkQtDG*6 zIfj5+*Mhq~_{@A{$8imZ5spNs(Z}p>rLfyQGy}Moe1MDb8rW6|sQ>Q2nr|t8oHkts zENC$gS%)_@2SYU1!x8`4X+?Bt>Pd=xWAVbA^M%Ii|Mzr?EhgGkr81IO z7AZB^v5K$8SiWlhPsy9BTDb1ILvVlEa%)738XoBls92cV$G{RJ_ z!+I419{Du?o}qmiuL#3uoVQ8J<01Zib=9K03smSLZmipG{FxFOddgW#dprlRM~4!@ zyFFVNTD%v@FK@sn$lnuekp%c&dV2Sw_9`T+lt43h98*?K$5omD+g{!-bmMW0W+l(i z&?8W(&}0QZI)E9*g=+=fG>oCj77L&+_Sh<8V*fEx;W?5$D#wb+^-JQP*A@?BbQ$uw zMrYtZ&~iQ4zRC@}-Oa+iAk9`=o)7~yQsL*OTn$HdY8XKbj1c98p&*AStdQ^f72p+y z8PW&p5GXr4IBVNWqF3x8`SzUZPfgVR`Gr!SE(G-)*#x<}vN`*<_r=-$MOC{gtKq4@ zV|j(_>4|`f{lygRi9^Kr*@H=)=2HpwWTF@}6Bam^t9D3ON+NZKLyZXMXbl{u*~&{$ zCvV8+=&6Fz{h$uozqfM8w1OV7v=OrFrIaBzff5g<7SW6h8mXSdY_3c#ww6Ly=xL%B zR6EHl^D(I0qZ@##a1Y>9uAP?;bn%77UE6k7pvTTzpgI<~Gcy`jst{UC)>OYilD%dJ zT}V@K)7`|@QMcE6XPdAa+PN67t{7o5K=!#w)>3Z?qTqvqx~hv_paNo)h4{Qh2q)0} zVxu-ye>80};5W9hglAL=3*G*q8%Wc2ZrMt3D^ATC0O9!s5CI=Z)Qh!~u5ehF!aT+v z8{Oq8{d%$Ljz3+bmVY?>sAJi8WfOv&Q0PK63($XSDAhYo&eRZ|PQ%}O?-|3Y(1v-C z`9$|<@B9Epu9+_K%8FFD_umrop&(s$ap3)m`Cw+Y=$yF0+y~Jrdg>_2V3~LaQ@x71b5MDOE2*lwHh6hO$8t}_!ooJt!2&vwr)C%Z0C-@D(eVMD2Q|9|(O-pD^l=jBz{3=;*xzl7dOuZ# zflI!XOQ#l9P{huD#(E1gU|vfpjGqKUB;K|D^Gu@j4wn8SMs(RvNTMP5Fskr^R&jN! zeqoH;bYT$=+GVvuf;KwFr_$2v&uW{lQV4^bZ&*`>T8RXP%WIM!z_wWZWY3;^xB)=B zHP03|U41m#fIwxmTrh$}Kx#{o4tnpwV~atJ7vc<_w#it^91L}nVozlhmu)_l?AcF% zcoS}&)YMhaHW7qR#@H0idWPURwi~}r*$+$0$J;CQeElpyO@;JZGS<2Jxv8cB&%u!1vW(ooa8Y-q5JaPTc~o?Wr)tJ-cCFvN?#;N{F*k zi2?qB&F&+Jm#uBnv<1Bv>X`mezbxX#z(;sLnE_iL@)eTBm@>M{5^?#2#P zFYf)rNg8gWeTwgcZ-xCXn4S`3C6`KZe~2R76;lWYy9HN6mxH49rEhDJDeHx!FEj#F zG{Z9%s`eG%TQd{2AI8sFI|6v4+6E-e9!lf`nE!hNv(cWo8-W~DgD5W{J<5YzLTqkxb}FcurDroZvAR?D+-SOkp-$=aW=U|oCTr~&g++Fx!j+3tF#mr9*?q_OD*PO7oX-udy)3kVJADOU1!mcxyB3E@9D z;hIn~sj|x~4FubI*>oXtZdzVV%W2E_dJ6s-c$%7EyZZ{AH-Vt^eIh}U^I?n%w@?7l zCr3*0Z0w$Y%NidpgBw%n?_tv_Ilh(o73=H3H2xxl;0e}C#C>Rn!t}<1ULfJ-pZ^j? zl4L{gMSAm(OC_hyU{*nYY-*vJHO2H)Gv@oEIrTcjncM2zK3)F zpV{g}@J|Wys8lQ*pO8*4`N{Zd#RD~CX`nOL(7!i7dDn$AeBZ?l$~|~fSk7FTrljE! zOzx;&likJ|6szh!_|S2;qwx^A9V5lF!X%Y;u+tV9@Z)9G;fG%)Px;11q&(CRZC!Fv zUZBOkHpiikz({@1U*k54?I&o0iEvj%d3C#y{`e%i?-c^$+hDIM3bsjCscUy|5tGk<#-O673mzbR}7zQOasAdwOL7_ z0`Jj0Im-!pHu^P~i<{ zHprI%dhwO({Lw#_-ppiuGd!+wN7*VTAyr{N4K(kVJ*#-5C-1fZ)Yw_a5IW2kT&BHl z?G@d(Y!JJIjwEyhIkI~qoK&@&A>#=9D4(5HQxhLT>*gV=r7Rhx=xIUz;b>4=z*OGW zo+NV(rt}iC@3@2_4U=#mz=Olmh0(0E$9ZVV``b~VYWGH>8A|{_c3wYrx8}hj=myU% zHC+mV=T2U!y5WiwkYd>OgHnbT>9BQco=8IM>WcN?s;VF9jD*?YJdCXq$UR_OoNQ^# z<}si!5N9mkQu~e>vr!;4gj;zqB$dlkp06Gh+P#CrY=1BNizXZ?E`tJ+Gl;~;(!gMo zRuP!2o?O{v$Rm4B*u4!lF^Hrs_Rmy_-Poek^mbH!iIpboAuMHVzV^Ze&%amr4>MM| z$9o?LLqLt};4CGOoMn-KxoVx2 zo65!gztmoq>Ff1374KXV+74mbzFmXg6;~67shisiq$phi^HoCq4A}PUpNHm*B0@33 z>zmoX`4+<{e7;PgPYi5_XSo>iRK}jN1wm6{RUOkH$P zue(8Az{CQ4L`jzms3vAwT7zwouHy|}U*}?N>Xm_78&V26dZV}nZTd+S#GTpn4vjQK zas)^UOL7EB;^^Ct8Es8E4P5hP5FqvXejCusW@zypkFvVh#^mseUPq1~v`NrDQi)D4 zy?CL=Fu5j8JrwPP%FK)gz;gLHNl}FM8N%F-BM&|!_ z)jN2~+*!p%60OWEy}hM(8nMO3nGbml^y_HHB(|uHFl3Rb;)}HmCWDQhzFoj(YZ0hc%IP z)c?#n7I8TF)MqEkf`_tA0 zRHe4cn=Waah6~5j6WV(<{M~tG1?djTL%o!7VTY%gX-n>hW_6liFeect?~C9lNWH*k zGw4xV9PDc^UQz;P*c|o_tq~^lhf{4uCF+}s?j%$uvHgrZt zKCx>OWW<6+u`jusqjioqT;pW@>ma$Cp>?hYrushX8}okSl9pjzP`l@Du zeltEVk6b+}`LDSeMShoW|InH=1qG1$idB01u;wVSOI86Wsr`^Pa5|vi222AY7|g69 zaz#Pif)GOnADE5Da*P5+qIbKSCm$GQm%$8+-)*hioe_`uu9M5dglrxCzzn$8BZLQf zrf`kqq~65&D@JG6& zbGaa@b&0Rcid)(~^bvKwUZ6je zr$~Io zi}|?TQ12`4B#}$TvwiK0{M^qOp_RUofa_09vOBSoT>^tM>AfIuT7uy`nAW79JV}8J zMJ(f&GaA}D5LZnz&3V2CNPvKpgl;hHicu%7v1}K2IKldr#D!4;Ern#Qi*s>(SSz&s zv4_D9x;IszEo#{O6!YLu7+J`iU$P(Q$FmC(l!@ z(Eu0KAL*PWCms3?k7LNc_h1x+2WWk7?2GTK1h2|Acbyk@_$SdVnvhCyle;y?9G^Ju zQofNKZGGn_W;ZI4*|o)JXOh&;P*~(lHae9?E`6eUgozHAvvstQbfi^ZkB4|g?bZIN zW|ZAGJU^;?rTY5k9;p?LQ_vJ)Qn46EVTWqLeo7#zmFIqtB+;-h6vB{D6JAURx;3f6YbksQ`jV{3jK-b3gp3nBw>Bo zsk!6V)~S``r1F?DmXX$05PWlH%Y9wv6NI+AY}|t_#_wK~7uS~{tbn8YQT1qEhAxBS zE^67{Yo&k+iTeEx1ds1mWEkR>`O2QLl#s=ZRzB6{$HL+HW|?SJ-it6P=PzJEc2UzQ zrO#E9Qb>O!iejS*2AiKY;&;f;=qsPxX>C42ffqDd?GOaIex8n??Ac_=Wkk|SgD;S0 zHNEYM{R+9*h&-SS^Z3YD-01NxjQx~d+XWW}9!T8}`-F9M`-n5(tgq~eg|O(EpYI~i z?HI(dPh{ewpogO!i7JB>%QRp)?noL&=%iWSL9N!lgI<%Ln2(@MlV?3(j!o^o3{KKdO~m6A`bO zoqNs!6~02^yjb=Xy3q zYfc?zP=;V>co3NM-X1Lol*$D=haWSiHs{3ytG=~$NWU=OGRABzB2N5UikNWF)mgUi zSA@BVh|ht+_l`WVlpRPxTVl{s1LgR8A;d!kalKo0!(4YUWSMSz-xXWHb}BiZL<3nX zWNhBf#XagCiGJEmS@z;v8=86iEUBWWzn9cxZ))+mCFUu) z|Jk1-o63}dbtN=IAQ9spm$-@JUUoGU;+K3CL&pv(i!8EUA3Z;CTz=^BTMI_yrL@kD z_%~~|&C!Apd9JW4eGaXyQ z-dbhmWR$g~vlDH#?}SUryrM_S`cDb78={5lG!faSX_>kZ=#e+x`AHa#%~45PP0eCipe{ncR<_ zSs9jNG7aDIp-p*kD+#mayUZ#uwLf5^DPq^AJjmr0H37emA_B_EEY{&lQ5k_V%=v_^ z|DdgxC%wxk3qh%alnpT{ny7>F%HR}~s*c6#38O8pe^v$c`qgbmJd*v0B4p=5%TPU7 z8ladqoR5C>!wx6yP$Fzyg0r~@7iR{UV+ zfVTmjJX!CEUl-7ljw|(n)G>A0&o5;=uyl*hS2@$kzBz}U8R~Y+zHo%%uN&Chi>}dv zESyV4`kE~c;a%&?t`tjp!4>j117gY$%t=Ia0J@kFPt#Z4S8KDiJ?Ox7k0hntqEOpt z>Z14ZXmIhWR)SFIGQxK>KMOi*19>(=tIC4NW(YY?D{pYhIY%L%*X7St9`!kzFCp4~ zGJX+hgjO2!t9$-m^IVYYX>Ew#Z8tef7g}HV?Yc;iLZqp(^il|az^*4HMU8rCM+Nhx z!rYgw5SJj}NA`Svka2&aOzOLu@I*_j_^DbXqs_)hUc0Ls-ED{$s69118snN^+p(hat1eAkkqTvYB|ogPx;LW~muK+yq=qT*%Pvt-k(T zrr4@F%{45-o-sQf`VdC`0B3uO}c#U^>l8pyJ{5(J-{?-#P2N>b-jzQ3Cjz zOu-&%pze3p^FHjL5FZ4NyU%krtN$V^#z4Wur}|PQWS63B?QA^;f69qQUF#5TH@-Mp z?LE#f>6ryrw`09SdK#P>v_ykn7!Rce60dk__+*h87k(veS23BVyivJ0GMOY6yT9E0>wFt}j^b@k2pZv`^ z{a_we-Z;_H8U<(6uB7#3_ zM9h3j|5#0i$Eg}1rW0Y&3)V_w(W3B-BTmjx0)8u^O2V{Wx%)_iU?U)d&&?DT8%wjY z(nnB+)|nbLbQv0LaNkcT6ui6hry4SVF;sBAKb&_Vc2<*-SSLdgq~3@=m)IrH+=^pQ zTVT|Kg~kjPRWK3OYqq-%4A75gB+<%7mb`(Oy!TS@r`6ji`m*bRtN9x4*wr`%Id7E;E~wF%Iws&ALABQIQJl9=}gu-oypo2y~T2V7P@^>KA>qtY+oC^ZTSp$h*XNS6p z27;t8_4V=a(J`Txi36j5{+qKX(ff{`4g!+MFcvpeZ|JFw|clYB@<#n^4Qe z=qOpP)O z$L7$FI2!st!Ev5lvi6H^cuaYYjZ0l*VDt^ACk|>1J80FiIQQ$po$joz7d_{+T>TIV z`;dO!acRP)kxamV{+!X{MeCl?a3+KEV}aZ+n*rqFNvui`#B9qq(;1>thA6!O#^-Z= zx5+aN2?;!!^KI#wlMQa8cE8R9e`ePNl#xT9<)T{s2G8dk%3UY$)P;~mZY3Z!^q7mA z@-UMyyHE?M%SUByru7-cQ=Bp2C`KKIFtRN(f`QuVu2_lt6(KW_^hKmmoezy=`N>=Y4%C44Q4ka>6J*xo=C4vXUqy@U^Z+DLSM@3M}O3D=r@C; zvXL_AU%^bFLa?o;Joj+ux6*a$7l4;rso^s;k5uFiLk>oF3#4yY1t^R)wnc~@+&iX* z4t&{SxP6py$K)%=&+-k0P@ecxwGX3vcSMs z$|;letSJ9cQ$G?Pk@-6q_tpJ3eZlC425p^0VFOCQ0F+Jt$zY70q&q9B;$fy;qoV?< z+j%#tlp$F?pKmt&K#&@_*-*r`?z!+&YeW1z8jVS~UHGEi0yGfK0D$#Ds7nYL%o~k& znbQgtPO1y;432$izV7?GsS)Ur*X&@=&sldYUF7yls1M(?nv)c61W|Vi3dv-x7s`=O zb)+}&qR>@#s8R^DINN_^kZ&34QD7yYl22!ha`4Uqh009vtvb*S$2EdI0)GVM&b}%7 zBWjM>(oWP$d#Z={A6+iF2Dg*L&_l#no-9`}9L0o7k-`gv`D9tHR=i2&!2xSDN9wEIs(dzdyO{M0g5xaWjOuFC4jN3VHG_oCX7zJevtw)>?jHoi-e!I97=c zmhrfv`3^E}KicqewG6O@Zx?F4lGM6?NQs44L3O6^(~!*FNbgL@?{gdw z(6vOVtu*-Ji0=^j%#AE@@+*@M84Uwe8tOyHIOfK(4;C7k=RAWDQ{c6t16glk{Sv{}S|g zsZ~Z!eh{v*B8O$he(*G0?wuw_V-_m;uIM2C@ki~}_HoQ7eT2$clug_7+uV+JusZ7P z|1NEi7l{G}*(*k*^&;nc)keU+2WVsI@eI+vU)Y{|&ZLu1vbZ3TMRgUUte%I^`(k+~ zb9HxKw8q$i<>iH<|r;I+ln z+w$9SDeHy`*ptmD-LrpW7YY$Y#WMZ99O(i%HWBVnh=$a+83Yol54Bup?bL%Bn>&R$PZ|uzLT^ z&pP4?FoP$8i${c-@?ur|3<*iO=Hu=Cddse(q+W8N)PCO~rTvq8A?Hy|2q`B_sSpcXT{jkz!T-Bx`QeVwz-!y?4fvtLernn$PB zdkS*iu|TUWOlNmg`vn1I{ZTgk2$!Nvmt?_z&A+rS%}qHBo`UFE+Nj)=L|9c9mNlC| zE~=$MTCF2VU5DzxMDa+2P5)8}=gwd*F$%o!EG;>sDas?7P?kA3-X`d&CDPm6cA_St zd}5o9o9fis00;eKsBb8%ti`=Pez9OVRLKgQLq>wvT5Ux?V!!#x4`ch>eYkksku|w^ z908=$a|D6l-5sWd0 zY#o*}Pxvpn4IJ#$dk`HoY?q8tJ5y_B*cZ_tG4w$I#e!Z`Sv$7(tsVW>roEqL`iiZ1 z5n6|9ux8$R1b&bwr`1%83J~qiDB}s~QCf||xi=pZBkpaE!dQ)xG7F`$D4I^?bV3Z8 z2_d<{!mnX7g5Rq31A#xQ<0B?{MF>;)YbY);yl;q;ob`Bbr#D*hAKdkD_ztZ;enCqM zppF77W)_Kh!-X5?nMHh)Ox!V-YP57o&^Zk1QF&Rta={1}+^Fop<1wT}SB)~uqqq@m zHw4c&0dFdF*4<)dQsEfBeo(6EfjP!^0@QRi)wejw(qNrOvlUupD>_t7)VTx>w)yrp zm$(({#f-b7wW?V6juvar=wFJ6PKfnlpv67gtr1tqj_SP&t8iQ301jSGjfa`npqQ<} zj2?Xjq0p<^BzematWiG09(;Pha0>*aRq)hS8~I$QvJLl=9Mub2^#Vng_>g|WS{rgm zlYqf4be*^}N@kX4O`n{}ZLx`!(`37YD-yV3kgI##Ou3;I<@Y6h}^3R%C7bL!N~jWSt7x+*7=wZtj*AaWeC>QJZ zB4vRBRN&R`!>|s}R}Ar+ETtI+-Oy1DwvOLLEW5@}jmb>J15G7*C zL}x}=UJQI(oM_VMe0ymK#zmR-Ne1J{6_F>CHig`!_QM{QlrGbP>(#M=ANCQ38&i>{ z)zRHZ1S2FX;MHIa0F1&~y8g)gz<$J9b!O~26Ep~>7)vmmdi|AE zhy5F?xpqW>0(ngJU!5m+6b^5`(=>Ma)&ES>r6&oTf9qvaZDL+SME48XSXXy)+;@IxlwO;5RCmAs`WgY!c| zzzL+-$qT12ZT{X*GBq>(*UiJ{b}u;hA}F6(PcYt=gu7a`s#L@V6ZgEwLoaBJ&6iZ9 zKacdmGPo!r-pI?eik{;v%*Gt~81M_I=fS%X6#7IYT8WK+9y~GC^85+ISrwa$+qTpF z6hrWfI>e+BX2gs&$i)SOYAjvPkgdpvDsYp!YkVegGp| zIVGrena)^@7ktDAJOEYxRAKCuI zij~|Xg6t;L_=2%en-A-+Rpou*cKUf#a9Qo4)4|27<09dd!od$0S1nT1mE93e|Bt&zJ?AzDJmJe4X=cvqOeW>2?X{+Dg56G+`rP2ZIBdA#jgV zy2tHgdYbRT)O!J6IoTh@*$Hz-I~2!O?4+Ix{+kM-F5uUX&G&RjNGFdinFi@xLKU7%qA04hBk9={_P5ug-Na`N< zwJl`g%42d8Sql04z>$gL+Nuc{{6z+S9ucUpPKFQxeqQbRK<%gTn^2rnny2rWM z>glmvGAFhH$kniyUya4(u!3- z4DD3zh573#$6ubhASQnX4m~4$!|Nn2hi5MXG60+u;!k94Ezp(a(5Iv`tR_DL))0t3 z^C4G6-Po)lIJPKFxb}3tpiOX@>}HIvCZR9*E-WOKpy+u1)E$i)KBfn!pd$Q;i3wph zC&lmuCvMrUOXQ^lK0wxva|+FnLRr0=ZR1Wuk&ws($FKArrH`2 zZ}qX@GKwDne?cJTr!uiHR1GZjdj#+#aZD0e4SdeJ<5j?F-QH$bgodhe}(5 zissT*l7(GVz~zv_9-T`H;DcZOQoI&@H1dxNdNUxU;{&ArqQ9jksJv)Bvug)K?#+%+ ztfk;49mo^d6*^3z&9p?F$TChNbhs4JqRFbm94iyW@Lm(I`s|Qa)~ixSRiy6};)_dv zH&K2gIS^+gcI@V z)~#JYmD?Zv%#Ve{11cmKzfB3pMoxZ=#}95YoAT@fCe$xb?WEE?dcFR6E%KxOmgJ9@ z&YgKNkbhi84dTdj=Y79c{f(pyOCOnRWKBhXlCddSZ}yHi)pCp z`#kX3w3Kn}x(SJmP-zw{KYyTtL~?OEE1MFo198mWF(xKN5R5BUQhz_!JZg#c7uzIQ zR$gzmB0|gl7(!$`m}98EFg6; zVm1`2WXfO}lg)W1d}u(vCA#VkS1)vks$q5d(@~mm3QKT9t{2K#A8R*s)3cjsPz_}4 zvw^=vOHnO@mS;mz?Sml|H2u8P_~2*pP-ZgHBsXuAk*KBwmCdz5v=BrPqHJ6M_eF4t zB}B<{05S6$#aqBO>ZnSIU)bS+Zd^WHpzGGQf#7>=gR4&qW)0W@7(jLCnu_L>59@{B zeFqK?-r_YA$1hud$*N(ExFP}>9}7*`(_v!)Pvj5?@lI7PokbT2f~J*QCwsxGbqq}`-05F zK(yDRD93TQd)_v(Wo@ElL^Lmoo0*^|*ghzyYppwaZ4qZ@MvmK#W-I8q~O`QFnJ3GVhCe(k7 zhd#f2b_k;v(2h%OrHu0jEuapOt2)mzCRp?c+=9wtg@@Zn%z&7WpBl^Ni%=s`B#hI| zIG7AoHYio;mP8je);4`rbw49Om5x8;-XPP{V^F=tF)R{3a5k%x^M{W$BWc33E^+yB|9R>dG zZr$}Is-AXbVFQwJs)R_m9u#8}j#-?KJr}A-Q3J73c49X~ZQ2g$rDRPIL;@Jl5-?{8 ztT{wy;|^Twit)y0xqaDTlr~{vnK?wR60yuaVsKJ?2yi(MZ|mJ+COJ zkkQh~L)^YxPqv3Md(ps$NeLBp;BzZE@I*0UY&G51AhYIEk2HJh&_kF0i9Iy%RA(L0 z1rIY1IQz-71({z7%pE3H{);BIINmeI8;{^);!pG3oXN$?$#S7!4|2!P&L6mz_>QfU z zcf)B2I2MmL;NM~97KiET0G6B!CsCYhS6a6gXMH+?Mk$_uy zGQYu3UtipJSY`CHBWh<#7>RIsIPHb6z->AM zS}4yJ6VVL{DQ-l!*gMU@krc#bkaU;>zovn{IndgMOQK{ZoA;Z(8kLK&4)2>3%6lvH zOfPXjI=uoaMG;+6u*7l@hy^8tye6uFQRUFxKxQgrx`BXoN~;423-iG~Rh{G@7BFsN z5e)9Og?du;?xee5|3CuxkF zWA3`k7w_=&^fVx9_ygpY`e4<5hD_WHRst^YjEehkiyvT%`k8;gfiOSd3w+C;sh{!d z5BodP2(7;Bu6Z;S173MG4`IKBd@$@@&L<4|p9je+gL>h;H`RBD*z*4i8mN}b%4PPsv^$|$@dP24P!9TX zD`(gUm%UGkxv<u0Vras6bTUH_q9#vp5k+RF(mbS>S%q%N6uBhpK)d!3$wzl&nF8~Q-v zxy(Qr#R?Iq7Ho*_I=d{MNKSV|91MhbNcCmeal+s%PR{=I&0g$lj}og%b$=W;#)lIq zI2fOKLpI-fSiNji)fxm{(6c1vuREDDq~Lc}E;ym5a>46}4b4tIX9b+1tK@7Fq3g|% zlMaq~8T@4I9n?go-B8O$EklfY^og0S%h<1>wt%4Ng>I$*aZ(&`?&IWEeDF6*H+&2P zye@pKAN4H5Ug^PEQxV)(RztA5hmR$F7O8=8g~DzraJaxXs+fm?>(KT2*aMuIRrU(OE*0QzFgDv71%wwv|0LcGpSQCd0Fo35KQmO^%c;)FP(nMj2z-i zuXy^-yh`K=rF}X*Y!-;si%*$sg))5uE4S5{tg!Eb?_ppG9f;?}w&)p1dmSd3#CDr^ zAiqwvt^(>+INMGoGUcqA=WZLBlc4{P$xG-G=~+&N@;@Fo#@oOhVCA?n=u|b3y)B`o zZ=N^R!JC2>)3=goj<%hx5@TtUAdu9!_xTKiTLgwd_|caT8?XI3MH($!p)5$)JXw9htgZyEIxZ{O z(QE5ogU0;;iIVaGP6L|*n_l{ees=ASpninQX9tA4e*K z8U%wr8FMZ3Y!`&jeAVc8YW$Y{w0X6vF}u{^ZDyq$-de$4u;s{oNaFOsBCTRptAW_< zKrGiIcffkYQ*QBW8KOkZS6)$S9d?`su-)#-{u~~+09@yz=G2CEH~{He9DvlY|32+7 zB3kpFt%evtH0)H=O{1{3^9hjAOIE$Ptd(oRcl$%h^w7K)oA*lF1X`#AI| zY!QR;j*7_oOR@a z7G$OpllONddPgnU)@K>}F1V21ML57y7CIU*6q=b3uT^BC7kc|Udi7kz&gS+k-!&^aDT zmuP4+si4WL355^}_E4v*hf3c+6yp6Hh#j<6;Q|Sy;(~1q&P4|;KV+th;=Q*0*qO8u z%25+drVc3keg@)`Pp|v)m@!6RyGVt>b3Hiv8_>gRNx_ z=yTRcT1`2?a_WF-29rs%n+02VLBllpf`6EpGvK%_&)3))Kom@zg)%@Ms01|1w1ytE z^=G#S0Szh(C;%#GNM;BDFoZHA$9{+rh`6@mx%;TX;+2&V62R5m5a}a1*WE922}umZ z>@4>bIDJ#H-2Ef-67>JH@?IyFQ|`WDyIV;F`1!xaVRD>FK^3up&RP!)FGt3(m!ZDm zC_h+hc%C@+TMmk)@pu8fc4L=l1-?Ifd3(DyI6=>=jYaA>#6P~}{12s9$1zYPph8rAqctX0#nP**~9dy@$mf=Y=Cj6#m@bObjx=kNjS*@!$rsoiFnAJwL{LZB{( zV#1gM_S0m`yGzOWlN|7IVPhFP{W_qs=TpZGgzj5czNgdq`5=rRSx*=TtvzxBacb?iJ8QcIdL(|dX$VUHXUzR&&HH>d8Ky)bo6fJ&gg=Wtzi66BEzh&LyrQ1N#)~@bYK!aODrFeEbgW?ByS_m+&Zg;tpP5i z3`eeZ_ViFiAJ(&SS#jv8I6+&7XZ<@?9BJW4E#N*5_Fx@2gCm&ro!y_aYny~f!s`AF z%95He5d6XiNk^-eEhLPYY#)N-s*Wy#Te(u0BNuRs69DPM>>EN% z?l^Z6;lxl_m$LZmU#lTEm2I3+dzsZ>aq7z5w4n}OX z2}W#fvi8o_U;TcH>9jP}H*HY_LU>kwGZ-{BqjJ5~@pp0(Tam5_SzOwIYXXzaOh)a?HW!EMgoU?ow8`ymc(DRh>Rx z9w0R)p&3HLs#1b;o{hpiE_i1gQgX-5UK+k-2lWj}ipOTGTui;vwx0 zUd%xhc8odL`XTD5C(*2{VeH&Rn~tap)~*qRgpt@$C&H!~1^Frq6TsSPCyQGU9PFHB z)P4_+rW*jVg$9ToSWVOlAf^fR_t%RKA#FNNg^hvRNCF?z2{I51B4L9yR4n2&4W2Df z;UPZP4$~|1@EnfFo)a$2BpZjFh{y54*cipm<4}{a!-|CFHVTNzZc0@k14VHb0|+_M zNK9n|PBsA2@L5vbS@G3{PkXKpMhBh*tYzlF84<;v5OAM!!3p9#BGV+;^#YD+3tU2| zg|7!x$-Kj3uytxF5B!Qwvo;w)4EY@KaEr~wO8UW_A0)~biCCvG|lIF1h3dO!QM%T)zz+QM>#bjZg&mu2F>@UwEqFY{2W@! z6pj&2<-e})UBOg>%wuhX*m(h?)gqu_$z!)z<|El%kWa$pbC`1BG$`9<0&Wj56E$^P zI1?u|sL*mnWuu7;N;EJq?E4qE>TBikj6}Gl1A0{_8)Lh`Q*dA59=G;*RNhTEgOt6` zjzAq*cqph$;?suDK&e)U_<|yi4M0du3`E4j?Por)oVYqLCxr3?H0LRmBLp__u?0Cdd!dpAG2}cFCm|yj@z;0>nnn?69S;l}e0yH+kOzOGwI$!|IFiOD z2Hj?77Y%Bdp97UiMfkfl^78 zyjNuLmHL>N$yY#y2}!C8M&@t8u&?^>2e*Jr#mVwGh7by#lDw&_kW za1@ilWO~9$!l-B9LiH6~AznotT|TU9*8$i>L7&k4fj(x~h#w!SCMNx;N!^P*W%00+|NuGXKn}~8YLEIht2#jk-Km;8_!}V#}T)&f5J)o z>^E6^`cfb_t~w9p#*c$y-N*&@C@nIq$LZAikUGDlA)ffq+3<-sntlV0K>iw@p}F(k zv0MIQ+T)f}qCo-ad;KFQAb;SrtUl;LwdH z+R!FG5I5_QOjWL}44d94$5CIzn3*0s%0kkodVTJ=0Sz z_i@>yZF~d013d$M0W*0iJZ^_4J;#?G(z2f9OAnLvK3rz~FqZgmIsW5w+*zLZC2*N9 zr|g%6jyyuqV9*$^7UL=JM|31^Gvh1vorK!dpHwL!xH^}?tF z*Am99;V=LW#8t;2<#WNehe2%IAlcBIi(0!9lGv3YL<@Ys2KsfToM$@H_#v0fv6rTs zx6|Lpk?=*GzGp08{s24n9&9KLz`isyGq6}|u*c>#?EU`%wg%C{R)fkOEYR?Yi8~_g z96a+WF)<)X_0ha$oQ*?tT2WO$FP@;DeQL7H6_s7NXKH9;PcDcWGzRi1 zWH;0y<>wclLVCj21{^n){|LtzRc2`^S%de4J7E*k$LLVCAWX=iA*wnW!TY#35;?PI z#hFi&c0^_Y=t(|J?C`Vgtjs(}+9PV|;yWwn4t~HhB<2M;H?DmgcKrcS)B#6h;ub!B%BX6C4F z3|r34^ApRm6%WjzA3eD^2yCElIVu*nZTw2fbk3ux^|y{%G>ElUBj4Nd zyHVVO+rGhP#IqgCB(Cpp_mv!FTKJpRIYUgb^JBd5V(D8bKE>^;!P>4(#JQIXmHNC5 zvcM$s0a-8@ZiQI+P5=FnGrxi8c*i96+UfA&)h;eA`qL6zS@P;}RL@rMpsD%*z-h#UKO)$T!AzDm2 zyCN|wOctw39QhVH&^2_+@OUPK|A!!P_d{sZXt1;Q!?y7N^ame9t2X+?ti(XLX!l8o z+UgEMbOi3PDM$kGJ=C{%;?T&~T&Xlsw}IxqhDiC>AQygbLy|m5Wvh{}4Bx5M6N}7X z2|88-VhUc;RpLXcati@lQ2TwpMDaa-KEi&Yx)uB#w~AW3i2CARga{*118&1d5X(~+ zS7(4I^>Fx_Ro3O)RZw!^O;H18+!|oJYv><-;aAKuAEA=ER&__1{kUQ} zvX@<~b-AB2Q6WPK-o%G4-7bBPcHtef%vZWyx<0fEZxXJ5K{A7^pShmab{cuKMDeE9)xHIr66Dd&Zd>=pFZpoXr!L(MYaS9!1N~&dkYw`g( zCTDvG_uIh=U@BU96Wz0={M!{cukQ>-;~*#B2ax@owR+#vI74nPJDsCJ+_Y*qTKd4V zZ2%uq78Qukg&$-hj8S|kgqxpdU~)O}Z$l6yZJMitM77<>xm=B1#X3wV*u7~0qjb*4Bvhv+cT7QX$+ zLm-;K8r*o{PU_N)P?JB+NwJxcbs(UFgFvdlYmm>T*r9}PMQ<9ON1%K~5(qH_-UcsC z#da`>#qS@1(d_)O10IQdqRGz-esN@y{#ZBuK-JyB4}ml(!ebWaWmr0@PoMP=%YzW+{kOE4?M$= zB}LSP3hH`r>vj%M0I`XK9){y>tAkP$K_gmvRfR(p0K15(JBY(x81-KU8GRGY`wT|G zS#PdJ%d+98H65JJgP>O?B67HR5FDz02FGFX5TCZx6eG6=OQeBGnD_%LxH9KH=?pnC z#BRTQVy2RB)_RLj>NnuuZ%;RaV+FK)ClKDK=@1Ua!aY^C1e(l&Bl^=@zp(fIw0<F)q9!L*n~n&l2OAxwH+Mrn*O0fBPT08{PIB@+tmjz8H6K`D#{(`L{F13J z>C++?S3?yZxYo{K}|VLjwcCr-zw=lfytmMNOb&O&t9l zd}``L#)1vvX5L^mlPce8fvL}0GFWT_o#d|nPK`YJh`n?`p!k3mdp9IR9-zSFCEJ5f z3;88e-}7M8bUy+M(;>JFs8=x1ca7T!XN7!tWrArb1XfkYE+yhgz$3PeqewACSHT)m z9m>w?&}=2*2QE6p;>N*HiHLMM(DpiN^<8MhE6=vWPK2G2v&6X&wRU_ga-QYYLm;tt zz%eV~KKpN!uu^;8JJg?h;86b(d$i=kIVTnoG<%T?{WQYw&LXzyEG(Aip@U_;5?j?z zLXuUd^PV!bOB%-sDlcsXd~O7iO}MyXfM`Xv|BC!JoGXYEIOT8}QZwOeC#7TQ>NlOtvoU0TtL%EKIQ4B`G)DB(|n!kvU76XKXI)OE6*FvuU&43a84) zoN_)0KC3z!;Xu&{JjV@|Y+Q@2k6b$sgk)*a80ZX!Av7~k*X*783=3qoX_m` z<-ciFUxM!1@5zRFY3+1f0^Wl<9kQ@txzn3ad4C9P{a75*C*(XF0dND31-PLwaI2po zkMT#uvHM3pk*K31{M+rgorE78rN0IW^g2)r@`8X-_+m*@h{w_(Y8a9F7`5o--Y9zE zcDz;KnJT%P#;bTU@3zX1Q;k*0cTjq6#&N!Pe`XbY8+@j#qe=+gd)RUI?j6kV?jm@$ z%|80=w=Py;+gxN75x;e#I%?9O`%>*1-m47HZ|6tWkJcLwt0=CyCRmd%5t*6?(B<5} z2P90#NMhmbt)90E$4FKsIYyq-4^+{XY@$B%qO5{%t!I&Co&~->N6fO?`;ntv(K9n5i-ky1z~TKrw-D%|M9<%9{o^|MMdwq4!ei28N5>>HNrO{uRZO z{DxI{(~#4B6N1*~olCS5at&J45Xxy`!1;$=exp+J5g5A>MGkJE8PO#ksPji#6Rd*G za3NA9-#Yo4AERhv-CEDuSXI&Y2(N+pWKiq~>S^@%$k{dWYZU8n`(W@H&HuT1orn&m zyuc9`^cPRM1Ru``KI!{OSq5f}{hwJZpIIHIgP%ZB*x9v5OebooDB?o#4P;8%-_A z6etYqHuy}PUhb!z;?6mYpT%J0l@HE1^oV}^L|6si2A}EbsFFnMV3R!s@&AXtHxG=e zy!ZdlgiJCFA+qE|L`;xH(Wr<<5jU*6rfR*WO3@-N*HWX@T57FQtrco@YTdBz;*J_? ztx{{%A|hHfh^W*BWD^k~>?BOWBy)bB*ZVm$2{^Ig-tWD??;l@UpPX~%EYJFRKI{9V zB?na4fe2@Jevjf*ohC9R7fgC!BVIFytZ~8CNrgJr<*?9c_FDEW_Nha#48M8;YMhd} zUs;2fA5U>&cp6?Ka;hIWn1=PubmW6korXVTe$8Hcx$P}wF3dQ1^4K*PW-qq3^cr?l zSm-o+Em%9(_=Z(?-iu$~*1r{Ud{1~a^HW%Gntesqr>e>r@s9<4``OFqhNApZkO)?h zOd!(j!gGRj14bsVbWEi&Z19CrAMA15!`7R7ftM@zC*f;3q^&;=TAYZbs#CnXm*cSlF5LmjnwB2*-NM!I;b?H^(;7UDnR zP1RL?ZA*1cVX7hjjCd_RXd&ixe$5VK3(jrQ%8jTLL@-oF@}_O@tBqnU5vaoXr-Z-+ zULJ|&WZ-np?f7Oyu=~2i0JOz!i12Tkg)>gzAXn3Z`%t_N*T7c{{u6fj8T32PWAv|p&0Gghrdax( z#J>MoYB};$DUZ=T_uK;$lC~)n>9J^kKZKD0!z5@Sc1&0L z0luvR`)+_>30!S6-rHN4l^X7?AcnwkDdye*54ixrt*fp|WTHd}QBR>S$djx4B;3-D z0$gMgeD-StK7buK!zf`Zio&hHrU`P|y`vd*eb9_rUX|H;#k+7==TVQ(!}*v3aJYz& zioBwe?uxkjs1`m{DGloUC2hO)k-Z1w`>rY($#%jv#90dORg= z#H*n`2?kV=JYQJCaY2q!f9cR{ysXcD$}=~L7yb#FzDtP?{ZAOqQk0}G)6c(W#&8t; zj1l42U=^|ePXxCU$gqONa1rhUHvvw0B0iWL1%ErEDZ1Tc!M(HHWC6oQkf_OtYyaP5 z`QMu?XbG!tl<5p94D{C6gcZ4OhR!|f-)ca7*q21-BoXDGv0cs5*z3_1zyhus*n z)1gNfV4wXDR1p^-JO2sY4!?TO;-JYB-qko#|CuP5T@dq6g_b?|St(eOfp>s{A9>4; zJ?j8PykVC;W>qA`q80Z9-Z5y5Ud7;iK7`i__~NNEDPALi;c+2y&}L;$+$;fmv#@MX z(``Y0+7#}p z6OAK07G#{`sQf@SsNGSxEJl^_IV=6;8}_yezRQZ(pX!Jbc z#R=d!Id_4|Pu)Ck7cRABnMsRV@a1ZKd91^p@$wZ|ismQ6>PulU!3W<(dUiq0+=3>U zN~wBLRW+>iCS@_AAsY$N4V(8dKsS2|!3j0FIwDwdXc!F;Nb};Ho8$>8%ej(DvR=F{ zpA^|D7*lDzap=aU0`JY@Gcg%}ozlWy+Msln0c26LU)ptMoyQaZNnPp%6hZ-EDb|c zL&D(1!(nm*#@Y*qF%RGsH@KLG0t_8Zl|+62zZv=eX5{}JGcrq+pZMRU%CPM(*>4eF zC~?P;m2G9;sW_()x3~r8Z;3ivBx!EB;vH9pa>W*Q(I77_JU*+>%T#S;--lqFh!5BZ z#FW58o&PbI2%9IDCnCcWP1rp!c2n2|W&g^P}fR1dAa-SnOCPMvncAHX}Bi0q}q_Fx?m`C5R$t2^C` zSyt9dF;!gCC+aG$=_9jYSXscuGNl57)G)FGS!4A)5=9ZVGAgd=qv|+d+#)1tn?5mB zT+=6$%BO(4BI?0$UEQPHpg0x*a>EcOMV=YD$X41(X5pAmRNh|IGF z3~tGxYNNw7o%1mvg&1TAysssVPCI2OMUto(0Zd`;9fz{xklZfyF_@51*a zCzCg0xRjjvxR2>On{hdy0l_AESew))VYgcYf?(k}L!x00PI(H@0D!W>Bpr==pg0`@ zde(xHtD{PgMJ()M=iIO1c36|m3R=+-WTJ&fnn9CqL2=VuKRKobC@?e{lFQ`Hr@00M zP54YC3Fc^4^j#jr_U+66qQGsgj@pR^tZ>uHdEB-Ls$wDWoHnhZVFQ%Ixe*H}`Yvn0 zst}}s1~9EEqpksNr_y|tr@srGRnUdxULC!BuFHl(12nB-VIr{Ma+Re44&u5=5Sq9E z={+$*9lX1+7Ctv(lutslH%*kq-RhrUx~{s-#H)IIvfi(HyWNpjI{q$h*)5DMt_O6# z?dT9RW!$1y>4&x>r=>W=CUo$=N%s6;t$vEA;%T46rG%aoczv(EB19x@5s^ z5*Y{`;i)Pu*PYj7w!3Ah5gG}Q+Qe>`LWEWHFxob+J2Lzigc&P_+o9%eMML6}#Gu*S z`WZQ@zYzJy2}=*^6;e%ZVjAfK%j6v;g$k*!!m0>?HB-riyXrz&Qpq`LRLni^nkrz{ z?!>@K9Vq-UsYEwv)lfk%s*HoUy9%6E8KDZs-yL)9kt)=MxF}OG?e_AC{Gl(rIIb27 z*>|*EaVh!zXD5V`>PpwcE^~}`@o#iz%vF%*so=z{4)(>&caXeyLsw%J>?;5}S3!rT z4oZy|1$D*gYBzy2s0Z~5LD+Uzrei)(2C|V$!R1~4=S)>XDA%^CDpd}upZr**0*GSn zdDm1`knwQ<;p!4~PIvstgy(F-z9Q3&>QK?0+s4IQd$QVS4TtsHs|57Vk^M}4plB_J zFG}4taE%%Fhf@>jWtoz}5_pGk*s`BFGV@=imAY+HYrU(YfmgPA8;~q)4q{1OE z$Z?OvDnPza8mjU z>{y|qy;Aj7bla~iPP8TUiEZ0|=`VBlA0k&+Azjed;PS3v5NQZUTAoXEso!tF(bF)W1aEY@@cDyDQMUGSq2 zh(rFxHs(49@GHdAW?m>GpVF^r>X1$;+jq%hQ2{#fH?GisF!pu+GM3lB7Qz!@OdKS+Wvu|?V_ z+!3f}X-TU}X^K;m@-8UGTJic0wkiy)&K^CGIZDoRBhu0A?zkVqndBxvdi7{-i(97e z2U*{fIZar^WID|pk*y%I`LE#+M+lW<$=X2P;xKVEh86YEZF|1mtZr8%9QaUnpkkTT z#iVD9bB4v`TCwG>Rc-4f+O~??X7yz`sKYkvw!S`^orxbaG5dv6)J;}5igR6DJ5V{| z;$1J{_I8mCWaO96@8_RM;EQ#2dI_=a9jts(3I?a)X(eBv^Y&PsdsK2_1qZ>EBSsap zn|W@Olpa^3^lu64`#A`!LkMWMBp%GMB*tWy#E0LyBqlk{m0J>5O1aj4;DT=@wdcX% zK1ar~)8MSzt>x`W?RMS13zX=^Q$Ea0->b6IcVei=QYJ|mPrIxfj~;Qq5T2-QlX9z+ zUPm&}NK2;_%XE9EXCK0@*tC+C?iSQz+uiQ9kD7^^Q zo-Wd}f^)@Cx?SfRi}ob)NqA+ixrFiCe5~u-z=)p)LDLnO!>C zKIVYyF)_#X@!>Yx2RH_8>o@Q8zHuM>#(m+wk$e7r%f1nK7e3<(d+3QB;VP3CCXLJCnMB)5I?d2*H}f)$NT^ji zF!NF+|7O~4&$X=1PP@z9mXMiT_h*kD+>Uc}dknuOGQWt2B)6U>?)E$+I4SL?-oz{= zzbZu0?&Q47&bVV+D!1?JuF*F3DdDnoZj+`tH_QA#*4OVj=$=ep|EZ%Te*Sh#{DN(J z{DCZ}$@WY9=Ij#Rxl>DgNBTKADf#99%(nYqU(v{E9rBx!r%Xu0)6KIzKAGB-LfhHKGUr_$Quv+T!o;v!kQuez?{6Iytts`CCz^+SV zaqKWlM!??@qMg+%2-Cl}Yhd`PKXf?cKmEp#w>7Q`f1dnDKk>6opXWwhu?>M7f}MH{ zgO;wPN$;$j^x%eX!Sm`OFUPWBUE zUdKJErnI}it=PVm)|MK=svkaWX*9I9&`n-GK+sZ_=8rhjZP4zTcI|w5Gqaw$NQHLb zf#G|+4=#JWtyLdpT7|Lezul^K_n#Xmz5BMUnwhIri`!cD-nX{u!ECFBw`&z6XIy0D zA1{yb2NHTyFepghk5MT*x`|Bt!jyzD*8t7<%-laLn&bY?^vA>4e5W+N5zcovg=v8E z5)$9Uk<)zWnp@#`d1}>bAp;AmNw0c5+|jJQ9L;>`OgQ~o_yp#*HDS(wvk6PTy$Sp0 zXu`qSCRFBZLc4_)1^|V1d${9Twhg99(R987quq zPp=T#FHRTuU?f~xQ4*``-0J-xR-K7G&X2ZTwMGvh)NQM>eF|e&Mo{H&m;O**WU@gD zw&FoHAr} z62Z?r2*`fs>JRbA1pGr2K~uuhLQtv~jLUB1!fW=Wt0(-!-a(FscF%MJcgrmTUCwl^k1nYFELfmj*bE@gLiQwvuY0n0NzZ4hSN zqL!YO?T?yv{jrUTTpIOur*qx()J$<2`Y_>kkMlK2z9>xG;HIYo6;!6!)+;}bwY^3i zRLiH%ri1Qm*FkM|vXayk|E%~nr=1qrQ~AmKf==r$Qu(R;Z-KMlP7qJp-36Ujgyk2u z4c|{7XyfjfkX6GTak+$&&$E)@w~I?pqJnyo@%#%xpl2oD?~G)aOVBu#C@sD23H)@P z5T5uqElZuSJDUNR@U>^c#AJIFDuRon#d;ys>t!iq<}`+KWwuR+ zigAp?+?Qj@gD1<`P{V98Z3kYB1uI zoKl}H+Yzd7{8ZNg+Gj_wb3x>~Q9X7nLunA~H*G`HHfh8Doj%chqtix?vS}MC{L%4m z9u(Kr`Xl1WhGc_(Xgrm#N?fDFhyVLk302~OHv+H7OGi$$rLi~uIRAn=j6kTR$6KwZol``J=u5Oq9aQg=U2#{h4q~ zXXD5D7>>1XjlYND?kH6&@z0Kbdk(glE@*e+x|S(m`1O}+t!;*MX9f4nWDedHPDD74 z@+Sl15jHW$gi6hCsq}4~fJ3=M;E}G@xgqx&I(SuO?pJk~E_KJ6a-Z=5Kj>^PCQ?&! zgJlN6QGKQ)D+!{z#HxG0osgrT&mBNN+qFa@Wn1;gm6s->IU5s1Y-kGqPYjJ~$=NoC zXWDd2j~%v$HR}S%_pb>mebuI4B3Tm6Mbo;t%HX+8J*J0=9_ zcg7x_6Y97;S-k_*sm{G2)K>UoaGvkq+5jzYn0+5i(rrIBo)r#wE5cY;tha#LdtG^5 z0F+KQ7^5f>F*tC6wv}nJE0koEQ-3a z@t%9_hQ;}PTJ#Pj6OdgCI2@(D+=>EY3u#H*5she+hb?yghS~Qc$PLKvlPs}rtZ`%4 z`FW9hcg@+6;dE%KwqIVyL?#5!4`C4%NZPqi2Hrl15WC|^r$k_7^w!R-jv)}|CVaH# zwKlNm*AtGFf@NC+x3&a;y>+mdt3b=#jJbUQ-k?im&He<~r_MGU(NsRTh~>poU$fP& zTo^EI`w=m_3y5qxL-Yp&GU*Lfp1jjhO955n4I*k}=1DJ?1?g+<`h&f-7o)>Jub9ZD zVg=v!5(=e$+6be?Pr+JHy;N+3*;BC=!JBJ#%OrQr9vg{Y%;_AD!mT@)i=A~aeZLeA z>mZ~9@357Z#stt5;wSzP)@)l~#o!UVdvC_w+7-BW>ze&qCZwu_%g*QJ(Z6e8_PUVh z;ynRG5RNv3s6pl9nlnF*&wBGhTRebS?Su)Z9ETfXkG(!4Mxke$VM1qQ;5kG5@7Qvl zk8bQZQa0Dy~87O*X1ejV1SXL#SAZB)<2UgBZz*JnOH~tkluy4o_k& z{{#ne6UFjbSxjJc7k07#SyOJGD{!FY zyfg47voI!Hd=1=7OvW;-V+Hc1BvL~eHUce=6KojMZx0*d9~W=eah@`Ge0NBrb(Ih0 z6M-Z~&GQw0wzD9{ccu>%J>>%&uo|^V9AChuK2vUSi9)@ugvxiJ6AD*ea*IPe^t#Hv ziEh(QO^EK#AgpITmN0LOY*=r7j_W(6&33H%OGvmRin5-Z$}XHn-hxWVfmFs(LgPRQ zQRs5me}-u!qufN=Fjs{xaJQ-)^@@cQ>em94PGif8A(IKvB*y%XL3VI&@J_{zWG8}X zMlh9+6RP+32$XBOYMJlI znX|39dgEeHKv=mPWBy&ezniW1^lZIRe|8Z01^BJr4{aTKKP1BLF2P%K7(7Di z!yjUYdqjDS$DyoxgkA0t;!Gc5N7d0dLKUQ7=2v^!v+f6u61?&)-m^q6iv^KAv6P(H zfA$V3atC!@ksAc(E;&q^+{ku1hB9fV5*eF<6kj7oCt?}U_8-vQClV?3H!LMj9QR0h z5PU&w|86%P(gEarN1}8`sZyqNpzPrjDhk@w!xeUFjd}nJ?GG{kyDH6wZ*lcH7(3)g zpfBvh9C-&a{|=6DAHg@Mc<1^3>>KCfsgZZZ+x}RSohy^mJCN!B54LG|*e1v3h7GG} zYgj@lr>)!{r@-ax$h(!jY~0`M2g4vw*`h#0b5XZ)%9NqeQ%ssvtE?Jl=Ez5d!}%#)V)~+stei(v8-*u@ zS@dtc#z#X_q%svNqEb=6It`R-ein2grSyET2X7E*=jci^x@O5u%~aaqRLK|g9f-@? z>k6Wd83{ImZR?VyjlYYy(|2FDyQTp-@Dk7oDs-B?=AFQZjN)ii_B3k>?v zR5-HTWGs@H`#Fw*uRlyQb{;zTJgjM5)B+gEE;g*O)cjO~-*M1uHb_=MuVLY5e&7^N zw~!E11$2QbAk2HO0P_{7%3cq!cGshT@5X&==De2xwIw;hKOye^nrH>az}|p7kTgDc z7j|96zt}FqYoFT;m^$MM781@y8zsIm(|X=G+;;r2sL_vEc}d|nwNaPCz)zj=i)i-I z*WL4W`nJ)BKhOAuy>%9{*n8M*4gfImh=l`b+#y0yVLROq&BVcMjfE11WYch44{RCd z*6X9##7`h-T7^!t*MgT|mZv@bB~JYf0746WngDKX%2G9W5sWj^-z(JKBUPg9rI~K) zba$mH6Vimy7dxy5OO-es7;m^VRbubL0CLa0)`#!V^Mx!+g6h5f}d3 zc{rCvWa|)RbM`6cbAY55%>CF|j+|`hg8I>WHw$S6vMLjxb5PI=mLNV8F5PwwycQRf z-2$YHJS`kzot&rP-NekhXGQ#+!^3CBRcu8HP0?84@u$$iY`vi(CUzwVvzGI-f~VT9 zr4&alm~3RH6xo4O?7XSTZyH9#on~1_C4CJ@Rp_2j4M64# z_(qGoupx0Rt;UMB!eXieS{0A%vdR+QudpwdKvr2e_^_}u*E01KR=g47vU0+!(EFcE zT*t{Jzej1uwonWqT7~mQuQR)Z{{PO>2fO2GHUL#Xs=o+MgKI75XW;X#R%kJJyI8?I z)G>TJg!z;$5?xY&V*&;{2b?J@Azc!B(@XB4ZDM5Icaf63*3Fr>2ycKc_wspR3JRAG z+@SoZ^4U3+dPHvgGBzp_rR`b@@hpn>M~Yu>{r#H0eD`6zUsjU+t!LFQQ!)4B|rvM#rx6C~i>u?Ygza9$3G2#zH{$Z>3f#0I$w z@nJIgZ5y&I5$|^oVjYFn&&;$X&SbCp4E?jzP*Ic4RnaD?pcViI2~P6AiJ1?bSAvhaU2dH9 zO-eX<-l!hnP|ldPAvGbVLEL87$mIJ$yp(_yylrJ@X;i2liEFp+ zyOU9cY3oBptB{cRL6MgF!HdE-d!u>JspIdl?|=Ww`8oBgx#k44U>W+C?;~NI-0vCO zZE#(TqLqlPy*=U15glSl+en56f#8KUIVG`GW}K_9tGU{sZBf8(DXBkL?kS~9Xc1nY zu-fEU(t<)EZ|ZBdOwrODo8gD?dzv1D++T?zQDVGep-2g8MJ&j9NcKULU5o9 zicX4Qh`nAe@lklMe610DqT3}5Ex64PZ()smP*2bdNhT6b^UG+d)rHm$|M|U}bGkz=d6qIiReXXp% z>)GDAUsqrgvDY*CUNx+L^dY}Rrtf=$qA*25aSn=WiJjp(~2rT zF8}chukW=j!TR?O2~3s8FumJ*dfGf@J4z$@G%7l-Va3>3F8H%taB5}WLU`>}?;iI^ zYDy5?bI-k`7rW>pkpB;Qc}#9Yh%Njp@^|r*?tx_HfncxH%G?eJ9XebDk+TQPLq8Lo zguAnMI2_^AGbaJnV;jGN*%9n=46@i=NOrCiM6%NM8;GPkpSaU=Xb-%kp z`i~a4WcQ9NoRxD#b9ku=x^9q9I~vm__OosZb1zzZTdb+1snTyLsm;BNlk;;g+2Z;d z|KxZoUu30|ORS>v4pXlrEB&f?cKVVCo?Xw_^DWIL%Pg11XAWIE_KpcrHz$-M*`cnn zpN6`x^yjCqA>EGh0J$JsbiL_|ek7;sSg3beVj@W7toY%%GmYn}cX^PW(%L|N8)Km| z+!ZDwZ6ICX99pE>M+8;WZa$}yf%9LzIELcIXxB-?C6_2b-X`b&=qc531e~kjONJ|f z#I}a5yBaQY@yzQ*s>C9rMfz5@%vMDGRCaW!O|$Q}suUslyu0z~s8dXu z@PD*xjpw2G%QJ!+OEu&l8Bb0xJrZ;8ytTInk=H(n``;zM1H$yoAzS?O!k?VlPf6P3 zuS$@R6I7GEE{i3|Px<1$#fb_+shbxLbcWnu3sep$8pg?5UWs<0^7ITOjf09dV9`~}5}}uc5Ebp*n!XFVHj3aYgvwpU{jBZ& zsIwoxLiTR1VKXnr~5k=H_H?f#O;b9TVi(g0Kj5SW=B0)h$WerW!K4_ z?E3pi0(K$7Hl1q4%^C?ClMBy|lGeD|KP8@;(o*f88c$A1&i2obSCqQ{Yz95a3Q9b_ z+;?FP&h#&RZwpd;Gtg*})0WulZlwu6j zHMF|xJ@;_>u5k_f?qqMAi(&g_3{5Yg1DGnCREtu>(fkx#P%9E+Dt<&l5KxH_2ukkI z61QX0nmG6n8Bs1-1@a6e~`e@Ni78@&5PXwIngon8q)bR!fA z)hQ9yXSq_GevZjEr1rW^4=AWvlw~D*@28B{0)hi(Uwm!UfjLVV;Hr~E#8VYjS%-LF zKZL>2_{-$?e={N7eInH0%lSJ`W=rAA9)|n-V6+H(qNM4g^m`H9Ih^~tAWoICPhl`23#+G-{;P7U<%LJ;#92o2_=N$ic*@NzK3-{g`FlcB^QD}E3Iu{bmxBLv7kxH zW2L8jCKjp{n^4bgM9cIuXm$;p&6p!D!`>UTVtQ>w58f&u5>z#qnnV3$J4`DDZ#lTD z_nps1sI&wQKENQA79VOGdUheoki;62dCXDVF#IeLWWv!7$QZYU87qWmM8;Nl=e*{H z*1O#vUmisM1`t>U)kPALBstP1SOx9!Zp>u;2wyl2)GVjaUB5>%p)MhClqO&QxGg`nUGT%h8b!M3}$FL z>AA=1#C`TZo!2F&MDLg?{`sy@hz%n9z&RRUyN}(|7FxCUwmL>Lwa>)H9FWMg zD)T`0LY9GPV`yx${}V&iih{w>Fg#D%fvu3|e8hs(1J5HCe3VyIAnj?W{2_@ea{^TV z>4(I=O=DvFV5%gMs!k;8a?8re4yCD*+|pD{VXCs$ud(L}vE;d<+8W=s?NkThFdeE7 zs*{y9I~en0ME#i<>eG)P0}GKw2C-!KNgTt}?sM_A38l`k^3QTd+K(){-qG4sSPaav;~>a>-$-$O}z>l7bsIj1aD?By#j-A zI#KN2L1d@HE==UsVkc6>$ux*+zLHneQP{;Ch0`?12YZRQk&!FMC!)o*#v|3XOsVNW zeceHzR8vXm4n;|&<~L2T>OZS6ZTA0Q#mH-{4y&;Mtrk1RKf4%HY25@fyBcP*FXpwr zFMW?|`%&z}wMp)pJzU^^u*W7^JO6@6w)=Gj_%OeT#_Pc=-e%bzI*nAChq8}Ds-B?=IukGg#$S{FngNgTK3tpiWD(M)y%jmrv2ma zmA4%8N7Qh)9CK%CK0SBYt2Hsoi@E92z#9$US>5LjW3VSQ4YEr83obxxu?n4LuQ@(* zZ;tkMr@Lmatq2RQWuGm31025~c=Gf$sb~29SxH`qD}0^fa1|MW$NxAs>Awc#*)4cK^RVP!t>t!aTb3`J*e zROtQau-(bv?p5@Ch!Q7)W*FYVaF}v>EXN13H;V0U>|?&L#Zm8<;#yc-pPb@f5Koqr zUJy?;q^kW3(d=FrFRrsq;6LN_rS89$N*l(DY%Z3DMQXkg>-HDOqz&8KG<}41)Yt5b z<*?FmLMrxWha6n|eXFwcoLG9hqIEAO_72;tSBzsz-n8{G=TyK>AC+GR$wxwh_2Uc| zfJxbHy-Yo&t#C(NBlVyQa~*&h$03{SL+*6%sc}COSB8}BqFf<%Zo6%qonaebk(_B6 z_)nlJPDl;#p`!Hf2 zpd6Pa6D_)eh(nEC(aE-1zccP~9#uLXS$P%mkiKO!0{MZVLX~)ppn*K_Ylur+i=4R; zua5;VQp=(KbCsb3)ArY}4h&7^=qF+FjQxrD9gLE$AMWBsBwOjKp+PaA>_){B&+oc9 zma)h8xIi{G9D{{7?9?edE)K=Hy`aWZsum5NyT&G4WHojUy#oM6hznqBALE1V&o#$A zlA0a_@5u4K$D;kvmo-Xsl6C_cE2IKaM93N!Y(VfMY%AD^ReuAD3l_jPIspUa*Tz=T z39+^~y7~T(SO!00Cc_Ox#x#HKhn^8B4VtjaIBJn&2Wpp~tgXh`otRG<=>(0(jl#N%8&aH&7?NSIwZ+32>!^&w}*#MB$yeJ}N zTFJH%Mc3hl-4}o1x#(W-HVRrXPC3`%me$RoZ<8{AD3C#Ywi&0#7nFz!PlT@lCTm5f zE>Dc14oJMyp)!-EyF7spO$Chp)&=}hR*0Nl}7|0l2=Ig*c(c=U%y)0 zAQ5@*%PX?|Z&Z&^WcKpjele7|@^HfNa6ZmMRZDU#7ph)_rF9q~=+%nV;#wE^$}rz# zJ_txxn8)HGX^PWaNO^LSlDs4I7GTHw`}6xj`KJ4}x!V7T2c0Tj%>?LFwUOUMvO0>* z-LI>wDy(WLsVn55n3(TWC3dQ@cl?|ceTm(ewA)kF^@*s_&j~z`oDx1&XziZ4XlRXW zN3Y>YGit;r<93cxl)WTNcDncWTh9IkV2a_GD}voveqd$E4bx{PLl%4glyPY?7K3> z1a%OTQtP501;P7l402Og$a3DBEMMLM%T8piown45v>0_~6WnwUIYQy=&{Mb#ml*4} zoWbeEw!aqLXn#fZ47&U|Y&+Z;C4!+BweAXR%T6@%KvwBY#JE%Fl8@QT&LV5A{CU$j zAQVa$1p$vaVNq`IBS4rQ%D$rFP}_v8nq@*z+7&-nh1~Rp4%MTj+gW&Luo9)P1u>3F zFwodWib~?w7;pY2r--+pYDI{P>&PCqFQhz=M6`#q=XSvZ>U@}GL7g2t+vwZ(xuq*k z@PHRNf=Umpv8i3$0K#^3>v={<4nu)B08p%774f+WfgwfRN z`;g*kysrck1}Mw}^p>$-Smfpd>8aLK#RK1#!ZTlw`n*q`@t2M*9$Bt5z}jE~G0{A{|OLOYUQ+RgjwTi$uoh{1Z653L1A1j%}4t?L!E^+?NG>cx;$Wh{>sy za%))`N@4%HaX5l-Kb8skt-PJE@GTJ-*Wyzsm*b_j0Tc2{+)GzsCR;~@%4!z!dWbrX zhC$QX+fZXYT!-zMEH*o9P9rN9p)5~gm>hWF*+K9X`o(V0(ys-E^x5$5S`*%9A$@?< z{64L#J@CM?Fb~bv=XSTPe*iv3N|VQny@7}?TS=g|FT2TBmg~N-Bun^p5VKA@jN*ve zj=m=8=OV?$G21_6&bcEt$o|0KEnrd%KmnsXbwLV3IxYD=(im<~+QdH~am7;U9QgOy zQ>}LAr;OZSrqdFvrw77UoXFbU1sSLeerM0V4-w?d0(W3D`B`^Ud50>Vu@nQOW^)`Z z=$G)(y;(v63+e*ZXkbknM{}*Xw^$GUir zTVOvw1~C~eaC&J$AIF~m3ZX-1KG(m%#btU0Y%-!fU5Qf`lUW2$UkqDQ#1!rZX(?t; zS3F}+roKCZzQ~B=3m^>A))%)R?>}xi2N(NmlXIh*co~#|&YWnpZS6I0T+JdPi zSPLgE7pZmf4dc!YShZp>|C_0RayV@!<9A$OM~HykSW783iz1d*3a(2>tvH+YTwZN; z-uc4O#t}CJ-iqQgeFgVhy;ov3Lk3`}*`2gYh2#Q_QO}3#%HVl|pbo)eKJ8PX)9f{` z0(x;+@_i=ck*uWMQeR_$IvVljqK!}c-?+JQ?d|36&FlCOU&~Y@Qxs=@P&EW(P>F!2 z=PTF(D|uaI=AFTO2=Rv{6Y+st%JJg-KG(|g?k=lWx!@h;&a@E@-Kk43r>@I<+=_QO zJ-AFDLt&L~%eMI^ZHB>M&>cTFHgcTp{|gb$_df0s|HpPxW{W2>qJENpv7P*b*uwkf zF7Rux0e`(>th@;14HT!}8(}T`D+M}$V z>4%mFkq;IQD9pa_AP2MsKV23?jy~ctp|1@a)#HK}Od^1HwBmvb+KykiKtHQ^;RXFM zLV3}&4XJ8BIl(Bp-kv94Nw`Eg6E>c<>){;3Ut(Vn&X;oc8|54X091C zz2MCJd<`{{yQ08ZY3px3HOzS{_wXb(%sttr-oYhtAVT;I$l)ot!0yI-`$L)cfp&Fa zyN!~~_cO@b0G9lFFxMq4^tUg*hVArGM6de8F0>UeYn~B?!Ni>&g#zPK0tpXRDn3*pg)1+yul$B@AKLF3-#Nkt|HOmA z7nB142?L0c`b@d$SU|C>zA)N%0n7g~G&X}^Mio6Q3@|62!8o}iyslgxRYYcOk3~w6 z3DaGK$@z9n&P&c{HUR+2CHvzR+(4aig)Bb6JUWS`Rp54tR`V7x69nHR9W=LP4*qu8uQykrxqk~5?fXkRprzu1RSqJBRJL(^V0Wa=aTuS3GOz9&yo~MO> zjrl3bzBm}^b~!|IKiovtp)o$-h6-5gtEj_ZLDURmI})S`ed$%gPIblZc(|--*O$1| zslgjW74(D)ctx&TD7pHvFaHH|Y_|uVuR?`|QS!O|R;#xG8k#ZYVEe*}(w)H|vd;$_ zNA(OnX9Za=)VTwhF>BFZ!Wah2;Jybdwe^MPgbqau*~UJgt$)VIumpiGivFMx@EUL( zf=2ja+!BLEz7b&pEAp}}2Ggk-#Ir^QKfhlPIbpy&tK!Zk@_4@=Z8YNZwYD5~$BkzB zC02}KTapLG7zSo6vf3}uFT5{zp!uyKCkDG8%%{y2Y+9gpdAp;~1RTX14BdO@vPT1N z4#MR|H1<6ZDK?_E*U`W5CtGY14@;{aRq3wB{88$}v)B}Vgs6SAv%T&Sc*iUEwR5dd;g$_#R|*ngQ1qNBCX<6H+WTyjXbah*aJntbgE(c*D_Q>;|IDaQMZg4A(HY zo;MLtK3_2w2HzT!obRV>qaD+{Fxg<#bC%+pl5?&5c8Ad)%VgMe!#=4Z>z=_pdLK;w zqI>Q|6S)h#gOWn`f^l0aD~=bj#?~p75OeCIC5I*K*#Yca4_)7jUHx3He>r3e@+uAL z24Bz<%H9JubASoKu^_#O?|(0LfS)U->?it*fQF);J8PuBO*0M z!Xt-}s@Xeqyor7d_}LwVwD%Qi!alI;a#&JOu4uSY2BQh~@^CF{UO3R+-U9|^hG+`J z{F2L`i=q^ShBJFhmEVpK>)z5~;zs2SU|Y}%Ivu9DH#W>*2|9{$X2_dNtle1Ua$H*j zH6Tl}OV=i_2YEC){ou{tvo{_Mn=%=o3s;{r^TU*|0*Y}+-Z5zkrB!AvZvd-yA9Q*} z>^=LUY3`3&co4aDdn3;Hh^&Ga>Vop9<|7<^x(MV_shZKSD{;N&5zLtFNUS4@VmMOiY*-P>#Jvf}sdPPQ;m7Ci z;?rrb&nsZ|UI4X>A+7l8ql^w6NN+V{~GT<8odf*x|U=UJLy@4IN*79G5O z?X%a)GM+r^Omwy$sdQ>ddI=&6FAzERttYL=H$Pyk?dCgwZEZr~(){i$#Hf{eRIV`W zzXb;!X*XHJje+?!w_g_?$-5KlxHU=U|DNoqLc1+SSq;A*M(PAj_3XNk@ zqI3JysX>^toy|>#A@>*ysw>(@y-JCQj~@kTv$Isjir5bG)^sQ zQj&Og^gM!o-%y&(7rqwvQQ4r8@5=|hacEzh5R`bZ0q9q#;+owwkh@RD0=vGHtUD zmZN0ox^RGv=BA6Vcr}poFQ1Xz0s-&JUb;mZ5{^=m=YeYTx+@^4I}(RfxZPlTrEl#@ z=xkSrJkJAtr-f*Hwsv`UI?^KC75v=g+apHjYG??>z-sYoL3! zK(DsIcy57)@p#ZcJg(xsHz^DuQnTKgaUc3)mxDn`0b=amo7tfY=-o{Upo4I3k{y`+ zZR5yaC4>TJ9droGwhUF=PZ+wN#f|)*p)@jV1Q(6J8?LB_f@fK_vJG`Z0ZId{2%G8^ zqjZQOkn~6#0}CgBfFh~v5uH@QBzsSswWy;4WhfUe1-s*BVxzH2cwKoWN*%9`gJQRIJ){QZuS!LkR3@?V#Vz%{)SrZM2mtB!IH!4zsZCAP;s^UJ@ z4Y{)r^HBGvwuafkWk!rH92DxuuzqC++UXPQ6Qg4$w*ZLrgKMxwoTDcR`V3qMTUQBRA1U-=O+sfye2(J&f>Ha!P zEP_6VOUBG6oUGK*ljHsZzXLpJ4J-B(tRe#7>#@)VZAk+6qH!kCJJe?dV&IWX@wTJCF;NQM{;P=^Xh(bCA@nLH5{{f7%b|?YaCr_8lYS6m zAe;fo`~QR>_YqtpWV27V2;W9z=f zR{!^e4uM)`9>V$(78((+!AyqN9U*d`Jo7ikv>nEbNFMf|fwvbS+0Bf=A%rZ{BlawY zT7HHZcqu7AK1a_u8wH&DcLN+=SG=z_Km&EO4u*dK%I7cWM`h*xf@Ps2Y27|!2@GWF zEFOQi4M~3nd>K2`0JNOzS*$0^V}0c%%;J}4P6{Ho2*`OaWKbkzuLPd|Ux(Uj04)427$f!}?cgA# zcO!}06|_+M?M$yfzNlwwQUCX?8`s zzW_dX@1m1J2(be|_wX*pG;r~%U*c8VU19i_!n+>v@|Z%CDv?26fDZoY1nY}A%-Dx< z$qp8iRytUshz}UtFUA~nm%Z&EYj)&UC`W<=;M)!ub5PX5gLu8M^vVCcL_YsM1m7D= z?G9oER-*wpjrgL9n@_b@EkwCr)F{_27ISbCjM<9^9ficR@hMPxje*<^UXJL6&{(!R zZr;Kt751R#*E)Aej-hpAG673okLMGW#u(|Ms^pLktol#(OYvtSp z$!crU_Z4h@DWs(p-QUyC^~W{yc8qaH4_ah*T#DjEm{(83z2AYDbvyiR>r<(yQ}m~6 z?);6_=76bNx#>o}J?>Z*BjT zMB%nC*X2XQB7C)b9GQ3Vsw;&~)=P#1IEFPi(X5?yiwXZX&0AqFdkl&5uZWm0(*2Lc z4zQMdcg`Fe?Z?pe{FVLnB-Z@dRsS?eRv0=Poek@AGJMO)Q0=opug_2D|&{%WlRa-ljZeNxp(sBl>D7LSBJKMq$`ZXr+-{O$-a}%ii%xd z5=!4C$l*y7XTAJqx|$#b;n@Y4&pLz#(2s+<_>tH~#MCZ*Mqn~`I#L@ldLTo#qGa0& zyy0gfcLV`CH#+mcR>($$!HN* z0*GN32b^%pO^MJ)Tug2k1gXOK5omgN$2re*^+O2XZb*+a1_-YfACQ4;j`=u<4xC(07aVJo!FVQu9yc&^569nR8KfT6Sm%GHL{Lft z>{2Pk9{o7saQ(bOiHB%JW8hCKYeYvl0Oexe`U~Y@%e)nYzhb0oMB;8F@N@HoSB?H` zk&{w?a9e|N`SIrjR!&af|2Ef$_KnikD`4G!8uIVPv6e};;-09}KBWUOCx8!oOJBV> zHNpMQPDb}Da7+0TTOvopdU&y6{-yD@i`Sw?A93Y;e|)=(y_0i;^viEg_kYrMF?h)Y zvh*1(&CTEQe-WqsQ*6crD>08AMsLlTeZT+9xJZ;utsdw5SH%hFvkl-o%d7pX?U%0+Fh67(XjMU7yml{+IFqKn+6_d4g7WXVpU5IKRKZ) zHNkeB-GQ84`|=q7I=eTGTWK$A?Qh!k)J;Y%(qpZz*V`TA5a$D{(WH3jkHnZxZudPV zY5J3MhWNj=XKQahEeQTTbXWg|c6S_Pf`0nV)Yty++Fk65;RcB58||@YVT5Ae`JI20 zoxF^qx9ORfpRl1Pi$!|zys!M9?Ni z@84o~91R_AK5dDgNS4%BMYFwo8D{zCnh1p*=;64Ne3pV1UBY5`UhLxB2x5Z6{`0A98{M)Tk&*%3^ z7WsFytEOx$zdq?@e~Jy{3P{?@x1RFvv|k=U(%SjOJrV>Q=&k3*k_u(SE%(k}3p)dW1e?JkP z6?yp&*e$;!!gPY>)30rp79H#0Bz3( z?G}A_5g;C0_Wt(EKJ!elVA+Yb>=PqH=cpMF#qU5ymy*mmc$lTK)np2G#qWo!Q}_of z5NE;G@O!wgWcJJ`C$H|#TSvZddrh)(=i z$3W5@0_oO`wZ?bCQ-ceLZxdV1uC^6L`sVlX1%h9BL0Qc0Jt#uA+B;#U*yzvGUb`k8y=crBVlzvpWacIS)ZqzHg z2v)!3z9(>RQ6kFmcVi4yY=#USf==H+zY2RcJ#$hb<8UwJ#Rehpl2^k!hPAuDXUxV> zHu7s=(`8~mU3fS=@6h?gUm1_BH^IayL<8tTZzoh(aqQ^9B{!kZk$ythPk5bC)pj*4 zbM81{O;NkJnljP8t)_TXTUTFziEZjkqt|#g?1^#uhz~c~N00w(XXHZ~EUj!g3at%% zdRHI-G!O!$5hh}@0P>p@^t}eDu?6k&>M-|;P2u~Vh-H_{{LF4v5kyLCt+9*YSZ=$T z5t0KdOWDf2B-76y{#|WLPr{qOYs*-xjlIafHXd?x|EQnLKIZMrY8Z0v9 zQteN*$F#lm-DZ2U$Gl;CBpduk;Z6Z+oB%#UkYwI(=CaR*T>B;GxYG83w2|>b%`U+qRb|~z-qxj+aM6x;&t*h~?QYCc- z6*gn3VY0G-R`|&&g!dFA8?@LXm(QG3g&X8B-Ys(WJ@pgVY$L@4DID9jnO=OCw1C9FRAP zVpQ61m!VUeGR{>B(^4#w+`L@=Q8LtWcdRyuoH=bnG|UZBj+E6G&zJt#MF47v2`kNE zxS-w<9n{@uk76y=EhYZ6xZBYqKivGHZ@cC65kY$4v%p%!08&sYpRP*2fr_K+hno_y zCSsYp%Ge^CWGh;(7!qGg47chpjc1Asyl`|hbZ77JjM1u%s5yGU{jIOa14X{T9l2jz z78{{JZy;G}WUNv7^zB6_8-1xV%948QYX7i!ac$|7@vH0or|jJ5T}veqp1a?3Z($gI zDG2JV*ww&lCiiv%Kg|~sXwxQAchJ6(}vbxt&Z zoQQBPm*ms&n*7xCrfSkb66j!Ly4Hq$*0c>(nS-P*1u~vB1NPy0U9Pf~Ib02SfX!3i<#;<#jkTn)rhj5}O{S-HTOiaA;>L`>&+U>am94VaHrM|) zmdlTiPv%0-sI!`14%Tq{5w6eQfmuF_G_svX9DD)^V3%;l{8BUK)_*@^eySOB!~ek< zvkOyY*BzQMCQTw<+;6ONqOK$4l)Bv8M54;J(cC*y?m1OoYWq=2p{Fn4w>%D)GjCTi z>UpIvoo=l|Q>|beXB^*?V7fUdqj!a@eTvlhnP4_ifXY9n5yycoWDMVQ!`_LEslN%@ zB-i&=TyVQ#nB71S^LJYtjdBrGKj1i%5W5j`(hapd&JA81{XKPX^ZQxX z?Tj;=5}B2skqrG~%8?YKRJjOxsz6}*z6ma_3mRbgBRi;k`bL;>5qb0C>nlVv87L(E zZ@~ei%2%U2 zAyG`QL0(IkW4FpY!EW3-6m_u!@DkiTB7Ya5mSW4rRvDyOwR^DCYQZEO!Le5@|@7m4XsqsM(j)n2#iTYP9C%_T?an9FygxDnkEJjG)R{Scxubk*PKZU;7TZrj7}?wU{hAfH8=+6qwr|N z!6y%o=`9)5NS7|nlly}b87Q!w$cW%8m`Q>MgEuiC<*5PEE1`VaDpG+{tFZ4PQdr^8 zBy4iI2IJG=iW0>{VmkB7{vL)ZmNJ1&F8<3s_ew$=1WDYBO>`kKVUN*B6|FdbT+Ov{ zjkByaBT9c~gK#2@IdO2oZ#O)^3l@QS6=l+B4M={fM#@v zkaG8sLu!1`;+il6!biQv+l!uQg|#@o6_6#DD6 zw_CNwTYG8}CcOpT8Q?rQd=zQOuyPu!&cYF}1Liq^2*SV+QAvJn-D6ck*w2YDoN+7e zfpTna#k8Ena(5TbL(gFroLi!-uHcl8J(@AEgv|HoPgWCXpfNI7%SPNdoc&8?QG8Z* z#z%S`w6GUsfvicS5H(gGedm7`pGhFYQ}w?s%?Vl;M9QXZ$O*=liy<)zxolLA!d!d_ z5e=s@#jaidpfT19F?oJ`O|wk|RJUhCI915-J&9{~#g8ZlS^p}uLu?bTvrd1h3VZvJ z942ien$qwGH^71{V3$$Cup1_qClc0=i-`XCL^&=#6Kz*Y#r^`k#)n}afYKR2tMlLM zCo?mHd#9ZPhUER0oCsIpxrGWn_?kB>gla9jcQM}Et04qE;A-#Hf{L73GO;u_ z?q7#vnrp_Cbv$G6YXQ12GSa31)qNQL!0T~7$*>q(VISe(?5%&c1Z@5WVgAeIxd*>- zSMWZ$XCp_j)W-tO;q7tDIn#vSW|N7%W+ZcKCW}LCaKA zeYT#dozuAvurXz504w!;goovM#pS7z z{B1kGAATrcmD)YSdE^~eWS$%Dp0gpoV?wQ8pXt-(dEFgYs`^FUWX14oU%lh{3MK87 z+#+m6ZV9%7%Pk$Gr0Gbo72}@>JvZ_jXGKG(;@GQ~gfL)otd8Lj85wuEt%$Rs3x_DE zNqEsrewPA7DxWUOkOr&TMcIIu7h(xoggq|TrMU}YE^$}z50+Qg8xKiDbGE&uy3{1) z%6bKL=Mt?tkk(7;3xf1t#~xkl2a*0_Tu9#J?fX=VweK&0wtjeKzMr%gR~FQs?GKMD zYeH=s{PZVT`02gEqF+|2hdxi#*b`K5fyEo~eLU zw3YXGE6xw~0-OfTCQhVmjIX-u4^fu~!amY3giC8xoDaTR3U||+JV3`<00VU4#PCL4 z6bth{NG^x4a{msQdt6x}l*CAx3+0KZn0%YmZ1Lw-XBEbh43?(P(%7^zO{4gC|i+HDQs7*;1sHOUmfdE8$X^LIO`C@T8Pz zzC~EYEo|A!8rMQFbl%(3tu}b30~BPxzgPCsx1`?LZu3kCbc*MV4SZca(|lbttd6)q zRZ$={1vX7wL|B2);9>e*o+{=~lr(SFN|WIKLjZ}xHousv?8w3~UGRE^>Ot3`-`FQ% z)^)9G!C>20hd#bMk!(mrQ}gqa(^Czp=~z3GmHwaOsrgA@ekarxrlzN+`?WPywS~#* zQp`xn>RP|1wyvhIxVE%oSlHZ(vW_fa9i=y}HU6iix~aszlbWBJ;-^aLk|l*?3rJ0` zOHMDWt@2Y7>XH)*T`HF6;;Duj-zm4Tb5$4A=T{}G>(H|$!5dgM@>l*}j2NFd=e-~@ zX67W{c<9uWIR*O--VrDv>BpR;Mcc+#Oz-v+=naZgVzw z!)vMl#1H-QS|;Ql5O*j{k^M>Q=l&^=_-fo@S2Kg`6e%>kYBR?toN`wr7#05Jzhn6TTL5n6O@8-v|9P7m=UGog zMjv#P)$>Pury9)SS`<`rgS;Cgj9MZ#YC#sfo4B#Nk=tvb*WBzLbI*?WLFU@}2TazQ z_N+0u-kDIJ@|0bZnnqDGct@O2Pnhfrx=%j7UB#1 z8~UP}S|pR%oVmDl?;WCI1B4TNHU5ub)Z-WPzOuP<>oYNvwN6<$!05$V!s!kGNAe3o zi+6{QUWQ>Yw)S?TeP=yj@Z|h-Rp6aFxeR!zUYFs!wlEC0^YN({2x4zSc7xwR zCtW1WG9{Hk9rOiMdNIuUTD;-jEB#%JN(?Nh$=Az?_MEuZ_%ASBNM9YS7HA>r*j0e* z*tg5=re9yRtkmtw&QhqDLthXc#Icnq-_t*zg%~EWFt1@uw+cI)S*Gj~tF9{mwES5g zK=hfX;}H-+(q09B9TnI(3LoJ=t^sh~J46|#Qm6z7$2;|Vzmh{V3^J^Scct* zh2I?srx$T@2asgOUbDCWpA&m;f%}k+z;$7WoDU=ADHIKEDtPFsFYKmkCzqAFN(ZYT zpvuyLHo+Qqtj(GkzsR)KahSb@=|j}5uSC!I^p#$-HAcU!sU_orx>~6?KsHlX>t1y~ z&u7NNNi+3?AmtHOv0BMqAOcnsyGaNRwK$4vE(hyT95cUz6-03|=Yu6^54@pzoix3> z384&S@Gbzl2$ihl`d;?Br;T+_&wuq|AH>=F^(fsqpVtixyaA{Y*0Z4rQmh0vO+aG1 zpe9vNhrQcA_8BW@y57Sxw#43Z@3CdK$i17TXkVPCNus!sFL?WAYWx+T7#rZs>L;#^ zZL>`^K`XwQX`5nsc={4hpzW{imLp5|^6a(U%2QMF+aZ8i@e@vObJv3TaAp+_s_ZfW zcx{X4HQrs*WBP$-%WLY{V4Es~$U(P_!((g>tvksr3_3?X9fTCdBD#?HL>nu0JIk)OW7 zpdpO7YiOW(d*IzP{_X;VB(#PKSB(M1Q2=0iLCMuIs=I689l?rtnTtnAq-|DuW_H;Y zbmFn;hq`yf^gVv9H2g{%4uX|XCS^VKq+gN5BPBzdy1}Ky(KQ$n+>|p3h91bCV`6h}#BVmO zxKNV;)gMP@`(sv){y38Um_>h(sxVBfk_C2m+F&TTaIy6(Y9Cp9fr7T)I&H$M$^KEN z2niF=g<^i@nt-c-=*fd8jNq?>-B=0B_#vhi6@;>{e2yJTJUXff!|aXjXE#m88)+Y5 z_*RbY7wxnTF%gDeU&U@TWbLgaw-o|5R=Yw7M@!>uscl1;00)ltEc+<96oC}u_;3V| ze;EtX_hC!vLsDn&5_0ea@4%>>d#A~T9$W)Y*>B^9k&r_!;$z;P9xYDJPnytES(vD) zQzD~;1FF9|x1A%^LHeKjLR|bhB|b{j#w58sPl(@Z6JGTlGD48Hea-10nrHn1^;n-N zvBcSl8l2ve0#rxsqx^==Db(2cePcB>Q5}SrT=GNRHn}VjONo)0j2lLhIoU<9oT%Fi zc(yj`@HM?C&$b90Q<%%KtGq` z_P*R!g8$)H&(f>sW?wzF{i_ReIptO@^#40~7IV*%$FBCz!$tSJcwsnc&yf z)D+f~QYI&$JF&|(wv2PUswTg!%>CNh{B~t+yH}?g@~dj=3X_%YVqLBLbZe@7uGZ(b z-B_Xf{wG{_3#@sSeud42l2k^2vwcdZZPFUI_r|prOhKVjZIdtafo(J2l-WGXng6)B zt|oV~$p4=_Xa6UBgDdO&X~tt;?GHDK`i3@ADe^mO47azB+yTRBdJRne`tQHAjbAOZ zc2vA7zvK68mliqjZhQCj0^FhgY6V8WUg$1?$Ms5-n=%_g#4rV|0`bS|qGiQc+b^oO zaeV!E-;xKe+xlh|r{=ec$Ta$C8=ggf|o2WD1Ag6m~E-GR~;V`38)8iV(s%;Ot zs|&{8?SHd_8J9&wIc+mIWg47S?FI)-A*Bz#Y1Nf}=o;ta)U;07hpfwk)l*+fs4o-Q zzTG{vvaD7rrPWXy-5QQt&s-yBEW`*X+E>#ygnIDez?*>);k1f8`}APUssb%26EGjF zWlLIC#|`dB{d0IwR5 z*L&Xh|Fw7KaZ*(0-mh7@r)Ob+VFrc)W>^J5KsE)(C@Km#DiJ}wifg#W048W~iSjY= zs&Q$Fxq?xHqPQEpylRLVKr8~@glKb9&-udH9 zb#+yB)v0ry^DMvT_Y4-n44^mvX@2TIQn$y>$mf|rp6F4wqS%Wbd4nJ)`^54?pjjO4 zhmpiU-&_*w9vqV@VNe39pbcSY8HfD|L&MSSbri`xPOn__aVXinj+iEyT&jlH>N zYUOi?WW0tjXhRIx)X!0E`~6P|8l)oxaLuKw?&iT2`Qrw>7KHyqLD(AqDmUt7U_x^9 zUP~yXc_5fS|E2h~L&xFQe!(j}4!>sC4_pbti1uv%Up{$DE>IOZT?}^SI|7a399=IE z`pt#OoTlTiNihl5IF6SZ7XJ}rbzpw{4m<(jBr>?k zH(zFdHy2l1p3t8Vo2ZORZzKcHp+epO{t7_jLg7<~?AwNyQ~ZhFK}|{paj(%WTu>u_*!@BS0IA{P5hT{hJ0O4N31BAM5ry>2XRe8KPGO{T zW=x;*QI3D3s@tslZeLfLAOFD|ddc40MEm-NHRAQDQ7vcf1Ll-jQCgf6(+Vgqin+YU z2PVyn2TW=$H6yl^g ztNmPHOR7%D6m|*uTsBFt2s%%cl2TiRO%|;>#m}Ilw5K#DnD`1|t*#3u#DOgp#YWf^ znEJy69i|VU0<;nj_K`5xRj`C3EF7Y9Eovetg) zGF6!Ve~n~fg|Sxa(O9O0E|Z=x37tlL|G$Dtva{z>5q}eYwD*nC2Pt)0#t6TxlJXE)s(Vjyyx$D$9`jeGVRC3!6?jU%Cel30ekFF<|TZCjS*sGeNnU9_Qirb-oa1q zJ&a&Kg(zrGpmGz~${>m{>ivuC%eY|Lk1M7GqbQ)vih({R$MX{B+Q&$}$@XT-^Pkf! z@jv?e?3k$hiCrGcXRW~zQ#U$7@Mw4N)sTkoQOEtggBz|?P%N}WPR}&^{N~3(0s)#4 z7{+0Kj)MC%0AwPd86Ose-XW|_6e<*j09iTJ3l08)xtR8Ut5|Ui3dQBBIOIzdisEmT z;WqOzF?Q7Ym>6XtR;d<@rUUpEcaj^cSS-o%foTa=>AOf9sdDbdYu-!t9las}DKt(L zzH}VSsR8~ z_Oa$qDMs_&oXLBo#6bJLu5|XlR$Vh!LBdxuc*UEc3(M#|aCp?v~Bk`QX z-zRQM8kqFkq)o~FlOGBU3;ZEa8XO&bHCUc9BIS=M`$89mo)1;0UXuE9TK}}sX>X`j z+xdAJd3WV4Z`Zlqs`kCwFX@oiVN!>M`JWVI7u-_tw~l!o@9wy&Q{PUHc3RPSaMw`R z`@62}c3t;JdzAFNrRVfseS5vt`}#hk`mFDJVc+*p&pQ3}e&_T%*#DCL3kS3rIAq}T zK`Dc78uZsehtHgL=7&StowcR#{j(oC=hSnr8oKqo<>zOgf8qI$od4Y}4jnn`;u|lXUzA&P=Os^Hvg^_dFP(K+>8Q@5 zZoWMC@;66s9P`^TTgIxe!W~h>+NSUcVj?07x>D%?<6VziX+#RZC>ho&j4LUeg&$k5E3N8qwzC1at+pg471{x1c$OzFiA1 zO^6b#%Z+z~DDuf5y)h`L$iQ<=ZPigr+?aC)^AI0{5|XU-V;)eLC2k7Ckq*k9)lXB;9qW_G=Uo`BqhxlLE(>ld^dLG<=`m3Y+o{H|fs^JM^J+lx} zJ2FPP#=OG2XP=qInyrR?w&~Bu58OVTYxfP%rR)_O%@H!A@p3f1@e+4Nj zy#tMyEu*c5k1_V?V0T)>$H+eQC(ga=@Oi$BT``TVY0;07eFds0AEuIPC*RAy3G1!B zCh?OdnFTj7VJ>5UsL@9n^KRq|>b3gKyOA#%_PIme^-rTmV#R3IG)*6f z7oks&xmPQ6tY4iH=U1o1{#AQ*Fk=>G`??rFB3j(&`>PY1ixqUT2UamA}yDTaff zQ=^YG=EKMr=8b6cVdRU3eeRGC{nNPOK*VM*6i7At7~N;qAZVAdwJiEE#=hve^yz)L z48{{2P@|7DW+s(<*k`TL?`gKOuYe|B7OHFPAzR%(ds+c9p>gx4vGb8D#u_EDff=z= zAF^YQg(k?ac}oh;`CVe*VucD=@n^$yp65l#*w!%pDGTVM(~Chy*BX} zdcC81GtL{0CsXF6q)$BdyQ9vTG12~f6UIUlY=SsrA)eQwiTIZ|@;3HJiy6&{lRy+( z);88Z81t9VXV4|4E_y!T7w7`D=MZ@n(B6XBv+LnScP&Zb0}gKo}7ubY*1Hefc~B8L;nJJVeDnB(*0oJ_y!2zt|$bs%!dFP@2~%P zE07+%H@bosB8)AY zbrj9D?xQ`wgD%KB=}ri72lV-Eu|L*{=zi6utKp0QnjjLEO+XO05v1GsfPI}o5?)kF zB9%8@0+di8^b$%R>^$?5u&WB>C91v)BS5ap-6Z15SM~#IX*IgT4na}3!31G;&?l51 zFuPP^QGV`UQk^S{aP(C`Bd%=!w(WtR7JUvk4e3_(1OqA0YU-5BV0EHnMGvmEmhbg} z{45zO!TYFWmfMa^uw}fFqrMONBseOD@GybtDHHA|0vkl@QK&{^Ac44jVEEjyz`tRI zb({ewiX8`ZPG@Y^qksWdFy%1wBofjuQz8xTt-hBAA_P6AjC5AfpOgcOC?%XxFK!{# zbD$8DBL%`hHB@$paI=Y*h6+eknPU}`!UcIRn6Jt3AytF5woepFkK~Ar6bGD_5YVkf z$0o`p<@y}1II#T+yM+^c1Tl+G_Wa5!m6SSKd*p+VN%-?zWbv1{-_}qw>Vvst1udB5 zN*6g=mugiq!f9P06IKIZ#kb7U_pyX(N@iIB?4`W6O(}6iSV za`f_{<1XS~DgN=cr*f3Y4nCrpfK<2s(jL%8^xbXnTpk98m2<1@=DqmbsoO{d=}8xG zapg-zrI{k$@938M0%OpAe8hMi2|blC@v`xqZc$`rlOi*l7?;I(O16O6p*RIchWyH} z^{R=E=fsF{LG1T0r$lq{}4YNe;I4?AacNa;;C4RS7Ir-cxqJE+uygzS}uZXTDkazs`oLE zzri2UN96zq>$MCfetjxl*FN}t&cHX4vhc33pD1C3#*yInRM<3{v2!2sEN+pOhoJ4W|*>f9K{^`_}l z;Hy(^A5z;Rl1jtSbmK`Y;dzhiX=8S5 zBb@vvh0&*1W>=KPH3{a$HTYw|7!=xWq~SzdH&)QVj*11;t;!(5=~D*#AbDc0**YTh zQRC^vuC;gaCYZPLx%qWy5@gtU(6)O+K?wGOxN}UXUw)IWY6ryY2*gi7+Ac*C`)@S8 z!vc~nSTNz3i=BjS)x4tux&~mnwga(xDyA9rQEZdTj>PdIrE4_Ke5MG@Vqi~V54ob+ z8O!1rJr(mR$JESg8b3t3#&FFL&8+ zl%t|_IW3MHo#rVa&6ADeo%a|i+$a*4k;ZW?lar*e}dt4 zjXuWM7d@BPeBJ!(Xs$QjGa|6Pj;?%}m6)Au*)F`5Py{=VX=dw-aP;sS8cwtqdWIRM z3t#7A9F5C*I?glwkKy`FxayeyiK`ZFY&?*$u<##<$K&o`V`1Ylh8t7T8+~2lZ6zC` zv5yy93fLF^u}n`?qna5_%SSQ^9Usg(Mut#kq`@7nf`y5w;K?`wI$Yf%j1!<~ewJgC z2pXN7klxrM8=bz8{?FV`oTvUL4fM&c#x>AGfQYDx?b6c|&{~xtDH)j#ywREBDz|>L zDehwl>#H_|O?_{|auUn+5YpD&^9_diU>`Ymv|&EnH*^jB*h+aP>&xnFUvVFOL(T>t z7q!8M`ZjnJ3%R}lF6f#D2w?i=*_#L1w1^ORmx@-eMnXZya?Z4p1cyL?!)Sa+Nq_@9EKK$;oGNL$st(Guc56 z=1c-x34-E%Cf7)+rEb3Qe7jaZW7q10HbsjuGuGMu+c_D)07mGxC$F@du#$KWgS}ZuJ;K*(wE6 z)^hf8-zd*inc0@Jm)f=!wo!9PYdHr#m$2?U9Lc#B(K`S!rEsk0{yMMx;VOG5X@rZR zUNz>=<4(05v;c7Ix4fM7#OFV&`2j|mJ-%llS(WWn&@Fd{y?pCE_t>_JpywZsMj#^c zJP#?8fWNc^GqAK@cPqMHT!?H^A+&mIfy3mWm@6uwN5JQvOI5qmk*7~U+Oru7glh}` zJ;3=sR^5~ey21kIuIhR720Os6t5cl54tn`3%F#)?;#W|@rQrUpaU@3XH2;`8#SP%@ zR6^FjQ^EIir?@t_({y{;ZVaY!kTxpseqigx#>*%5KphObii7o5!argvJ1!y>j-;y^ z{5iYuIVw$S>jNo_Cr-Mc=yN+L&Li(kq`D&iAGW3r#nzfh$6^V%*E?`o{Bu}>0Nn-G zj9DqalG2^>?q@hR6QoDPC(6cJu_0dtJ?!z^?b_K(?X>@rZYYJ3V<$TAn&rz2d;rn+ zYdt%Ho^y`rup_GRPPye4`t%kw_#tk5Vzoc_+#i7@iIiVLK8+;8bciQJ#|%Ezlq&In zXz~$-U2tg}!Jk9+v7GUC>TaO=ydA3<__kD9T9v$YMkOOz3395AbBNTQI^DnW`S3|8 zs(_Ed?B6~nEKVc*EX2cY6P6E!&_@kqTJp3hn-15QsUZn(*$eOb5s0tB*|w!f!}sL) zodU2FDtK3(8j3VirmL4?6q&sska2OCeT?N6d|wI&X4zXcF0b3Cl!upxFqN0QU;?9j zz<>zMb}MvKIlP7+K#R9$-NXCt$^wyvZK@$Ql1IP#N4JL~%xxmd!FDsX9X}yo_-9U| zF+Tu}YC|9I2XfYq3`t5`I$ADGl^y&_8IJjFcYT4I6;WWSfm12jphjgbrr&9&cRSId zgJ$mpT1E1!%hM0oLGVlIUgt8*Zp19|u285&b+r}Da9hj=yTwcxhCr@H**yg<=VB43 zvNepvwTc(!8SiYy%cn^1d_qTm!y#OWU|tT}jmW6KH3M09~rX<9=Z%Vdoj5Fbl&V(5*5cGcUH0FWdUB^U{yXZ6YSPLoyM=Xv`dE~ zU3QRIN&O`r=t2n6I8SA-tx&($ zo{zYFuJ~cRL94($uHijz#s#oWK6HM#0JZQtw1qxTjw?`}K-h<1i-jkNzK|2K7V05Q zpE^;U;9xLS^1GH!zmt@K&92zGm$L9~qY|s88qlSR#JG&1DvG$6&qZUvD_+AK+qk9B z?%W_MgpHl88PXSpV>g3nF!fVyw|AWRdeJf~I70ocM)NoPuv?fLL%}wFOafd1M$8>}#+Oh$9qXQe76k6hs9r}KT+iYExZqgt7twTf}h86ehb zO^2O`5|4`QJ8>_`6TU048HR;5cWRihoyp#DTg++2UgY)3V*7Coz)1m{4t6 zj7={MX_-i}u&TBu@&1|t%M13-WFawj-R(1IXuwsOHD%jJyD~ne4j|@1tx^?=)K?<2 z63MKVo|BB@kkUe45<;+s;U3_oMb{NTD!DC%jd1m+T{s)9b=BdJuK-;1qsdYL7^i8x zV|BlkxVTLApaQmF^wRfU2Y{}j@G$0m?@X(xbY#qKWr*g}EgP_l)v(Vs_G7+pG`t!f z7VsC$BfM1ok{bIF1vt7_cY^L=ICK&6sj=ibb(sG%Xr-@CJMM0yo1hqCa{Z6~Nnuvx2tOxJX+nNiVIn?Yamu2Mu73`ZR{5)KdhqLwkp zdqOO+79{gPW}cd!EMq+ZqYiv9i*6o3VH}b7_htz`j8F;u=L9Cs?WpL3ZP#N)inDS( zb9*CHXS_f4Z z#vuVa_9*9`&IT)M!s?Rk5%B+gv}!TfcG##Z=m`^#gjTeWkSw@)XSCTKXbIVzHkT^KSvj%t7s; zxTaZ+?)Vq_pcVn93_?+Sc0gPlr0Y&0Tx2R%+E*#brsO^;AO2Q@9 zUd~j>ML?=9Q#oo|vT!iq;*$Zem!s&_@x~34M}cmt`uO{>^X%e*)>w@9Z2^nExCg~B zE^UD#;a-2HQD>s?J#n-3R<$3@s${v|NHk>qH0v0y?MMszYVn&~TYLjG_y%_|yU|L_ zXOxE9OSPDtC~p0%2shi9@jVElh_5$@`!IvIEgr@U)Fvg8HS62XcGIb@IvhZngABv= z44ogYAIP})8IxF;udx&=7z?k5-MK8}f91oAty264#^WD&13nCS1Ru|EO$4qyQYXuu z%rLx>o>uAte6i*boF{Xz$hx429QKQEq-FWksz_w@&YLUWY%NytIXCiZshN?m&y}PfZ3G1woT+8 zZ5bfh^kRs*LuI73hEy1yJid+uQI#o~hHkJ2e{L#5Xdga^JgYjJovcdj>HI7t4c3<3 zvV-e}UDo2ceEV4A3ZmXPZwOuAf~Bn)kD|tY#P!?)jYZ;!y{2T6EMm&Xmf+as8`qQ& zwWINxVfpKn7Sr##6rCScsk5w{4VqPw) znPPRS$M3IB5x$I<+Rjc+uankjFEIoQ@bjwDNgY?Kn3XJkv%r`;9|)pzw#j>uf=DG& z(?wQX;Gkh%Yb3&cn0&I35>~BcP2G)-wx1k?{Y-^Dh!RmQ(_>~oJ<=wz8BcTe<;5@w zkTc?_1;(Kt{x0L zSZ~c_t~=yvuKPBR@=Ne0Ptf&Oj3+|Lh3$7?B;@V9hu<;UrcC%XH}ulxK6at)Q6BIK zlas0brJ8oh2x&nolVG7J8Q0U5U^5%>jJ2c)-Fg)xU=V(*>MqQ9usp8Z-&*>j3fWpO zyIl45ScjA$UC-pOTL4s$DS1~W2Pmi5%x76UEG};>*dvm-RG9Ocsc6q@I|6Y3Twz}c z({aBYs^$n+KdgFWB4=W5?_!Wu&}@a#I!y#a;zl9VAY`BX4b@1uB$&RdpP3e-PwcQi z4R_vZl)cd(js~fLd(EMOAYKvyYJye3-M$gRCeWAN;RD!*_+%|Jd+jo6jSpN(;K%H+ zursmiydgX*_!-#;2T}3lw>Uum)Y@U3?(&?y){H{(!M(O<0R>E<7HjJ5UFObw%^LgR z3#?{o9!CKkT=r?ePxy8WuGqoef{9^$wrAXlX)<`{O#y%H5>_~sMY2}hNbht+j^uHz z9Oky{YKYt&oBLiCLiU-RxD$3F0NLjnyAN$vd3IsO=jSiX1GvCo2~sk!jJGUi)lzF+ zhy1Jf7uXrOD6fYf*FNsWYNx4_LFiJ4QR}dC*djQLNrN55-lVA-he?S;yDSXoY$s?nR=R?FGBQ^g4C^f^;??)}bC3d;%V z^C?uFc`-`gLw?R=qCiN>mqu_`0|ZD$9jm!uhCE#UR)9!Ytu<<0mL)%>Oibt4RpA#Y zktrfgPPw8o?AM8rPgn_&IF2Hle50B*qDM(q)h2E+85UiA)EE4!Tu+hH{=?7zbXWcO zKcc^-$}aUUe(aZ{@$YYPrPW}&{PijHyYd@U_Def zLWtk8%&T#HsA~Y5lw(n*AW}H`s4Z2as6`1*+w&_dQ7lF;71_Yh_ELbOArb94Z@3d3 zxp%4%9PV%^)N}`a2@d}!LYSV9`2w{Z=6yF?7EB0phgUK*=?#9~J%zPYc`Q+FR9n5t z)S+HhsyJ(f9J+F)I#YbnAK`#_-zVUp;Fr$vQUn@BEcsA+*`6u*jHH3NknjxMvIwQ^i83L0ygV0cpLd z<5wiZYZzfcA|-l!sx|u-tELl#sfqG}_DV$Nmc3O&&-2QW`SzXkbuY#bCbNQh1g0tq zDFtf}523YN$vtrTokhmGI(K>z8d4v8l-)2-y5Z&O;|ig-M2D1xMR7$_jznqp*cm=- zRZ_;of(>4oj0D4@?p=!P`VO)|S)V71TX#xzK zlC&S$qrXP@U{IM2cqljU8|*}&l;q8#=G~|MSs|9r!>l|i+ggdY&d3Ee^L2jr-mSKM z4;gSS2F>4DH7+H4)C(7F;NoMyb05%MyYxh?>NYJyOw05X|`e9eTR{k zL7w<7OdU;~O}t0(v#v%`v_h9fh4Q+w04D){l`BRlj8>?g`Q-9zxj99$4ap>bHxVPR z6(UxzsWpb;K8#uAAM8b+JcQaRRNobsLcUZ@YOzr^_bBHSJ9%O~tZcPh&Ju4#i@>V54R?D@h$d&qUHLIj5yzJE&aJ9PaTyBG;sUr;U z6%lKw!7n|Qx2~GJBhb_W1l3#P@JuRs!45N=9qn)ys}@Sms4c7td%(xK?jsSv6yt}l zT)y01_)#Rx-CEio-VV{r9@W=D`0S!rlX;#W9yu+nSn!`PS^p1b+s5jSEnvdmz-VsI zD*HWdh%QJ9-j5{Fw~TG(wu@U=!8-Lf9395_+K*TE zCq~{Fl;fxH%&njc$3AwZzQ1uO+g3Rn_jYR7eP@qf!gt~*lw+X-24siKtHR>u3;7Iv z+n9EICALA=u+KGOB@_*z4$;B(wEQMsc#+?n?80YrVfnRmVQPDrio|A4hX|=Pu0Tiy z{_L_~SF8CxD&{m}0{-{<<9kMh3u}e^;8uu`A!Eh<$VN~{WhyJ`4rU#c1!8ra*e4jT za9vt3@)bi)_fm!=IPumBBC(EGQ;*i#a$16<(sg}Tu~U`>yOd>1OCO3ECBL< zlCTxa@OX%*O)LdUG^kQc4riHS>Q#gZO&tM7+u{~NF_4v>KyYOh>UC>;4PWsV2#=WM z6cjZ(bU8FYVF0&wHE}tYz(*IxD>8XA!S3hu5jT88-(fu|C=v**(;->9Z9#Behl^6A`s- zRppe&%Ok%_OL!hr%j-LJKP?tkDR1vo8SX#2od-XWqro)|Tn_)3^PzzoBEs+Rdx~Ag zW^A9_?-cvwzgV#$EIdj$!qG!?&NcR9f&ZmF@U`u>oqSD)KrFzeoxs26dft;<&r7zd zpHH9X1yIw~*pCJJj-}-{Xw$#J;s5K`wzK2cR2=v&+|4t-(%^?~># zUkK4Y(eju-kCw-r6h5kTKGLH}yGUN0nC8m2W}3@8bm@kTeybk0nc1xT;?Q^9*UeI>4vWvQ<@5_M~tgpJHR4focJ=)LW~x zWeoqG!nPnV(SKY3FqA%VnVYan{i&@gFCj7my98RfCo>%%T@LCmY~FC;1a!wGRuj{xprh`%scBDRig+y$Gn4Wv?IuxjDOub zOR#oT`*18QxDf=qpmLiSNo;d38od=co$p$5Bzz?7KAFt~kHuM1)%v%g_}nwL{S25W zKkG+5(E6F3{;f4*IS?ayqF`&_9(WWp3k23S{BvjGdl-VA__?4A`Sa}+QPjE?#SDH5?m!wpPb#&m=!pJ)htA+;Q=!XpZQ%>wASOkaY;_v z3iShDGya+;Wc<2ystWXDFio{6RvDSVd!;uhD(2zpEp#B z?lAI-X{~yIBWfrw{B*|7={-v0vuieNg<2sN8s!%uur%^YU|1eJ&bub;$j*_XXkM z=U7uc>BF_yT36vzeUoRKhG$uE%Bx6!zbfygCgg)Qv4T@f^)pT~WV~8Wv6CVHFVur) z0001ZoMT{MU}OM-lb!j7Ao^VKW-S;E076v;FaQ8}oMT{QU|`?_VhIKiU}9ioU}Ve$ zk}O~z0{{rw0G$AMoMT{SVql!Wz{@g$H) z5-n&+D_YZrwzQ)?9q33WI@5)&bfY^x=t(bn(}%wFqdx-}$RGwYgrN*$I3pOzC`L1e zv5aFp6PU;(CNqVpOk+ATn8_?=Gl#j%V?GO5$RZZAgrzKFIV)JnDps?GwX9=38`#Ju zHnWATY-2k+*vT$-vxmLxV?PHt$RQ4MgrgkeI43yCDNb{Svz+5R7r4kJE^~#eT;n=7 zxXCSUbBDVmlfpgj^MHpu;xSKn$}^txf|tDFwb8h@yyHC|_{b+d^M$W`<2yh2$uClk zW=aN`$W$3*ri?O|g)C*IOvHa?4hB%A>rpmxJ=jQBHD}i}I_0 z3d&V(Dx|_HqM|A$cX_C|N~okf<)u<8tupdfjN+A`ST$CZ64gwRs;My5P<=H}lIp60 zs>(-|RZW2^r}Ap5Xf;<8#VK6X6`|T{q&f;!L)BA=YN?8RRY_$PqyYJ=qWlyLGX6&T zll%n+6VnW48O<#$tukfKlGWNKTlO3|bLFu z5+yyoN|i3-UAA2L3O>FS{VMra4hXCgR5iF-NcGUL8sRl-)vi;wUi}6UkqsL~MK^Bp zuj~IEzX4a3p#cDRoMT{QU|;}Zu26x3cz&C&4BSi%AaJgDvlfj0|NsAeCPu~wKrROZ zSQ-Ev<_nZ~oMT{QU|@Xk|2~5r6T|=i{}`AU8Gs@vfEfUst_AdXoV`&y4#F@DeeDTY zSdgklJp~g95+m$va1qpq&&tezL~jDe;5NmdR7nsp;wQ(B|4vFMmB0-hoWRO?$6j2l z*D!<&;ejVkIKtzMhG67u#NQG+iZB6|qCBqHgnPl|`d%usN4tS?n70z+up(A{gn>+u zTw$kmB(o*f-YGdbE9sD0^~O~#b@0S&J>VP7i6@z*OeV^a+v1x<6mOaNX2W*r22JLj zeb^=Lu_T#BBW$O(ad>lJDxMfQXf^&zF8doBq=C+??^6*kMB|A)kmUgDA6f1NYo9FS z0000008jt{Y5)LuoQ;mbO2a@9hQG8)MJyhrcyVufN!Y}K(2J)QdJ_-5hq8o1*g%>- zh!-Em=kNu53~&Bf_uxh7!m{7Yd^0=1oOcq&lZbC4Pq^SI@{|YOBBydbBWGOk9eKt) zxs#csm&zMh3CkroR7#EH+)5&u}Cu3v^W}SJOf+ybfP1yTi4Wn*zP;8 z=ru?u$u+$~*PPl~unGDQ-d={oP*Gs@u5|w!|65&>Q_9WNV?~b|*!f}8^^G%CVa>|? zT|?nAFKu4gQs$YP? + + + + Your Font/Glyphs + + + + + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+

Class Names

+
+ + +  arrow_up + + + +  arrow_down + + + +  arrow_left + + + +  arrow_right + + + +  arrow_left-up + + + +  arrow_right-up + + + +  arrow_right-down + + + +  arrow_left-down + + + +  arrow-up-down + + + +  arrow_up-down_alt + + + +  arrow_left-right_alt + + + +  arrow_left-right + + + +  arrow_expand_alt2 + + + +  arrow_expand_alt + + + +  arrow_condense + + + +  arrow_expand + + + +  arrow_move + + + +  arrow_carrot-up + + + +  arrow_carrot-down + + + +  arrow_carrot-left + + + +  arrow_carrot-right + + + +  arrow_carrot-2up + + + +  arrow_carrot-2down + + + +  arrow_carrot-2left + + + +  arrow_carrot-2right + + + +  arrow_carrot-up_alt2 + + + +  arrow_carrot-down_alt2 + + + +  arrow_carrot-left_alt2 + + + +  arrow_carrot-right_alt2 + + + +  arrow_carrot-2up_alt2 + + + +  arrow_carrot-2down_alt2 + + + +  arrow_carrot-2left_alt2 + + + +  arrow_carrot-2right_alt2 + + + +  arrow_triangle-up + + + +  arrow_triangle-down + + + +  arrow_triangle-left + + + +  arrow_triangle-right + + + +  arrow_triangle-up_alt2 + + + +  arrow_triangle-down_alt2 + + + +  arrow_triangle-left_alt2 + + + +  arrow_triangle-right_alt2 + + + +  arrow_back + + + +  icon_minus-06 + + + +  icon_plus + + + +  icon_close + + + +  icon_check + + + +  icon_minus_alt2 + + + +  icon_plus_alt2 + + + +  icon_close_alt2 + + + +  icon_check_alt2 + + + +  icon_zoom-out_alt + + + +  icon_zoom-in_alt + + + +  icon_search + + + +  icon_box-empty + + + +  icon_box-selected + + + +  icon_minus-box + + + +  icon_plus-box + + + +  icon_box-checked + + + +  icon_circle-empty + + + +  icon_circle-slelected + + + +  icon_stop_alt2 + + + +  icon_stop + + + +  icon_pause_alt2 + + + +  icon_pause + + + +  icon_menu + + + +  icon_menu-square_alt2 + + + +  icon_menu-circle_alt2 + + + +  icon_ul + + + +  icon_ol + + + +  icon_adjust-horiz + + + +  icon_adjust-vert + + + +  icon_document_alt + + + +  icon_documents_alt + + + +  icon_pencil + + + +  icon_pencil-edit_alt + + + +  icon_pencil-edit + + + +  icon_folder-alt + + + +  icon_folder-open_alt + + + +  icon_folder-add_alt + + + +  icon_info_alt + + + +  icon_error-oct_alt + + + +  icon_error-circle_alt + + + +  icon_error-triangle_alt + + + +  icon_question_alt2 + + + +  icon_question + + + +  icon_comment_alt + + + +  icon_chat_alt + + + +  icon_vol-mute_alt + + + +  icon_volume-low_alt + + + +  icon_volume-high_alt + + + +  icon_quotations + + + +  icon_quotations_alt2 + + + +  icon_clock_alt + + + +  icon_lock_alt + + + +  icon_lock-open_alt + + + +  icon_key_alt + + + +  icon_cloud_alt + + + +  icon_cloud-upload_alt + + + +  icon_cloud-download_alt + + + +  icon_image + + + +  icon_images + + + +  icon_lightbulb_alt + + + +  icon_gift_alt + + + +  icon_house_alt + + + +  icon_genius + + + +  icon_mobile + + + +  icon_tablet + + + +  icon_laptop + + + +  icon_desktop + + + +  icon_camera_alt + + + +  icon_mail_alt + + + +  icon_cone_alt + + + +  icon_ribbon_alt + + + +  icon_bag_alt + + + +  icon_creditcard + + + +  icon_cart_alt + + + +  icon_paperclip + + + +  icon_tag_alt + + + +  icon_tags_alt + + + +  icon_trash_alt + + + +  icon_cursor_alt + + + +  icon_mic_alt + + + +  icon_compass_alt + + + +  icon_pin_alt + + + +  icon_pushpin_alt + + + +  icon_map_alt + + + +  icon_drawer_alt + + + +  icon_toolbox_alt + + + +  icon_book_alt + + + +  icon_calendar + + + +  icon_film + + + +  icon_table + + + +  icon_contacts_alt + + + +  icon_headphones + + + +  icon_lifesaver + + + +  icon_piechart + + + +  icon_refresh + + + +  icon_link_alt + + + +  icon_link + + + +  icon_loading + + + +  icon_blocked + + + +  icon_archive_alt + + + +  icon_heart_alt + + +
+ + + +  icon_printer + + + +  icon_calulator + + + +  icon_building + + + +  icon_floppy + + + +  icon_drive + + + +  icon_search-2 + + + +  icon_id + + + +  icon_id-2 + + + +  icon_puzzle + + + +  icon_like + + + +  icon_dislike + + + +  icon_mug + + + +  icon_currency + + + +  icon_wallet + + + +  icon_pens + + + +  icon_easel + + + +  icon_flowchart + + + +  icon_datareport + + + +  icon_briefcase + + + +  icon_shield + + + +  icon_percent + + + +  icon_globe + + + +  icon_globe-2 + + + +  icon_target + + + +  icon_hourglass + + + +  icon_balance + + +
+ + + +  icon_star_alt + + + +  icon_star-half_alt + + + +  icon_star + + + +  icon_star-half + + + +  icon_tools + + + +  icon_tool + + + +  icon_cog + + + +  icon_cogs + + + +  arrow_up_alt + + + +  arrow_down_alt + + + +  arrow_left_alt + + + +  arrow_right_alt + + + +  arrow_left-up_alt + + + +  arrow_right-up_alt + + + +  arrow_right-down_alt + + + +  arrow_left-down_alt + + + +  arrow_condense_alt + + + +  arrow_expand_alt3 + + + +  arrow_carrot_up_alt + + + +  arrow_carrot-down_alt + + + +  arrow_carrot-left_alt + + + +  arrow_carrot-right_alt + + + +  arrow_carrot-2up_alt + + + +  arrow_carrot-2dwnn_alt + + + +  arrow_carrot-2left_alt + + + +  arrow_carrot-2right_alt + + + +  arrow_triangle-up_alt + + + +  arrow_triangle-down_alt + + + +  arrow_triangle-left_alt + + + +  arrow_triangle-right_alt + + + +  icon_minus_alt + + + +  icon_plus_alt + + + +  icon_close_alt + + + +  icon_check_alt + + + +  icon_zoom-out + + + +  icon_zoom-in + + + +  icon_stop_alt + + + +  icon_menu-square_alt + + + +  icon_menu-circle_alt + + + +  icon_document + + + +  icon_documents + + + +  icon_pencil_alt + + + +  icon_folder + + + +  icon_folder-open + + + +  icon_folder-add + + + +  icon_folder_upload + + + +  icon_folder_download + + + +  icon_info + + + +  icon_error-circle + + + +  icon_error-oct + + + +  icon_error-triangle + + + +  icon_question_alt + + + +  icon_comment + + + +  icon_chat + + + +  icon_vol-mute + + + +  icon_volume-low + + + +  icon_volume-high + + + +  icon_quotations_alt + + + +  icon_clock + + + +  icon_lock + + + +  icon_lock-open + + + +  icon_key + + + +  icon_cloud + + + +  icon_cloud-upload + + + +  icon_cloud-download + + + +  icon_lightbulb + + + +  icon_gift + + + +  icon_house + + + +  icon_camera + + + +  icon_mail + + + +  icon_cone + + + +  icon_ribbon + + + +  icon_bag + + + +  icon_cart + + + +  icon_tag + + + +  icon_tags + + + +  icon_trash + + + +  icon_cursor + + + +  icon_mic + + + +  icon_compass + + + +  icon_pin + + + +  icon_pushpin + + + +  icon_map + + + +  icon_drawer + + + +  icon_toolbox + + + +  icon_book + + + +  icon_contacts + + + +  icon_archive + + + +  icon_heart + + + +  icon_profile + + + +  icon_group + + + +  icon_grid-2x2 + + + +  icon_grid-3x3 + + + +  icon_music + + + +  icon_pause_alt + + + +  icon_phone + + + +  icon_upload + + + +  icon_download + + + +  icon_rook + + +
+ + + +  icon_printer-alt + + + +  icon_calculator_alt + + + +  icon_building_alt + + + +  icon_floppy_alt + + + +  icon_drive_alt + + + +  icon_search_alt + + + +  icon_id_alt + + + +  icon_id-2_alt + + + +  icon_puzzle_alt + + + +  icon_like_alt + + + +  icon_dislike_alt + + + +  icon_mug_alt + + + +  icon_currency_alt + + + +  icon_wallet_alt + + + +  icon_pens_alt + + + +  icon_easel_alt + + + +  icon_flowchart_alt + + + +  icon_datareport_alt + + + +  icon_briefcase_alt + + + +  icon_shield_alt + + + +  icon_percent_alt + + + +  icon_globe_alt + + + +  icon_clipboard + + +
+ + + +  social_facebook + + + +  social_twitter + + + +  social_pinterest + + + +  social_googleplus + + + +  social_tumblr + + + +  social_tumbleupon + + + +  social_wordpress + + + +  social_instagram + + + +  social_dribbble + + + +  social_vimeo + + + +  social_linkedin + + + +  social_rss + + + +  social_deviantart + + + +  social_share + + + +  social_myspace + + + +  social_skype + + + +  social_youtube + + + +  social_picassa + + + +  social_googledrive + + + +  social_flickr + + + +  social_blogger + + + +  social_spotify + + + +  social_delicious + + + +  social_facebook_circle + + + +  social_twitter_circle + + + +  social_pinterest_circle + + + +  social_googleplus_circle + + + +  social_tumblr_circle + + + +  social_stumbleupon_circle + + + +  social_wordpress_circle + + + +  social_instagram_circle + + + +  social_dribbble_circle + + + +  social_vimeo_circle + + + +  social_linkedin_circle + + + +  social_rss_circle + + + +  social_deviantart_circle + + + +  social_share_circle + + + +  social_myspace_circle + + + +  social_skype_circle + + + +  social_youtube_circle + + + +  social_picassa_circle + + + +  social_googledrive_alt2 + + + +  social_flickr_circle + + + +  social_blogger_circle + + + +  social_spotify_circle + + + +  social_delicious_circle + + + +  social_facebook_square + + + +  social_twitter_square + + + +  social_pinterest_square + + + +  social_googleplus_square + + + +  social_tumblr_square + + + +  social_stumbleupon_square + + + +  social_wordpress_square + + + +  social_instagram_square + + + +  social_dribbble_square + + + +  social_vimeo_square + + + +  social_linkedin_square + + + +  social_rss_square + + + +  social_deviantart_square + + + +  social_share_square + + + +  social_myspace_square + + + +  social_skype_square + + + +  social_youtube_square + + + +  social_picassa_square + + + +  social_googledrive_square + + + +  social_flickr_square + + + +  social_blogger_square + + + +  social_spotify_square + + + +  social_delicious_square + +
+ +
+ + + + diff --git a/extensions/vscode-colorize-tests/producticons/mit_license.txt b/extensions/vscode-colorize-tests/producticons/mit_license.txt new file mode 100644 index 00000000000..effefee5f0c --- /dev/null +++ b/extensions/vscode-colorize-tests/producticons/mit_license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) <2013> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json b/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json new file mode 100644 index 00000000000..6c908a223e2 --- /dev/null +++ b/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json @@ -0,0 +1,36 @@ +{ + // ElegantIcons from https://www.elegantthemes.com/icons/elegant_font.zip + "fonts": [ + { + "id": "elegant", + "src": [ + { + "path": "./ElegantIcons.woff", + "format": "woff" + } + ], + "weight": "normal", + "style": "normal", + } + ], + "iconDefinitions": { + "chevron-down": { + "fontCharacter": "\\43", + }, + "chevron-right": { + "fontCharacter": "\\45" + }, + "error": { + "fontCharacter": "\\e062" + }, + "warning": { + "fontCharacter": "\\e063" + }, + "settings-gear": { + "fontCharacter": "\\e035" + }, + "settings-files": { + "fontCharacter": "\\e006;" + } + } +} diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index 3cd45716954..1044c382e9b 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -81,7 +81,7 @@ export class FileIconThemeData implements IWorkbenchFileIconTheme { private static _noIconTheme: FileIconThemeData | null = null; - static noIconTheme(): FileIconThemeData { + static get noIconTheme(): FileIconThemeData { let themeData = FileIconThemeData._noIconTheme; if (!themeData) { themeData = FileIconThemeData._noIconTheme = new FileIconThemeData('', '', null); diff --git a/src/vs/workbench/services/themes/browser/productIconThemeData.ts b/src/vs/workbench/services/themes/browser/productIconThemeData.ts index 21d2a44033a..8b200a513cf 100644 --- a/src/vs/workbench/services/themes/browser/productIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/productIconThemeData.ts @@ -83,7 +83,7 @@ export class ProductIconThemeData implements IWorkbenchProductIconTheme { private static _defaultProductIconTheme: ProductIconThemeData | null = null; - static defaultTheme(): ProductIconThemeData { + static get defaultTheme(): ProductIconThemeData { let themeData = ProductIconThemeData._defaultProductIconTheme; if (!themeData) { themeData = ProductIconThemeData._defaultProductIconTheme = new ProductIconThemeData(DEFAULT_PRODUCT_ICON_THEME_ID, nls.localize('defaultTheme', 'Default theme'), DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE); diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 9f5bb2c1ba2..e9ee725d3c7 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -29,7 +29,7 @@ import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; import { ThemeRegistry, registerColorThemeExtensionPoint, registerFileIconThemeExtensionPoint, registerProductIconThemeExtensionPoint } from 'vs/workbench/services/themes/common/themeExtensionPoints'; -import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationSchemas, ThemeConfiguration, updateProductIconThemeConfigurationSchemas } from 'vs/workbench/services/themes/common/themeConfiguration'; +import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationSchemas, ThemeConfiguration, updateProductIconThemeConfigurationSchemas, DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE } from 'vs/workbench/services/themes/common/themeConfiguration'; import { ProductIconThemeData, DEFAULT_PRODUCT_ICON_THEME_ID } from 'vs/workbench/services/themes/browser/productIconThemeData'; import { registerProductIconThemeSchemas } from 'vs/workbench/services/themes/common/productIconThemeSchema'; @@ -108,12 +108,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.currentColorTheme = ColorThemeData.createUnloadedTheme(''); this.fileIconThemeWatcher = new ThemeFileWatcher(fileService, environmentService, this.reloadCurrentFileIconTheme.bind(this)); - this.fileIconThemeRegistry = new ThemeRegistry(extensionService, fileIconThemesExtPoint, FileIconThemeData.fromExtensionTheme, true); + this.fileIconThemeRegistry = new ThemeRegistry(extensionService, fileIconThemesExtPoint, FileIconThemeData.fromExtensionTheme, true, FileIconThemeData.noIconTheme); this.onFileIconThemeChange = new Emitter(); this.currentFileIconTheme = FileIconThemeData.createUnloadedTheme(''); this.productIconThemeWatcher = new ThemeFileWatcher(fileService, environmentService, this.reloadCurrentProductIconTheme.bind(this)); - this.productIconThemeRegistry = new ThemeRegistry(extensionService, productIconThemesExtPoint, ProductIconThemeData.fromExtensionTheme, true); + this.productIconThemeRegistry = new ThemeRegistry(extensionService, productIconThemesExtPoint, ProductIconThemeData.fromExtensionTheme, true, ProductIconThemeData.defaultTheme); this.onProductIconThemeChange = new Emitter(); this.currentProductIconTheme = ProductIconThemeData.createUnloadedTheme(''); @@ -187,7 +187,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (!await this.restoreFileIconTheme()) { // checks if theme from settings exists and is set // restore theme - if (this.currentFileIconTheme.id === DEFAULT_FILE_ICON_THEME_ID && !types.isUndefined(prevFileIconId) && await this.findFileIconThemeById(prevFileIconId)) { + if (this.currentFileIconTheme.id === DEFAULT_FILE_ICON_THEME_ID && !types.isUndefined(prevFileIconId) && await this.fileIconThemeRegistry.findThemeById(prevFileIconId)) { this.setFileIconTheme(prevFileIconId, 'auto'); prevFileIconId = undefined; } else { @@ -206,7 +206,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (await this.restoreProductIconTheme()) { // checks if theme from settings exists and is set // restore theme - if (this.currentProductIconTheme.id === DEFAULT_PRODUCT_ICON_THEME_ID && !types.isUndefined(prevProductIconId) && await this.findProductIconThemeById(prevProductIconId)) { + if (this.currentProductIconTheme.id === DEFAULT_PRODUCT_ICON_THEME_ID && !types.isUndefined(prevProductIconId) && await this.productIconThemeRegistry.findThemeById(prevProductIconId)) { this.setProductIconTheme(prevProductIconId, 'auto'); prevProductIconId = undefined; } else { @@ -256,7 +256,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (devThemes.length) { return this.setFileIconTheme(devThemes[0].id, ConfigurationTarget.MEMORY); } - const theme = await this.findFileIconThemeBySettingsId(this.settings.fileIconTheme); + const theme = await this.fileIconThemeRegistry.findThemeBySettingsId(this.settings.fileIconTheme); return this.setFileIconTheme(theme ? theme.id : DEFAULT_FILE_ICON_THEME_ID, undefined); }; @@ -265,7 +265,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (devThemes.length) { return this.setProductIconTheme(devThemes[0].id, ConfigurationTarget.MEMORY); } - const theme = await this.findProductIconThemeBySettingsId(this.settings.productIconTheme); + const theme = await this.productIconThemeRegistry.findThemeBySettingsId(this.settings.productIconTheme); return this.setProductIconTheme(theme ? theme.id : DEFAULT_PRODUCT_ICON_THEME_ID, undefined); }; @@ -514,7 +514,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.currentFileIconTheme; } - const newThemeData = (await this.findFileIconThemeById(iconTheme)) || FileIconThemeData.noIconTheme(); + const newThemeData = (await this.fileIconThemeRegistry.findThemeById(iconTheme)) || FileIconThemeData.noIconTheme; await newThemeData.ensureLoaded(this.fileService); _applyRules(newThemeData.styleSheetContent!, fileIconThemeRulesClassName); @@ -529,14 +529,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return newThemeData; } - private async findFileIconThemeById(id: string): Promise { - return id.length === 0 ? FileIconThemeData.noIconTheme() : this.fileIconThemeRegistry.findThemeById(id); - } - - private async findFileIconThemeBySettingsId(settingsId: string | null): Promise { - return !settingsId ? FileIconThemeData.noIconTheme() : this.fileIconThemeRegistry.findThemeBySettingsId(settingsId); - } - private async reloadCurrentFileIconTheme() { await this.currentFileIconTheme.reload(this.fileService); _applyRules(this.currentFileIconTheme.styleSheetContent!, fileIconThemeRulesClassName); @@ -545,7 +537,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { public async restoreFileIconTheme(): Promise { const settingId = this.settings.fileIconTheme; - const theme = await this.findFileIconThemeBySettingsId(settingId); + const theme = await this.fileIconThemeRegistry.findThemeBySettingsId(settingId); if (theme) { if (settingId !== this.currentFileIconTheme.settingsId) { await this.setFileIconTheme(theme.id, undefined); @@ -588,7 +580,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.currentProductIconTheme; } - const newThemeData = await this.findProductIconThemeById(iconTheme) || ProductIconThemeData.defaultTheme(); + const newThemeData = await this.productIconThemeRegistry.findThemeById(iconTheme) || ProductIconThemeData.defaultTheme; await newThemeData.ensureLoaded(this.fileService); _applyRules(newThemeData.styleSheetContent!, fileIconThemeRulesClassName); @@ -603,14 +595,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return newThemeData; } - private async findProductIconThemeById(id: string): Promise { - return id.length === 0 ? ProductIconThemeData.defaultTheme() : this.productIconThemeRegistry.findThemeById(id); - } - - private async findProductIconThemeBySettingsId(settingsId: string | null): Promise { - return !settingsId ? ProductIconThemeData.defaultTheme() : this.productIconThemeRegistry.findThemeBySettingsId(settingsId); - } - private async reloadCurrentProductIconTheme() { await this.currentProductIconTheme.reload(this.fileService); _applyRules(this.currentProductIconTheme.styleSheetContent!, productIconThemeRulesClassName); @@ -619,7 +603,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { public async restoreProductIconTheme(): Promise { const settingId = this.settings.productIconTheme; - const theme = await this.findProductIconThemeBySettingsId(settingId); + const theme = await this.productIconThemeRegistry.findThemeBySettingsId(settingId); if (theme) { if (settingId !== this.currentProductIconTheme.settingsId) { await this.setProductIconTheme(theme.id, undefined); diff --git a/src/vs/workbench/services/themes/common/themeExtensionPoints.ts b/src/vs/workbench/services/themes/common/themeExtensionPoints.ts index 026b48b2547..2d01c6b95ea 100644 --- a/src/vs/workbench/services/themes/common/themeExtensionPoints.ts +++ b/src/vs/workbench/services/themes/common/themeExtensionPoints.ts @@ -126,7 +126,8 @@ export class ThemeRegistry { @IExtensionService private readonly extensionService: IExtensionService, private readonly themesExtPoint: IExtensionPoint, private create: (theme: IThemeExtensionPoint, themeLocation: URI, extensionData: ExtensionData) => T, - private idRequired = false + private idRequired = false, + private builtInTheme: T | undefined = undefined ) { this.extensionThemes = []; this.initialize(); @@ -198,34 +199,38 @@ export class ThemeRegistry { }); } - public findThemeById(themeId: string, defaultId?: string): Promise { - return this.getThemes().then(allThemes => { - let defaultTheme: T | undefined = undefined; - for (let t of allThemes) { - if (t.id === themeId) { - return t; - } - if (t.id === defaultId) { - defaultTheme = t; - } + public async findThemeById(themeId: string, defaultId?: string): Promise { + if (this.builtInTheme && this.builtInTheme.id === themeId) { + return this.builtInTheme; + } + const allThemes = await this.getThemes(); + let defaultTheme: T | undefined = undefined; + for (let t of allThemes) { + if (t.id === themeId) { + return t; } - return defaultTheme; - }); + if (t.id === defaultId) { + defaultTheme = t; + } + } + return defaultTheme; } - public findThemeBySettingsId(settingsId: string | null, defaultId?: string): Promise { - return this.getThemes().then(allThemes => { - let defaultTheme: T | undefined = undefined; - for (let t of allThemes) { - if (t.settingsId === settingsId) { - return t; - } - if (t.id === defaultId) { - defaultTheme = t; - } + public async findThemeBySettingsId(settingsId: string | null, defaultId?: string): Promise { + if (this.builtInTheme && this.builtInTheme.settingsId === settingsId) { + return this.builtInTheme; + } + const allThemes = await this.getThemes(); + let defaultTheme: T | undefined = undefined; + for (let t of allThemes) { + if (t.settingsId === settingsId) { + return t; } - return defaultTheme; - }); + if (t.id === defaultId) { + defaultTheme = t; + } + } + return defaultTheme; } public findThemeByExtensionLocation(extLocation: URI | undefined): Promise { From 7631ea7d250363ecd4a2558bb9a2fe0281568e3b Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 6 Mar 2020 16:28:35 +0100 Subject: [PATCH 034/137] fix unused type --- .../workbench/services/themes/browser/workbenchThemeService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index e9ee725d3c7..c9a8b794e6c 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -29,7 +29,7 @@ import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; import { ThemeRegistry, registerColorThemeExtensionPoint, registerFileIconThemeExtensionPoint, registerProductIconThemeExtensionPoint } from 'vs/workbench/services/themes/common/themeExtensionPoints'; -import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationSchemas, ThemeConfiguration, updateProductIconThemeConfigurationSchemas, DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE } from 'vs/workbench/services/themes/common/themeConfiguration'; +import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationSchemas, ThemeConfiguration, updateProductIconThemeConfigurationSchemas } from 'vs/workbench/services/themes/common/themeConfiguration'; import { ProductIconThemeData, DEFAULT_PRODUCT_ICON_THEME_ID } from 'vs/workbench/services/themes/browser/productIconThemeData'; import { registerProductIconThemeSchemas } from 'vs/workbench/services/themes/common/productIconThemeSchema'; From 785eb0872a97f18775ca294fe2a4e4e35fc6a10e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 6 Mar 2020 15:49:08 +0100 Subject: [PATCH 035/137] jsonValidation takes an array for fileMatch --- .../client/src/jsonMain.ts | 47 ++++++++++--------- .../server/src/jsonServerMain.ts | 25 ++++++---- .../platform/extensions/common/extensions.ts | 2 +- .../common/jsonValidationExtensionPoint.ts | 16 ++++--- .../extensions/browser/extensionEditor.ts | 2 +- 5 files changed, 54 insertions(+), 38 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts index 7b307332241..5d41458931c 100644 --- a/extensions/json-language-features/client/src/jsonMain.ts +++ b/extensions/json-language-features/client/src/jsonMain.ts @@ -40,8 +40,13 @@ export interface ISchemaAssociations { [pattern: string]: string[]; } +export interface ISchemaAssociation { + fileMatch: string[]; + uri: string; +} + namespace SchemaAssociationNotification { - export const type: NotificationType = new NotificationType('json/schemaAssociations'); + export const type: NotificationType = new NotificationType('json/schemaAssociations'); } namespace ResultLimitReachedNotification { @@ -264,10 +269,10 @@ export function activate(context: ExtensionContext) { toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand)); - client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context)); + client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); extensions.onDidChange(_ => { - client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context)); + client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); }); // manually register / deregister format provider based on the `html.format.enable` setting avoiding issues with late registration. See #71652. @@ -324,8 +329,8 @@ export function deactivate(): Promise { return telemetryReporter ? telemetryReporter.dispose() : Promise.resolve(null); } -function getSchemaAssociation(_context: ExtensionContext): ISchemaAssociations { - const associations: ISchemaAssociations = {}; +function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] { + const associations: ISchemaAssociation[] = []; extensions.all.forEach(extension => { const packageJSON = extension.packageJSON; if (packageJSON && packageJSON.contributes && packageJSON.contributes.jsonValidation) { @@ -333,23 +338,21 @@ function getSchemaAssociation(_context: ExtensionContext): ISchemaAssociations { if (Array.isArray(jsonValidation)) { jsonValidation.forEach(jv => { let { fileMatch, url } = jv; - if (fileMatch && url) { - if (url[0] === '.' && url[1] === '/') { - url = Uri.file(path.join(extension.extensionPath, url)).toString(); - } - if (fileMatch[0] === '%') { - fileMatch = fileMatch.replace(/%APP_SETTINGS_HOME%/, '/User'); - fileMatch = fileMatch.replace(/%MACHINE_SETTINGS_HOME%/, '/Machine'); - fileMatch = fileMatch.replace(/%APP_WORKSPACES_HOME%/, '/Workspaces'); - } else if (fileMatch.charAt(0) !== '/' && !fileMatch.match(/\w+:\/\//)) { - fileMatch = '/' + fileMatch; - } - let association = associations[fileMatch]; - if (!association) { - association = []; - associations[fileMatch] = association; - } - association.push(url); + if (typeof fileMatch === 'string') { + fileMatch = [fileMatch]; + } + if (Array.isArray(fileMatch) && url) { + fileMatch = fileMatch.map(fm => { + if (fm[0] === '%') { + fm = fm.replace(/%APP_SETTINGS_HOME%/, '/User'); + fm = fm.replace(/%MACHINE_SETTINGS_HOME%/, '/Machine'); + fm = fm.replace(/%APP_WORKSPACES_HOME%/, '/Workspaces'); + } else if (!fm.match(/^(\w+:\/\/|\/|!)/)) { + fm = '/' + fm; + } + return fm; + }); + associations.push({ fileMatch, uri: url }); } }); } diff --git a/extensions/json-language-features/server/src/jsonServerMain.ts b/extensions/json-language-features/server/src/jsonServerMain.ts index 182eef7e9ee..e339620d1e1 100644 --- a/extensions/json-language-features/server/src/jsonServerMain.ts +++ b/extensions/json-language-features/server/src/jsonServerMain.ts @@ -23,8 +23,13 @@ interface ISchemaAssociations { [pattern: string]: string[]; } +interface ISchemaAssociation { + fileMatch: string[]; + uri: string; +} + namespace SchemaAssociationNotification { - export const type: NotificationType = new NotificationType('json/schemaAssociations'); + export const type: NotificationType = new NotificationType('json/schemaAssociations'); } namespace VSCodeContentRequest { @@ -230,7 +235,7 @@ namespace LimitExceededWarnings { } let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined; -let schemaAssociations: ISchemaAssociations | undefined = undefined; +let schemaAssociations: ISchemaAssociations | ISchemaAssociation[] | undefined = undefined; let formatterRegistration: Thenable | null = null; // The settings have changed. Is send on server activation as well. @@ -291,12 +296,16 @@ function updateConfiguration() { schemas: new Array() }; if (schemaAssociations) { - for (const pattern in schemaAssociations) { - const association = schemaAssociations[pattern]; - if (Array.isArray(association)) { - association.forEach(uri => { - languageSettings.schemas.push({ uri, fileMatch: [pattern] }); - }); + if (Array.isArray(schemaAssociations)) { + Array.prototype.push.apply(languageSettings.schemas, schemaAssociations); + } else { + for (const pattern in schemaAssociations) { + const association = schemaAssociations[pattern]; + if (Array.isArray(association)) { + association.forEach(uri => { + languageSettings.schemas.push({ uri, fileMatch: [pattern] }); + }); + } } } } diff --git a/src/vs/platform/extensions/common/extensions.ts b/src/vs/platform/extensions/common/extensions.ts index 87d90b14746..ac6ec196a03 100644 --- a/src/vs/platform/extensions/common/extensions.ts +++ b/src/vs/platform/extensions/common/extensions.ts @@ -38,7 +38,7 @@ export interface IGrammar { } export interface IJSONValidation { - fileMatch: string; + fileMatch: string | string[]; url: string; } diff --git a/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts b/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts index c3f09c4cdb1..dd2ad38b467 100644 --- a/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts +++ b/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts @@ -7,9 +7,10 @@ import * as nls from 'vs/nls'; import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import * as strings from 'vs/base/common/strings'; import * as resources from 'vs/base/common/resources'; +import { isString } from 'vs/base/common/types'; interface IJSONValidationExtensionPoint { - fileMatch: string; + fileMatch: string | string[]; url: string; } @@ -25,8 +26,11 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint { - if (typeof extension.fileMatch !== 'string') { - collector.error(nls.localize('invalid.fileMatch', "'configuration.jsonValidation.fileMatch' must be defined")); + if (!isString(extension.fileMatch) && !(Array.isArray(extension.fileMatch) && extension.fileMatch.every(isString))) { + collector.error(nls.localize('invalid.fileMatch', "'configuration.jsonValidation.fileMatch' must be defined as a string or an array of strings.")); return; } let uri = extension.url; - if (typeof extension.url !== 'string') { + if (!isString(uri)) { collector.error(nls.localize('invalid.url', "'configuration.jsonValidation.url' must be a URL or relative path")); return; } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 733bff5f29a..b68c1e206e8 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -1208,7 +1208,7 @@ export class ExtensionEditor extends BaseEditor { $('th', undefined, localize('schema', "Schema")) ), ...contrib.map(v => $('tr', undefined, - $('td', undefined, $('code', undefined, v.fileMatch)), + $('td', undefined, $('code', undefined, Array.isArray(v.fileMatch) ? v.fileMatch.join(', ') : v.fileMatch)), $('td', undefined, v.url) )))); From 765fa66e7801739efa3e9acd10c33a4ffc52350d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 16:34:12 +0100 Subject: [PATCH 036/137] use proper fs errors --- build/lib/i18n.resources.json | 4 ++++ .../services/log/common/keyValueLogProvider.ts | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index ae71fd3bf63..2da9d84eaa5 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -262,6 +262,10 @@ "name": "vs/workbench/services/files", "project": "vscode-workbench" }, + { + "name": "vs/workbench/services/log", + "project": "vscode-workbench" + }, { "name": "vs/workbench/services/integrity", "project": "vscode-workbench" diff --git a/src/vs/workbench/services/log/common/keyValueLogProvider.ts b/src/vs/workbench/services/log/common/keyValueLogProvider.ts index 9180d49303e..da0fdb3f167 100644 --- a/src/vs/workbench/services/log/common/keyValueLogProvider.ts +++ b/src/vs/workbench/services/log/common/keyValueLogProvider.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { IFileSystemProviderWithFileReadWriteCapability, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileDeleteOptions, FileWriteOptions, FileChangeType } from 'vs/platform/files/common/files'; +import { IFileSystemProviderWithFileReadWriteCapability, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileDeleteOptions, FileWriteOptions, FileChangeType, createFileSystemProviderError, FileSystemProviderErrorCode } from 'vs/platform/files/common/files'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { VSBuffer } from 'vs/base/common/buffer'; -import { FileSystemError } from 'vs/workbench/api/common/extHostTypes'; import { isEqualOrParent, joinPath, relativePath } from 'vs/base/common/resources'; import { values } from 'vs/base/common/map'; +import { localize } from 'vs/nls'; export abstract class KeyValueLogProvider extends Disposable implements IFileSystemProviderWithFileReadWriteCapability { @@ -53,13 +53,13 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys size: 0 }; } - return Promise.reject(FileSystemError.FileNotFound(resource)); + throw createFileSystemProviderError(localize('fileNotExists', "File does not exist"), FileSystemProviderErrorCode.FileNotFound); } async readdir(resource: URI): Promise<[string, FileType][]> { const hasKey = await this.hasKey(resource.path); if (hasKey) { - return Promise.reject(FileSystemError.FileNotADirectory(resource)); + throw createFileSystemProviderError(localize('fileNotDirectory', "File is not a directory"), FileSystemProviderErrorCode.FileNotADirectory); } const keys = await this.getAllKeys(); const files: Map = new Map(); @@ -79,7 +79,7 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys async readFile(resource: URI): Promise { const hasKey = await this.hasKey(resource.path); if (!hasKey) { - return Promise.reject(FileSystemError.FileNotFound(resource)); + throw createFileSystemProviderError(localize('fileNotFound', "File not found"), FileSystemProviderErrorCode.FileNotFound); } const value = await this.getValue(resource.path); return VSBuffer.fromString(value).buffer; @@ -90,7 +90,7 @@ export abstract class KeyValueLogProvider extends Disposable implements IFileSys if (!hasKey) { const files = await this.readdir(resource); if (files.length) { - return Promise.reject(FileSystemError.FileIsADirectory(resource)); + throw createFileSystemProviderError(localize('fileIsDirectory', "File is Directory"), FileSystemProviderErrorCode.FileIsADirectory); } } await this.setValue(resource.path, VSBuffer.wrap(content).toString()); From d8b4303f2954ce2e04f9b416b560128b448e3bca Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 17:23:22 +0100 Subject: [PATCH 037/137] Clean up disconnection dialog/notification code (fixes #82315) --- .../contrib/remote/browser/remote.ts | 216 ++++++++++-------- 1 file changed, 117 insertions(+), 99 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index 7d69b78bc83..9767a932bfa 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -584,26 +584,100 @@ Registry.as(WorkbenchActionExtensions.WorkbenchActions nls.localize('view', "View") ); +class VisibleProgress { -class ProgressReporter { - private _currentProgress: IProgress | null = null; - private lastReport: string | null = null; + private _isDisposed: boolean; + private _lastReport: string | null; + private _currentProgressPromiseResolve: (() => void) | null; + private _currentProgress: IProgress | null; + private _currentTimer: ReconnectionTimer2 | null; - constructor(currentProgress: IProgress | null) { - this._currentProgress = currentProgress; + public get lastReport(): string | null { + return this._lastReport; } - set currentProgress(progress: IProgress) { - this._currentProgress = progress; + constructor(progressService: IProgressService, location: ProgressLocation, initialReport: string | null, buttons: string[], onDidCancel: (choice: number | undefined, lastReport: string | null) => void) { + this._isDisposed = false; + this._lastReport = initialReport; + this._currentProgressPromiseResolve = null; + this._currentProgress = null; + this._currentTimer = null; + + const promise = new Promise((resolve) => this._currentProgressPromiseResolve = resolve); + + progressService.withProgress( + { location: location, buttons: buttons }, + (progress) => { if (!this._isDisposed) { this._currentProgress = progress; } return promise; }, + (choice) => onDidCancel(choice, this._lastReport) + ); + + if (this._lastReport) { + this.report(); + } } - report(message?: string) { + public dispose(): void { + this._isDisposed = true; + if (this._currentProgressPromiseResolve) { + this._currentProgressPromiseResolve(); + this._currentProgressPromiseResolve = null; + } + this._currentProgress = null; + if (this._currentTimer) { + this._currentTimer.dispose(); + this._currentTimer = null; + } + } + + public report(message?: string) { if (message) { - this.lastReport = message; + this._lastReport = message; } - if (this.lastReport && this._currentProgress) { - this._currentProgress.report({ message: this.lastReport }); + if (this._lastReport && this._currentProgress) { + this._currentProgress.report({ message: this._lastReport }); + } + } + + public startTimer(completionTime: number): void { + this.stopTimer(); + this._currentTimer = new ReconnectionTimer2(this, completionTime); + } + + public stopTimer(): void { + if (this._currentTimer) { + this._currentTimer.dispose(); + this._currentTimer = null; + } + } +} + +class ReconnectionTimer2 implements IDisposable { + private readonly _parent: VisibleProgress; + private readonly _completionTime: number; + private readonly _token: any; + + constructor(parent: VisibleProgress, completionTime: number) { + this._parent = parent; + this._completionTime = completionTime; + this._token = setInterval(() => this._render(), 1000); + this._render(); + } + + public dispose(): void { + clearInterval(this._token); + } + + private _render() { + const remainingTimeMs = this._completionTime - Date.now(); + if (remainingTimeMs < 0) { + return; + } + const remainingTime = Math.ceil(remainingTimeMs / 1000); + if (remainingTime === 1) { + this._parent.report(nls.localize('reconnectionWaitOne', "Attempting to reconnect in {0} second...", remainingTime)); + } else { + this._parent.report(nls.localize('reconnectionWaitMany', "Attempting to reconnect in {0} seconds...", remainingTime)); } } } @@ -618,58 +692,41 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { ) { const connection = remoteAgentService.getConnection(); if (connection) { - let currentProgressPromiseResolve: (() => void) | null = null; - let progressReporter: ProgressReporter | null = null; - let lastLocation: ProgressLocation | null = null; - let currentTimer: ReconnectionTimer | null = null; + let visibleProgress: VisibleProgress | null = null; + let lastLocation: ProgressLocation.Dialog | ProgressLocation.Notification | null = null; let reconnectWaitEvent: ReconnectionWaitEvent | null = null; let disposableListener: IDisposable | null = null; - function showProgress(location: ProgressLocation, buttons: { label: string, callback: () => void }[]) { - if (currentProgressPromiseResolve) { - currentProgressPromiseResolve(); + function showProgress(location: ProgressLocation.Dialog | ProgressLocation.Notification, buttons: { label: string, callback: () => void }[], initialReport: string | null = null): VisibleProgress { + if (visibleProgress) { + visibleProgress.dispose(); + visibleProgress = null; } - const promise = new Promise((resolve) => currentProgressPromiseResolve = resolve); lastLocation = location; - if (location === ProgressLocation.Dialog) { - // Show dialog - progressService!.withProgress( - { location: ProgressLocation.Dialog, buttons: buttons.map(button => button.label) }, - (progress) => { if (progressReporter) { progressReporter.currentProgress = progress; } return promise; }, - (choice?) => { - // Handle choice from dialog - if (typeof choice !== 'undefined' && buttons[choice]) { - buttons[choice].callback(); - } else { - showProgress(ProgressLocation.Notification, buttons); - } - - progressReporter!.report(); - }); - } else { - // Show notification - progressService!.withProgress( - { location: ProgressLocation.Notification, buttons: buttons.map(button => button.label) }, - (progress) => { if (progressReporter) { progressReporter.currentProgress = progress; } return promise; }, - (choice?) => { - // Handle choice from dialog - if (typeof choice !== 'undefined' && buttons[choice]) { - buttons[choice].callback(); + return new VisibleProgress( + progressService, location, initialReport, buttons.map(button => button.label), + (choice, lastReport) => { + // Handle choice from dialog + if (typeof choice !== 'undefined' && buttons[choice]) { + buttons[choice].callback(); + } else { + if (location === ProgressLocation.Dialog) { + visibleProgress = showProgress(ProgressLocation.Notification, buttons, lastReport); } else { hideProgress(); } - }); - } + } + } + ); } function hideProgress() { - if (currentProgressPromiseResolve) { - currentProgressPromiseResolve(); + if (visibleProgress) { + visibleProgress.dispose(); + visibleProgress = null; } - - currentProgressPromiseResolve = null; } const reconnectButton = { @@ -689,9 +746,8 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { }; connection.onDidStateChange((e) => { - if (currentTimer) { - currentTimer.dispose(); - currentTimer = null; + if (visibleProgress) { + visibleProgress.stopTimer(); } if (disposableListener) { @@ -700,33 +756,27 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { } switch (e.type) { case PersistentConnectionEventType.ConnectionLost: - if (!currentProgressPromiseResolve) { - progressReporter = new ProgressReporter(null); - showProgress(ProgressLocation.Dialog, [reconnectButton, reloadButton]); + if (!visibleProgress) { + visibleProgress = showProgress(ProgressLocation.Dialog, [reconnectButton, reloadButton]); } - - progressReporter!.report(nls.localize('connectionLost', "Connection Lost")); + visibleProgress.report(nls.localize('connectionLost', "Connection Lost")); break; case PersistentConnectionEventType.ReconnectionWait: - hideProgress(); reconnectWaitEvent = e; - showProgress(lastLocation || ProgressLocation.Notification, [reconnectButton, reloadButton]); - currentTimer = new ReconnectionTimer(progressReporter!, Date.now() + 1000 * e.durationSeconds); + visibleProgress = showProgress(lastLocation || ProgressLocation.Notification, [reconnectButton, reloadButton]); + visibleProgress.startTimer(Date.now() + 1000 * e.durationSeconds); break; case PersistentConnectionEventType.ReconnectionRunning: - hideProgress(); - showProgress(lastLocation || ProgressLocation.Notification, [reloadButton]); - progressReporter!.report(nls.localize('reconnectionRunning', "Attempting to reconnect...")); + visibleProgress = showProgress(lastLocation || ProgressLocation.Notification, [reloadButton]); + visibleProgress.report(nls.localize('reconnectionRunning', "Attempting to reconnect...")); // Register to listen for quick input is opened disposableListener = contextKeyService.onDidChangeContext((contextKeyChangeEvent) => { const reconnectInteraction = new Set(['inQuickOpen']); if (contextKeyChangeEvent.affectsSome(reconnectInteraction)) { // Need to move from dialog if being shown and user needs to type in a prompt - if (lastLocation === ProgressLocation.Dialog && progressReporter !== null) { - hideProgress(); - showProgress(ProgressLocation.Notification, [reloadButton]); - progressReporter.report(); + if (lastLocation === ProgressLocation.Dialog && visibleProgress !== null) { + visibleProgress = showProgress(ProgressLocation.Notification, [reloadButton], visibleProgress.lastReport); } } }); @@ -734,7 +784,6 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { break; case PersistentConnectionEventType.ReconnectionPermanentFailure: hideProgress(); - progressReporter = null; dialogService.show(Severity.Error, nls.localize('reconnectionPermanentFailure', "Cannot reconnect. Please reload the window."), [nls.localize('reloadWindow', "Reload Window"), nls.localize('cancel', "Cancel")], { cancelId: 1 }).then(result => { // Reload the window @@ -745,7 +794,6 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { break; case PersistentConnectionEventType.ConnectionGain: hideProgress(); - progressReporter = null; break; } }); @@ -753,35 +801,5 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { } } -class ReconnectionTimer implements IDisposable { - private readonly _progressReporter: ProgressReporter; - private readonly _completionTime: number; - private readonly _token: any; - - constructor(progressReporter: ProgressReporter, completionTime: number) { - this._progressReporter = progressReporter; - this._completionTime = completionTime; - this._token = setInterval(() => this._render(), 1000); - this._render(); - } - - public dispose(): void { - clearInterval(this._token); - } - - private _render() { - const remainingTimeMs = this._completionTime - Date.now(); - if (remainingTimeMs < 0) { - return; - } - const remainingTime = Math.ceil(remainingTimeMs / 1000); - if (remainingTime === 1) { - this._progressReporter.report(nls.localize('reconnectionWaitOne', "Attempting to reconnect in {0} second...", remainingTime)); - } else { - this._progressReporter.report(nls.localize('reconnectionWaitMany', "Attempting to reconnect in {0} seconds...", remainingTime)); - } - } -} - const workbenchContributionsRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteAgentConnectionStatusListener, LifecyclePhase.Eventually); From ef26b31ab9a8863acd3c3ae281d096aa2d919a09 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 6 Mar 2020 17:30:43 +0100 Subject: [PATCH 038/137] Add warning for using horizontalScrolling setting #92151 --- src/vs/platform/list/browser/listService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 0f084e82add..58a9d5e09ee 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -1153,7 +1153,7 @@ configurationRegistry.registerConfiguration({ [horizontalScrollingKey]: { 'type': 'boolean', 'default': false, - 'description': localize('horizontalScrolling setting', "Controls whether lists and trees support horizontal scrolling in the workbench.") + 'description': localize('horizontalScrolling setting', "Controls whether lists and trees support horizontal scrolling in the workbench. Warning: turning on this setting has a performance implication.") }, 'workbench.tree.horizontalScrolling': { 'type': 'boolean', From 99cc1f22c6203cef3a6b4293c48f36e2b5a1bc01 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Fri, 6 Mar 2020 17:39:20 +0100 Subject: [PATCH 039/137] node-debug@1.44.2; fixes #75932 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 9d176d98076..63c41b403da 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.44.1", + "version": "1.44.2", "repo": "https://github.com/Microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", From c7a2ac36148f8416fd66bda160ae0ae7297fa9ed Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 5 Mar 2020 03:41:57 +0100 Subject: [PATCH 040/137] FIrst cut - sync history view --- .../common/abstractSynchronizer.ts | 23 ++- .../userDataSync/common/keybindingsSync.ts | 5 + .../userDataSync/common/settingsSync.ts | 9 + .../userDataSync/common/userDataSync.ts | 2 + .../userDataSync/common/userDataSyncIpc.ts | 2 + .../common/userDataSyncService.ts | 10 +- .../browser/userDataSync.contribution.ts | 2 + .../userDataSync/browser/userDataSync.ts | 11 +- .../browser/userDataSyncHistory.ts | 159 ++++++++++++++++++ .../electron-browser/settingsSyncService.ts | 4 + .../electron-browser/userDataSyncService.ts | 6 +- 11 files changed, 225 insertions(+), 8 deletions(-) create mode 100644 src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts diff --git a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts index 938f0bc8ac9..cb3e1dc35e1 100644 --- a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts +++ b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts @@ -18,6 +18,7 @@ import { FormattingOptions } from 'vs/base/common/jsonFormatter'; import { IStringDictionary } from 'vs/base/common/collections'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { isString } from 'vs/base/common/types'; type SyncSourceClassification = { source?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; @@ -157,6 +158,11 @@ export abstract class AbstractSynchroniser extends Disposable { return syncData ? syncData.content : null; } + async resolveContent(ref: string): Promise { + const { syncData } = await this.getRemoteUserData(ref); + return syncData ? syncData.content : null; + } + async resetLocal(): Promise { try { await this.fileService.del(this.lastSyncResource); @@ -189,9 +195,20 @@ export abstract class AbstractSynchroniser extends Disposable { await this.fileService.writeFile(this.lastSyncResource, VSBuffer.fromString(JSON.stringify(lastSyncUserData))); } - protected async getRemoteUserData(lastSyncData: IRemoteUserData | null): Promise { - const lastSyncUserData: IUserData | null = lastSyncData ? { ref: lastSyncData.ref, content: lastSyncData.syncData ? JSON.stringify(lastSyncData.syncData) : null } : null; - const { ref, content } = await this.userDataSyncStoreService.read(this.resourceKey, lastSyncUserData, this.source); + protected async getRemoteUserData(ref: string): Promise + protected async getRemoteUserData(lastSyncData: IRemoteUserData | null): Promise + protected async getRemoteUserData(arg: string | IRemoteUserData | null): Promise { + let ref: string; + let content: string | null = null; + if (isString(arg)) { + ref = arg; + content = await this.userDataSyncStoreService.resolveContent(this.resourceKey, ref); + } else { + const lastSyncUserData: IUserData | null = arg ? { ref: arg.ref, content: arg.syncData ? JSON.stringify(arg.syncData) : null } : null; + const userData = await this.userDataSyncStoreService.read(this.resourceKey, lastSyncUserData, this.source); + ref = userData.ref; + content = userData.content; + } let syncData: ISyncData | null = null; if (content !== null) { try { diff --git a/src/vs/platform/userDataSync/common/keybindingsSync.ts b/src/vs/platform/userDataSync/common/keybindingsSync.ts index 773be441b2f..5726f7d1b35 100644 --- a/src/vs/platform/userDataSync/common/keybindingsSync.ts +++ b/src/vs/platform/userDataSync/common/keybindingsSync.ts @@ -161,6 +161,11 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem return content !== null ? this.getKeybindingsContentFromSyncContent(content) : null; } + async resolveContent(ref: string): Promise { + let content = await super.resolveContent(ref); + return content !== null ? this.getKeybindingsContentFromSyncContent(content) : null; + } + protected async performSync(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null): Promise { try { const result = await this.getPreview(remoteUserData, lastSyncUserData); diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index fa85bc9a3ac..edeac6292ff 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -202,6 +202,15 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement return content; } + async resolveContent(ref: string): Promise { + let content = await super.resolveContent(ref); + if (content !== null) { + const settingsSyncContent = this.parseSettingsSyncContent(content); + content = settingsSyncContent ? settingsSyncContent.settings : null; + } + return content; + } + async accept(content: string): Promise { if (this.status === SyncStatus.HasConflicts) { const preview = await this.syncPreviewResultPromise!; diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index f45f10187df..7094cd20651 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -255,6 +255,7 @@ export interface IUserDataSynchroniser { resetLocal(): Promise; getRemoteContent(preivew?: boolean): Promise; + resolveContent(ref: string): Promise; accept(content: string): Promise; } @@ -300,6 +301,7 @@ export interface IUserDataSyncService { isFirstTimeSyncWithMerge(): Promise; getRemoteContent(source: SyncSource, preview: boolean): Promise; + resolveContent(resource: ResourceKey, ref: string): Promise; accept(source: SyncSource, content: string): Promise; } diff --git a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts index 1c346ac1360..678056671cf 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts @@ -35,6 +35,7 @@ export class UserDataSyncChannel implements IServerChannel { case 'reset': return this.service.reset(); case 'resetLocal': return this.service.resetLocal(); case 'getRemoteContent': return this.service.getRemoteContent(args[0], args[1]); + case 'resolveContent': return this.service.resolveContent(args[0], args[1]); case 'isFirstTimeSyncWithMerge': return this.service.isFirstTimeSyncWithMerge(); } throw new Error('Invalid call'); @@ -68,6 +69,7 @@ export class SettingsSyncChannel implements IServerChannel { case 'hasLocalData': return this.service.hasLocalData(); case 'resolveSettingsConflicts': return this.service.resolveSettingsConflicts(args[0]); case 'getRemoteContent': return this.service.getRemoteContent(args[0]); + case 'resolveContent': return this.service.resolveContent(args[0]); } throw new Error('Invalid call'); } diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index f88cce3588c..da8cb31aa1b 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IUserDataSyncService, SyncStatus, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataSynchroniser, UserDataSyncStoreError, UserDataSyncErrorCode, UserDataSyncError } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncService, SyncStatus, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataSynchroniser, UserDataSyncStoreError, UserDataSyncErrorCode, UserDataSyncError, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; import { Disposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Emitter, Event } from 'vs/base/common/event'; @@ -186,6 +186,14 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ return null; } + async resolveContent(resourceKey: ResourceKey, ref: string): Promise { + const synchronizer = this.synchronisers.filter(s => s.resourceKey === resourceKey)[0]; + if (synchronizer) { + return synchronizer.resolveContent(ref); + } + return null; + } + async isFirstTimeSyncWithMerge(): Promise { await this.checkEnablement(); if (!await this.userDataSyncStoreService.manifest()) { diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts index 367dd0b6fb3..fe0fe425437 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts @@ -7,6 +7,8 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { UserDataSyncWorkbenchContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSync'; +import { UserDataSyncHistoryViewContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncHistory'; const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(UserDataSyncWorkbenchContribution, LifecyclePhase.Ready); +workbenchRegistry.registerWorkbenchContribution(UserDataSyncHistoryViewContribution, LifecyclePhase.Ready); diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 05c609878ac..0fd29982702 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -9,7 +9,7 @@ import { canceled, isPromiseCanceledError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, dispose, MutableDisposable, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; -import { isEqual } from 'vs/base/common/resources'; +import { isEqual, dirname, basename } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import type { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; @@ -1059,9 +1059,14 @@ class UserDataRemoteContentProvider implements ITextModelContentProvider { let promise: Promise | undefined; if (isEqual(uri, toRemoteContentResource(SyncSource.Settings))) { promise = this.userDataSyncService.getRemoteContent(SyncSource.Settings, true); - } - if (isEqual(uri, toRemoteContentResource(SyncSource.Keybindings))) { + } else if (isEqual(uri, toRemoteContentResource(SyncSource.Keybindings))) { promise = this.userDataSyncService.getRemoteContent(SyncSource.Keybindings, true); + } else { + const resourceKey: ResourceKey = basename(dirname(uri)) as ResourceKey; + const ref = basename(uri); + if (resourceKey && ref) { + promise = this.userDataSyncService.resolveContent(resourceKey, ref); + } } if (promise) { return promise.then(content => this.modelService.createModel(content || '', this.modeService.create('jsonc'), uri)); diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts new file mode 100644 index 00000000000..85cdf5bfbe5 --- /dev/null +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -0,0 +1,159 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IViewsRegistry, Extensions, ITreeViewDescriptor, ITreeViewDataProvider, ITreeItem, TreeItemCollapsibleState, IViewsService, TreeViewItemHandleArg } from 'vs/workbench/common/views'; +import { localize } from 'vs/nls'; +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { CustomTreeViewPane, CustomTreeView } from 'vs/workbench/browser/parts/views/customView'; +import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, USER_DATA_SYNC_SCHEME, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; +import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; +import { IContextKeyService, RawContextKey, ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; +import { URI } from 'vs/base/common/uri'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { FolderThemeIcon, FileThemeIcon } from 'vs/platform/theme/common/themeService'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; + +const CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW = new RawContextKey('showUserDataSyncHistoryView', false); + +export class UserDataSyncHistoryViewContribution implements IWorkbenchContribution { + + private readonly viewId = 'workbench.views.syncHistory'; + + constructor( + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + ) { + this.registerView(); + this.registerActions(); + } + + private registerView(): void { + const that = this; + const name = localize('title', "Sync History"); + const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW.bindTo(this.contextKeyService); + const treeView = this.instantiationService.createInstance(CustomTreeView, this.viewId, name); + const viewsRegistry = Registry.as(Extensions.ViewsRegistry); + viewsRegistry.registerViews([{ + id: this.viewId, + name, + ctorDescriptor: new SyncDescriptor(CustomTreeViewPane), + when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW), + canToggleVisibility: false, + canMoveView: true, + treeView, + collapsed: false, + order: 100, + }], VIEW_CONTAINER); + + registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.actions.showSyncHistory', + title: { value: localize('workbench.action.showRemoteUserDatraView', "Show Sync History"), original: `Show Sync History` }, + category: { value: localize('sync', "Sync"), original: `Sync` }, + menu: { + id: MenuId.CommandPalette, + when: CONTEXT_SYNC_ENABLEMENT + }, + }); + } + async run(accessor: ServicesAccessor): Promise { + const instantiationService = accessor.get(IInstantiationService); + const viewsService = accessor.get(IViewsService); + if (!treeView.dataProvider) { + treeView.dataProvider = instantiationService.createInstance(UserDataSyncHistoryViewDataProvider); + } + viewEnablementContext.set(true); + viewsService.openView(that.viewId, true); + } + }); + } + + private registerActions() { + const that = this; + registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.actions.openRef', + title: localize('workbench.action.openRef', "Open Ref"), + }); + } + async run(accessor: ServicesAccessor, resource: URI): Promise { + const editorService = accessor.get(IEditorService); + await editorService.openEditor({ resource }); + } + }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.actions.deleteRef', + title: localize('workbench.action.deleteRef', "Delete"), + menu: { + id: MenuId.ViewItemContext, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /sync-.*/i)) + }, + }); + } + async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise { + const dialogService = accessor.get(IDialogService); + const userDataSyncStoreService = accessor.get(IUserDataSyncStoreService); + const result = await dialogService.confirm({ + message: 'Would you like to delete' + }); + if (result) { + return userDataSyncStoreService.delete(handle.$treeItemHandle as ResourceKey); + } + } + }); + } + +} + +class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { + + constructor( + @IUserDataSyncStoreService private readonly userDataSyncStoreService: IUserDataSyncStoreService, + ) { + } + + async getChildren(element?: ITreeItem): Promise { + if (element) { + return this.getResources(element.handle); + } + return ALL_RESOURCE_KEYS.map(resourceKey => ({ + handle: resourceKey, + collapsibleState: TreeItemCollapsibleState.Collapsed, + label: { label: resourceKey }, + themeIcon: FolderThemeIcon, + contextValue: `sync-${resourceKey}` + })); + } + + private async getResources(handle: string): Promise { + const resourceKey = ALL_RESOURCE_KEYS.filter(key => key === handle)[0]; + if (resourceKey) { + const refs = await this.userDataSyncStoreService.getAllRefs(resourceKey); + return refs.map(ref => { + const resourceUri = URI.from({ scheme: USER_DATA_SYNC_SCHEME, path: `${resourceKey}/${ref}` }); + return { + handle: `${resourceKey}/${ref}`, + collapsibleState: TreeItemCollapsibleState.None, + label: { label: ref }, + resourceUri, + command: { id: 'workbench.actions.openRef', title: '', arguments: [resourceUri] }, + themeIcon: FileThemeIcon, + contextValue: `syncref-${resourceKey}` + }; + }); + } + return []; + } + +} + diff --git a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts index c02286f7208..b35d77dcde4 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts @@ -88,6 +88,10 @@ export class SettingsSyncService extends Disposable implements ISettingsSyncServ return this.channel.call('getRemoteContent', [!!preview]); } + resolveContent(ref: string): Promise { + return this.channel.call('resolveContent', [ref]); + } + private async updateStatus(status: SyncStatus): Promise { this._status = status; this._onDidChangeStatus.fire(status); diff --git a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts index b3ec8ffeb95..8199966d278 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SyncStatus, SyncSource, IUserDataSyncService, UserDataSyncError } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncStatus, SyncSource, IUserDataSyncService, UserDataSyncError, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { Disposable } from 'vs/base/common/lifecycle'; import { Emitter, Event } from 'vs/base/common/event'; @@ -92,6 +92,10 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ return this.channel.call('getRemoteContent', [source, preview]); } + resolveContent(key: ResourceKey, ref: string): Promise { + return this.channel.call('resolveContent', [key, ref]); + } + isFirstTimeSyncWithMerge(): Promise { return this.channel.call('isFirstTimeSyncWithMerge'); } From 46c98a9d77c2508721504d40500d42f293115976 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 5 Mar 2020 10:18:45 +0100 Subject: [PATCH 041/137] set data provide on tree visibility --- .../userDataSync/browser/userDataSyncHistory.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index 85cdf5bfbe5..de4edb494e2 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -38,6 +38,12 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi const name = localize('title', "Sync History"); const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(CustomTreeView, this.viewId, name); + const disposable = treeView.onDidChangeVisibility(visible => { + if (visible && !treeView.dataProvider) { + disposable.dispose(); + treeView.dataProvider = this.instantiationService.createInstance(UserDataSyncHistoryViewDataProvider); + } + }); const viewsRegistry = Registry.as(Extensions.ViewsRegistry); viewsRegistry.registerViews([{ id: this.viewId, @@ -64,13 +70,8 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi }); } async run(accessor: ServicesAccessor): Promise { - const instantiationService = accessor.get(IInstantiationService); - const viewsService = accessor.get(IViewsService); - if (!treeView.dataProvider) { - treeView.dataProvider = instantiationService.createInstance(UserDataSyncHistoryViewDataProvider); - } viewEnablementContext.set(true); - viewsService.openView(that.viewId, true); + accessor.get(IViewsService).openView(that.viewId, true); } }); } From acc91e10d0277cf7996ff6a814297fc95b9b3a23 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 5 Mar 2020 10:37:24 +0100 Subject: [PATCH 042/137] separate tree view and custom view --- .../api/browser/viewsExtensionPoint.ts | 4 +- .../views/{customView.ts => treeView.ts} | 86 ++++++++++++------- .../browser/userDataSyncHistory.ts | 6 +- 3 files changed, 60 insertions(+), 36 deletions(-) rename src/vs/workbench/browser/parts/views/{customView.ts => treeView.ts} (94%) diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 67e90081285..8375e443d49 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -9,7 +9,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import * as resources from 'vs/base/common/resources'; import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { ViewContainer, IViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID, IViewDescriptor, ViewContainerLocation } from 'vs/workbench/common/views'; -import { CustomTreeViewPane, CustomTreeView } from 'vs/workbench/browser/parts/views/customView'; +import { TreeViewPane, CustomTreeView } from 'vs/workbench/browser/parts/views/treeView'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { coalesce, } from 'vs/base/common/arrays'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -396,7 +396,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { const viewDescriptor = { id: item.id, name: item.name, - ctorDescriptor: new SyncDescriptor(CustomTreeViewPane), + ctorDescriptor: new SyncDescriptor(TreeViewPane), when: ContextKeyExpr.deserialize(item.when), canToggleVisibility: true, canMoveView: true, diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/treeView.ts similarity index 94% rename from src/vs/workbench/browser/parts/views/customView.ts rename to src/vs/workbench/browser/parts/views/treeView.ts index e538874807c..f991c36243f 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -44,7 +44,7 @@ import { SIDE_BAR_BACKGROUND, PANEL_BACKGROUND } from 'vs/workbench/common/theme import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -export class CustomTreeViewPane extends ViewPane { +export class TreeViewPane extends ViewPane { private treeView: ITreeView; @@ -79,7 +79,7 @@ export class CustomTreeViewPane extends ViewPane { renderBody(container: HTMLElement): void { super.renderBody(container); - if (this.treeView instanceof CustomTreeView) { + if (this.treeView instanceof TreeView) { this.treeView.show(container); } } @@ -119,12 +119,11 @@ class Root implements ITreeItem { const noDataProviderMessage = localize('no-dataprovider', "There is no data provider registered that can provide view data."); -class CustomTree extends WorkbenchAsyncDataTree { } +class Tree extends WorkbenchAsyncDataTree { } -export class CustomTreeView extends Disposable implements ITreeView { +export class TreeView extends Disposable implements ITreeView { private isVisible: boolean = false; - private activated: boolean = false; private _hasIconForParentNode = false; private _hasIconForLeafNode = false; private _showCollapseAllAction = false; @@ -135,7 +134,7 @@ export class CustomTreeView extends Disposable implements ITreeView { private _messageValue: string | undefined; private _canSelectMany: boolean = false; private messageElement!: HTMLDivElement; - private tree: CustomTree | undefined; + private tree: Tree | undefined; private treeLabels: ResourceLabels | undefined; private root: ITreeItem; @@ -165,14 +164,13 @@ export class CustomTreeView extends Disposable implements ITreeView { private readonly _onDidCompleteRefresh: Emitter = this._register(new Emitter()); constructor( - private id: string, + protected readonly id: string, private _title: string, - @IExtensionService private readonly extensionService: IExtensionService, @IThemeService private readonly themeService: IThemeService, @IInstantiationService private readonly instantiationService: IInstantiationService, @ICommandService private readonly commandService: ICommandService, @IConfigurationService private readonly configurationService: IConfigurationService, - @IProgressService private readonly progressService: IProgressService, + @IProgressService protected readonly progressService: IProgressService, @IContextMenuService private readonly contextMenuService: IContextMenuService, @IKeybindingService private readonly keybindingService: IKeybindingService, @INotificationService private readonly notificationService: INotificationService, @@ -305,9 +303,6 @@ export class CustomTreeView extends Disposable implements ITreeView { } this.isVisible = isVisible; - if (this.isVisible) { - this.activate(); - } if (this.tree) { if (this.isVisible) { @@ -365,9 +360,9 @@ export class CustomTreeView extends Disposable implements ITreeView { const aligner = new Aligner(this.themeService); const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, treeMenus, this.treeLabels, actionViewItemProvider, aligner); - this.tree = this._register(this.instantiationService.createInstance(CustomTree, 'CustomView', this.treeContainer, new CustomTreeDelegate(), [renderer], + this.tree = this._register(this.instantiationService.createInstance(Tree, this.id, this.treeContainer, new TreeViewDelegate(), [renderer], dataSource, { - identityProvider: new CustomViewIdentityProvider(), + identityProvider: new TreeViewIdentityProvider(), accessibilityProvider: { getAriaLabel(element: ITreeItem): string { return element.tooltip ? element.tooltip : element.label ? element.label.label : ''; @@ -409,9 +404,9 @@ export class CustomTreeView extends Disposable implements ITreeView { })); this.tree.setInput(this.root).then(() => this.updateContentAreas()); - const customTreeNavigator = ResourceNavigator.createTreeResourceNavigator(this.tree, { openOnFocus: false, openOnSelection: false }); - this._register(customTreeNavigator); - this._register(customTreeNavigator.onDidOpenResource(e => { + const treeNavigator = ResourceNavigator.createTreeResourceNavigator(this.tree, { openOnFocus: false, openOnSelection: false }); + this._register(treeNavigator); + this._register(treeNavigator.onDidOpenResource(e => { if (!e.browserEvent) { return; } @@ -462,7 +457,7 @@ export class CustomTreeView extends Disposable implements ITreeView { }); } - private updateMessage(): void { + protected updateMessage(): void { if (this._message) { this.showMessage(this._message); } else if (!this.dataProvider) { @@ -579,17 +574,6 @@ export class CustomTreeView extends Disposable implements ITreeView { return Promise.resolve(); } - private activate() { - if (!this.activated) { - this.progressService.withProgress({ location: this.viewContainer.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`)) - .then(() => timeout(2000)) - .then(() => { - this.updateMessage(); - }); - this.activated = true; - } - } - private refreshing: boolean = false; private async doRefresh(elements: ITreeItem[]): Promise { const tree = this.tree; @@ -618,13 +602,13 @@ export class CustomTreeView extends Disposable implements ITreeView { } } -class CustomViewIdentityProvider implements IIdentityProvider { +class TreeViewIdentityProvider implements IIdentityProvider { getId(element: ITreeItem): { toString(): string; } { return element.handle; } } -class CustomTreeDelegate implements IListVirtualDelegate { +class TreeViewDelegate implements IListVirtualDelegate { getHeight(element: ITreeItem): number { return TreeRenderer.ITEM_HEIGHT; @@ -943,3 +927,43 @@ class TreeMenus extends Disposable implements IDisposable { return result; } } + +export class CustomTreeView extends TreeView { + + private activated: boolean = false; + + constructor( + id: string, + title: string, + @IThemeService themeService: IThemeService, + @IInstantiationService instantiationService: IInstantiationService, + @ICommandService commandService: ICommandService, + @IConfigurationService configurationService: IConfigurationService, + @IProgressService progressService: IProgressService, + @IContextMenuService contextMenuService: IContextMenuService, + @IKeybindingService keybindingService: IKeybindingService, + @INotificationService notificationService: INotificationService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService, + @IExtensionService private readonly extensionService: IExtensionService, + ) { + super(id, title, themeService, instantiationService, commandService, configurationService, progressService, contextMenuService, keybindingService, notificationService, viewDescriptorService); + } + + setVisibility(isVisible: boolean): void { + super.setVisibility(isVisible); + if (this.visible) { + this.activate(); + } + } + + private activate() { + if (!this.activated) { + this.progressService.withProgress({ location: this.viewContainer.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`)) + .then(() => timeout(2000)) + .then(() => { + this.updateMessage(); + }); + this.activated = true; + } + } +} diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index de4edb494e2..f72aa2e5c1f 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -8,7 +8,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IViewsRegistry, Extensions, ITreeViewDescriptor, ITreeViewDataProvider, ITreeItem, TreeItemCollapsibleState, IViewsService, TreeViewItemHandleArg } from 'vs/workbench/common/views'; import { localize } from 'vs/nls'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; -import { CustomTreeViewPane, CustomTreeView } from 'vs/workbench/browser/parts/views/customView'; +import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, USER_DATA_SYNC_SCHEME, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; @@ -37,7 +37,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi const that = this; const name = localize('title', "Sync History"); const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW.bindTo(this.contextKeyService); - const treeView = this.instantiationService.createInstance(CustomTreeView, this.viewId, name); + const treeView = this.instantiationService.createInstance(TreeView, this.viewId, name); const disposable = treeView.onDidChangeVisibility(visible => { if (visible && !treeView.dataProvider) { disposable.dispose(); @@ -48,7 +48,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi viewsRegistry.registerViews([{ id: this.viewId, name, - ctorDescriptor: new SyncDescriptor(CustomTreeViewPane), + ctorDescriptor: new SyncDescriptor(TreeViewPane), when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW), canToggleVisibility: false, canMoveView: true, From ecf67444f8d9592924e8a9b012803406ff53a2cb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 5 Mar 2020 16:12:35 +0100 Subject: [PATCH 043/137] separate getting remote content and preview content --- .../common/abstractSynchronizer.ts | 51 +++++++++---------- .../userDataSync/common/extensionsSync.ts | 4 -- .../userDataSync/common/globalStateSync.ts | 4 -- .../userDataSync/common/keybindingsSync.ts | 9 +--- .../userDataSync/common/settingsSync.ts | 15 ++---- .../userDataSync/common/userDataSync.ts | 44 ++++++++++++---- .../userDataSync/common/userDataSyncIpc.ts | 5 +- .../common/userDataSyncService.ts | 25 ++++----- .../userDataSync/browser/userDataSync.ts | 30 ++++------- .../browser/userDataSyncHistory.ts | 5 +- .../electron-browser/settingsSyncService.ts | 8 +-- .../electron-browser/userDataSyncService.ts | 11 ++-- 12 files changed, 95 insertions(+), 116 deletions(-) diff --git a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts index cb3e1dc35e1..54e3ef5bf78 100644 --- a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts +++ b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts @@ -152,15 +152,14 @@ export abstract class AbstractSynchroniser extends Disposable { return !!lastSyncData; } - async getRemoteContent(): Promise { - const lastSyncData = await this.getLastSyncUserData(); - const { syncData } = await this.getRemoteUserData(lastSyncData); - return syncData ? syncData.content : null; + async getRemoteContentFromPreview(): Promise { + return null; } - async resolveContent(ref: string): Promise { - const { syncData } = await this.getRemoteUserData(ref); - return syncData ? syncData.content : null; + async getRemoteContent(ref?: string): Promise { + const refOrLastSyncUserData: string | IRemoteUserData | null = ref || await this.getLastSyncUserData(); + const { content } = await this.getUserData(refOrLastSyncUserData); + return content; } async resetLocal(): Promise { @@ -195,20 +194,8 @@ export abstract class AbstractSynchroniser extends Disposable { await this.fileService.writeFile(this.lastSyncResource, VSBuffer.fromString(JSON.stringify(lastSyncUserData))); } - protected async getRemoteUserData(ref: string): Promise - protected async getRemoteUserData(lastSyncData: IRemoteUserData | null): Promise - protected async getRemoteUserData(arg: string | IRemoteUserData | null): Promise { - let ref: string; - let content: string | null = null; - if (isString(arg)) { - ref = arg; - content = await this.userDataSyncStoreService.resolveContent(this.resourceKey, ref); - } else { - const lastSyncUserData: IUserData | null = arg ? { ref: arg.ref, content: arg.syncData ? JSON.stringify(arg.syncData) : null } : null; - const userData = await this.userDataSyncStoreService.read(this.resourceKey, lastSyncUserData, this.source); - ref = userData.ref; - content = userData.content; - } + protected async getRemoteUserData(lastSyncData: IRemoteUserData | null): Promise { + const { ref, content } = await this.getUserData(lastSyncData); let syncData: ISyncData | null = null; if (content !== null) { try { @@ -226,6 +213,16 @@ export abstract class AbstractSynchroniser extends Disposable { return { ref, syncData }; } + private async getUserData(refOrLastSyncData: string | IRemoteUserData | null): Promise { + if (isString(refOrLastSyncData)) { + const content = await this.userDataSyncStoreService.resolveContent(this.resourceKey, refOrLastSyncData); + return { ref: refOrLastSyncData, content }; + } else { + const lastSyncUserData: IUserData | null = refOrLastSyncData ? { ref: refOrLastSyncData.ref, content: refOrLastSyncData.syncData ? JSON.stringify(refOrLastSyncData.syncData) : null } : null; + return this.userDataSyncStoreService.read(this.resourceKey, lastSyncUserData, this.source); + } + } + protected async updateRemoteUserData(content: string, ref: string | null): Promise { const syncData: ISyncData = { version: this.version, content }; ref = await this.userDataSyncStoreService.write(this.resourceKey, JSON.stringify(syncData), ref, this.source); @@ -282,14 +279,12 @@ export abstract class AbstractFileSynchroniser extends AbstractSynchroniser { this.setStatus(SyncStatus.Idle); } - async getRemoteContent(preview?: boolean): Promise { - if (preview) { - if (this.syncPreviewResultPromise) { - const result = await this.syncPreviewResultPromise; - return result.remoteUserData && result.remoteUserData.syncData ? result.remoteUserData.syncData.content : null; - } + async getRemoteContentFromPreview(): Promise { + if (this.syncPreviewResultPromise) { + const result = await this.syncPreviewResultPromise; + return result.remoteUserData && result.remoteUserData.syncData ? result.remoteUserData.syncData.content : null; } - return super.getRemoteContent(); + return null; } protected async getLocalFileContent(): Promise { diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index d953a8c7d93..2a3d640c6e0 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -136,10 +136,6 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse return false; } - async getRemoteContent(): Promise { - return null; - } - protected async performSync(remoteUserData: IRemoteUserData, lastSyncUserData: ILastSyncUserData | null): Promise { const previewResult = await this.getPreview(remoteUserData, lastSyncUserData); await this.apply(previewResult); diff --git a/src/vs/platform/userDataSync/common/globalStateSync.ts b/src/vs/platform/userDataSync/common/globalStateSync.ts index cef7d798ab5..01a8d964fc8 100644 --- a/src/vs/platform/userDataSync/common/globalStateSync.ts +++ b/src/vs/platform/userDataSync/common/globalStateSync.ts @@ -120,10 +120,6 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs return false; } - async getRemoteContent(): Promise { - return null; - } - protected async performSync(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null): Promise { const result = await this.getPreview(remoteUserData, lastSyncUserData); await this.apply(result); diff --git a/src/vs/platform/userDataSync/common/keybindingsSync.ts b/src/vs/platform/userDataSync/common/keybindingsSync.ts index 5726f7d1b35..d6bd759c239 100644 --- a/src/vs/platform/userDataSync/common/keybindingsSync.ts +++ b/src/vs/platform/userDataSync/common/keybindingsSync.ts @@ -156,13 +156,8 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem return false; } - async getRemoteContent(preview?: boolean): Promise { - const content = await super.getRemoteContent(preview); - return content !== null ? this.getKeybindingsContentFromSyncContent(content) : null; - } - - async resolveContent(ref: string): Promise { - let content = await super.resolveContent(ref); + async getRemoteContentFromPreview(): Promise { + const content = await super.getRemoteContentFromPreview(); return content !== null ? this.getKeybindingsContentFromSyncContent(content) : null; } diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index edeac6292ff..c1876d666f1 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -187,13 +187,13 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement return false; } - async getRemoteContent(preview?: boolean): Promise { - let content = await super.getRemoteContent(preview); + async getRemoteContentFromPreview(): Promise { + let content = await super.getRemoteContentFromPreview(); if (content !== null) { const settingsSyncContent = this.parseSettingsSyncContent(content); content = settingsSyncContent ? settingsSyncContent.settings : null; } - if (preview && content !== null) { + if (content !== null) { const formatUtils = await this.getFormattingOptions(); // remove ignored settings from the remote content for preview const ignoredSettings = await this.getIgnoredSettings(); @@ -202,15 +202,6 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement return content; } - async resolveContent(ref: string): Promise { - let content = await super.resolveContent(ref); - if (content !== null) { - const settingsSyncContent = this.parseSettingsSyncContent(content); - content = settingsSyncContent ? settingsSyncContent.settings : null; - } - return content; - } - async accept(content: string): Promise { if (this.status === SyncStatus.HasConflicts) { const preview = await this.syncPreviewResultPromise!; diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 7094cd20651..30c25f16104 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -18,7 +18,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IStringDictionary } from 'vs/base/common/collections'; import { FormattingOptions } from 'vs/base/common/jsonFormatter'; import { URI } from 'vs/base/common/uri'; -import { isEqual, joinPath } from 'vs/base/common/resources'; +import { isEqual, joinPath, dirname, basename } from 'vs/base/common/resources'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IProductService } from 'vs/platform/product/common/productService'; import { distinct } from 'vs/base/common/arrays'; @@ -254,8 +254,8 @@ export interface IUserDataSynchroniser { hasLocalData(): Promise; resetLocal(): Promise; - getRemoteContent(preivew?: boolean): Promise; - resolveContent(ref: string): Promise; + getRemoteContentFromPreview(): Promise; + getRemoteContent(ref?: string): Promise; accept(content: string): Promise; } @@ -300,8 +300,7 @@ export interface IUserDataSyncService { resetLocal(): Promise; isFirstTimeSyncWithMerge(): Promise; - getRemoteContent(source: SyncSource, preview: boolean): Promise; - resolveContent(resource: ResourceKey, ref: string): Promise; + resolveContent(resource: URI): Promise; accept(source: SyncSource, content: string): Promise; } @@ -343,12 +342,23 @@ export const CONTEXT_SYNC_STATE = new RawContextKey('syncStatus', SyncSt export const CONTEXT_SYNC_ENABLEMENT = new RawContextKey('syncEnabled', false); export const USER_DATA_SYNC_SCHEME = 'vscode-userdata-sync'; -export function toRemoteContentResource(source: SyncSource): URI { - return URI.from({ scheme: USER_DATA_SYNC_SCHEME, path: `${source}/remoteContent` }); +export const PREVIEW_QUERY = 'preview=true'; +export function toSyncResourceFromSource(source: SyncSource, ref?: string): URI { + return toSyncResource(getResourceKey(source), ref); } -export function getSyncSourceFromRemoteContentResource(uri: URI): SyncSource | undefined { - return [SyncSource.Settings, SyncSource.Keybindings, SyncSource.Extensions, SyncSource.GlobalState].filter(source => isEqual(uri, toRemoteContentResource(source)))[0]; +export function toSyncResource(resourceKey: ResourceKey, ref?: string): URI { + return URI.from({ scheme: USER_DATA_SYNC_SCHEME, path: `${resourceKey}/${ref ? ref : 'latest'}` }); } + +export function resolveSyncResource(resource: URI): { resourceKey: ResourceKey, ref?: string, query?: string } | null { + const resourceKey: ResourceKey = basename(dirname(resource)) as ResourceKey; + const ref = basename(resource); + if (resourceKey && ref) { + return { resourceKey, ref: ref !== 'latest' ? ref : undefined, query: resource.query }; + } + return null; +} + export function getSyncSourceFromPreviewResource(uri: URI, environmentService: IEnvironmentService): SyncSource | undefined { if (isEqual(uri, environmentService.settingsSyncPreviewResource)) { return SyncSource.Settings; @@ -358,3 +368,19 @@ export function getSyncSourceFromPreviewResource(uri: URI, environmentService: I } return undefined; } +export function getResourceKey(source: SyncSource): ResourceKey { + switch (source) { + case SyncSource.Settings: return 'settings'; + case SyncSource.Keybindings: return 'keybindings'; + case SyncSource.Extensions: return 'extensions'; + case SyncSource.GlobalState: return 'globalState'; + } +} +export function getSyncSource(resourceKey: ResourceKey): SyncSource { + switch (resourceKey) { + case 'settings': return SyncSource.Settings; + case 'keybindings': return SyncSource.Keybindings; + case 'extensions': return SyncSource.Extensions; + case 'globalState': return SyncSource.GlobalState; + } +} diff --git a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts index 678056671cf..2f25ff6ae66 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts @@ -34,8 +34,7 @@ export class UserDataSyncChannel implements IServerChannel { case 'stop': this.service.stop(); return Promise.resolve(); case 'reset': return this.service.reset(); case 'resetLocal': return this.service.resetLocal(); - case 'getRemoteContent': return this.service.getRemoteContent(args[0], args[1]); - case 'resolveContent': return this.service.resolveContent(args[0], args[1]); + case 'resolveContent': return this.service.resolveContent(URI.revive(args[0])); case 'isFirstTimeSyncWithMerge': return this.service.isFirstTimeSyncWithMerge(); } throw new Error('Invalid call'); @@ -68,8 +67,8 @@ export class SettingsSyncChannel implements IServerChannel { case 'hasPreviouslySynced': return this.service.hasPreviouslySynced(); case 'hasLocalData': return this.service.hasLocalData(); case 'resolveSettingsConflicts': return this.service.resolveSettingsConflicts(args[0]); + case 'getRemoteContentFromPreview': return this.service.getRemoteContentFromPreview(); case 'getRemoteContent': return this.service.getRemoteContent(args[0]); - case 'resolveContent': return this.service.resolveContent(args[0]); } throw new Error('Invalid call'); } diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index da8cb31aa1b..0928911e167 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IUserDataSyncService, SyncStatus, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataSynchroniser, UserDataSyncStoreError, UserDataSyncErrorCode, UserDataSyncError, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncService, SyncStatus, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataSynchroniser, UserDataSyncStoreError, UserDataSyncErrorCode, UserDataSyncError, resolveSyncResource, PREVIEW_QUERY } from 'vs/platform/userDataSync/common/userDataSync'; import { Disposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Emitter, Event } from 'vs/base/common/event'; @@ -15,6 +15,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { equals } from 'vs/base/common/arrays'; import { localize } from 'vs/nls'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { URI } from 'vs/base/common/uri'; type SyncErrorClassification = { source: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; @@ -176,24 +177,20 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ await synchroniser.accept(content); } - async getRemoteContent(source: SyncSource, preview: boolean): Promise { - await this.checkEnablement(); - for (const synchroniser of this.synchronisers) { - if (synchroniser.source === source) { - return synchroniser.getRemoteContent(preview); + async resolveContent(resource: URI): Promise { + const result = resolveSyncResource(resource); + if (result) { + const synchronizer = this.synchronisers.filter(s => s.resourceKey === result.resourceKey)[0]; + if (synchronizer) { + if (PREVIEW_QUERY === result.query) { + return synchronizer.getRemoteContentFromPreview(); + } + return synchronizer.getRemoteContent(result.ref); } } return null; } - async resolveContent(resourceKey: ResourceKey, ref: string): Promise { - const synchronizer = this.synchronisers.filter(s => s.resourceKey === resourceKey)[0]; - if (synchronizer) { - return synchronizer.resolveContent(ref); - } - return null; - } - async isFirstTimeSyncWithMerge(): Promise { await this.checkEnablement(); if (!await this.userDataSyncStoreService.manifest()) { diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 0fd29982702..e24b4fcfbf1 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -9,7 +9,7 @@ import { canceled, isPromiseCanceledError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, dispose, MutableDisposable, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; -import { isEqual, dirname, basename } from 'vs/base/common/resources'; +import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import type { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; @@ -30,7 +30,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { CONTEXT_SYNC_STATE, getSyncSourceFromRemoteContentResource, getUserDataSyncStore, ISyncConfiguration, IUserDataAutoSyncService, IUserDataSyncService, IUserDataSyncStore, registerConfiguration, SyncSource, SyncStatus, toRemoteContentResource, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncEnablementService, ResourceKey, getSyncSourceFromPreviewResource, CONTEXT_SYNC_ENABLEMENT } from 'vs/platform/userDataSync/common/userDataSync'; +import { CONTEXT_SYNC_STATE, getUserDataSyncStore, ISyncConfiguration, IUserDataAutoSyncService, IUserDataSyncService, IUserDataSyncStore, registerConfiguration, SyncSource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncEnablementService, ResourceKey, getSyncSourceFromPreviewResource, CONTEXT_SYNC_ENABLEMENT, toSyncResourceFromSource, PREVIEW_QUERY, resolveSyncResource, getSyncSource } from 'vs/platform/userDataSync/common/userDataSync'; import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets'; import { GLOBAL_ACTIVITY_ID } from 'vs/workbench/common/activity'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -354,7 +354,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo private async acceptRemote(syncSource: SyncSource) { try { - const contents = await this.userDataSyncService.getRemoteContent(syncSource, false); + const contents = await this.userDataSyncService.resolveContent(toSyncResourceFromSource(syncSource).with({ query: PREVIEW_QUERY })); if (contents) { await this.userDataSyncService.accept(syncSource, contents); } @@ -754,7 +754,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo label = localize('keybindings conflicts preview', "Keybindings Conflicts (Remote ↔ Local)"); } if (previewResource) { - const remoteContentResource = toRemoteContentResource(source); + const remoteContentResource = toSyncResourceFromSource(source).with({ query: PREVIEW_QUERY }); await this.editorService.openEditor({ leftResource: remoteContentResource, rightResource: previewResource, @@ -1056,20 +1056,8 @@ class UserDataRemoteContentProvider implements ITextModelContentProvider { } provideTextContent(uri: URI): Promise | null { - let promise: Promise | undefined; - if (isEqual(uri, toRemoteContentResource(SyncSource.Settings))) { - promise = this.userDataSyncService.getRemoteContent(SyncSource.Settings, true); - } else if (isEqual(uri, toRemoteContentResource(SyncSource.Keybindings))) { - promise = this.userDataSyncService.getRemoteContent(SyncSource.Keybindings, true); - } else { - const resourceKey: ResourceKey = basename(dirname(uri)) as ResourceKey; - const ref = basename(uri); - if (resourceKey && ref) { - promise = this.userDataSyncService.resolveContent(resourceKey, ref); - } - } - if (promise) { - return promise.then(content => this.modelService.createModel(content || '', this.modeService.create('jsonc'), uri)); + if (uri.scheme === USER_DATA_SYNC_SCHEME) { + return this.userDataSyncService.resolveContent(uri).then(content => this.modelService.createModel(content || '', this.modeService.create('jsonc'), uri)); } return null; } @@ -1125,7 +1113,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio return true; } - if (getSyncSourceFromRemoteContentResource(model.uri) !== undefined) { + if (resolveSyncResource(model.uri)?.query === PREVIEW_QUERY) { return this.configurationService.getValue('diffEditor.renderSideBySide'); } @@ -1135,14 +1123,14 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio private createAcceptChangesWidgetRenderer(): void { if (!this.acceptChangesButton) { - const isRemote = getSyncSourceFromRemoteContentResource(this.editor.getModel()!.uri) !== undefined; + const isRemote = resolveSyncResource(this.editor.getModel()!.uri) !== null; const acceptRemoteLabel = localize('accept remote', "Accept Remote"); const acceptLocalLabel = localize('accept local', "Accept Local"); this.acceptChangesButton = this.instantiationService.createInstance(FloatingClickWidget, this.editor, isRemote ? acceptRemoteLabel : acceptLocalLabel, null); this._register(this.acceptChangesButton.onClick(async () => { const model = this.editor.getModel(); if (model) { - const conflictsSource = (getSyncSourceFromPreviewResource(model.uri, this.environmentService) || getSyncSourceFromRemoteContentResource(model.uri))!; + const conflictsSource = (getSyncSourceFromPreviewResource(model.uri, this.environmentService) || getSyncSource(resolveSyncResource(model.uri)!.resourceKey))!; this.telemetryService.publicLog2<{ source: string, action: string }, SyncConflictsClassification>('sync/handleConflicts', { source: conflictsSource, action: isRemote ? 'acceptRemote' : 'acceptLocal' }); const syncAreaLabel = getSyncAreaLabel(conflictsSource); const result = await this.dialogService.confirm({ diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index f72aa2e5c1f..1be5e2cced4 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -11,7 +11,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, USER_DATA_SYNC_SCHEME, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; +import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, ResourceKey, toSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; import { IContextKeyService, RawContextKey, ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; import { URI } from 'vs/base/common/uri'; @@ -141,12 +141,11 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { if (resourceKey) { const refs = await this.userDataSyncStoreService.getAllRefs(resourceKey); return refs.map(ref => { - const resourceUri = URI.from({ scheme: USER_DATA_SYNC_SCHEME, path: `${resourceKey}/${ref}` }); + const resourceUri = toSyncResource(resourceKey, ref); return { handle: `${resourceKey}/${ref}`, collapsibleState: TreeItemCollapsibleState.None, label: { label: ref }, - resourceUri, command: { id: 'workbench.actions.openRef', title: '', arguments: [resourceUri] }, themeIcon: FileThemeIcon, contextValue: `syncref-${resourceKey}` diff --git a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts index b35d77dcde4..429517bea3e 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts @@ -84,12 +84,12 @@ export class SettingsSyncService extends Disposable implements ISettingsSyncServ return this.channel.call('resolveConflicts', [conflicts]); } - getRemoteContent(preview?: boolean): Promise { - return this.channel.call('getRemoteContent', [!!preview]); + getRemoteContent(ref?: string): Promise { + return this.channel.call('getRemoteContent', [ref]); } - resolveContent(ref: string): Promise { - return this.channel.call('resolveContent', [ref]); + getRemoteContentFromPreview(): Promise { + return this.channel.call('getRemoteContentFromPreview', []); } private async updateStatus(status: SyncStatus): Promise { diff --git a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts index 8199966d278..686866cfc79 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts @@ -3,13 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SyncStatus, SyncSource, IUserDataSyncService, UserDataSyncError, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncStatus, SyncSource, IUserDataSyncService, UserDataSyncError } from 'vs/platform/userDataSync/common/userDataSync'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { Disposable } from 'vs/base/common/lifecycle'; import { Emitter, Event } from 'vs/base/common/event'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { URI } from 'vs/base/common/uri'; export class UserDataSyncService extends Disposable implements IUserDataSyncService { @@ -88,12 +89,8 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ return this.channel.call('stop'); } - getRemoteContent(source: SyncSource, preview: boolean): Promise { - return this.channel.call('getRemoteContent', [source, preview]); - } - - resolveContent(key: ResourceKey, ref: string): Promise { - return this.channel.call('resolveContent', [key, ref]); + resolveContent(resource: URI): Promise { + return this.channel.call('resolveContent', [resource]); } isFirstTimeSyncWithMerge(): Promise { From d23e8a3c7d61abdd3c3851880644c1b8ebd1ddf7 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 5 Mar 2020 17:52:50 +0100 Subject: [PATCH 044/137] compare with local action --- .../common/abstractSynchronizer.ts | 28 ++++++++----- .../userDataSync/common/keybindingsSync.ts | 15 +++++++ .../userDataSync/common/settingsSync.ts | 18 +++++++++ .../userDataSync/common/userDataSync.ts | 6 +-- .../userDataSync/common/userDataSyncIpc.ts | 2 +- .../common/userDataSyncService.ts | 4 +- .../userDataSync/browser/userDataSync.ts | 2 +- .../browser/userDataSyncHistory.ts | 40 +++++++++++++------ .../electron-browser/settingsSyncService.ts | 4 +- 9 files changed, 87 insertions(+), 32 deletions(-) diff --git a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts index 54e3ef5bf78..5d8e7648c1d 100644 --- a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts +++ b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts @@ -198,21 +198,27 @@ export abstract class AbstractSynchroniser extends Disposable { const { ref, content } = await this.getUserData(lastSyncData); let syncData: ISyncData | null = null; if (content !== null) { - try { - syncData = JSON.parse(content); - - // Migration from old content to sync data - if (!isSyncData(syncData)) { - syncData = { version: this.version, content }; - } - - } catch (e) { - this.logService.error(e); - } + syncData = this.parseSyncData(content); } return { ref, syncData }; } + protected parseSyncData(content: string): ISyncData | null { + let syncData: ISyncData | null = null; + try { + syncData = JSON.parse(content); + + // Migration from old content to sync data + if (!isSyncData(syncData)) { + syncData = { version: this.version, content }; + } + + } catch (e) { + this.logService.error(e); + } + return syncData; + } + private async getUserData(refOrLastSyncData: string | IRemoteUserData | null): Promise { if (isString(refOrLastSyncData)) { const content = await this.userDataSyncStoreService.resolveContent(this.resourceKey, refOrLastSyncData); diff --git a/src/vs/platform/userDataSync/common/keybindingsSync.ts b/src/vs/platform/userDataSync/common/keybindingsSync.ts index d6bd759c239..33f5eb92dd7 100644 --- a/src/vs/platform/userDataSync/common/keybindingsSync.ts +++ b/src/vs/platform/userDataSync/common/keybindingsSync.ts @@ -161,6 +161,21 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem return content !== null ? this.getKeybindingsContentFromSyncContent(content) : null; } + async getRemoteContent(ref?: string, fragment?: string): Promise { + const content = await super.getRemoteContent(ref); + if (content !== null && fragment) { + const syncData = this.parseSyncData(content); + if (syncData) { + switch (fragment) { + case 'keybindings': + return this.getKeybindingsContentFromSyncContent(syncData.content); + } + } + return null; + } + return content; + } + protected async performSync(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null): Promise { try { const result = await this.getPreview(remoteUserData, lastSyncUserData); diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index c1876d666f1..79d0b2494e8 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -202,6 +202,24 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement return content; } + async getRemoteContent(ref?: string, fragment?: string): Promise { + let content = await super.getRemoteContent(ref); + if (content !== null && fragment) { + const syncData = this.parseSyncData(content); + if (syncData) { + const settingsSyncContent = this.parseSettingsSyncContent(syncData.content); + if (settingsSyncContent) { + switch (fragment) { + case 'settings': + return settingsSyncContent.settings; + } + } + } + return null; + } + return content; + } + async accept(content: string): Promise { if (this.status === SyncStatus.HasConflicts) { const preview = await this.syncPreviewResultPromise!; diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 30c25f16104..e85515b3984 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -255,7 +255,7 @@ export interface IUserDataSynchroniser { resetLocal(): Promise; getRemoteContentFromPreview(): Promise; - getRemoteContent(ref?: string): Promise; + getRemoteContent(ref?: string, fragment?: string): Promise; accept(content: string): Promise; } @@ -350,11 +350,11 @@ export function toSyncResource(resourceKey: ResourceKey, ref?: string): URI { return URI.from({ scheme: USER_DATA_SYNC_SCHEME, path: `${resourceKey}/${ref ? ref : 'latest'}` }); } -export function resolveSyncResource(resource: URI): { resourceKey: ResourceKey, ref?: string, query?: string } | null { +export function resolveSyncResource(resource: URI): { resourceKey: ResourceKey, ref?: string } | null { const resourceKey: ResourceKey = basename(dirname(resource)) as ResourceKey; const ref = basename(resource); if (resourceKey && ref) { - return { resourceKey, ref: ref !== 'latest' ? ref : undefined, query: resource.query }; + return { resourceKey, ref: ref !== 'latest' ? ref : undefined }; } return null; } diff --git a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts index 2f25ff6ae66..08e0a4c9aa3 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts @@ -68,7 +68,7 @@ export class SettingsSyncChannel implements IServerChannel { case 'hasLocalData': return this.service.hasLocalData(); case 'resolveSettingsConflicts': return this.service.resolveSettingsConflicts(args[0]); case 'getRemoteContentFromPreview': return this.service.getRemoteContentFromPreview(); - case 'getRemoteContent': return this.service.getRemoteContent(args[0]); + case 'getRemoteContent': return this.service.getRemoteContent(args[0], args[1]); } throw new Error('Invalid call'); } diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index 0928911e167..90a7cf151f8 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -182,10 +182,10 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ if (result) { const synchronizer = this.synchronisers.filter(s => s.resourceKey === result.resourceKey)[0]; if (synchronizer) { - if (PREVIEW_QUERY === result.query) { + if (PREVIEW_QUERY === resource.query) { return synchronizer.getRemoteContentFromPreview(); } - return synchronizer.getRemoteContent(result.ref); + return synchronizer.getRemoteContent(result.ref, resource.fragment); } } return null; diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index e24b4fcfbf1..6dc2bf59441 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -1113,7 +1113,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio return true; } - if (resolveSyncResource(model.uri)?.query === PREVIEW_QUERY) { + if (resolveSyncResource(model.uri) !== null && model.uri.query === PREVIEW_QUERY) { return this.configurationService.getValue('diffEditor.renderSideBySide'); } diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index 1be5e2cced4..09519bc05fd 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -11,13 +11,13 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, ResourceKey, toSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; +import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, toSyncResource, resolveSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; import { IContextKeyService, RawContextKey, ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; import { URI } from 'vs/base/common/uri'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { FolderThemeIcon, FileThemeIcon } from 'vs/platform/theme/common/themeService'; -import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; const CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW = new RawContextKey('showUserDataSyncHistoryView', false); @@ -93,22 +93,38 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.deleteRef', - title: localize('workbench.action.deleteRef', "Delete"), + id: 'workbench.actions.commpareWithLocal', + title: localize('workbench.action.deleteRef', "Compare with Local"), menu: { id: MenuId.ViewItemContext, - when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /sync-.*/i)) + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /syncref-(settings|keybindings).*/i)) }, }); } async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise { - const dialogService = accessor.get(IDialogService); - const userDataSyncStoreService = accessor.get(IUserDataSyncStoreService); - const result = await dialogService.confirm({ - message: 'Would you like to delete' - }); + const editorService = accessor.get(IEditorService); + const environmentService = accessor.get(IEnvironmentService); + const resource = URI.parse(handle.$treeItemHandle); + const result = resolveSyncResource(resource); if (result) { - return userDataSyncStoreService.delete(handle.$treeItemHandle as ResourceKey); + let leftResource: URI; + let rightResource: URI; + if (result.resourceKey === 'settings') { + leftResource = resource.with({ fragment: 'settings' }); + rightResource = environmentService.settingsResource; + } else { + leftResource = resource.with({ fragment: 'keybindings' }); + rightResource = environmentService.keybindingsResource; + } + await editorService.openEditor({ + leftResource, + rightResource, + options: { + preserveFocus: false, + pinned: true, + revealIfVisible: true, + }, + }); } } }); @@ -143,7 +159,7 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { return refs.map(ref => { const resourceUri = toSyncResource(resourceKey, ref); return { - handle: `${resourceKey}/${ref}`, + handle: resourceUri.toString(), collapsibleState: TreeItemCollapsibleState.None, label: { label: ref }, command: { id: 'workbench.actions.openRef', title: '', arguments: [resourceUri] }, diff --git a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts index 429517bea3e..8fe78318d4c 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts @@ -84,8 +84,8 @@ export class SettingsSyncService extends Disposable implements ISettingsSyncServ return this.channel.call('resolveConflicts', [conflicts]); } - getRemoteContent(ref?: string): Promise { - return this.channel.call('getRemoteContent', [ref]); + getRemoteContent(ref?: string, fragment?: string): Promise { + return this.channel.call('getRemoteContent', [ref, fragment]); } getRemoteContentFromPreview(): Promise { From eeaaa17d8c154dd86e7d169c71d944c35e97bb95 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 5 Mar 2020 19:42:18 +0100 Subject: [PATCH 045/137] - show resolved content on click - action to show full content --- .../userDataSync/common/extensionsSync.ts | 15 ++++++ .../userDataSync/common/globalStateSync.ts | 15 ++++++ .../browser/userDataSyncHistory.ts | 46 ++++++++++++------- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index 2a3d640c6e0..4a108b0814e 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -120,6 +120,21 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse async stop(): Promise { } + async getRemoteContent(ref?: string, fragment?: string): Promise { + const content = await super.getRemoteContent(ref); + if (content !== null && fragment) { + const syncData = this.parseSyncData(content); + if (syncData) { + switch (fragment) { + case 'extensions': + return syncData.content; + } + } + return null; + } + return content; + } + accept(content: string): Promise { throw new Error('Extensions: Conflicts should not occur'); } diff --git a/src/vs/platform/userDataSync/common/globalStateSync.ts b/src/vs/platform/userDataSync/common/globalStateSync.ts index 01a8d964fc8..d125cd05e4e 100644 --- a/src/vs/platform/userDataSync/common/globalStateSync.ts +++ b/src/vs/platform/userDataSync/common/globalStateSync.ts @@ -104,6 +104,21 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs async stop(): Promise { } + async getRemoteContent(ref?: string, fragment?: string): Promise { + let content = await super.getRemoteContent(ref); + if (content !== null && fragment) { + const syncData = this.parseSyncData(content); + if (syncData) { + switch (fragment) { + case 'globalState': + return syncData.content; + } + } + return null; + } + return content; + } + accept(content: string): Promise { throw new Error('UI State: Conflicts should not occur'); } diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index 09519bc05fd..f130aa5809c 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -81,13 +81,34 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.openRef', - title: localize('workbench.action.openRef', "Open Ref"), + id: 'workbench.actions.sync.resolveResourceRef', + title: localize('workbench.actions.sync.resolveResourceRef', "Resolve Resource Ref"), }); } - async run(accessor: ServicesAccessor, resource: URI): Promise { + async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise { const editorService = accessor.get(IEditorService); - await editorService.openEditor({ resource }); + let resource = URI.parse(handle.$treeItemHandle); + const result = resolveSyncResource(resource); + if (result) { + resource = resource.with({ fragment: result.resourceKey }); + await editorService.openEditor({ resource }); + } + } + }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.actions.sync.resolveResourceRefCompletely', + title: localize('workbench.actions.sync.resolveResourceRefCompletely', "Show full content"), + menu: { + id: MenuId.ViewItemContext, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /syncref-.*/i)) + }, + }); + } + async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise { + const editorService = accessor.get(IEditorService); + await editorService.openEditor({ resource: URI.parse(handle.$treeItemHandle) }); } }); registerAction2(class extends Action2 { @@ -107,15 +128,8 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi const resource = URI.parse(handle.$treeItemHandle); const result = resolveSyncResource(resource); if (result) { - let leftResource: URI; - let rightResource: URI; - if (result.resourceKey === 'settings') { - leftResource = resource.with({ fragment: 'settings' }); - rightResource = environmentService.settingsResource; - } else { - leftResource = resource.with({ fragment: 'keybindings' }); - rightResource = environmentService.keybindingsResource; - } + const leftResource: URI = resource.with({ fragment: result.resourceKey }); + const rightResource: URI = result.resourceKey === 'settings' ? environmentService.settingsResource : environmentService.keybindingsResource; await editorService.openEditor({ leftResource, rightResource, @@ -157,12 +171,12 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { if (resourceKey) { const refs = await this.userDataSyncStoreService.getAllRefs(resourceKey); return refs.map(ref => { - const resourceUri = toSyncResource(resourceKey, ref); + const handle = toSyncResource(resourceKey, ref).toString(); return { - handle: resourceUri.toString(), + handle, collapsibleState: TreeItemCollapsibleState.None, label: { label: ref }, - command: { id: 'workbench.actions.openRef', title: '', arguments: [resourceUri] }, + command: { id: 'workbench.actions.sync.resolveResourceRef', title: '', arguments: [{ $treeItemHandle: handle, $treeViewId: '' }] }, themeIcon: FileThemeIcon, contextValue: `syncref-${resourceKey}` }; From a311d7bf188388f54571cfea2d882dd30c7573ff Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 09:30:26 +0100 Subject: [PATCH 046/137] show time of sync as label --- .../userDataSync/common/userDataSync.ts | 7 ++++++- .../common/userDataSyncStoreService.ts | 8 ++++---- .../browser/userDataSyncHistory.ts | 19 +++++++++++++++---- .../userDataSyncStoreService.ts | 4 ++-- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index e85515b3984..5e789abd52b 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -143,6 +143,11 @@ export interface IUserDataManifest { session: string; } +export interface IResourceRefHandle { + ref: string; + created: number; +} + export const IUserDataSyncStoreService = createDecorator('IUserDataSyncStoreService'); export interface IUserDataSyncStoreService { _serviceBrand: undefined; @@ -151,7 +156,7 @@ export interface IUserDataSyncStoreService { write(key: ResourceKey, content: string, ref: string | null, source?: SyncSource): Promise; manifest(): Promise; clear(): Promise; - getAllRefs(key: ResourceKey): Promise; + getAllRefs(key: ResourceKey): Promise; resolveContent(key: ResourceKey, ref: string): Promise; delete(key: ResourceKey): Promise; } diff --git a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts index 3057e9052a5..091170c7abc 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, } from 'vs/base/common/lifecycle'; -import { IUserData, IUserDataSyncStoreService, UserDataSyncErrorCode, IUserDataSyncStore, getUserDataSyncStore, SyncSource, UserDataSyncStoreError, IUserDataSyncLogService, IUserDataManifest, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserData, IUserDataSyncStoreService, UserDataSyncErrorCode, IUserDataSyncStore, getUserDataSyncStore, SyncSource, UserDataSyncStoreError, IUserDataSyncLogService, IUserDataManifest, ResourceKey, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync'; import { IRequestService, asText, isSuccess, asJson } from 'vs/platform/request/common/request'; import { joinPath, relativePath } from 'vs/base/common/resources'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -31,7 +31,7 @@ export class UserDataSyncStoreService extends Disposable implements IUserDataSyn this.userDataSyncStore = getUserDataSyncStore(productService, configurationService); } - async getAllRefs(key: ResourceKey): Promise { + async getAllRefs(key: ResourceKey): Promise { if (!this.userDataSyncStore) { throw new Error('No settings sync store url configured.'); } @@ -45,8 +45,8 @@ export class UserDataSyncStoreService extends Disposable implements IUserDataSyn throw new UserDataSyncStoreError('Server returned ' + context.res.statusCode, UserDataSyncErrorCode.Unknown, undefined); } - const resources: string[] = await asJson(context) || []; - return resources.map(resource => relativePath(uri, URI.parse(resource))!); + const result = await asJson<{ url: string, created: number }[]>(context) || []; + return result.map(({ url, created }) => ({ ref: relativePath(uri, URI.parse(url))!, created: created })); } async resolveContent(key: ResourceKey, ref: string): Promise { diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index f130aa5809c..c54ca8e290c 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -18,6 +18,8 @@ import { URI } from 'vs/base/common/uri'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { FolderThemeIcon, FileThemeIcon } from 'vs/platform/theme/common/themeService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { fromNow } from 'vs/base/common/date'; +import { pad } from 'vs/base/common/strings'; const CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW = new RawContextKey('showUserDataSyncHistoryView', false); @@ -115,7 +117,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi constructor() { super({ id: 'workbench.actions.commpareWithLocal', - title: localize('workbench.action.deleteRef', "Compare with Local"), + title: localize('workbench.action.deleteRef', "Open Changes"), menu: { id: MenuId.ViewItemContext, when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /syncref-(settings|keybindings).*/i)) @@ -169,13 +171,15 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { private async getResources(handle: string): Promise { const resourceKey = ALL_RESOURCE_KEYS.filter(key => key === handle)[0]; if (resourceKey) { - const refs = await this.userDataSyncStoreService.getAllRefs(resourceKey); - return refs.map(ref => { + const refHandles = await this.userDataSyncStoreService.getAllRefs(resourceKey); + return refHandles.map(({ ref, created }) => { const handle = toSyncResource(resourceKey, ref).toString(); return { handle, collapsibleState: TreeItemCollapsibleState.None, - label: { label: ref }, + label: { label: label(new Date(created)) }, + description: fromNow(created, true), + tooltip: ref, command: { id: 'workbench.actions.sync.resolveResourceRef', title: '', arguments: [{ $treeItemHandle: handle, $treeViewId: '' }] }, themeIcon: FileThemeIcon, contextValue: `syncref-${resourceKey}` @@ -187,3 +191,10 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { } +function label(date: Date): string { + return date.toLocaleDateString() + + ' ' + pad(date.getHours(), 2) + + ':' + pad(date.getMinutes(), 2) + + ':' + pad(date.getSeconds(), 2); +} + diff --git a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts index a79674273a5..dd3273ab5f0 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SyncSource, IUserDataSyncStoreService, IUserDataSyncStore, getUserDataSyncStore, ResourceKey, IUserData, IUserDataManifest } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncSource, IUserDataSyncStoreService, IUserDataSyncStore, getUserDataSyncStore, ResourceKey, IUserData, IUserDataManifest, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -41,7 +41,7 @@ export class UserDataSyncStoreService implements IUserDataSyncStoreService { throw new Error('Not Supported'); } - getAllRefs(key: ResourceKey): Promise { + getAllRefs(key: ResourceKey): Promise { return this.channel.call('getAllRefs', [key]); } From ac5492cd4855fb29e2e6f99654836d8d3c58e2af Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 09:30:55 +0100 Subject: [PATCH 047/137] show refresh and collapse all actions --- .../workbench/browser/parts/views/treeView.ts | 25 +++++++++++++++---- .../browser/userDataSyncHistory.ts | 4 ++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index f991c36243f..3e68a7e5920 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -127,6 +127,7 @@ export class TreeView extends Disposable implements ITreeView { private _hasIconForParentNode = false; private _hasIconForLeafNode = false; private _showCollapseAllAction = false; + private _showRefreshAction = false; private focused: boolean = false; private domNode!: HTMLElement; @@ -284,14 +285,28 @@ export class TreeView extends Disposable implements ITreeView { } } - getPrimaryActions(): IAction[] { - if (this.showCollapseAllAction) { - return [new Action('vs.tree.collapse', localize('collapseAll', "Collapse All"), 'monaco-tree-action codicon-collapse-all', true, () => this.tree ? new CollapseAllAction(this.tree, true).run() : Promise.resolve())]; - } else { - return []; + get showRefreshAction(): boolean { + return this._showRefreshAction; + } + + set showRefreshAction(showRefreshAction: boolean) { + if (this._showRefreshAction !== !!showRefreshAction) { + this._showRefreshAction = !!showRefreshAction; + this._onDidChangeActions.fire(); } } + getPrimaryActions(): IAction[] { + const actions: IAction[] = []; + if (this.showRefreshAction) { + actions.push(new Action('vs.tree.refresh', localize('refresh', "Refresh"), 'monaco-tree-action codicon-refresh', true, () => this.refresh())); + } + if (this.showCollapseAllAction) { + actions.push(new Action('vs.tree.collapse', localize('collapseAll', "Collapse All"), 'monaco-tree-action codicon-collapse-all', true, () => this.tree ? new CollapseAllAction(this.tree, true).run() : Promise.resolve())); + } + return actions; + } + getSecondaryActions(): IAction[] { return []; } diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index c54ca8e290c..7da0a13d394 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -40,6 +40,8 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi const name = localize('title', "Sync History"); const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(TreeView, this.viewId, name); + treeView.showCollapseAllAction = true; + treeView.showRefreshAction = true; const disposable = treeView.onDidChangeVisibility(visible => { if (visible && !treeView.dataProvider) { disposable.dispose(); @@ -52,7 +54,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi name, ctorDescriptor: new SyncDescriptor(TreeViewPane), when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW), - canToggleVisibility: false, + canToggleVisibility: true, canMoveView: true, treeView, collapsed: false, From 3ceb796cfe52eff095f2ee1f25b4784567b9fbac Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 09:39:37 +0100 Subject: [PATCH 048/137] fine tune titles --- .../contrib/userDataSync/browser/userDataSyncHistory.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index 7da0a13d394..35b2428ab81 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -37,7 +37,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi private registerView(): void { const that = this; - const name = localize('title', "Sync History"); + const name = localize('title', "Sync History (Remote)"); const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(TreeView, this.viewId, name); treeView.showCollapseAllAction = true; @@ -64,8 +64,8 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.showSyncHistory', - title: { value: localize('workbench.action.showRemoteUserDatraView', "Show Sync History"), original: `Show Sync History` }, + id: 'workbench.actions.showSyncRemoteHistoryView', + title: { value: localize('workbench.action.showSyncRemoteHistory', "Show History (Remote)"), original: `Show History (Remote)` }, category: { value: localize('sync', "Sync"), original: `Sync` }, menu: { id: MenuId.CommandPalette, @@ -181,7 +181,6 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { collapsibleState: TreeItemCollapsibleState.None, label: { label: label(new Date(created)) }, description: fromNow(created, true), - tooltip: ref, command: { id: 'workbench.actions.sync.resolveResourceRef', title: '', arguments: [{ $treeItemHandle: handle, $treeViewId: '' }] }, themeIcon: FileThemeIcon, contextValue: `syncref-${resourceKey}` From 7d17f6f926f2d00d88cac9eb290db5a43a32179d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 09:46:30 +0100 Subject: [PATCH 049/137] introduce authority for sync resources --- .../userDataSync/common/userDataSync.ts | 19 +++++++++++-------- .../common/userDataSyncService.ts | 4 ++-- .../userDataSync/browser/userDataSync.ts | 8 ++++---- .../browser/userDataSyncHistory.ts | 4 ++-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 5e789abd52b..2518c3e365b 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -348,18 +348,19 @@ export const CONTEXT_SYNC_ENABLEMENT = new RawContextKey('syncEnabled', export const USER_DATA_SYNC_SCHEME = 'vscode-userdata-sync'; export const PREVIEW_QUERY = 'preview=true'; -export function toSyncResourceFromSource(source: SyncSource, ref?: string): URI { - return toSyncResource(getResourceKey(source), ref); +export function toRemoteSyncResourceFromSource(source: SyncSource, ref?: string): URI { + return toRemoteSyncResource(getResourceKeyFromSyncSource(source), ref); } -export function toSyncResource(resourceKey: ResourceKey, ref?: string): URI { - return URI.from({ scheme: USER_DATA_SYNC_SCHEME, path: `${resourceKey}/${ref ? ref : 'latest'}` }); +export function toRemoteSyncResource(resourceKey: ResourceKey, ref?: string): URI { + return URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'remote', path: `/${resourceKey}/${ref ? ref : 'latest'}` }); } -export function resolveSyncResource(resource: URI): { resourceKey: ResourceKey, ref?: string } | null { +export function resolveSyncResource(resource: URI): { remote: boolean, resourceKey: ResourceKey, ref?: string } | null { + const remote = resource.authority === 'remote'; const resourceKey: ResourceKey = basename(dirname(resource)) as ResourceKey; const ref = basename(resource); if (resourceKey && ref) { - return { resourceKey, ref: ref !== 'latest' ? ref : undefined }; + return { remote, resourceKey, ref: ref !== 'latest' ? ref : undefined }; } return null; } @@ -373,7 +374,8 @@ export function getSyncSourceFromPreviewResource(uri: URI, environmentService: I } return undefined; } -export function getResourceKey(source: SyncSource): ResourceKey { + +export function getResourceKeyFromSyncSource(source: SyncSource): ResourceKey { switch (source) { case SyncSource.Settings: return 'settings'; case SyncSource.Keybindings: return 'keybindings'; @@ -381,7 +383,8 @@ export function getResourceKey(source: SyncSource): ResourceKey { case SyncSource.GlobalState: return 'globalState'; } } -export function getSyncSource(resourceKey: ResourceKey): SyncSource { + +export function getSyncSourceFromResourceKey(resourceKey: ResourceKey): SyncSource { switch (resourceKey) { case 'settings': return SyncSource.Settings; case 'keybindings': return SyncSource.Keybindings; diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index 90a7cf151f8..5c7f3950cfe 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -183,9 +183,9 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ const synchronizer = this.synchronisers.filter(s => s.resourceKey === result.resourceKey)[0]; if (synchronizer) { if (PREVIEW_QUERY === resource.query) { - return synchronizer.getRemoteContentFromPreview(); + return result.remote ? synchronizer.getRemoteContentFromPreview() : null; } - return synchronizer.getRemoteContent(result.ref, resource.fragment); + return result.remote ? synchronizer.getRemoteContent(result.ref, resource.fragment) : null; } } return null; diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 6dc2bf59441..d7f3ea4d80d 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -30,7 +30,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { CONTEXT_SYNC_STATE, getUserDataSyncStore, ISyncConfiguration, IUserDataAutoSyncService, IUserDataSyncService, IUserDataSyncStore, registerConfiguration, SyncSource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncEnablementService, ResourceKey, getSyncSourceFromPreviewResource, CONTEXT_SYNC_ENABLEMENT, toSyncResourceFromSource, PREVIEW_QUERY, resolveSyncResource, getSyncSource } from 'vs/platform/userDataSync/common/userDataSync'; +import { CONTEXT_SYNC_STATE, getUserDataSyncStore, ISyncConfiguration, IUserDataAutoSyncService, IUserDataSyncService, IUserDataSyncStore, registerConfiguration, SyncSource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncEnablementService, ResourceKey, getSyncSourceFromPreviewResource, CONTEXT_SYNC_ENABLEMENT, toRemoteSyncResourceFromSource, PREVIEW_QUERY, resolveSyncResource, getSyncSourceFromResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets'; import { GLOBAL_ACTIVITY_ID } from 'vs/workbench/common/activity'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -354,7 +354,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo private async acceptRemote(syncSource: SyncSource) { try { - const contents = await this.userDataSyncService.resolveContent(toSyncResourceFromSource(syncSource).with({ query: PREVIEW_QUERY })); + const contents = await this.userDataSyncService.resolveContent(toRemoteSyncResourceFromSource(syncSource).with({ query: PREVIEW_QUERY })); if (contents) { await this.userDataSyncService.accept(syncSource, contents); } @@ -754,7 +754,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo label = localize('keybindings conflicts preview', "Keybindings Conflicts (Remote ↔ Local)"); } if (previewResource) { - const remoteContentResource = toSyncResourceFromSource(source).with({ query: PREVIEW_QUERY }); + const remoteContentResource = toRemoteSyncResourceFromSource(source).with({ query: PREVIEW_QUERY }); await this.editorService.openEditor({ leftResource: remoteContentResource, rightResource: previewResource, @@ -1130,7 +1130,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio this._register(this.acceptChangesButton.onClick(async () => { const model = this.editor.getModel(); if (model) { - const conflictsSource = (getSyncSourceFromPreviewResource(model.uri, this.environmentService) || getSyncSource(resolveSyncResource(model.uri)!.resourceKey))!; + const conflictsSource = (getSyncSourceFromPreviewResource(model.uri, this.environmentService) || getSyncSourceFromResourceKey(resolveSyncResource(model.uri)!.resourceKey))!; this.telemetryService.publicLog2<{ source: string, action: string }, SyncConflictsClassification>('sync/handleConflicts', { source: conflictsSource, action: isRemote ? 'acceptRemote' : 'acceptLocal' }); const syncAreaLabel = getSyncAreaLabel(conflictsSource); const result = await this.dialogService.confirm({ diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index 35b2428ab81..caf1b630667 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -11,7 +11,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, toSyncResource, resolveSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; +import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, toRemoteSyncResource, resolveSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; import { IContextKeyService, RawContextKey, ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; import { URI } from 'vs/base/common/uri'; @@ -175,7 +175,7 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { if (resourceKey) { const refHandles = await this.userDataSyncStoreService.getAllRefs(resourceKey); return refHandles.map(({ ref, created }) => { - const handle = toSyncResource(resourceKey, ref).toString(); + const handle = toRemoteSyncResource(resourceKey, ref).toString(); return { handle, collapsibleState: TreeItemCollapsibleState.None, From c584c5c1775c319b5333742f3bbed27743a9695d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 11:54:09 +0100 Subject: [PATCH 050/137] Implement getAllRefs and resolveContent for backup store --- .../sharedProcess/sharedProcessMain.ts | 6 +- .../common/abstractSynchronizer.ts | 4 ++ .../userDataSync/common/extensionsSync.ts | 28 +++++++--- .../userDataSync/common/globalStateSync.ts | 28 +++++++--- .../userDataSync/common/keybindingsSync.ts | 28 +++++++--- .../userDataSync/common/settingsSync.ts | 34 ++++++++---- .../userDataSync/common/userDataSync.ts | 6 ++ .../common/userDataSyncBackupStoreService.ts | 55 ++++++++++++++----- .../userDataSync/common/userDataSyncIpc.ts | 20 ++++++- .../common/userDataSyncService.ts | 2 +- .../electron-browser/settingsSyncService.ts | 4 ++ .../userDataSyncBackupStoreService.ts | 37 +++++++++++++ src/vs/workbench/workbench.desktop.main.ts | 1 + 13 files changed, 202 insertions(+), 51 deletions(-) create mode 100644 src/vs/workbench/services/userDataSync/electron-browser/userDataSyncBackupStoreService.ts diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 79e8473bcc6..0e6c2358199 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -52,7 +52,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IUserDataSyncService, IUserDataSyncStoreService, registerConfiguration, IUserDataSyncLogService, IUserDataSyncUtilService, ISettingsSyncService, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService'; import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; -import { UserDataSyncChannel, UserDataSyncUtilServiceClient, SettingsSyncChannel, UserDataAutoSyncChannel, UserDataSyncStoreServiceChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc'; +import { UserDataSyncChannel, UserDataSyncUtilServiceClient, SettingsSyncChannel, UserDataAutoSyncChannel, UserDataSyncStoreServiceChannel, UserDataSyncBackupStoreServiceChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc'; import { IElectronService } from 'vs/platform/electron/node/electron'; import { LoggerService } from 'vs/platform/log/node/loggerService'; import { UserDataSyncLogService } from 'vs/platform/userDataSync/common/userDataSyncLog'; @@ -225,6 +225,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat const userDataSyncStoreServiceChannel = new UserDataSyncStoreServiceChannel(userDataSyncStoreService); server.registerChannel('userDataSyncStoreService', userDataSyncStoreServiceChannel); + const userDataSyncBackupStoreService = accessor.get(IUserDataSyncBackupStoreService); + const userDataSyncBackupStoreServiceChannel = new UserDataSyncBackupStoreServiceChannel(userDataSyncBackupStoreService); + server.registerChannel('userDataSyncBackupStoreService', userDataSyncBackupStoreServiceChannel); + const settingsSyncService = accessor.get(ISettingsSyncService); const settingsSyncChannel = new SettingsSyncChannel(settingsSyncService); server.registerChannel('settingsSync', settingsSyncChannel); diff --git a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts index 5d8e7648c1d..8f79415fe07 100644 --- a/src/vs/platform/userDataSync/common/abstractSynchronizer.ts +++ b/src/vs/platform/userDataSync/common/abstractSynchronizer.ts @@ -162,6 +162,10 @@ export abstract class AbstractSynchroniser extends Disposable { return content; } + async getLocalBackupContent(ref?: string): Promise { + return this.userDataSyncBackupStoreService.resolveContent(this.resourceKey, ref); + } + async resetLocal(): Promise { try { await this.fileService.del(this.lastSyncResource); diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index 4a108b0814e..cdc3d6faab5 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -123,18 +123,30 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse async getRemoteContent(ref?: string, fragment?: string): Promise { const content = await super.getRemoteContent(ref); if (content !== null && fragment) { - const syncData = this.parseSyncData(content); - if (syncData) { - switch (fragment) { - case 'extensions': - return syncData.content; - } - } - return null; + return this.getFragment(content, fragment); } return content; } + async getLocalBackupContent(ref?: string, fragment?: string): Promise { + let content = await super.getLocalBackupContent(ref); + if (content !== null && fragment) { + return this.getFragment(content, fragment); + } + return content; + } + + private getFragment(content: string, fragment: string): string | null { + const syncData = this.parseSyncData(content); + if (syncData) { + switch (fragment) { + case 'extensions': + return syncData.content; + } + } + return null; + } + accept(content: string): Promise { throw new Error('Extensions: Conflicts should not occur'); } diff --git a/src/vs/platform/userDataSync/common/globalStateSync.ts b/src/vs/platform/userDataSync/common/globalStateSync.ts index d125cd05e4e..a095a09b482 100644 --- a/src/vs/platform/userDataSync/common/globalStateSync.ts +++ b/src/vs/platform/userDataSync/common/globalStateSync.ts @@ -107,18 +107,30 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs async getRemoteContent(ref?: string, fragment?: string): Promise { let content = await super.getRemoteContent(ref); if (content !== null && fragment) { - const syncData = this.parseSyncData(content); - if (syncData) { - switch (fragment) { - case 'globalState': - return syncData.content; - } - } - return null; + return this.getFragment(content, fragment); } return content; } + async getLocalBackupContent(ref?: string, fragment?: string): Promise { + let content = await super.getLocalBackupContent(ref); + if (content !== null && fragment) { + return this.getFragment(content, fragment); + } + return content; + } + + private getFragment(content: string, fragment: string): string | null { + const syncData = this.parseSyncData(content); + if (syncData) { + switch (fragment) { + case 'globalState': + return syncData.content; + } + } + return null; + } + accept(content: string): Promise { throw new Error('UI State: Conflicts should not occur'); } diff --git a/src/vs/platform/userDataSync/common/keybindingsSync.ts b/src/vs/platform/userDataSync/common/keybindingsSync.ts index 33f5eb92dd7..c3f02bac0da 100644 --- a/src/vs/platform/userDataSync/common/keybindingsSync.ts +++ b/src/vs/platform/userDataSync/common/keybindingsSync.ts @@ -164,18 +164,30 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem async getRemoteContent(ref?: string, fragment?: string): Promise { const content = await super.getRemoteContent(ref); if (content !== null && fragment) { - const syncData = this.parseSyncData(content); - if (syncData) { - switch (fragment) { - case 'keybindings': - return this.getKeybindingsContentFromSyncContent(syncData.content); - } - } - return null; + return this.getFragment(content, fragment); } return content; } + async getLocalBackupContent(ref?: string, fragment?: string): Promise { + let content = await super.getLocalBackupContent(ref); + if (content !== null && fragment) { + return this.getFragment(content, fragment); + } + return content; + } + + private getFragment(content: string, fragment: string): string | null { + const syncData = this.parseSyncData(content); + if (syncData) { + switch (fragment) { + case 'keybindings': + return this.getKeybindingsContentFromSyncContent(syncData.content); + } + } + return null; + } + protected async performSync(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null): Promise { try { const result = await this.getPreview(remoteUserData, lastSyncUserData); diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index 79d0b2494e8..219f2c2a698 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -205,21 +205,33 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement async getRemoteContent(ref?: string, fragment?: string): Promise { let content = await super.getRemoteContent(ref); if (content !== null && fragment) { - const syncData = this.parseSyncData(content); - if (syncData) { - const settingsSyncContent = this.parseSettingsSyncContent(syncData.content); - if (settingsSyncContent) { - switch (fragment) { - case 'settings': - return settingsSyncContent.settings; - } - } - } - return null; + return this.getFragment(content, fragment); } return content; } + async getLocalBackupContent(ref?: string, fragment?: string): Promise { + let content = await super.getLocalBackupContent(ref); + if (content !== null && fragment) { + return this.getFragment(content, fragment); + } + return content; + } + + private getFragment(content: string, fragment: string): string | null { + const syncData = this.parseSyncData(content); + if (syncData) { + const settingsSyncContent = this.parseSettingsSyncContent(syncData.content); + if (settingsSyncContent) { + switch (fragment) { + case 'settings': + return settingsSyncContent.settings; + } + } + } + return null; + } + async accept(content: string): Promise { if (this.status === SyncStatus.HasConflicts) { const preview = await this.syncPreviewResultPromise!; diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 2518c3e365b..0744514d2f5 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -165,6 +165,8 @@ export const IUserDataSyncBackupStoreService = createDecorator; + getAllRefs(key: ResourceKey): Promise; + resolveContent(key: ResourceKey, ref?: string): Promise; } //#endregion @@ -261,6 +263,7 @@ export interface IUserDataSynchroniser { getRemoteContentFromPreview(): Promise; getRemoteContent(ref?: string, fragment?: string): Promise; + getLocalBackupContent(ref?: string, fragment?: string): Promise; accept(content: string): Promise; } @@ -354,6 +357,9 @@ export function toRemoteSyncResourceFromSource(source: SyncSource, ref?: string) export function toRemoteSyncResource(resourceKey: ResourceKey, ref?: string): URI { return URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'remote', path: `/${resourceKey}/${ref ? ref : 'latest'}` }); } +export function toLocalBackupSyncResource(resourceKey: ResourceKey, ref?: string): URI { + return URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'local-backup', path: `/${resourceKey}/${ref ? ref : 'latest'}` }); +} export function resolveSyncResource(resource: URI): { remote: boolean, resourceKey: ResourceKey, ref?: string } | null { const remote = resource.authority === 'remote'; diff --git a/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts index 8875ec93336..b439de0bc02 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncBackupStoreService.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, } from 'vs/base/common/lifecycle'; -import { IUserDataSyncLogService, ResourceKey, ALL_RESOURCE_KEYS, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncLogService, ResourceKey, ALL_RESOURCE_KEYS, IUserDataSyncBackupStoreService, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync'; import { joinPath } from 'vs/base/common/resources'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IFileService } from 'vs/platform/files/common/files'; +import { IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { toLocalISOString } from 'vs/base/common/date'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -26,6 +26,34 @@ export class UserDataSyncBackupStoreService extends Disposable implements IUserD ALL_RESOURCE_KEYS.forEach(resourceKey => this.cleanUpBackup(resourceKey)); } + async getAllRefs(resourceKey: ResourceKey): Promise { + const folder = joinPath(this.environmentService.userDataSyncHome, resourceKey); + const stat = await this.fileService.resolve(folder); + if (stat.children) { + const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}(\.json)?$/.test(stat.name)).sort().reverse(); + return all.map(stat => ({ + ref: stat.name, + created: this.getCreationTime(stat) + })); + } + return []; + } + + async resolveContent(resourceKey: ResourceKey, ref?: string): Promise { + if (!ref) { + const refs = await this.getAllRefs(resourceKey); + if (refs.length) { + ref = refs[refs.length - 1].ref; + } + } + if (ref) { + const file = joinPath(this.environmentService.userDataSyncHome, resourceKey, ref); + const content = await this.fileService.readFile(file); + return content.value.toString(); + } + return null; + } + async backup(resourceKey: ResourceKey, content: string): Promise { const folder = joinPath(this.environmentService.userDataSyncHome, resourceKey); const resource = joinPath(folder, `${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}.json`); @@ -53,17 +81,7 @@ export class UserDataSyncBackupStoreService extends Disposable implements IUserD if (stat.children) { const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}(\.json)?$/.test(stat.name)).sort(); const backUpMaxAge = 1000 * 60 * 60 * 24 * (this.configurationService.getValue('sync.localBackupDuration') || 30 /* Default 30 days */); - let toDelete = all.filter(stat => { - const ctime = stat.ctime || new Date( - parseInt(stat.name.substring(0, 4)), - parseInt(stat.name.substring(4, 6)) - 1, - parseInt(stat.name.substring(6, 8)), - parseInt(stat.name.substring(9, 11)), - parseInt(stat.name.substring(11, 13)), - parseInt(stat.name.substring(13, 15)) - ).getTime(); - return Date.now() - ctime > backUpMaxAge; - }); + let toDelete = all.filter(stat => Date.now() - this.getCreationTime(stat) > backUpMaxAge); const remaining = all.length - toDelete.length; if (remaining < 10) { toDelete = toDelete.slice(10 - remaining); @@ -77,4 +95,15 @@ export class UserDataSyncBackupStoreService extends Disposable implements IUserD this.logService.error(e); } } + + private getCreationTime(stat: IFileStat) { + return stat.ctime || new Date( + parseInt(stat.name.substring(0, 4)), + parseInt(stat.name.substring(4, 6)) - 1, + parseInt(stat.name.substring(6, 8)), + parseInt(stat.name.substring(9, 11)), + parseInt(stat.name.substring(11, 13)), + parseInt(stat.name.substring(13, 15)) + ).getTime(); + } } diff --git a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts index 08e0a4c9aa3..de2736a2fe3 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts @@ -5,7 +5,7 @@ import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event } from 'vs/base/common/event'; -import { IUserDataSyncService, IUserDataSyncUtilService, ISettingsSyncService, IUserDataAutoSyncService, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncService, IUserDataSyncUtilService, ISettingsSyncService, IUserDataAutoSyncService, IUserDataSyncStoreService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; import { URI } from 'vs/base/common/uri'; import { IStringDictionary } from 'vs/base/common/collections'; import { FormattingOptions } from 'vs/base/common/jsonFormatter'; @@ -69,6 +69,7 @@ export class SettingsSyncChannel implements IServerChannel { case 'resolveSettingsConflicts': return this.service.resolveSettingsConflicts(args[0]); case 'getRemoteContentFromPreview': return this.service.getRemoteContentFromPreview(); case 'getRemoteContent': return this.service.getRemoteContent(args[0], args[1]); + case 'getLocalBackupContent': return this.service.getLocalBackupContent(args[0], args[1]); } throw new Error('Invalid call'); } @@ -149,3 +150,20 @@ export class UserDataSyncStoreServiceChannel implements IServerChannel { throw new Error('Invalid call'); } } + +export class UserDataSyncBackupStoreServiceChannel implements IServerChannel { + + constructor(private readonly service: IUserDataSyncBackupStoreService) { } + + listen(_: unknown, event: string): Event { + throw new Error(`Event not found: ${event}`); + } + + call(context: any, command: string, args?: any): Promise { + switch (command) { + case 'getAllRefs': return this.service.getAllRefs(args[0]); + case 'resolveContent': return this.service.resolveContent(args[0], args[1]); + } + throw new Error('Invalid call'); + } +} diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index 5c7f3950cfe..4be50d8387a 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -185,7 +185,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ if (PREVIEW_QUERY === resource.query) { return result.remote ? synchronizer.getRemoteContentFromPreview() : null; } - return result.remote ? synchronizer.getRemoteContent(result.ref, resource.fragment) : null; + return result.remote ? synchronizer.getRemoteContent(result.ref, resource.fragment) : synchronizer.getLocalBackupContent(result.ref, resource.fragment); } } return null; diff --git a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts index 8fe78318d4c..7d48e03e84c 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/settingsSyncService.ts @@ -88,6 +88,10 @@ export class SettingsSyncService extends Disposable implements ISettingsSyncServ return this.channel.call('getRemoteContent', [ref, fragment]); } + getLocalBackupContent(ref?: string, fragment?: string): Promise { + return this.channel.call('getLocalBackupContent', [ref, fragment]); + } + getRemoteContentFromPreview(): Promise { return this.channel.call('getRemoteContentFromPreview', []); } diff --git a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncBackupStoreService.ts b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncBackupStoreService.ts new file mode 100644 index 00000000000..3a395b1c5b4 --- /dev/null +++ b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncBackupStoreService.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ResourceKey, IResourceRefHandle, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync'; +import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; +import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; + +export class UserDataSyncBackupStoreService implements IUserDataSyncBackupStoreService { + + _serviceBrand: undefined; + private readonly channel: IChannel; + + constructor( + @ISharedProcessService sharedProcessService: ISharedProcessService, + ) { + this.channel = sharedProcessService.getChannel('userDataSyncBackupStoreService'); + } + + backup(key: ResourceKey, content: string): Promise { + return this.channel.call('backup', [key, content]); + } + + + getAllRefs(key: ResourceKey): Promise { + return this.channel.call('getAllRefs', [key]); + } + + resolveContent(key: ResourceKey, ref: string): Promise { + return this.channel.call('resolveContent', [key, ref]); + } + +} + +registerSingleton(IUserDataSyncBackupStoreService, UserDataSyncBackupStoreService); diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 33ba47dadd6..a8f926566d4 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -53,6 +53,7 @@ import 'vs/workbench/services/userDataSync/electron-browser/userDataSyncService' import 'vs/workbench/services/userDataSync/electron-browser/settingsSyncService'; import 'vs/workbench/services/userDataSync/electron-browser/userDataAutoSyncService'; import 'vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService'; +import 'vs/workbench/services/userDataSync/electron-browser/userDataSyncBackupStoreService'; import 'vs/workbench/services/authentication/electron-browser/authenticationTokenService'; import 'vs/workbench/services/authentication/browser/authenticationService'; import 'vs/workbench/services/host/electron-browser/desktopHostService'; From ba98449d4d873a324b0fcf6686da3e43493c22cf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 11:54:27 +0100 Subject: [PATCH 051/137] Sync local backup view --- .../browser/userDataSyncHistory.ts | 107 +++++++++++++----- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index caf1b630667..8c5cd474fbd 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -11,7 +11,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, toRemoteSyncResource, resolveSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; +import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, toRemoteSyncResource, resolveSyncResource, IUserDataSyncBackupStoreService, IResourceRefHandle, ResourceKey, toLocalBackupSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; import { IContextKeyService, RawContextKey, ContextKeyExpr, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; import { URI } from 'vs/base/common/uri'; @@ -21,39 +21,41 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { fromNow } from 'vs/base/common/date'; import { pad } from 'vs/base/common/strings'; -const CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW = new RawContextKey('showUserDataSyncHistoryView', false); +const CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW = new RawContextKey('showUserDataSyncRemoteHistoryView', false); +const CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW = new RawContextKey('showUserDataSyncLocalHistoryView', false); export class UserDataSyncHistoryViewContribution implements IWorkbenchContribution { - private readonly viewId = 'workbench.views.syncHistory'; - constructor( @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IUserDataSyncStoreService private readonly userDataSyncStoreService: IUserDataSyncStoreService, + @IUserDataSyncBackupStoreService private readonly userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, ) { - this.registerView(); - this.registerActions(); + this.registerRemoteHistoryView(); + this.registerLocalHistoryView(); } - private registerView(): void { - const that = this; - const name = localize('title', "Sync History (Remote)"); - const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW.bindTo(this.contextKeyService); - const treeView = this.instantiationService.createInstance(TreeView, this.viewId, name); + private registerRemoteHistoryView(): void { + const id = 'workbench.views.sync.remoteHistory'; + const name = localize('title', "Sync: Backup (Remote)"); + const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW.bindTo(this.contextKeyService); + const treeView = this.instantiationService.createInstance(TreeView, id, name); treeView.showCollapseAllAction = true; treeView.showRefreshAction = true; const disposable = treeView.onDidChangeVisibility(visible => { if (visible && !treeView.dataProvider) { disposable.dispose(); - treeView.dataProvider = this.instantiationService.createInstance(UserDataSyncHistoryViewDataProvider); + treeView.dataProvider = this.instantiationService.createInstance(UserDataSyncHistoryViewDataProvider, id, + (resourceKey: ResourceKey) => this.userDataSyncStoreService.getAllRefs(resourceKey), (resourceKey: ResourceKey, ref: string) => toRemoteSyncResource(resourceKey, ref)); } }); const viewsRegistry = Registry.as(Extensions.ViewsRegistry); viewsRegistry.registerViews([{ - id: this.viewId, + id, name, ctorDescriptor: new SyncDescriptor(TreeViewPane), - when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW), + when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW), canToggleVisibility: true, canMoveView: true, treeView, @@ -65,7 +67,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi constructor() { super({ id: 'workbench.actions.showSyncRemoteHistoryView', - title: { value: localize('workbench.action.showSyncRemoteHistory', "Show History (Remote)"), original: `Show History (Remote)` }, + title: { value: localize('workbench.action.showSyncRemoteHistory', "Show Backup (Remote)"), original: `Show Backup (Remote)` }, category: { value: localize('sync', "Sync"), original: `Sync` }, menu: { id: MenuId.CommandPalette, @@ -75,17 +77,66 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi } async run(accessor: ServicesAccessor): Promise { viewEnablementContext.set(true); - accessor.get(IViewsService).openView(that.viewId, true); + accessor.get(IViewsService).openView(id, true); } }); + + this.registerActions(id); } - private registerActions() { - const that = this; + private registerLocalHistoryView(): void { + const id = 'workbench.views.sync.LocalHistory'; + const name = localize('local view title', "Sync: Backup (Local)"); + const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW.bindTo(this.contextKeyService); + const treeView = this.instantiationService.createInstance(TreeView, id, name); + treeView.showCollapseAllAction = true; + treeView.showRefreshAction = true; + const disposable = treeView.onDidChangeVisibility(visible => { + if (visible && !treeView.dataProvider) { + disposable.dispose(); + treeView.dataProvider = this.instantiationService.createInstance(UserDataSyncHistoryViewDataProvider, id, + (resourceKey: ResourceKey) => this.userDataSyncBackupStoreService.getAllRefs(resourceKey), (resourceKey: ResourceKey, ref: string) => toLocalBackupSyncResource(resourceKey, ref)); + } + }); + const viewsRegistry = Registry.as(Extensions.ViewsRegistry); + viewsRegistry.registerViews([{ + id, + name, + ctorDescriptor: new SyncDescriptor(TreeViewPane), + when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW), + canToggleVisibility: true, + canMoveView: true, + treeView, + collapsed: false, + order: 100, + }], VIEW_CONTAINER); + registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.sync.resolveResourceRef', + id: 'workbench.actions.showSyncLocalHistoryView', + title: { value: localize('workbench.action.showSyncLocalHistory', "Show Backup (Local)"), original: `Show Backup (Local)` }, + category: { value: localize('sync', "Sync"), original: `Sync` }, + menu: { + id: MenuId.CommandPalette, + when: CONTEXT_SYNC_ENABLEMENT + }, + }); + } + async run(accessor: ServicesAccessor): Promise { + viewEnablementContext.set(true); + accessor.get(IViewsService).openView(id, true); + } + }); + + this.registerActions(id); + } + + private registerActions(viewId: string) { + registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.actions.sync.${viewId}.resolveResourceRef`, title: localize('workbench.actions.sync.resolveResourceRef', "Resolve Resource Ref"), }); } @@ -102,11 +153,11 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.sync.resolveResourceRefCompletely', + id: `workbench.actions.sync.${viewId}.resolveResourceRefCompletely`, title: localize('workbench.actions.sync.resolveResourceRefCompletely', "Show full content"), menu: { id: MenuId.ViewItemContext, - when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /syncref-.*/i)) + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', viewId), ContextKeyExpr.regex('viewItem', /syncref-.*/i)) }, }); } @@ -118,11 +169,11 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.commpareWithLocal', + id: `workbench.actions.${viewId}.commpareWithLocal`, title: localize('workbench.action.deleteRef', "Open Changes"), menu: { id: MenuId.ViewItemContext, - when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /syncref-(settings|keybindings).*/i)) + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', viewId), ContextKeyExpr.regex('viewItem', /syncref-(settings|keybindings).*/i)) }, }); } @@ -153,7 +204,9 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { constructor( - @IUserDataSyncStoreService private readonly userDataSyncStoreService: IUserDataSyncStoreService, + private readonly viewId: string, + private getAllRefs: (resourceKey: ResourceKey) => Promise, + private toResource: (resourceKey: ResourceKey, ref: string) => URI ) { } @@ -173,15 +226,15 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { private async getResources(handle: string): Promise { const resourceKey = ALL_RESOURCE_KEYS.filter(key => key === handle)[0]; if (resourceKey) { - const refHandles = await this.userDataSyncStoreService.getAllRefs(resourceKey); + const refHandles = await this.getAllRefs(resourceKey); return refHandles.map(({ ref, created }) => { - const handle = toRemoteSyncResource(resourceKey, ref).toString(); + const handle = this.toResource(resourceKey, ref).toString(); return { handle, collapsibleState: TreeItemCollapsibleState.None, label: { label: label(new Date(created)) }, description: fromNow(created, true), - command: { id: 'workbench.actions.sync.resolveResourceRef', title: '', arguments: [{ $treeItemHandle: handle, $treeViewId: '' }] }, + command: { id: `workbench.actions.sync.${this.viewId}.resolveResourceRef`, title: '', arguments: [{ $treeItemHandle: handle, $treeViewId: '' }] }, themeIcon: FileThemeIcon, contextValue: `syncref-${resourceKey}` }; From 120888878498299ffa22d4fb294e8eb601b6cc8a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 15:54:33 +0100 Subject: [PATCH 052/137] move sync views to sync viewlet --- .../browser/userDataSync.contribution.ts | 4 +- ...DataSyncHistory.ts => userDataSyncView.ts} | 39 +++++++++++++------ 2 files changed, 29 insertions(+), 14 deletions(-) rename src/vs/workbench/contrib/userDataSync/browser/{userDataSyncHistory.ts => userDataSyncView.ts} (88%) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts index fe0fe425437..d215668d3f0 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts @@ -7,8 +7,8 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { UserDataSyncWorkbenchContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSync'; -import { UserDataSyncHistoryViewContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncHistory'; +import { UserDataSyncViewContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncView'; const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(UserDataSyncWorkbenchContribution, LifecyclePhase.Ready); -workbenchRegistry.registerWorkbenchContribution(UserDataSyncHistoryViewContribution, LifecyclePhase.Ready); +workbenchRegistry.registerWorkbenchContribution(UserDataSyncViewContribution, LifecyclePhase.Ready); diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts similarity index 88% rename from src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts rename to src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts index 8c5cd474fbd..e085ff7d57c 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts @@ -5,11 +5,10 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IViewsRegistry, Extensions, ITreeViewDescriptor, ITreeViewDataProvider, ITreeItem, TreeItemCollapsibleState, IViewsService, TreeViewItemHandleArg } from 'vs/workbench/common/views'; +import { IViewsRegistry, Extensions, ITreeViewDescriptor, ITreeViewDataProvider, ITreeItem, TreeItemCollapsibleState, IViewsService, TreeViewItemHandleArg, IViewContainersRegistry, ViewContainerLocation, ViewContainer } from 'vs/workbench/common/views'; import { localize } from 'vs/nls'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView'; -import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ALL_RESOURCE_KEYS, CONTEXT_SYNC_ENABLEMENT, IUserDataSyncStoreService, toRemoteSyncResource, resolveSyncResource, IUserDataSyncBackupStoreService, IResourceRefHandle, ResourceKey, toLocalBackupSyncResource } from 'vs/platform/userDataSync/common/userDataSync'; import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; @@ -20,11 +19,12 @@ import { FolderThemeIcon, FileThemeIcon } from 'vs/platform/theme/common/themeSe import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { fromNow } from 'vs/base/common/date'; import { pad } from 'vs/base/common/strings'; +import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; const CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW = new RawContextKey('showUserDataSyncRemoteHistoryView', false); const CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW = new RawContextKey('showUserDataSyncLocalHistoryView', false); -export class UserDataSyncHistoryViewContribution implements IWorkbenchContribution { +export class UserDataSyncViewContribution implements IWorkbenchContribution { constructor( @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -32,13 +32,28 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi @IUserDataSyncStoreService private readonly userDataSyncStoreService: IUserDataSyncStoreService, @IUserDataSyncBackupStoreService private readonly userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, ) { - this.registerRemoteHistoryView(); - this.registerLocalHistoryView(); + const container = this.registerSyncViewContainer(); + this.registerRemoteHistoryView(container); + this.registerLocalHistoryView(container); } - private registerRemoteHistoryView(): void { + private registerSyncViewContainer(): ViewContainer { + return Registry.as(Extensions.ViewContainersRegistry).registerViewContainer( + { + id: 'workbench.view.sync', + name: localize('sync', "Sync"), + ctorDescriptor: new SyncDescriptor( + ViewPaneContainer, + ['workbench.view.sync', `workbench.view.sync.state`, { mergeViewWithContainerWhenSingleView: true }] + ), + icon: 'codicon-sync', + hideIfEmpty: true, + }, ViewContainerLocation.Sidebar); + } + + private registerRemoteHistoryView(container: ViewContainer): void { const id = 'workbench.views.sync.remoteHistory'; - const name = localize('title', "Sync: Backup (Remote)"); + const name = localize('title', "Backup (Remote)"); const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(TreeView, id, name); treeView.showCollapseAllAction = true; @@ -61,7 +76,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi treeView, collapsed: false, order: 100, - }], VIEW_CONTAINER); + }], container); registerAction2(class extends Action2 { constructor() { @@ -84,9 +99,9 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi this.registerActions(id); } - private registerLocalHistoryView(): void { - const id = 'workbench.views.sync.LocalHistory'; - const name = localize('local view title', "Sync: Backup (Local)"); + private registerLocalHistoryView(container: ViewContainer): void { + const id = 'workbench.views.sync.localHistory'; + const name = localize('local view title', "Backup (Local)"); const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(TreeView, id, name); treeView.showCollapseAllAction = true; @@ -109,7 +124,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi treeView, collapsed: false, order: 100, - }], VIEW_CONTAINER); + }], container); registerAction2(class extends Action2 { constructor() { From 1ebdb3354802dc2f3fd571d5f4383f79882ff89d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 16:03:09 +0100 Subject: [PATCH 053/137] reuse code --- .../userDataSync/browser/userDataSyncView.ts | 75 ++++--------------- 1 file changed, 14 insertions(+), 61 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts index e085ff7d57c..15337dc25f9 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts @@ -21,9 +21,6 @@ import { fromNow } from 'vs/base/common/date'; import { pad } from 'vs/base/common/strings'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; -const CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW = new RawContextKey('showUserDataSyncRemoteHistoryView', false); -const CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW = new RawContextKey('showUserDataSyncLocalHistoryView', false); - export class UserDataSyncViewContribution implements IWorkbenchContribution { constructor( @@ -33,8 +30,8 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { @IUserDataSyncBackupStoreService private readonly userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, ) { const container = this.registerSyncViewContainer(); - this.registerRemoteHistoryView(container); - this.registerLocalHistoryView(container); + this.registerBackupView(container, true); + this.registerBackupView(container, false); } private registerSyncViewContainer(): ViewContainer { @@ -51,10 +48,11 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { }, ViewContainerLocation.Sidebar); } - private registerRemoteHistoryView(container: ViewContainer): void { - const id = 'workbench.views.sync.remoteHistory'; - const name = localize('title', "Backup (Remote)"); - const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW.bindTo(this.contextKeyService); + private registerBackupView(container: ViewContainer, remote: boolean): void { + const id = `workbench.views.sync.${remote ? 'remote' : 'local'}BackupView`; + const name = remote ? localize('remote title', "Backup (Remote)") : localize('local title', "Backup (Local)"); + const contextKey = new RawContextKey(`showUserDataSync${remote ? 'Remote' : 'Local'}BackupView`, false); + const viewEnablementContext = contextKey.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(TreeView, id, name); treeView.showCollapseAllAction = true; treeView.showRefreshAction = true; @@ -62,7 +60,8 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { if (visible && !treeView.dataProvider) { disposable.dispose(); treeView.dataProvider = this.instantiationService.createInstance(UserDataSyncHistoryViewDataProvider, id, - (resourceKey: ResourceKey) => this.userDataSyncStoreService.getAllRefs(resourceKey), (resourceKey: ResourceKey, ref: string) => toRemoteSyncResource(resourceKey, ref)); + (resourceKey: ResourceKey) => remote ? this.userDataSyncStoreService.getAllRefs(resourceKey) : this.userDataSyncBackupStoreService.getAllRefs(resourceKey), + (resourceKey: ResourceKey, ref: string) => remote ? toRemoteSyncResource(resourceKey, ref) : toLocalBackupSyncResource(resourceKey, ref)); } }); const viewsRegistry = Registry.as(Extensions.ViewsRegistry); @@ -70,7 +69,7 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { id, name, ctorDescriptor: new SyncDescriptor(TreeViewPane), - when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_REMOTE_HISTORY_VIEW), + when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, contextKey), canToggleVisibility: true, canMoveView: true, treeView, @@ -81,56 +80,10 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.actions.showSyncRemoteHistoryView', - title: { value: localize('workbench.action.showSyncRemoteHistory', "Show Backup (Remote)"), original: `Show Backup (Remote)` }, - category: { value: localize('sync', "Sync"), original: `Sync` }, - menu: { - id: MenuId.CommandPalette, - when: CONTEXT_SYNC_ENABLEMENT - }, - }); - } - async run(accessor: ServicesAccessor): Promise { - viewEnablementContext.set(true); - accessor.get(IViewsService).openView(id, true); - } - }); - - this.registerActions(id); - } - - private registerLocalHistoryView(container: ViewContainer): void { - const id = 'workbench.views.sync.localHistory'; - const name = localize('local view title', "Backup (Local)"); - const viewEnablementContext = CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW.bindTo(this.contextKeyService); - const treeView = this.instantiationService.createInstance(TreeView, id, name); - treeView.showCollapseAllAction = true; - treeView.showRefreshAction = true; - const disposable = treeView.onDidChangeVisibility(visible => { - if (visible && !treeView.dataProvider) { - disposable.dispose(); - treeView.dataProvider = this.instantiationService.createInstance(UserDataSyncHistoryViewDataProvider, id, - (resourceKey: ResourceKey) => this.userDataSyncBackupStoreService.getAllRefs(resourceKey), (resourceKey: ResourceKey, ref: string) => toLocalBackupSyncResource(resourceKey, ref)); - } - }); - const viewsRegistry = Registry.as(Extensions.ViewsRegistry); - viewsRegistry.registerViews([{ - id, - name, - ctorDescriptor: new SyncDescriptor(TreeViewPane), - when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, CONTEXT_SHOW_USER_DATA_SYNC_LOCAL_HISTORY_VIEW), - canToggleVisibility: true, - canMoveView: true, - treeView, - collapsed: false, - order: 100, - }], container); - - registerAction2(class extends Action2 { - constructor() { - super({ - id: 'workbench.actions.showSyncLocalHistoryView', - title: { value: localize('workbench.action.showSyncLocalHistory', "Show Backup (Local)"), original: `Show Backup (Local)` }, + id: `workbench.actions.showSync${remote ? 'Remote' : 'Local'}BackupView`, + title: remote ? + { value: localize('workbench.action.showSyncRemoteBackup', "Show Backup (Remote)"), original: `Show Backup (Remote)` } + : { value: localize('workbench.action.showSyncLocalBackup', "Show Backup (Local)"), original: `Show Backup (Local)` }, category: { value: localize('sync', "Sync"), original: `Sync` }, menu: { id: MenuId.CommandPalette, From 03ed9422c464c7f5bac8ea5f2a254de8d2049f67 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 18:05:08 +0100 Subject: [PATCH 054/137] disable sync backup views --- .../contrib/userDataSync/browser/userDataSync.contribution.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts index d215668d3f0..367dd0b6fb3 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts @@ -7,8 +7,6 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { UserDataSyncWorkbenchContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSync'; -import { UserDataSyncViewContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncView'; const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(UserDataSyncWorkbenchContribution, LifecyclePhase.Ready); -workbenchRegistry.registerWorkbenchContribution(UserDataSyncViewContribution, LifecyclePhase.Ready); From 0c66f25b8195271ce310e98b40788482832877ae Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 18:09:09 +0100 Subject: [PATCH 055/137] disable remote backup view only --- .../contrib/userDataSync/browser/userDataSync.contribution.ts | 2 ++ .../workbench/contrib/userDataSync/browser/userDataSyncView.ts | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts index 367dd0b6fb3..d215668d3f0 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.contribution.ts @@ -7,6 +7,8 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { UserDataSyncWorkbenchContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSync'; +import { UserDataSyncViewContribution } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncView'; const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(UserDataSyncWorkbenchContribution, LifecyclePhase.Ready); +workbenchRegistry.registerWorkbenchContribution(UserDataSyncViewContribution, LifecyclePhase.Ready); diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts index 15337dc25f9..fef03371c14 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts @@ -30,7 +30,8 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { @IUserDataSyncBackupStoreService private readonly userDataSyncBackupStoreService: IUserDataSyncBackupStoreService, ) { const container = this.registerSyncViewContainer(); - this.registerBackupView(container, true); + // Disable remote backup view until server is upgraded. + // this.registerBackupView(container, true); this.registerBackupView(container, false); } From 3cadb517b00cc9a1246f40070c5a3bcfb0a2d663 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 19:16:31 +0100 Subject: [PATCH 056/137] Fies #44465: Clear leftoverVisibleColumns at file edges --- .../common/controller/cursorMoveOperations.ts | 16 +++++++++++++--- .../test/browser/controller/cursor.test.ts | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/controller/cursorMoveOperations.ts b/src/vs/editor/common/controller/cursorMoveOperations.ts index df45d78e9f9..0687dbb6426 100644 --- a/src/vs/editor/common/controller/cursorMoveOperations.ts +++ b/src/vs/editor/common/controller/cursorMoveOperations.ts @@ -91,9 +91,10 @@ export class MoveOperations { public static down(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): CursorPosition { const currentVisibleColumn = CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns; + const lineCount = model.getLineCount(); + const wasOnLastPosition = (lineNumber === lineCount && column === model.getLineMaxColumn(lineNumber)); lineNumber = lineNumber + count; - let lineCount = model.getLineCount(); if (lineNumber > lineCount) { lineNumber = lineCount; if (allowMoveOnLastLine) { @@ -105,7 +106,11 @@ export class MoveOperations { column = CursorColumns.columnFromVisibleColumn2(config, model, lineNumber, currentVisibleColumn); } - leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize); + if (wasOnLastPosition) { + leftoverVisibleColumns = 0; + } else { + leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize); + } return new CursorPosition(lineNumber, column, leftoverVisibleColumns); } @@ -144,6 +149,7 @@ export class MoveOperations { public static up(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): CursorPosition { const currentVisibleColumn = CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns; + const wasOnFirstPosition = (lineNumber === 1 && column === 1); lineNumber = lineNumber - count; if (lineNumber < 1) { @@ -157,7 +163,11 @@ export class MoveOperations { column = CursorColumns.columnFromVisibleColumn2(config, model, lineNumber, currentVisibleColumn); } - leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize); + if (wasOnFirstPosition) { + leftoverVisibleColumns = 0; + } else { + leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize); + } return new CursorPosition(lineNumber, column, leftoverVisibleColumns); } diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 42c4dff0db2..34902600555 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -397,6 +397,25 @@ suite('Editor Controller - Cursor', () => { assertCursor(thisCursor, new Position(1, LINE1.length + 1)); }); + test('issue #44465: cursor position not correct when move', () => { + thisCursor.setSelections('test', [new Selection(1, 5, 1, 5)]); + // going once up on the first line remembers the offset visual columns + moveUp(thisCursor); + assertCursor(thisCursor, new Position(1, 1)); + moveDown(thisCursor); + assertCursor(thisCursor, new Position(2, 2)); + moveUp(thisCursor); + assertCursor(thisCursor, new Position(1, 5)); + + // going twice up on the first line discards the offset visual columns + moveUp(thisCursor); + assertCursor(thisCursor, new Position(1, 1)); + moveUp(thisCursor); + assertCursor(thisCursor, new Position(1, 1)); + moveDown(thisCursor); + assertCursor(thisCursor, new Position(2, 1)); + }); + // --------- move to beginning of line test('move to beginning of line', () => { From 42707865694431c17ba2268e79b32803f0fe98af Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 6 Mar 2020 11:53:22 -0800 Subject: [PATCH 057/137] Remove callback for protocol registration Fixes #92138 --- .../electron-browser/webviewElement.ts | 8 +++- .../electron-browser/webviewProtocols.ts | 37 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index e2a484ad05e..c840aa894be 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -133,8 +133,12 @@ class WebviewProtocolProvider extends Disposable { }); this._register(handle.onFirstLoad(contents => { - registerFileProtocol(contents, WebviewResourceScheme, fileService, getExtensionLocation(), getLocalResourceRoots) - .then(this._resolve, this._reject); + try { + registerFileProtocol(contents, WebviewResourceScheme, fileService, getExtensionLocation(), getLocalResourceRoots); + this._resolve(); + } catch { + this._reject(); + } })); } } diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts index 39e4349cb40..e84ce9bf6fb 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts @@ -14,27 +14,24 @@ export function registerFileProtocol( extensionLocation: URI | undefined, getRoots: () => ReadonlyArray ) { - return new Promise((resolve, reject) => - contents.session.protocol.registerBufferProtocol(protocol, async (request, callback: any) => { - try { - const result = await loadLocalResource(URI.parse(request.url), fileService, extensionLocation, getRoots); - if (result.type === WebviewResourceResponse.Type.Success) { - return callback({ - data: Buffer.from(result.data.buffer), - mimeType: result.mimeType - }); - } - if (result.type === WebviewResourceResponse.Type.AccessDenied) { - console.error('Webview: Cannot load resource outside of protocol root'); - return callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); - } - } catch { - // noop + contents.session.protocol.registerBufferProtocol(protocol, async (request, callback: any) => { + try { + const result = await loadLocalResource(URI.parse(request.url), fileService, extensionLocation, getRoots); + if (result.type === WebviewResourceResponse.Type.Success) { + return callback({ + data: Buffer.from(result.data.buffer), + mimeType: result.mimeType + }); } + if (result.type === WebviewResourceResponse.Type.AccessDenied) { + console.error('Webview: Cannot load resource outside of protocol root'); + return callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); + } + } catch { + // noop + } - return callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); - }, (err) => { - err ? reject(err) : resolve(); - })); + return callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); + }); } From cee82c08874f81c21829d81d9f02efd5e26a2c2d Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 6 Mar 2020 11:54:49 -0800 Subject: [PATCH 058/137] Workaround fix #92170. Ideally we'd fix by tracking if the match region was totally removed on every change operation, but that seems costly. --- .../workbench/contrib/searchEditor/browser/searchEditorInput.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts index 698bb4c8f97..4b351522614 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts @@ -249,6 +249,7 @@ export class SearchEditorInput extends EditorInput { public getMatchRanges(): Range[] { return (this._cachedContentsModel?.getAllDecorations() ?? []) .filter(decoration => decoration.options.className === SearchEditorFindMatchClass) + .filter(({ range }) => !(range.startColumn === 1 && range.endColumn === 1)) .map(({ range }) => range); } From 223a90d3b38c10ca53a5635083a6dbf864e17705 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 6 Mar 2020 21:37:51 +0100 Subject: [PATCH 059/137] Fixes #73734: If the editor's container is scrollable, do not use fixedOverflowWidgets --- .../contrib/welcome/walkThrough/browser/walkThroughPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts index 1803459b953..7cc9d291293 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts @@ -426,7 +426,7 @@ export class WalkThroughPart extends BaseEditor { alwaysConsumeMouseWheel: false }, overviewRulerLanes: 3, - fixedOverflowWidgets: true, + fixedOverflowWidgets: false, lineNumbersMinChars: 1, minimap: { enabled: false }, }; From 6f230c5f04064262c60d993dd80c81af4a2738fe Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Fri, 6 Mar 2020 12:44:50 -0800 Subject: [PATCH 060/137] Expose functions under authentication namespace instead of providers array, #88309 --- src/vs/vscode.proposed.d.ts | 30 +++++++- .../workbench/api/common/extHost.api.impl.ts | 17 ++++- .../api/common/extHostAuthentication.ts | 73 ++++++++----------- 3 files changed, 71 insertions(+), 49 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 706ebf4325d..442e2651a96 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -35,7 +35,7 @@ declare module 'vscode' { readonly added: string[]; /** - * The ids of the [authenticationProvider](#AuthenticationProvider)s that have been removed.. + * The ids of the [authenticationProvider](#AuthenticationProvider)s that have been removed. */ readonly removed: string[]; } @@ -50,7 +50,7 @@ declare module 'vscode' { readonly displayName: string; /** - * A [enent](#Event) which fires when the array of sessions has changed, or data + * A [event](#Event) which fires when the array of sessions has changed, or data * within a session has changed. */ readonly onDidChangeSessions: Event; @@ -75,7 +75,31 @@ declare module 'vscode' { */ export const onDidChangeAuthenticationProviders: Event; - export const providers: ReadonlyArray; + /** + * Returns whether a provider with providerId is currently registered. + */ + export function hasProvider(providerId: string): boolean; + + /** + * Get existing authentication sessions. Rejects if a provider with providerId is not + * registered, or if the user does not consent to sharing authentication information with + * the extension. + */ + export function getSessions(providerId: string): Thenable; + + /** + * Prompt a user to login to create a new authenticaiton session. Rejects if a provider with + * providerId is not registered, or if the user does not consent to sharing authentication + * information with the extension. + */ + export function login(providerId: string, scopes: string[]): Thenable; + + /** + * A [event](#Event) which fires when the array of sessions has changed, or data + * within a session has changed for a provider. Fires with the ids of the providers + * that have had session data change. + */ + export const onDidChangeSessions: Event; } //#endregion diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index c57fae94bbd..409da2f66d3 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -185,12 +185,21 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerAuthenticationProvider(provider: vscode.AuthenticationProvider): vscode.Disposable { return extHostAuthentication.registerAuthenticationProvider(provider); }, - get providers() { - return extHostAuthentication.providers(extension); - }, get onDidChangeAuthenticationProviders(): Event { return extHostAuthentication.onDidChangeAuthenticationProviders; - } + }, + hasProvider(providerId: string): boolean { + return extHostAuthentication.hasProvider(providerId); + }, + getSessions(providerId: string): Thenable { + return extHostAuthentication.getSessions(extension, providerId); + }, + login(providerId: string, scopes: string[]): Thenable { + return extHostAuthentication.login(extension, providerId, scopes); + }, + get onDidChangeSessions(): Event { + return extHostAuthentication.onDidChangeSessions; + }, }; // namespace: commands diff --git a/src/vs/workbench/api/common/extHostAuthentication.ts b/src/vs/workbench/api/common/extHostAuthentication.ts index b3b2d4d0f4a..88ce55c51ea 100644 --- a/src/vs/workbench/api/common/extHostAuthentication.ts +++ b/src/vs/workbench/api/common/extHostAuthentication.ts @@ -10,36 +10,41 @@ import { IMainContext, MainContext, MainThreadAuthenticationShape, ExtHostAuthen import { Disposable } from 'vs/workbench/api/common/extHostTypes'; import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -export class AuthenticationProviderWrapper implements vscode.AuthenticationProvider { - readonly onDidChangeSessions: vscode.Event; +export class ExtHostAuthentication implements ExtHostAuthenticationShape { + private _proxy: MainThreadAuthenticationShape; + private _authenticationProviders: Map = new Map(); - constructor(private _requestingExtension: IExtensionDescription, - private _provider: vscode.AuthenticationProvider, - private _proxy: MainThreadAuthenticationShape) { + private _onDidChangeAuthenticationProviders = new Emitter(); + readonly onDidChangeAuthenticationProviders: Event = this._onDidChangeAuthenticationProviders.event; - this.onDidChangeSessions = this._provider.onDidChangeSessions; + private _onDidChangeSessions = new Emitter(); + readonly onDidChangeSessions: Event = this._onDidChangeSessions.event; + + constructor(mainContext: IMainContext) { + this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication); } - get id(): string { - return this._provider.id; + hasProvider(providerId: string): boolean { + return !!this._authenticationProviders.get(providerId); } - get displayName(): string { - return this._provider.displayName; - } + async getSessions(requestingExtension: IExtensionDescription, providerId: string): Promise { + const provider = this._authenticationProviders.get(providerId); + if (!provider) { + throw new Error(`No authentication provider with id '${providerId}' is currently registered.`); + } - async getSessions(): Promise> { - return (await this._provider.getSessions()).map(session => { + return (await provider.getSessions()).map(session => { return { id: session.id, accountName: session.accountName, scopes: session.scopes, getAccessToken: async () => { const isAllowed = await this._proxy.$getSessionsPrompt( - this._provider.id, - this.displayName, - ExtensionIdentifier.toKey(this._requestingExtension.identifier), - this._requestingExtension.displayName || this._requestingExtension.name); + provider.id, + provider.displayName, + ExtensionIdentifier.toKey(requestingExtension.identifier), + requestingExtension.displayName || requestingExtension.name); if (!isAllowed) { throw new Error('User did not consent to token access.'); @@ -51,35 +56,18 @@ export class AuthenticationProviderWrapper implements vscode.AuthenticationProvi }); } - async login(scopes: string[]): Promise { - const isAllowed = await this._proxy.$loginPrompt(this._provider.id, this.displayName, ExtensionIdentifier.toKey(this._requestingExtension.identifier), this._requestingExtension.displayName || this._requestingExtension.name); + async login(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise { + const provider = this._authenticationProviders.get(providerId); + if (!provider) { + throw new Error(`No authentication provider with id '${providerId}' is currently registered.`); + } + + const isAllowed = await this._proxy.$loginPrompt(provider.id, provider.displayName, ExtensionIdentifier.toKey(requestingExtension.identifier), requestingExtension.displayName || requestingExtension.name); if (!isAllowed) { throw new Error('User did not consent to login.'); } - return this._provider.login(scopes); - } - - logout(sessionId: string): Thenable { - return this._provider.logout(sessionId); - } -} - -export class ExtHostAuthentication implements ExtHostAuthenticationShape { - private _proxy: MainThreadAuthenticationShape; - private _authenticationProviders: Map = new Map(); - - private _onDidChangeAuthenticationProviders = new Emitter(); - readonly onDidChangeAuthenticationProviders: Event = this._onDidChangeAuthenticationProviders.event; - - constructor(mainContext: IMainContext) { - this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication); - } - - providers(requestingExtension: IExtensionDescription): vscode.AuthenticationProvider[] { - let providers: vscode.AuthenticationProvider[] = []; - this._authenticationProviders.forEach(provider => providers.push(new AuthenticationProviderWrapper(requestingExtension, provider, this._proxy))); - return providers; + return provider.login(scopes); } registerAuthenticationProvider(provider: vscode.AuthenticationProvider): vscode.Disposable { @@ -91,6 +79,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape { const listener = provider.onDidChangeSessions(_ => { this._proxy.$onDidChangeSessions(provider.id); + this._onDidChangeSessions.fire([provider.id]); }); this._proxy.$registerAuthenticationProvider(provider.id, provider.displayName); From 14657a93e945d98d1da18722f1a0ae20385387a4 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 6 Mar 2020 22:21:11 +0100 Subject: [PATCH 061/137] move viewlet & panel registry into views service --- src/vs/workbench/browser/parts/views/views.ts | 153 +++++++++--------- 1 file changed, 74 insertions(+), 79 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index c431d4e0904..4d4cb205a2d 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -486,11 +486,10 @@ export class ViewsService extends Disposable implements IViewsService { this._register(this.viewContainersRegistry.onDidRegister(({ viewContainer, viewContainerLocation }) => this.onDidRegisterViewContainer(viewContainer, viewContainerLocation))); } - registerViewPaneContainer(viewPaneContainer: ViewPaneContainer): ViewPaneContainer { + private registerViewPaneContainer(viewPaneContainer: ViewPaneContainer): void { this._register(viewPaneContainer.onDidAddViews(views => this.onViewsAdded(views))); this._register(viewPaneContainer.onDidChangeViewVisibility(view => this.onViewsVisibilityChanged(view, view.isBodyVisible()))); this._register(viewPaneContainer.onDidRemoveViews(views => this.onViewsRemoved(views))); - return viewPaneContainer; } private onViewsAdded(added: IView[]): void { @@ -520,7 +519,8 @@ export class ViewsService extends Disposable implements IViewsService { return contextKey; } - private onDidRegisterViewContainer(viewContainer: ViewContainer, location: ViewContainerLocation): void { + private onDidRegisterViewContainer(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void { + this.registerViewletOrPanel(viewContainer, viewContainerLocation); const viewDescriptorCollection = this.viewDescriptorService.getViewDescriptors(viewContainer); this.onViewDescriptorsAdded(viewDescriptorCollection.allViewDescriptors, viewContainer); this._register(viewDescriptorCollection.onDidChangeViews(({ added, removed }) => { @@ -698,6 +698,77 @@ export class ViewsService extends Disposable implements IViewsService { return null; } + + private registerViewletOrPanel(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void { + switch (viewContainerLocation) { + case ViewContainerLocation.Panel: + this.registerPanel(viewContainer); + break; + case ViewContainerLocation.Sidebar: + if (viewContainer.ctorDescriptor) { + this.registerViewlet(viewContainer); + } + break; + } + } + + private registerPanel(viewContainer: ViewContainer): void { + const that = this; + class PaneContainerPanel extends PaneCompositePanel { + constructor( + @ITelemetryService telemetryService: ITelemetryService, + @IStorageService storageService: IStorageService, + @IInstantiationService instantiationService: IInstantiationService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + ) { + // Use composite's instantiation service to get the editor progress service for any editors instantiated within the composite + const viewPaneContainer = (instantiationService as any).createInstance(viewContainer.ctorDescriptor!.ctor, ...(viewContainer.ctorDescriptor!.staticArguments || [])); + super(viewContainer.id, viewPaneContainer, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + that.registerViewPaneContainer(this.viewPaneContainer); + } + } + Registry.as(PanelExtensions.Panels).registerPanel(PanelDescriptor.create( + PaneContainerPanel, + viewContainer.id, + viewContainer.name, + isString(viewContainer.icon) ? viewContainer.icon : undefined, + viewContainer.order, + viewContainer.focusCommand?.id, + )); + } + + private registerViewlet(viewContainer: ViewContainer): void { + const that = this; + class PaneContainerViewlet extends Viewlet { + constructor( + @IConfigurationService configurationService: IConfigurationService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IStorageService storageService: IStorageService, + @IInstantiationService instantiationService: IInstantiationService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService, + ) { + // Use composite's instantiation service to get the editor progress service for any editors instantiated within the composite + const viewPaneContainer = (instantiationService as any).createInstance(viewContainer.ctorDescriptor!.ctor, ...(viewContainer.ctorDescriptor!.staticArguments || [])); + super(viewContainer.id, viewPaneContainer, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService, layoutService, configurationService); + that.registerViewPaneContainer(this.viewPaneContainer); + } + } + Registry.as(ViewletExtensions.Viewlets).registerViewlet(ViewletDescriptor.create( + PaneContainerViewlet, + viewContainer.id, + viewContainer.name, + isString(viewContainer.icon) ? viewContainer.icon : undefined, + viewContainer.order, + viewContainer.icon instanceof URI ? viewContainer.icon : undefined + )); + } } export function createFileIconThemableTreeContainerScope(container: HTMLElement, themeService: IThemeService): IDisposable { @@ -714,79 +785,3 @@ export function createFileIconThemableTreeContainerScope(container: HTMLElement, } registerSingleton(IViewsService, ViewsService); - -// Viewlets & Panels -(function registerViewletsAndPanels(): void { - const registerPanel = (viewContainer: ViewContainer): void => { - class PaneContainerPanel extends PaneCompositePanel { - constructor( - @ITelemetryService telemetryService: ITelemetryService, - @IStorageService storageService: IStorageService, - @IInstantiationService instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService, - @IWorkspaceContextService contextService: IWorkspaceContextService, - @IViewsService viewsService: ViewsService - ) { - // Use composite's instantiation service to get the editor progress service for any editors instantiated within the composite - const viewPaneContainer = viewsService.registerViewPaneContainer((instantiationService as any).createInstance(viewContainer.ctorDescriptor!.ctor, ...(viewContainer.ctorDescriptor!.staticArguments || []))); - super(viewContainer.id, viewPaneContainer, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); - } - } - Registry.as(PanelExtensions.Panels).registerPanel(PanelDescriptor.create( - PaneContainerPanel, - viewContainer.id, - viewContainer.name, - isString(viewContainer.icon) ? viewContainer.icon : undefined, - viewContainer.order, - viewContainer.focusCommand?.id, - )); - }; - - const registerViewlet = (viewContainer: ViewContainer): void => { - class PaneContainerViewlet extends Viewlet { - constructor( - @IConfigurationService configurationService: IConfigurationService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService contextService: IWorkspaceContextService, - @IStorageService storageService: IStorageService, - @IInstantiationService instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService, - @IViewsService viewsService: ViewsService - ) { - // Use composite's instantiation service to get the editor progress service for any editors instantiated within the composite - const viewPaneContainer = viewsService.registerViewPaneContainer((instantiationService as any).createInstance(viewContainer.ctorDescriptor!.ctor, ...(viewContainer.ctorDescriptor!.staticArguments || []))); - super(viewContainer.id, viewPaneContainer, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService, layoutService, configurationService); - } - } - const viewletDescriptor = ViewletDescriptor.create( - PaneContainerViewlet, - viewContainer.id, - viewContainer.name, - isString(viewContainer.icon) ? viewContainer.icon : undefined, - viewContainer.order, - viewContainer.icon instanceof URI ? viewContainer.icon : undefined - ); - - Registry.as(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor); - }; - - const viewContainerRegistry = Registry.as(ViewExtensions.ViewContainersRegistry); - viewContainerRegistry.getViewContainers(ViewContainerLocation.Panel).forEach(viewContainer => registerPanel(viewContainer)); - viewContainerRegistry.onDidRegister(({ viewContainer, viewContainerLocation }) => { - switch (viewContainerLocation) { - case ViewContainerLocation.Panel: - registerPanel(viewContainer); - return; - case ViewContainerLocation.Sidebar: - if (viewContainer.ctorDescriptor) { - registerViewlet(viewContainer); - } - return; - } - }); -})(); From 9b40aa3cb42f7cc7c073391abc7b93b46db21cc4 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sat, 7 Mar 2020 00:26:27 +0100 Subject: [PATCH 062/137] #92038 Move tree view away from get*Actions and use menus --- .../workbench/browser/parts/views/treeView.ts | 100 +++++++++++------- src/vs/workbench/common/views.ts | 3 - 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 3e68a7e5920..93485f37d59 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -7,12 +7,12 @@ import 'vs/css!./media/views'; import { Event, Emitter } from 'vs/base/common/event'; import { IDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IAction, ActionRunner, Action } from 'vs/base/common/actions'; +import { IAction, ActionRunner } from 'vs/base/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; +import { IMenuService, MenuId, MenuItemAction, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, ContextKeyExpr, ContextKeyEqualsExpr, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ITreeItemLabel, Extensions, IViewDescriptorService, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -92,14 +92,6 @@ export class TreeViewPane extends ViewPane { this.treeView.layout(height, width); } - getActions(): IAction[] { - return [...super.getActions(), ...this.treeView.getPrimaryActions()]; - } - - getSecondaryActions(): IAction[] { - return [...super.getSecondaryActions(), ...this.treeView.getSecondaryActions()]; - } - getOptimalWidth(): number { return this.treeView.getOptimalWidth(); } @@ -126,8 +118,11 @@ export class TreeView extends Disposable implements ITreeView { private isVisible: boolean = false; private _hasIconForParentNode = false; private _hasIconForLeafNode = false; - private _showCollapseAllAction = false; - private _showRefreshAction = false; + + private readonly collapseAllContextKey: RawContextKey; + private readonly collapseAllContext: IContextKey; + private readonly refreshContextKey: RawContextKey; + private readonly refreshContext: IContextKey; private focused: boolean = false; private domNode!: HTMLElement; @@ -175,10 +170,16 @@ export class TreeView extends Disposable implements ITreeView { @IContextMenuService private readonly contextMenuService: IContextMenuService, @IKeybindingService private readonly keybindingService: IKeybindingService, @INotificationService private readonly notificationService: INotificationService, - @IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService + @IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService, + @IContextKeyService contextKeyService: IContextKeyService ) { super(); this.root = new Root(); + this.collapseAllContextKey = new RawContextKey(`treeView.${this.id}.enableCollapseAll`, false); + this.collapseAllContext = this.collapseAllContextKey.bindTo(contextKeyService); + this.refreshContextKey = new RawContextKey(`treeView.${this.id}.enableRefresh`, false); + this.refreshContext = this.refreshContextKey.bindTo(contextKeyService); + this._register(this.themeService.onDidFileIconThemeChange(() => this.doRefresh([this.root]) /** soft refresh **/)); this._register(this.themeService.onDidColorThemeChange(() => this.doRefresh([this.root]) /** soft refresh **/)); this._register(this.configurationService.onDidChangeConfiguration(e => { @@ -191,6 +192,7 @@ export class TreeView extends Disposable implements ITreeView { this.tree?.updateOptions({ overrideStyles: { listBackground: this.viewLocation === ViewContainerLocation.Sidebar ? SIDE_BAR_BACKGROUND : PANEL_BACKGROUND } }); } })); + this.registerActions(); this.create(); } @@ -275,40 +277,61 @@ export class TreeView extends Disposable implements ITreeView { } get showCollapseAllAction(): boolean { - return this._showCollapseAllAction; + return !!this.collapseAllContext.get(); } set showCollapseAllAction(showCollapseAllAction: boolean) { - if (this._showCollapseAllAction !== !!showCollapseAllAction) { - this._showCollapseAllAction = !!showCollapseAllAction; - this._onDidChangeActions.fire(); - } + this.collapseAllContext.set(showCollapseAllAction); } get showRefreshAction(): boolean { - return this._showRefreshAction; + return !!this.refreshContext.get(); } set showRefreshAction(showRefreshAction: boolean) { - if (this._showRefreshAction !== !!showRefreshAction) { - this._showRefreshAction = !!showRefreshAction; - this._onDidChangeActions.fire(); - } + this.refreshContext.set(showRefreshAction); } - getPrimaryActions(): IAction[] { - const actions: IAction[] = []; - if (this.showRefreshAction) { - actions.push(new Action('vs.tree.refresh', localize('refresh', "Refresh"), 'monaco-tree-action codicon-refresh', true, () => this.refresh())); - } - if (this.showCollapseAllAction) { - actions.push(new Action('vs.tree.collapse', localize('collapseAll', "Collapse All"), 'monaco-tree-action codicon-collapse-all', true, () => this.tree ? new CollapseAllAction(this.tree, true).run() : Promise.resolve())); - } - return actions; - } - - getSecondaryActions(): IAction[] { - return []; + private registerActions() { + const that = this; + registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.actions.treeView.${that.id}.refresh`, + title: localize('refresh', "Refresh"), + menu: { + id: MenuId.ViewTitle, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.id), that.refreshContextKey), + group: 'navigation', + order: Number.MAX_SAFE_INTEGER - 1, + }, + icon: { id: 'codicon/refresh' } + }); + } + async run(): Promise { + return that.refresh(); + } + }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.actions.treeView.${that.id}.collapseAll`, + title: localize('collapseAll', "Collapse All"), + menu: { + id: MenuId.ViewTitle, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.id), that.collapseAllContextKey), + group: 'navigation', + order: Number.MAX_SAFE_INTEGER, + }, + icon: { id: 'codicon/collapse-all' } + }); + } + async run(): Promise { + if (that.tree) { + return new CollapseAllAction(that.tree, true).run(); + } + } + }); } setVisibility(isVisible: boolean): void { @@ -959,9 +982,10 @@ export class CustomTreeView extends TreeView { @IKeybindingService keybindingService: IKeybindingService, @INotificationService notificationService: INotificationService, @IViewDescriptorService viewDescriptorService: IViewDescriptorService, + @IContextKeyService contextKeyService: IContextKeyService, @IExtensionService private readonly extensionService: IExtensionService, ) { - super(id, title, themeService, instantiationService, commandService, configurationService, progressService, contextMenuService, keybindingService, notificationService, viewDescriptorService); + super(id, title, themeService, instantiationService, commandService, configurationService, progressService, contextMenuService, keybindingService, notificationService, viewDescriptorService, contextKeyService); } setVisibility(isVisible: boolean): void { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 1cc7f5b050f..dbd8958dc5c 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -508,9 +508,6 @@ export interface ITreeView extends IDisposable { setFocus(item: ITreeItem): void; - getPrimaryActions(): IAction[]; - - getSecondaryActions(): IAction[]; } export interface IRevealOptions { From 8202955fee126fdcbcb6d1858457d89d5479f18e Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 6 Mar 2020 16:00:47 -0800 Subject: [PATCH 063/137] fix width issue with custom dialogs --- src/vs/base/browser/ui/dialog/dialog.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/dialog/dialog.css b/src/vs/base/browser/ui/dialog/dialog.css index 876f2168fe3..911b5616e70 100644 --- a/src/vs/base/browser/ui/dialog/dialog.css +++ b/src/vs/base/browser/ui/dialog/dialog.css @@ -25,7 +25,7 @@ flex-direction: column-reverse; width: min-content; min-width: 500px; - max-width: 90%; + max-width: 90vw; min-height: 75px; padding: 10px; transform: translate3d(0px, 0px, 0px); From 3444dd91a67f33686a960d4446dd802e4ed2b587 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Wed, 4 Mar 2020 15:54:45 -0500 Subject: [PATCH 064/137] Adds timeline filter context menu --- .../contrib/timeline/browser/timelinePane.ts | 108 +++++++----------- .../contrib/timeline/common/timeline.ts | 7 +- .../timeline/common/timelineService.ts | 2 +- 3 files changed, 50 insertions(+), 67 deletions(-) diff --git a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts index 9c5881e6e64..4f91deaa1ec 100644 --- a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts +++ b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts @@ -18,23 +18,23 @@ import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/vie import { ResourceNavigator, WorkbenchObjectTree } from 'vs/platform/list/browser/listService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ITimelineService, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvidersChangeEvent, TimelineRequest, Timeline, TimelinePaneId } from 'vs/workbench/contrib/timeline/common/timeline'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { SideBySideEditor, toResource } from 'vs/workbench/common/editor'; -import { ICommandService, CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; +import { ICommandService } from 'vs/platform/commands/common/commands'; import { IThemeService, LIGHT, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { IViewDescriptorService } from 'vs/workbench/common/views'; import { basename } from 'vs/base/common/path'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { debounce } from 'vs/base/common/decorators'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IActionViewItemProvider, ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IAction, ActionRunner } from 'vs/base/common/actions'; +import { IActionViewItemProvider, ActionBar, ActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; +import { IAction, ActionRunner, Action } from 'vs/base/common/actions'; import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { MenuItemAction, IMenuService, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; +import { MenuItemAction, IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { fromNow } from 'vs/base/common/date'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -85,8 +85,6 @@ interface TimelineCursors { more: boolean; } -export const TimelineFollowActiveEditorContext = new RawContextKey('timelineFollowActiveEditor', true); - export class TimelinePane extends ViewPane { static readonly TITLE = localize('timeline', 'Timeline'); @@ -99,8 +97,6 @@ export class TimelinePane extends ViewPane { private _menus: TimelinePaneMenus; private _visibilityDisposables: DisposableStore | undefined; - private _followActiveEditorContext: IContextKey; - private _excludedSources: Set; private _cursorsByProvider: Map = new Map(); private _items: { element: TreeElement }[] = []; @@ -126,13 +122,10 @@ export class TimelinePane extends ViewPane { super({ ...options, titleMenuId: MenuId.TimelineTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this._menus = this._register(this.instantiationService.createInstance(TimelinePaneMenus, this.id)); - this._register(this.instantiationService.createInstance(TimelinePaneCommands, this)); const scopedContextKeyService = this._register(this.contextKeyService.createScoped()); scopedContextKeyService.createKey('view', TimelinePaneId); - this._followActiveEditorContext = TimelineFollowActiveEditorContext.bindTo(this.contextKeyService); - this._excludedSources = new Set(configurationService.getValue('timeline.excludeSources')); configurationService.onDidChangeConfiguration(this.onConfigurationChanged, this); @@ -149,7 +142,7 @@ export class TimelinePane extends ViewPane { } this._followActiveEditor = value; - this._followActiveEditorContext.set(value); + this.updateActions(); if (value) { this.onActiveEditorChanged(); @@ -180,6 +173,7 @@ export class TimelinePane extends ViewPane { } this._excludedSources = new Set(this.configurationService.getValue('timeline.excludeSources')); + this.updateActions(); this.loadTimeline(true); } @@ -205,6 +199,8 @@ export class TimelinePane extends ViewPane { } private onProvidersChanged(e: TimelineProvidersChangeEvent) { + this.updateActions(); + if (e.removed) { for (const source of e.removed) { this.replaceItems(source); @@ -305,7 +301,7 @@ export class TimelinePane extends ViewPane { return; } - const filteredSources = (sources ?? this.timelineService.getSources()).filter(s => !this._excludedSources.has(s)); + const filteredSources = (sources ?? this.timelineService.getSources().map(s => s.id)).filter(s => !this._excludedSources.has(s)); if (filteredSources.length === 0) { if (reset) { this.refresh(); @@ -603,6 +599,39 @@ export class TimelinePane extends ViewPane { this.refresh(); } + getActions(): IAction[] { + return [ + ...super.getActions(), + this.followActiveEditor + ? new Action('toggleFollowActiveEditorCommand', localize('timeline.toggleFollowActiveEditorCommand.stop', "Stop following the Active Editor"), 'explorer-action codicon-eye', true, () => Promise.resolve(this.followActiveEditor = !this.followActiveEditor)) + : new Action('toggleFollowActiveEditorCommand', localize('timeline.toggleFollowActiveEditorCommand.follow', "Follow the Active Editor"), 'explorer-action codicon-eye-closed', true, () => Promise.resolve(this.followActiveEditor = !this.followActiveEditor)), + new Action('refresh', localize('refresh', "Refresh"), 'explorer-action codicon-refresh', true, () => Promise.resolve(this.reset())), + ]; + } + + getSecondaryActions(): IAction[] { + const actions: IAction[] = [new Separator()]; + + const excluded = new Set(this._excludedSources); + + for (const source of this.timelineService.getSources()) { + const action = new Action(`filter:${source.id}`, localize('timeline.filterSource', "Include: {0}", source.label), undefined, true, () => { + if (excluded.has(source.id)) { + excluded.delete(source.id); + } else { + excluded.add(source.id); + } + this.configurationService.updateValue('timeline.excludeSources', [...excluded.keys()]); + return Promise.resolve(); + }); + action.checked = !excluded.has(source.id); + + actions.push(action); + } + + return [...super.getSecondaryActions(), ...actions]; + } + focus(): void { super.focus(); this._tree.domFocus(); @@ -895,57 +924,6 @@ class TimelineTreeRenderer implements ITreeRenderer this._pane.reset(); - } - - toggleFollowActiveEditorCommand(): ICommandHandler { - return (accessor, arg) => this._pane.followActiveEditor = !this._pane.followActiveEditor; - } -} - class TimelinePaneMenus extends Disposable { constructor( diff --git a/src/vs/workbench/contrib/timeline/common/timeline.ts b/src/vs/workbench/contrib/timeline/common/timeline.ts index d9e4720eb00..6555bc8deb6 100644 --- a/src/vs/workbench/contrib/timeline/common/timeline.ts +++ b/src/vs/workbench/contrib/timeline/common/timeline.ts @@ -69,6 +69,11 @@ export interface TimelineProvider extends TimelineProviderDescriptor, IDisposabl provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: InternalTimelineOptions): Promise; } +export interface TimelineSource { + id: string; + label: string; +} + export interface TimelineProviderDescriptor { id: string; label: string; @@ -98,7 +103,7 @@ export interface ITimelineService { registerTimelineProvider(provider: TimelineProvider): IDisposable; unregisterTimelineProvider(id: string): void; - getSources(): string[]; + getSources(): TimelineSource[]; getTimeline(id: string, uri: URI, options: TimelineOptions, tokenSource: CancellationTokenSource, internalOptions?: InternalTimelineOptions): TimelineRequest | undefined; diff --git a/src/vs/workbench/contrib/timeline/common/timelineService.ts b/src/vs/workbench/contrib/timeline/common/timelineService.ts index fc996a3d8c5..5d2b7242c50 100644 --- a/src/vs/workbench/contrib/timeline/common/timelineService.ts +++ b/src/vs/workbench/contrib/timeline/common/timelineService.ts @@ -98,7 +98,7 @@ export class TimelineService implements ITimelineService { } getSources() { - return [...this._providers.keys()]; + return [...this._providers.values()].map(p => ({ id: p.id, label: p.label })); } getTimeline(id: string, uri: URI, options: TimelineOptions, tokenSource: CancellationTokenSource, internalOptions?: InternalTimelineOptions) { From 9f29782486dd19378ee1dceb0cb4064100096f73 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Fri, 6 Mar 2020 19:41:34 -0500 Subject: [PATCH 065/137] Allows menus to override some command props --- src/vs/platform/actions/common/actions.ts | 40 +++++++++++++---------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 72dc61aa5af..ab37df3e9fa 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -373,7 +373,7 @@ export interface IAction2Options extends ICommandAction { /** * One or many menu items. */ - menu?: OneOrN<{ id: MenuId } & Omit>; + menu?: OneOrN<{ id: MenuId } & Omit & { command?: Partial> }>; /** * One keybinding. @@ -396,39 +396,43 @@ export function registerAction2(ctor: { new(): Action2 }): IDisposable { const disposables = new DisposableStore(); const action = new ctor(); + const { f1, menu: menus, keybinding, description, ...command } = action.desc; + // command disposables.add(CommandsRegistry.registerCommand({ - id: action.desc.id, + id: command.id, handler: (accessor, ...args) => action.run(accessor, ...args), - description: action.desc.description, + description: description, })); // menu - if (Array.isArray(action.desc.menu)) { - for (let item of action.desc.menu) { - disposables.add(MenuRegistry.appendMenuItem(item.id, { command: action.desc, ...item })); + if (Array.isArray(menus)) { + for (let item of menus) { + const { command: commandOverrides, ...menu } = item; + disposables.add(MenuRegistry.appendMenuItem(item.id, { command: { ...command, ...commandOverrides }, ...menu })); } - } else if (action.desc.menu) { - disposables.add(MenuRegistry.appendMenuItem(action.desc.menu.id, { command: action.desc, ...action.desc.menu })); + } else if (menus) { + const { command: commandOverrides, ...menu } = menus; + disposables.add(MenuRegistry.appendMenuItem(menu.id, { command: { ...command, ...commandOverrides }, ...menu })); } - if (action.desc.f1) { - disposables.add(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: action.desc, ...action.desc })); + if (f1) { + disposables.add(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: command })); } // keybinding - if (Array.isArray(action.desc.keybinding)) { - for (let item of action.desc.keybinding) { + if (Array.isArray(keybinding)) { + for (let item of keybinding) { KeybindingsRegistry.registerKeybindingRule({ ...item, - id: action.desc.id, - when: ContextKeyExpr.and(action.desc.precondition, item.when) + id: command.id, + when: ContextKeyExpr.and(command.precondition, item.when) }); } - } else if (action.desc.keybinding) { + } else if (keybinding) { KeybindingsRegistry.registerKeybindingRule({ - ...action.desc.keybinding, - id: action.desc.id, - when: ContextKeyExpr.and(action.desc.precondition, action.desc.keybinding.when) + ...keybinding, + id: command.id, + when: ContextKeyExpr.and(command.precondition, keybinding.when) }); } From 59c57e1e899db397deb331f13e1c8c431c7dcb93 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Fri, 6 Mar 2020 19:43:25 -0500 Subject: [PATCH 066/137] Stringifies non-intrinsic config in context keys --- src/vs/platform/contextkey/browser/contextKeyService.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/platform/contextkey/browser/contextKeyService.ts b/src/vs/platform/contextkey/browser/contextKeyService.ts index 58d6e846e52..8724786b589 100644 --- a/src/vs/platform/contextkey/browser/contextKeyService.ts +++ b/src/vs/platform/contextkey/browser/contextKeyService.ts @@ -142,6 +142,8 @@ class ConfigAwareContextValuesContainer extends Context { case 'string': value = configValue; break; + default: + value = JSON.stringify(configValue); } this._values.set(key, value); From b9877ccc888876e8b0f4cf804473d5d1a361f3c0 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Fri, 6 Mar 2020 19:44:39 -0500 Subject: [PATCH 067/137] Converts back to using MenuRegistry for commands --- .../contrib/timeline/browser/timelinePane.ts | 179 ++++++++++++------ 1 file changed, 123 insertions(+), 56 deletions(-) diff --git a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts index 4f91deaa1ec..b96337ce6f5 100644 --- a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts +++ b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts @@ -18,9 +18,9 @@ import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/vie import { ResourceNavigator, WorkbenchObjectTree } from 'vs/platform/list/browser/listService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ITimelineService, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvidersChangeEvent, TimelineRequest, Timeline, TimelinePaneId } from 'vs/workbench/contrib/timeline/common/timeline'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { SideBySideEditor, toResource } from 'vs/workbench/common/editor'; @@ -31,12 +31,13 @@ import { basename } from 'vs/base/common/path'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { debounce } from 'vs/base/common/decorators'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IActionViewItemProvider, ActionBar, ActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IAction, ActionRunner, Action } from 'vs/base/common/actions'; +import { IActionViewItemProvider, ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; +import { IAction, ActionRunner } from 'vs/base/common/actions'; import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { MenuItemAction, IMenuService, MenuId } from 'vs/platform/actions/common/actions'; +import { MenuItemAction, IMenuService, MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { fromNow } from 'vs/base/common/date'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { escapeRegExpCharacters } from 'vs/base/common/strings'; const InitialPageSize = 20; const SubsequentPageSize = 40; @@ -85,8 +86,10 @@ interface TimelineCursors { more: boolean; } +export const TimelineFollowActiveEditorContext = new RawContextKey('timelineFollowActiveEditor', true); + export class TimelinePane extends ViewPane { - static readonly TITLE = localize('timeline', 'Timeline'); + static readonly TITLE = localize('timeline', "Timeline"); private _$container!: HTMLElement; private _$message!: HTMLDivElement; @@ -94,9 +97,11 @@ export class TimelinePane extends ViewPane { private _$tree!: HTMLDivElement; private _tree!: WorkbenchObjectTree; private _treeRenderer: TimelineTreeRenderer | undefined; - private _menus: TimelinePaneMenus; + private commands: TimelinePaneCommands; private _visibilityDisposables: DisposableStore | undefined; + private _followActiveEditorContext: IContextKey; + private _excludedSources: Set; private _cursorsByProvider: Map = new Map(); private _items: { element: TreeElement }[] = []; @@ -121,11 +126,13 @@ export class TimelinePane extends ViewPane { ) { super({ ...options, titleMenuId: MenuId.TimelineTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); - this._menus = this._register(this.instantiationService.createInstance(TimelinePaneMenus, this.id)); + this.commands = this._register(this.instantiationService.createInstance(TimelinePaneCommands, this)); const scopedContextKeyService = this._register(this.contextKeyService.createScoped()); scopedContextKeyService.createKey('view', TimelinePaneId); + this._followActiveEditorContext = TimelineFollowActiveEditorContext.bindTo(this.contextKeyService); + this._excludedSources = new Set(configurationService.getValue('timeline.excludeSources')); configurationService.onDidChangeConfiguration(this.onConfigurationChanged, this); @@ -142,7 +149,7 @@ export class TimelinePane extends ViewPane { } this._followActiveEditor = value; - this.updateActions(); + this._followActiveEditorContext.set(value); if (value) { this.onActiveEditorChanged(); @@ -163,6 +170,7 @@ export class TimelinePane extends ViewPane { } this._uri = uri; + this.titleDescription = uri ? basename(uri.fsPath) : ''; this._treeRenderer?.setUri(uri); this.loadTimeline(true); } @@ -173,7 +181,6 @@ export class TimelinePane extends ViewPane { } this._excludedSources = new Set(this.configurationService.getValue('timeline.excludeSources')); - this.updateActions(); this.loadTimeline(true); } @@ -199,8 +206,6 @@ export class TimelinePane extends ViewPane { } private onProvidersChanged(e: TimelineProvidersChangeEvent) { - this.updateActions(); - if (e.removed) { for (const source of e.removed) { this.replaceItems(source); @@ -599,39 +604,6 @@ export class TimelinePane extends ViewPane { this.refresh(); } - getActions(): IAction[] { - return [ - ...super.getActions(), - this.followActiveEditor - ? new Action('toggleFollowActiveEditorCommand', localize('timeline.toggleFollowActiveEditorCommand.stop', "Stop following the Active Editor"), 'explorer-action codicon-eye', true, () => Promise.resolve(this.followActiveEditor = !this.followActiveEditor)) - : new Action('toggleFollowActiveEditorCommand', localize('timeline.toggleFollowActiveEditorCommand.follow', "Follow the Active Editor"), 'explorer-action codicon-eye-closed', true, () => Promise.resolve(this.followActiveEditor = !this.followActiveEditor)), - new Action('refresh', localize('refresh', "Refresh"), 'explorer-action codicon-refresh', true, () => Promise.resolve(this.reset())), - ]; - } - - getSecondaryActions(): IAction[] { - const actions: IAction[] = [new Separator()]; - - const excluded = new Set(this._excludedSources); - - for (const source of this.timelineService.getSources()) { - const action = new Action(`filter:${source.id}`, localize('timeline.filterSource', "Include: {0}", source.label), undefined, true, () => { - if (excluded.has(source.id)) { - excluded.delete(source.id); - } else { - excluded.add(source.id); - } - this.configurationService.updateValue('timeline.excludeSources', [...excluded.keys()]); - return Promise.resolve(); - }); - action.checked = !excluded.has(source.id); - - actions.push(action); - } - - return [...super.getSecondaryActions(), ...actions]; - } - focus(): void { super.focus(); this._tree.domFocus(); @@ -665,6 +637,8 @@ export class TimelinePane extends ViewPane { } protected renderBody(container: HTMLElement): void { + super.renderBody(container); + this._$container = container; DOM.addClasses(container, 'tree-explorer-viewlet-tree-view', 'timeline-tree-view'); @@ -678,7 +652,7 @@ export class TimelinePane extends ViewPane { // DOM.addClass(this._treeElement, 'show-file-icons'); container.appendChild(this._$tree); - this._treeRenderer = this.instantiationService.createInstance(TimelineTreeRenderer, this._menus); + this._treeRenderer = this.instantiationService.createInstance(TimelineTreeRenderer, this.commands); this._tree = >this.instantiationService.createInstance(WorkbenchObjectTree, 'TimelinePane', this._$tree, new TimelineListVirtualDelegate(), [this._treeRenderer], { identityProvider: new TimelineIdentityProvider(), @@ -691,7 +665,7 @@ export class TimelinePane extends ViewPane { const customTreeNavigator = ResourceNavigator.createTreeResourceNavigator(this._tree, { openOnFocus: false, openOnSelection: false }); this._register(customTreeNavigator); - this._register(this._tree.onContextMenu(e => this.onContextMenu(this._menus, e))); + this._register(this._tree.onContextMenu(e => this.onContextMenu(this.commands, e))); this._register(this._tree.onDidChangeSelection(e => this.ensureValidItems())); this._register( customTreeNavigator.onDidOpenResource(e => { @@ -741,7 +715,7 @@ export class TimelinePane extends ViewPane { this.message = file ? localize('timeline.loading', 'Loading timeline for {0}...', file) : ''; } - private onContextMenu(menus: TimelinePaneMenus, treeEvent: ITreeContextMenuEvent): void { + private onContextMenu(commands: TimelinePaneCommands, treeEvent: ITreeContextMenuEvent): void { const item = treeEvent.element; if (item === null) { return; @@ -756,7 +730,7 @@ export class TimelinePane extends ViewPane { } this._tree.setFocus([item]); - const actions = menus.getResourceContextActions(item); + const actions = commands.getItemContextActions(item); if (!actions.length) { return; } @@ -865,7 +839,7 @@ class TimelineTreeRenderer implements ITreeRenderer this.updateTimelineSourceFilters())); + this.updateTimelineSourceFilters(); } - getResourceActions(element: TreeElement): IAction[] { + getItemActions(element: TreeElement): IAction[] { return this.getActions(MenuId.TimelineItemContext, { key: 'timelineItem', value: element.contextValue }).primary; } - getResourceContextActions(element: TreeElement): IAction[] { + getItemContextActions(element: TreeElement): IAction[] { return this.getActions(MenuId.TimelineItemContext, { key: 'timelineItem', value: element.contextValue }).secondary; } private getActions(menuId: MenuId, context: { key: string, value?: string }): { primary: IAction[]; secondary: IAction[]; } { const contextKeyService = this.contextKeyService.createScoped(); - contextKeyService.createKey('view', this.id); + contextKeyService.createKey('view', this.pane.id); contextKeyService.createKey(context.key, context.value); const menu = this.menuService.createMenu(menuId, contextKeyService); @@ -959,4 +993,37 @@ class TimelinePaneMenus extends Disposable { return result; } + + private updateTimelineSourceFilters() { + this.sourceDisposables.clear(); + + const excluded = new Set(this.configurationService.getValue('timeline.excludeSources') ?? []); + + for (const source of this.timelineService.getSources()) { + this.sourceDisposables.add(registerAction2(class extends Action2 { + constructor() { + super({ + id: `timeline.toggleExcludeSource:${source.id}`, + title: { value: localize('timeline.filterSource', "Include: {0}", source.label), original: `Include: ${source.label}` }, + category: { value: localize('timeline', "Timeline"), original: 'Timeline' }, + menu: { + id: MenuId.TimelineTitle, + group: '2_sources', + }, + toggled: ContextKeyExpr.regex(`config.timeline.excludeSources`, new RegExp(`\\b${escapeRegExpCharacters(source.id)}\\b`)).negate() + }); + } + run(accessor: ServicesAccessor, ...args: any[]) { + if (excluded.has(source.id)) { + excluded.delete(source.id); + } else { + excluded.add(source.id); + } + + const configurationService = accessor.get(IConfigurationService); + configurationService.updateValue('timeline.excludeSources', [...excluded.keys()]); + } + })); + } + } } From 9e2573a9d3380d24f82503593732f28fcdd57976 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 6 Mar 2020 18:48:10 -0800 Subject: [PATCH 068/137] Add command for deleting a block of results. Closes #92169. --- .../search/browser/search.contribution.ts | 13 +++++ .../searchEditor/browser/searchEditor.ts | 51 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index c7a28d962bb..950b1f164ba 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -80,6 +80,19 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'workbench.action.searchEditor.deleteResultBlock', + weight: KeybindingWeight.WorkbenchContrib, + when: SearchEditorConstants.InSearchEditor, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Backspace, + handler: accessor => { + const contextService = accessor.get(IContextKeyService).getContext(document.activeElement); + if (contextService.getValue(SearchEditorConstants.InSearchEditor.serialize())) { + (accessor.get(IEditorService).activeEditorPane as SearchEditor).deleteResultBlock(); + } + } +}); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: Constants.FocusSearchFromResults, weight: KeybindingWeight.WorkbenchContrib, diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index f8e1edbb330..61717d14936 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -299,6 +299,57 @@ export class SearchEditor extends BaseTextEditor { this.toggleIncludesExcludes(); } + deleteResultBlock() { + const linesToDelete = new Set(); + + const selections = this.searchResultEditor.getSelections(); + const model = this.searchResultEditor.getModel(); + if (!(selections && model)) { return; } + + const maxLine = model.getLineCount(); + const minLine = 1; + + const deleteUp = (start: number) => { + for (let cursor = start; cursor >= minLine; cursor--) { + const line = model.getLineContent(cursor); + linesToDelete.add(cursor); + if (line[0] !== undefined && line[0] !== ' ') { + break; + } + } + }; + + const deleteDown = (start: number): number | undefined => { + linesToDelete.add(start); + for (let cursor = start + 1; cursor <= maxLine; cursor++) { + const line = model.getLineContent(cursor); + if (line[0] !== undefined && line[0] !== ' ') { + return cursor; + } + linesToDelete.add(cursor); + } + return; + }; + + const endingCursorLines: Array = []; + for (const selection of selections) { + const lineNumber = selection.startLineNumber; + endingCursorLines.push(deleteDown(lineNumber)); + deleteUp(lineNumber); + for (let inner = selection.startLineNumber; inner <= selection.endLineNumber; inner++) { + linesToDelete.add(inner); + } + } + + if (endingCursorLines.length === 0) { endingCursorLines.push(1); } + + const isDefined = (x: T | undefined): x is T => x !== undefined; + + model.pushEditOperations(this.searchResultEditor.getSelections(), + [...linesToDelete].map(line => ({ range: new Range(line, 1, line + 1, 1), text: '' })), + () => endingCursorLines.filter(isDefined).map(line => new Selection(line, 1, line, 1))); + } + cleanState() { this.getInput()?.setDirty(false); } From b643600eb466c007d537feea4da2d43234666742 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 08:28:42 +0100 Subject: [PATCH 069/137] quick access - operate on picker from providers --- .../parts/quickinput/browser/quickInput.ts | 7 +-- .../parts/quickinput/common/quickInput.ts | 6 +++ .../quickinput/browser/quickAccess.ts | 48 +++++++++++++++---- .../quickinput/browser/quickAccessHelp.ts | 21 ++++++-- .../platform/quickinput/common/quickAccess.ts | 34 +++++++++---- .../browser/parts/quickopen/quickopen.ts | 10 ++-- 6 files changed, 98 insertions(+), 28 deletions(-) diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 322fa757457..e4654f52d6e 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -402,7 +402,6 @@ class QuickPick extends QuickInput implements IQuickPi quickNavigate: IQuickNavigateConfiguration | undefined; - get value() { return this._value; } @@ -412,6 +411,8 @@ class QuickPick extends QuickInput implements IQuickPi this.update(); } + filterValue = (value: string) => value; + get placeholder() { return this._placeholder; } @@ -597,7 +598,7 @@ class QuickPick extends QuickInput implements IQuickPi return; } this._value = value; - this.ui.list.filter(this.ui.inputBox.value); + this.ui.list.filter(this.filterValue(this.ui.inputBox.value)); this.trySelectFirst(); this.onDidChangeValueEmitter.fire(value); })); @@ -771,7 +772,7 @@ class QuickPick extends QuickInput implements IQuickPi if (this.itemsUpdated) { this.itemsUpdated = false; this.ui.list.setElements(this.items); - this.ui.list.filter(this.ui.inputBox.value); + this.ui.list.filter(this.filterValue(this.ui.inputBox.value)); this.ui.checkAll.checked = this.ui.list.getAllVisibleChecked(); this.ui.visibleCount.setCount(this.ui.list.getVisibleCount()); this.ui.count.setCount(this.ui.list.getCheckedCount()); diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index 10c8255a444..0535a70e9c7 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -156,6 +156,12 @@ export interface IQuickPick extends IQuickInput { value: string; + /** + * A method that allows to massage the value used + * for filtering, e.g, to remove certain parts. + */ + filterValue: (value: string) => string; + placeholder: string | undefined; readonly onDidChangeValue: Event; diff --git a/src/vs/platform/quickinput/browser/quickAccess.ts b/src/vs/platform/quickinput/browser/quickAccess.ts index f733bc8ecbf..a7f9ca9c010 100644 --- a/src/vs/platform/quickinput/browser/quickAccess.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -5,15 +5,17 @@ import 'vs/platform/quickinput/browser/quickAccessHelp'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { IQuickAccessController, IQuickAccessProvider, IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; -import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { once } from 'vs/base/common/functional'; export class QuickAccessController extends Disposable implements IQuickAccessController { private readonly registry = Registry.as(Extensions.Quickaccess); + private readonly mapProviderToDescriptor = new Map(); constructor( @IQuickInputService private readonly quickInputService: IQuickInputService, @@ -22,16 +24,42 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon super(); } - async show(prefix = ''): Promise { - const provider = this.getOrInstantiateProvider(prefix); + show(value = ''): void { - provider.provide(this.quickInputService, CancellationToken.None); + // Find provider for the value to show + const [provider, prefix] = this.getOrInstantiateProvider(value); + + // Create a picker for the provider to use with the initial value + // and adjust the filtering to exclude the prefix from filtering + const picker = this.quickInputService.createQuickPick(); + picker.value = value; + picker.valueSelection = [value.length, value.length]; + picker.filterValue = (value: string) => value.substring(prefix.length); + + // Cleanup when picker hides + const disposables = new DisposableStore(); + once(picker.onDidHide)(() => disposables.dispose()); + + // Whenever the value changes, check if the provider has + // changed and if so - re-create the picker from the beginning + disposables.add(picker.onDidChangeValue(value => { + const [providerForValue] = this.getOrInstantiateProvider(value); + if (providerForValue !== provider) { + this.show(value); + } + })); + + // Create a cancellation token source that is valid + // as long as the picker has not been closed + const cts = new CancellationTokenSource(); + disposables.add(toDisposable(() => cts.dispose(true))); + + // Finally ask provider to fill the picker as needed + provider.provide(picker, cts.token); } - private mapProviderToDescriptor = new Map(); - - private getOrInstantiateProvider(prefix: string): IQuickAccessProvider { - const providerDescriptor = this.registry.getQuickAccessProvider(prefix) || this.registry.defaultProvider; + private getOrInstantiateProvider(value: string): [IQuickAccessProvider, string /* prefix */] { + const providerDescriptor = this.registry.getQuickAccessProvider(value) || this.registry.defaultProvider; let provider = this.mapProviderToDescriptor.get(providerDescriptor); if (!provider) { @@ -39,6 +67,6 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon this.mapProviderToDescriptor.set(providerDescriptor, provider); } - return provider; + return [provider, providerDescriptor.prefix]; } } diff --git a/src/vs/platform/quickinput/browser/quickAccessHelp.ts b/src/vs/platform/quickinput/browser/quickAccessHelp.ts index ffdb95d4865..2c69614a0c9 100644 --- a/src/vs/platform/quickinput/browser/quickAccessHelp.ts +++ b/src/vs/platform/quickinput/browser/quickAccessHelp.ts @@ -3,17 +3,21 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; +import { QuickPickInput, IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IQuickAccessProvider, IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; import { CancellationToken } from 'vs/base/common/cancellation'; import { localize } from 'vs/nls'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { once } from 'vs/base/common/functional'; class HelpQuickAccessProvider implements IQuickAccessProvider { private readonly registry = Registry.as(Extensions.Quickaccess); - async provide(service: IQuickInputService, token: CancellationToken): Promise { + constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } + + async provide(picker: IQuickPick, token: CancellationToken): Promise { const picks: QuickPickInput[] = []; for (const provider of this.registry.getQuickAccessProviders()) { @@ -25,7 +29,18 @@ class HelpQuickAccessProvider implements IQuickAccessProvider { } } - await service.pick(picks); + const disposables = new DisposableStore(); + once(token.onCancellationRequested)(() => disposables.dispose()); + + disposables.add(picker.onDidAccept(() => { + const items = picker.selectedItems; + if (items.length === 1) { + this.quickInputService.quickAccess.show(items[0].label); + } + })); + + picker.items = picks; + picker.show(); } } diff --git a/src/vs/platform/quickinput/common/quickAccess.ts b/src/vs/platform/quickinput/common/quickAccess.ts index eaa37e0b957..263c1d625c3 100644 --- a/src/vs/platform/quickinput/common/quickAccess.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; import { first } from 'vs/base/common/arrays'; import { startsWith } from 'vs/base/common/strings'; @@ -14,9 +13,9 @@ import { assertIsDefined } from 'vs/base/common/types'; export interface IQuickAccessController { /** - * Open the quick access picker with the optional prefix. + * Open the quick access picker with the optional value prefilled. */ - show(prefix?: string): Promise; + show(value?: string): void; } export interface IQuickAccessProvider { @@ -24,10 +23,12 @@ export interface IQuickAccessProvider { /** * Called whenever a prefix was typed into quick pick that matches the provider. * - * @param service the service to use to drive the quick input widget - * @param token cancellation support + * @param picker the picker to use for showing provider results. + * @param token providers have to check the cancellation token everytime after + * a long running operation because it could be that the picker has been closed + * or changed meanwhile. */ - provide(service: IQuickInputService, token: CancellationToken): Promise; + provide(picker: IQuickPick, token: CancellationToken): Promise; } export interface QuickAccessProviderHelp { @@ -50,9 +51,26 @@ export interface QuickAccessProviderHelp { } export interface IQuickAccessProviderDescriptor { - readonly ctor: IConstructorSignature0; + + /** + * The actual provider that will be instantiated as needed. + */ + readonly ctor: { new(...services: any /* TS BrandedService but no clue how to type this properly */[]): IQuickAccessProvider }; + + /** + * The prefix for quick access picker to use the provider for. + */ readonly prefix: string; + + /** + * Documentation for the provider in the quick access help. + */ readonly helpEntries: QuickAccessProviderHelp[]; + + /** + * A context key that will be set automatically when the + * picker for the provider is showing. + */ readonly contextKey?: string; } diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index 49a6ef401fc..1d32e5304c4 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -209,12 +209,14 @@ export class LegacyQuickInputQuickOpenController extends Disposable { Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); class SampleQuickAccessProvider implements IQuickAccessProvider { - async provide(service: IQuickInputService, token: CancellationToken): Promise { - service.pick([ + async provide(picker: IQuickPick, token: CancellationToken): Promise { + picker.items = [ { label: '1' }, { label: '2' }, { label: '3' } - ]); + ]; + + picker.show(); } } From 2c7c95fb32a034fcb421a24c168e55c24ad27238 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 09:46:53 +0100 Subject: [PATCH 070/137] quick access - test coverage --- .../parts/quickinput/browser/quickInput.ts | 14 +- .../parts/quickinput/common/quickInput.ts | 10 +- .../quickinput/browser/quickAccess.ts | 14 +- .../platform/quickinput/common/quickAccess.ts | 11 +- .../browser/parts/quickopen/quickopen.ts | 8 +- .../test/browser/quickAccess.test.ts | 159 ++++++++++++++++++ .../test/browser/workbenchTestServices.ts | 31 +++- 7 files changed, 220 insertions(+), 27 deletions(-) create mode 100644 src/vs/workbench/test/browser/quickAccess.test.ts diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index e4654f52d6e..ed56b52dd03 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -129,6 +129,10 @@ type Visibilities = { class QuickInput extends Disposable implements IQuickInput { + private readonly onDidTriggerButtonEmitter = this._register(new Emitter()); + private readonly onDidHideEmitter = this._register(new Emitter()); + private readonly onDisposeEmitter = this._register(new Emitter()); + private _title: string | undefined; private _description: string | undefined; private _steps: number | undefined; @@ -140,8 +144,6 @@ class QuickInput extends Disposable implements IQuickInput { private _ignoreFocusOut = false; private _buttons: IQuickInputButton[] = []; private buttonsUpdated = false; - private readonly onDidTriggerButtonEmitter = this._register(new Emitter()); - private readonly onDidHideEmitter = this._register(new Emitter()); protected readonly visibleDisposables = this._register(new DisposableStore()); @@ -235,7 +237,7 @@ class QuickInput extends Disposable implements IQuickInput { this.update(); } - onDidTriggerButton = this.onDidTriggerButtonEmitter.event; + readonly onDidTriggerButton = this.onDidTriggerButtonEmitter.event; show(): void { if (this.visible) { @@ -266,7 +268,7 @@ class QuickInput extends Disposable implements IQuickInput { this.onDidHideEmitter.fire(); } - onDidHide = this.onDidHideEmitter.event; + readonly onDidHide = this.onDidHideEmitter.event; protected update() { if (!this.visible) { @@ -360,8 +362,12 @@ class QuickInput extends Disposable implements IQuickInput { } } + readonly onDispose = this.onDisposeEmitter.event; + public dispose(): void { this.hide(); + this.onDisposeEmitter.fire(); + super.dispose(); } } diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index 0535a70e9c7..4300551997b 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -6,6 +6,7 @@ import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; +import { IDisposable } from 'vs/base/common/lifecycle'; export interface IQuickPickItem { type?: 'item'; @@ -125,7 +126,10 @@ export interface IInputOptions { validateInput?: (input: string) => Promise; } -export interface IQuickInput { +export interface IQuickInput extends IDisposable { + + readonly onDidHide: Event; + readonly onDispose: Event; title: string | undefined; @@ -146,10 +150,6 @@ export interface IQuickInput { show(): void; hide(): void; - - onDidHide: Event; - - dispose(): void; } export interface IQuickPick extends IQuickInput { diff --git a/src/vs/platform/quickinput/browser/quickAccess.ts b/src/vs/platform/quickinput/browser/quickAccess.ts index a7f9ca9c010..df2922392a1 100644 --- a/src/vs/platform/quickinput/browser/quickAccess.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -4,19 +4,22 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/platform/quickinput/browser/quickAccessHelp'; -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { IQuickAccessController, IQuickAccessProvider, IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { once } from 'vs/base/common/functional'; +import { Event } from 'vs/base/common/event'; export class QuickAccessController extends Disposable implements IQuickAccessController { private readonly registry = Registry.as(Extensions.Quickaccess); private readonly mapProviderToDescriptor = new Map(); + private lastActivePicker: IQuickPick | undefined = undefined; + constructor( @IQuickInputService private readonly quickInputService: IQuickInputService, @IInstantiationService private readonly instantiationService: IInstantiationService @@ -26,19 +29,22 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon show(value = ''): void { + // Hide any previous picker if any + this.lastActivePicker?.dispose(); + // Find provider for the value to show const [provider, prefix] = this.getOrInstantiateProvider(value); // Create a picker for the provider to use with the initial value // and adjust the filtering to exclude the prefix from filtering - const picker = this.quickInputService.createQuickPick(); + const picker = this.lastActivePicker = this.quickInputService.createQuickPick(); picker.value = value; picker.valueSelection = [value.length, value.length]; picker.filterValue = (value: string) => value.substring(prefix.length); - // Cleanup when picker hides + // Cleanup when picker hides or gets disposed const disposables = new DisposableStore(); - once(picker.onDidHide)(() => disposables.dispose()); + once(Event.any(picker.onDidHide, picker.onDispose))(() => disposables.dispose()); // Whenever the value changes, check if the provider has // changed and if so - re-create the picker from the beginning diff --git a/src/vs/platform/quickinput/common/quickAccess.ts b/src/vs/platform/quickinput/common/quickAccess.ts index 263c1d625c3..6c638252ed6 100644 --- a/src/vs/platform/quickinput/common/quickAccess.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -9,6 +9,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { first } from 'vs/base/common/arrays'; import { startsWith } from 'vs/base/common/strings'; import { assertIsDefined } from 'vs/base/common/types'; +import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; export interface IQuickAccessController { @@ -28,7 +29,7 @@ export interface IQuickAccessProvider { * a long running operation because it could be that the picker has been closed * or changed meanwhile. */ - provide(picker: IQuickPick, token: CancellationToken): Promise; + provide(picker: IQuickPick, token: CancellationToken): void; } export interface QuickAccessProviderHelp { @@ -88,7 +89,7 @@ export interface IQuickAccessRegistry { /** * Registers a quick access provider to the platform. */ - registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): void; + registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): IDisposable; /** * Get all registered quick access providers. @@ -108,16 +109,18 @@ class QuickAccessRegistry implements IQuickAccessRegistry { get defaultProvider(): IQuickAccessProviderDescriptor { return assertIsDefined(this._defaultProvider); } set defaultProvider(provider: IQuickAccessProviderDescriptor) { this._defaultProvider = provider; } - registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): void { + registerQuickAccessProvider(provider: IQuickAccessProviderDescriptor): IDisposable { this.providers.push(provider); // sort the providers by decreasing prefix length, such that longer // prefixes take priority: 'ext' vs 'ext install' - the latter should win this.providers.sort((providerA, providerB) => providerB.prefix.length - providerA.prefix.length); + + return toDisposable(() => this.providers.splice(this.providers.indexOf(provider), 1)); } getQuickAccessProviders(): IQuickAccessProviderDescriptor[] { - return this.providers.slice(0); + return [this.defaultProvider, ...this.providers]; } getQuickAccessProvider(prefix: string): IQuickAccessProviderDescriptor | undefined { diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index 1d32e5304c4..b2cb9d7a08f 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -209,11 +209,11 @@ export class LegacyQuickInputQuickOpenController extends Disposable { Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); class SampleQuickAccessProvider implements IQuickAccessProvider { - async provide(picker: IQuickPick, token: CancellationToken): Promise { + provide(picker: IQuickPick, token: CancellationToken): void { picker.items = [ - { label: '1' }, - { label: '2' }, - { label: '3' } + { label: 'Hello World' }, + { label: 'Lorem Ipsum' }, + { label: 'Something Else' } ]; picker.show(); diff --git a/src/vs/workbench/test/browser/quickAccess.test.ts b/src/vs/workbench/test/browser/quickAccess.test.ts new file mode 100644 index 00000000000..da960ecb035 --- /dev/null +++ b/src/vs/workbench/test/browser/quickAccess.test.ts @@ -0,0 +1,159 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IQuickAccessRegistry, Extensions, IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; +import { IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { timeout } from 'vs/base/common/async'; + +suite('QuickAccess', () => { + + let instantiationService: IInstantiationService; + let accessor: TestServiceAccessor; + + let provider1Called = false; + let provider1Canceled = false; + + let provider2Called = false; + let provider2Canceled = false; + + let provider3Called = false; + let provider3Canceled = false; + + let provider4Called = false; + let provider4Canceled = false; + + class TestProvider1 implements IQuickAccessProvider { + provide(picker: IQuickPick, token: CancellationToken) { + assert.ok(picker); + provider1Called = true; + token.onCancellationRequested(() => provider1Canceled = true); + + picker.show(); + } + } + + class TestProvider2 implements IQuickAccessProvider { + provide(picker: IQuickPick, token: CancellationToken) { + assert.ok(picker); + provider2Called = true; + token.onCancellationRequested(() => provider2Canceled = true); + + // Not calling picker show explicitly to test bad provider + // picker.show(); + } + } + + class TestProvider3 implements IQuickAccessProvider { + + constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } + + async provide(picker: IQuickPick, token: CancellationToken) { + assert.ok(picker); + provider3Called = true; + token.onCancellationRequested(() => provider3Canceled = true); + + picker.show(); + + // bring up provider #4 + await timeout(0); + this.quickInputService.quickAccess.show(providerDescriptor4.prefix); + } + } + + class TestProvider4 implements IQuickAccessProvider { + provide(picker: IQuickPick, token: CancellationToken) { + assert.ok(picker); + provider4Called = true; + token.onCancellationRequested(() => provider4Canceled = true); + + picker.show(); + } + } + + const providerDescriptor1 = { ctor: TestProvider1, prefix: 'test', helpEntries: [] }; + const providerDescriptor2 = { ctor: TestProvider2, prefix: 'test something', helpEntries: [] }; + const providerDescriptor3 = { ctor: TestProvider3, prefix: 'default', helpEntries: [] }; + const providerDescriptor4 = { ctor: TestProvider4, prefix: 'changed', helpEntries: [] }; + + setup(() => { + instantiationService = workbenchInstantiationService(); + accessor = instantiationService.createInstance(TestServiceAccessor); + }); + + test('registry', () => { + const registry = (Registry.as(Extensions.Quickaccess)); + const initialSize = registry.getQuickAccessProviders().length; + + const disposable = registry.registerQuickAccessProvider(providerDescriptor1); + + assert(registry.getQuickAccessProvider('test') === providerDescriptor1); + + const providers = registry.getQuickAccessProviders(); + assert(providers.some(provider => provider.prefix === 'test')); + + disposable.dispose(); + assert.ok(!registry.getQuickAccessProvider('test')); + assert.equal(registry.getQuickAccessProviders().length - initialSize, 0); + }); + + test('provider', async () => { + const registry = (Registry.as(Extensions.Quickaccess)); + const defaultProvider = registry.defaultProvider; + + const disposables = new DisposableStore(); + + disposables.add(registry.registerQuickAccessProvider(providerDescriptor1)); + disposables.add(registry.registerQuickAccessProvider(providerDescriptor2)); + disposables.add(registry.registerQuickAccessProvider(providerDescriptor4)); + registry.defaultProvider = providerDescriptor3; + + accessor.quickInputService.quickAccess.show('test'); + assert.equal(provider1Called, true); + assert.equal(provider2Called, false); + assert.equal(provider3Called, false); + assert.equal(provider4Called, false); + assert.equal(provider1Canceled, false); + assert.equal(provider2Canceled, false); + assert.equal(provider3Canceled, false); + assert.equal(provider4Canceled, false); + provider1Called = false; + + accessor.quickInputService.quickAccess.show('test something'); + assert.equal(provider1Called, false); + assert.equal(provider2Called, true); + assert.equal(provider3Called, false); + assert.equal(provider4Called, false); + assert.equal(provider1Canceled, true); + assert.equal(provider2Canceled, false); + assert.equal(provider3Canceled, false); + assert.equal(provider4Canceled, false); + provider2Called = false; + provider1Canceled = false; + + accessor.quickInputService.quickAccess.show('usedefault'); + assert.equal(provider1Called, false); + assert.equal(provider2Called, false); + assert.equal(provider3Called, true); + assert.equal(provider4Called, false); + assert.equal(provider1Canceled, false); + assert.equal(provider2Canceled, true); + assert.equal(provider3Canceled, false); + assert.equal(provider4Canceled, false); + + await timeout(1); + + assert.equal(provider3Canceled, true); + assert.equal(provider4Called, true); + + disposables.dispose(); + registry.defaultProvider = defaultProvider; + }); +}); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 7672be5ade0..ef9c609850a 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -98,13 +98,16 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEditorService'; import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { IDiffEditor } from 'vs/editor/common/editorCommon'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; export import TestTextResourcePropertiesService = CommonWorkbenchTestServices.TestTextResourcePropertiesService; export import TestContextService = CommonWorkbenchTestServices.TestContextService; export import TestStorageService = CommonWorkbenchTestServices.TestStorageService; export import TestWorkingCopyService = CommonWorkbenchTestServices.TestWorkingCopyService; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { IDiffEditor } from 'vs/editor/common/editorCommon'; +import { IListService } from 'vs/platform/list/browser/listService'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); @@ -130,9 +133,11 @@ export function workbenchInstantiationService(overrides?: { textFileService?: (i instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService)); instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService)); instantiationService.stub(IStorageService, new TestStorageService()); - instantiationService.stub(IWorkbenchLayoutService, new TestLayoutService()); + const layoutService = new TestLayoutService(); + instantiationService.stub(IWorkbenchLayoutService, layoutService); instantiationService.stub(IDialogService, new TestDialogService()); - instantiationService.stub(IAccessibilityService, new TestAccessibilityService()); + const accessibilityService = new TestAccessibilityService(); + instantiationService.stub(IAccessibilityService, accessibilityService); instantiationService.stub(IFileDialogService, new TestFileDialogService()); instantiationService.stub(IModeService, instantiationService.createInstance(ModeServiceImpl)); instantiationService.stub(IHistoryService, new TestHistoryService()); @@ -145,7 +150,8 @@ export function workbenchInstantiationService(overrides?: { textFileService?: (i instantiationService.stub(INotificationService, new TestNotificationService()); instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService)); instantiationService.stub(IMenuService, new TestMenuService()); - instantiationService.stub(IKeybindingService, new MockKeybindingService()); + const keybindingService = new MockKeybindingService(); + instantiationService.stub(IKeybindingService, keybindingService); instantiationService.stub(IDecorationsService, new TestDecorationsService()); instantiationService.stub(IExtensionService, new TestExtensionService()); instantiationService.stub(IWorkingCopyFileService, instantiationService.createInstance(WorkingCopyFileService)); @@ -162,6 +168,8 @@ export function workbenchInstantiationService(overrides?: { textFileService?: (i instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new CodeEditorService(editorService, themeService)); instantiationService.stub(IViewletService, new TestViewletService()); + instantiationService.stub(IListService, new TestListService()); + instantiationService.stub(IQuickInputService, new QuickInputService(TestEnvironmentService, configService, instantiationService, keybindingService, contextKeyService, themeService, accessibilityService, layoutService)); return instantiationService; } @@ -184,7 +192,8 @@ export class TestServiceAccessor { @IUntitledTextEditorService public untitledTextEditorService: UntitledTextEditorService, @IConfigurationService public testConfigurationService: TestConfigurationService, @IBackupFileService public backupFileService: TestBackupFileService, - @IHostService public hostService: TestHostService + @IHostService public hostService: TestHostService, + @IQuickInputService public quickInputService: IQuickInputService ) { } } @@ -1065,3 +1074,13 @@ export class TestEditorPart extends EditorPart { } } } + +export class TestListService implements IListService { + _serviceBrand: undefined; + + lastFocusedList: any | undefined = undefined; + + register(): IDisposable { + return Disposable.None; + } +} From dbcd07627454740f6f02b3cda14f13595067b0c4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 10:47:47 +0100 Subject: [PATCH 071/137] quick access - implement help provider --- .../quickinput/browser/quickInputList.ts | 22 +++++--- .../parts/quickinput/common/quickInput.ts | 1 + .../quickinput/browser/quickAccessHelp.ts | 55 ++++++++++++------- .../browser/parts/quickopen/quickopen.ts | 2 +- 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index 051f7f56333..bc730ff2a9b 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -35,6 +35,7 @@ interface IListElement { readonly saneLabel: string; readonly saneDescription?: string; readonly saneDetail?: string; + readonly saneAriaLabel: string; readonly checked: boolean; readonly separator?: IQuickPickSeparator; readonly fireButtonTriggered: (event: IQuickPickItemButtonEvent) => void; @@ -46,6 +47,7 @@ class ListElement implements IListElement { saneLabel!: string; saneDescription?: string; saneDetail?: string; + saneAriaLabel!: string; hidden = false; private readonly _onChecked = new Emitter(); onChecked = this._onChecked.event; @@ -148,10 +150,7 @@ class ListElementRenderer implements IListRenderer s && parseCodicons(s).text) - .filter(s => !!s) - .join(', ')); + data.entry.setAttribute('aria-label', element.saneAriaLabel); // Separator if (element.separator && element.separator.label) { @@ -364,12 +363,21 @@ export class QuickInputList { this.elements = inputElements.reduce((result, item, index) => { if (item.type !== 'separator') { const previous = index && inputElements[index - 1]; + const saneLabel = item.label && item.label.replace(/\r?\n/g, ' '); + const saneDescription = item.description && item.description.replace(/\r?\n/g, ' '); + const saneDetail = item.detail && item.detail.replace(/\r?\n/g, ' '); + const saneAriaLabel = item.ariaLabel || [saneLabel, saneDescription, saneDetail] + .map(s => s && parseCodicons(s).text) + .filter(s => !!s) + .join(', '); + result.push(new ListElement({ index, item, - saneLabel: item.label && item.label.replace(/\r?\n/g, ' '), - saneDescription: item.description && item.description.replace(/\r?\n/g, ' '), - saneDetail: item.detail && item.detail.replace(/\r?\n/g, ' '), + saneLabel, + saneDescription, + saneDetail, + saneAriaLabel, checked: false, separator: previous && previous.type === 'separator' ? previous : undefined, fireButtonTriggered diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index 4300551997b..46acde67797 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -14,6 +14,7 @@ export interface IQuickPickItem { label: string; description?: string; detail?: string; + ariaLabel?: string; iconClasses?: string[]; buttons?: IQuickInputButton[]; picked?: boolean; diff --git a/src/vs/platform/quickinput/browser/quickAccessHelp.ts b/src/vs/platform/quickinput/browser/quickAccessHelp.ts index 2c69614a0c9..b148593ff77 100644 --- a/src/vs/platform/quickinput/browser/quickAccessHelp.ts +++ b/src/vs/platform/quickinput/browser/quickAccessHelp.ts @@ -17,30 +17,47 @@ class HelpQuickAccessProvider implements IQuickAccessProvider { constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } - async provide(picker: IQuickPick, token: CancellationToken): Promise { - const picks: QuickPickInput[] = []; + provide(picker: IQuickPick, token: CancellationToken): void { + const disposables = new DisposableStore(); + once(token.onCancellationRequested)(() => disposables.dispose()); - for (const provider of this.registry.getQuickAccessProviders()) { - for (const helpEntries of provider.helpEntries) { - picks.push({ - label: helpEntries.prefix || provider.prefix, - description: helpEntries.description + // Open a picker with the selected value if picked + disposables.add(picker.onDidAccept(() => { + const items = picker.selectedItems; + if (items.length === 1) { + this.quickInputService.quickAccess.show(`${items[0].label} `); + } + })); + + // Fill in all providers separated by editor/global scope + const { editorProviders, globalProviders } = this.getQuickAccessProviders(); + picker.items = [ + { label: localize('globalCommands', "global commands"), type: 'separator' }, + ...globalProviders, + { label: localize('editorCommands', "editor commands"), type: 'separator' }, + ...editorProviders + ]; + + picker.show(); + } + + private getQuickAccessProviders(): { editorProviders: QuickPickInput[], globalProviders: QuickPickInput[] } { + const globalProviders: QuickPickInput[] = []; + const editorProviders: QuickPickInput[] = []; + + for (const provider of this.registry.getQuickAccessProviders().sort((p1, p2) => p1.prefix.localeCompare(p2.prefix))) { + for (const helpEntry of provider.helpEntries) { + const label = helpEntry.prefix || provider.prefix || '\u2026' /* ... */; + + (helpEntry.needsEditor ? editorProviders : globalProviders).push({ + label, + description: helpEntry.description, + ariaLabel: localize('entryAriaLabel', "{0}, picker help", label) }); } } - const disposables = new DisposableStore(); - once(token.onCancellationRequested)(() => disposables.dispose()); - - disposables.add(picker.onDidAccept(() => { - const items = picker.selectedItems; - if (items.length === 1) { - this.quickInputService.quickAccess.show(items[0].label); - } - })); - - picker.items = picks; - picker.show(); + return { editorProviders, globalProviders }; } } diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index b2cb9d7a08f..29a81d9202f 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -221,7 +221,7 @@ class SampleQuickAccessProvider implements IQuickAccessProvider { } const quickAccessRegistry = Registry.as(QuickinputExtensions.Quickaccess); -['', '>', '@'].forEach(prefix => { +['', '>', '@', 'edt', 'edt active', 'edt mru', 'view'].forEach(prefix => { const provider = { ctor: SampleQuickAccessProvider, prefix, From e8c44468779cbda9e5e5170214750b0969a93fa0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 10:56:41 +0100 Subject: [PATCH 072/137] quick access help bugixes --- .../quickinput/browser/quickAccessHelp.ts | 20 ++++++++++++------- .../browser/parts/quickopen/quickopen.ts | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/quickinput/browser/quickAccessHelp.ts b/src/vs/platform/quickinput/browser/quickAccessHelp.ts index b148593ff77..267a86b818e 100644 --- a/src/vs/platform/quickinput/browser/quickAccessHelp.ts +++ b/src/vs/platform/quickinput/browser/quickAccessHelp.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { QuickPickInput, IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IQuickAccessProvider, IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -11,13 +11,17 @@ import { localize } from 'vs/nls'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { once } from 'vs/base/common/functional'; +interface IQuickAccessHelpPickItem extends IQuickPickItem { + prefix: string; +} + class HelpQuickAccessProvider implements IQuickAccessProvider { private readonly registry = Registry.as(Extensions.Quickaccess); constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } - provide(picker: IQuickPick, token: CancellationToken): void { + provide(picker: IQuickPick, token: CancellationToken): void { const disposables = new DisposableStore(); once(token.onCancellationRequested)(() => disposables.dispose()); @@ -25,7 +29,7 @@ class HelpQuickAccessProvider implements IQuickAccessProvider { disposables.add(picker.onDidAccept(() => { const items = picker.selectedItems; if (items.length === 1) { - this.quickInputService.quickAccess.show(`${items[0].label} `); + this.quickInputService.quickAccess.show(`${items[0].prefix} `); } })); @@ -41,15 +45,17 @@ class HelpQuickAccessProvider implements IQuickAccessProvider { picker.show(); } - private getQuickAccessProviders(): { editorProviders: QuickPickInput[], globalProviders: QuickPickInput[] } { - const globalProviders: QuickPickInput[] = []; - const editorProviders: QuickPickInput[] = []; + private getQuickAccessProviders(): { editorProviders: IQuickAccessHelpPickItem[], globalProviders: IQuickAccessHelpPickItem[] } { + const globalProviders: IQuickAccessHelpPickItem[] = []; + const editorProviders: IQuickAccessHelpPickItem[] = []; for (const provider of this.registry.getQuickAccessProviders().sort((p1, p2) => p1.prefix.localeCompare(p2.prefix))) { for (const helpEntry of provider.helpEntries) { - const label = helpEntry.prefix || provider.prefix || '\u2026' /* ... */; + const prefix = helpEntry.prefix || provider.prefix; + const label = prefix || '\u2026' /* ... */; (helpEntry.needsEditor ? editorProviders : globalProviders).push({ + prefix, label, description: helpEntry.description, ariaLabel: localize('entryAriaLabel', "{0}, picker help", label) diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index 29a81d9202f..6317058023a 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -221,11 +221,11 @@ class SampleQuickAccessProvider implements IQuickAccessProvider { } const quickAccessRegistry = Registry.as(QuickinputExtensions.Quickaccess); -['', '>', '@', 'edt', 'edt active', 'edt mru', 'view'].forEach(prefix => { +['', '>', '@', ':', 'edt', 'edt active', 'edt mru', 'view'].forEach(prefix => { const provider = { ctor: SampleQuickAccessProvider, prefix, - helpEntries: [{ description: `Sample Provider with prefix ${prefix}`, needsEditor: false }] + helpEntries: [{ description: `Sample Provider with prefix ${prefix}`, needsEditor: prefix === '@' || prefix === ':' }] }; if (!prefix) { From c2a6e09c7d5a9b5cfd090ced5c1d4548cb2d64b5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 10:57:53 +0100 Subject: [PATCH 073/137] quick access :lipstick: --- src/vs/platform/quickinput/common/quickAccess.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/quickinput/common/quickAccess.ts b/src/vs/platform/quickinput/common/quickAccess.ts index 6c638252ed6..ac45cc1c104 100644 --- a/src/vs/platform/quickinput/common/quickAccess.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -32,7 +32,7 @@ export interface IQuickAccessProvider { provide(picker: IQuickPick, token: CancellationToken): void; } -export interface QuickAccessProviderHelp { +export interface IQuickAccessProviderHelp { /** * The prefix to show for the help entry. If not provided, @@ -66,7 +66,7 @@ export interface IQuickAccessProviderDescriptor { /** * Documentation for the provider in the quick access help. */ - readonly helpEntries: QuickAccessProviderHelp[]; + readonly helpEntries: IQuickAccessProviderHelp[]; /** * A context key that will be set automatically when the From 37e042c29163321ff167aa3e4c335c54f0602a1e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 16:26:44 +0100 Subject: [PATCH 074/137] quick access - contribute help for standalone and workbench separately --- build/lib/i18n.resources.json | 4 ++++ src/vs/editor/common/standaloneStrings.ts | 4 ++++ src/vs/editor/editor.main.ts | 1 + .../quickAccess/standaloneHelpQuickAccess.ts | 15 ++++++++++++ ...{quickAccessHelp.ts => helpQuickAccess.ts} | 23 ++++++++----------- .../quickinput/browser/quickAccess.ts | 1 - .../browser/quickAccess.contribution.ts | 15 ++++++++++++ src/vs/workbench/workbench.common.main.ts | 3 +++ 8 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts rename src/vs/platform/quickinput/browser/{quickAccessHelp.ts => helpQuickAccess.ts} (73%) create mode 100644 src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 2da9d84eaa5..3494753b30a 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -122,6 +122,10 @@ "name": "vs/workbench/contrib/preferences", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/quickaccess", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/quickopen", "project": "vscode-workbench" diff --git a/src/vs/editor/common/standaloneStrings.ts b/src/vs/editor/common/standaloneStrings.ts index 130e4884908..164708bd894 100644 --- a/src/vs/editor/common/standaloneStrings.ts +++ b/src/vs/editor/common/standaloneStrings.ts @@ -45,6 +45,10 @@ export namespace GoToLineNLS { export const gotoLineActionLabel = nls.localize('gotoLineActionLabel', "Go to Line..."); } +export namespace QuickHelpNLS { + export const helpQuickAccessActionLabel = nls.localize('helpQuickAccess', "Show all Quick Access Providers"); +} + export namespace QuickCommandNLS { export const ariaLabelEntryWithKey = nls.localize('ariaLabelEntryWithKey', "{0}, {1}, commands"); export const ariaLabelEntry = nls.localize('ariaLabelEntry', "{0}, commands"); diff --git a/src/vs/editor/editor.main.ts b/src/vs/editor/editor.main.ts index 2566ecac65b..0868614ed38 100644 --- a/src/vs/editor/editor.main.ts +++ b/src/vs/editor/editor.main.ts @@ -10,6 +10,7 @@ import 'vs/editor/standalone/browser/inspectTokens/inspectTokens'; import 'vs/editor/standalone/browser/quickOpen/gotoLine'; import 'vs/editor/standalone/browser/quickOpen/quickCommand'; import 'vs/editor/standalone/browser/quickOpen/quickOutline'; +import 'vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess'; import 'vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch'; import 'vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast'; diff --git a/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts b/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts new file mode 100644 index 00000000000..d521022ee81 --- /dev/null +++ b/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Registry } from 'vs/platform/registry/common/platform'; +import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; +import { QuickHelpNLS } from 'vs/editor/common/standaloneStrings'; +import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuickAccess'; + +Registry.as(Extensions.Quickaccess).defaultProvider = { + ctor: HelpQuickAccessProvider, + prefix: '', + helpEntries: [{ description: QuickHelpNLS.helpQuickAccessActionLabel, needsEditor: false }] +}; diff --git a/src/vs/platform/quickinput/browser/quickAccessHelp.ts b/src/vs/platform/quickinput/browser/helpQuickAccess.ts similarity index 73% rename from src/vs/platform/quickinput/browser/quickAccessHelp.ts rename to src/vs/platform/quickinput/browser/helpQuickAccess.ts index 267a86b818e..9742ff6a23a 100644 --- a/src/vs/platform/quickinput/browser/quickAccessHelp.ts +++ b/src/vs/platform/quickinput/browser/helpQuickAccess.ts @@ -11,25 +11,25 @@ import { localize } from 'vs/nls'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { once } from 'vs/base/common/functional'; -interface IQuickAccessHelpPickItem extends IQuickPickItem { +interface IHelpQuickAccessPickItem extends IQuickPickItem { prefix: string; } -class HelpQuickAccessProvider implements IQuickAccessProvider { +export class HelpQuickAccessProvider implements IQuickAccessProvider { private readonly registry = Registry.as(Extensions.Quickaccess); constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } - provide(picker: IQuickPick, token: CancellationToken): void { + provide(picker: IQuickPick, token: CancellationToken): void { const disposables = new DisposableStore(); once(token.onCancellationRequested)(() => disposables.dispose()); // Open a picker with the selected value if picked disposables.add(picker.onDidAccept(() => { - const items = picker.selectedItems; - if (items.length === 1) { - this.quickInputService.quickAccess.show(`${items[0].prefix} `); + const [item] = picker.selectedItems; + if (item) { + this.quickInputService.quickAccess.show(item.prefix); } })); @@ -45,9 +45,9 @@ class HelpQuickAccessProvider implements IQuickAccessProvider { picker.show(); } - private getQuickAccessProviders(): { editorProviders: IQuickAccessHelpPickItem[], globalProviders: IQuickAccessHelpPickItem[] } { - const globalProviders: IQuickAccessHelpPickItem[] = []; - const editorProviders: IQuickAccessHelpPickItem[] = []; + private getQuickAccessProviders(): { editorProviders: IHelpQuickAccessPickItem[], globalProviders: IHelpQuickAccessPickItem[] } { + const globalProviders: IHelpQuickAccessPickItem[] = []; + const editorProviders: IHelpQuickAccessPickItem[] = []; for (const provider of this.registry.getQuickAccessProviders().sort((p1, p2) => p1.prefix.localeCompare(p2.prefix))) { for (const helpEntry of provider.helpEntries) { @@ -67,8 +67,3 @@ class HelpQuickAccessProvider implements IQuickAccessProvider { } } -Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ - ctor: HelpQuickAccessProvider, - prefix: '?', - helpEntries: [{ description: localize('quickAccessHelp', "Show all Quick Access Providers"), needsEditor: false }] -}); diff --git a/src/vs/platform/quickinput/browser/quickAccess.ts b/src/vs/platform/quickinput/browser/quickAccess.ts index df2922392a1..f58d550fa5c 100644 --- a/src/vs/platform/quickinput/browser/quickAccess.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/platform/quickinput/browser/quickAccessHelp'; import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { IQuickAccessController, IQuickAccessProvider, IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess'; diff --git a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts new file mode 100644 index 00000000000..f5a304b7bed --- /dev/null +++ b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuickAccess'; + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ + ctor: HelpQuickAccessProvider, + prefix: '?', + helpEntries: [{ description: localize('helpQuickAccess', "Show all Quick Access Providers"), needsEditor: false }] +}); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 402477b4e3f..ec284cc0e58 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -148,6 +148,9 @@ import 'vs/workbench/contrib/logs/common/logs.contribution'; // Quick Open Handlers import 'vs/workbench/contrib/quickopen/browser/quickopen.contribution'; +// Quick Access Providers +import 'vs/workbench/contrib/quickaccess/browser/quickAccess.contribution'; + // Explorer import 'vs/workbench/contrib/files/browser/explorerViewlet'; import 'vs/workbench/contrib/files/browser/fileActions.contribution'; From 618ea672fa5a3856b75681009c5cccfa4b9f2245 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 7 Mar 2020 16:34:39 +0100 Subject: [PATCH 075/137] quick input - allow to set aria-label --- src/vs/base/browser/ui/inputbox/inputBox.ts | 4 ++++ .../parts/quickinput/browser/quickInput.ts | 18 +++++++++++++++--- .../parts/quickinput/browser/quickInputBox.ts | 8 ++++++++ .../base/parts/quickinput/common/quickInput.ts | 2 ++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 96d5013909b..e5ccf0f4bf2 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -248,6 +248,10 @@ export class InputBox extends Widget { } } + public getAriaLabel(): string { + return this.ariaLabel; + } + public get mirrorElement(): HTMLElement | undefined { return this.mirror; } diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index ed56b52dd03..db75187e82e 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -374,9 +374,10 @@ class QuickInput extends Disposable implements IQuickInput { class QuickPick extends QuickInput implements IQuickPick { - private static readonly INPUT_BOX_ARIA_LABEL = localize('quickInputBox.ariaLabel', "Type to narrow down results."); + private static readonly DEFAULT_ARIA_LABEL = localize('quickInputBox.ariaLabel', "Type to narrow down results."); private _value = ''; + private _ariaLabel = QuickPick.DEFAULT_ARIA_LABEL; private _placeholder: string | undefined; private readonly onDidChangeValueEmitter = this._register(new Emitter()); private readonly onDidAcceptEmitter = this._register(new Emitter()); @@ -419,6 +420,15 @@ class QuickPick extends QuickInput implements IQuickPi filterValue = (value: string) => value; + set ariaLabel(ariaLabel: string) { + this._ariaLabel = ariaLabel || QuickPick.DEFAULT_ARIA_LABEL; + this.update(); + } + + get ariaLabel() { + return this._ariaLabel; + } + get placeholder() { return this._placeholder; } @@ -775,6 +785,9 @@ class QuickPick extends QuickInput implements IQuickPi if (this.ui.inputBox.placeholder !== (this.placeholder || '')) { this.ui.inputBox.placeholder = (this.placeholder || ''); } + if (this.ui.inputBox.ariaLabel !== this.ariaLabel) { + this.ui.inputBox.ariaLabel = this.ariaLabel; + } if (this.itemsUpdated) { this.itemsUpdated = false; this.ui.list.setElements(this.items); @@ -825,7 +838,6 @@ class QuickPick extends QuickInput implements IQuickPi this.ui.list.matchOnLabel = this.matchOnLabel; this.ui.list.sortByLabel = this.sortByLabel; this.ui.setComboboxAccessibility(true); - this.ui.inputBox.setAttribute('aria-label', QuickPick.INPUT_BOX_ARIA_LABEL); } } @@ -1383,7 +1395,7 @@ export class QuickInputController extends Disposable { ui.list.sortByLabel = true; ui.ignoreFocusOut = false; this.setComboboxAccessibility(false); - ui.inputBox.removeAttribute('aria-label'); + ui.inputBox.ariaLabel = ''; const backKeybindingLabel = this.options.backKeybindingLabel(); backButton.tooltip = backKeybindingLabel ? localize('quickInput.backWithKeybinding', "Back ({0})", backKeybindingLabel) : localize('quickInput.back', "Back"); diff --git a/src/vs/base/parts/quickinput/browser/quickInputBox.ts b/src/vs/base/parts/quickinput/browser/quickInputBox.ts index 31c4f7cb160..6ae2b873034 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputBox.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputBox.ts @@ -66,6 +66,14 @@ export class QuickInputBox extends Disposable { this.inputBox.setPlaceHolder(placeholder); } + get ariaLabel() { + return this.inputBox.getAriaLabel(); + } + + set ariaLabel(ariaLabel: string) { + this.inputBox.setAriaLabel(ariaLabel); + } + get password() { return this.inputBox.inputElement.type === 'password'; } diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index 46acde67797..3ad4be0a5f1 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -163,6 +163,8 @@ export interface IQuickPick extends IQuickInput { */ filterValue: (value: string) => string; + ariaLabel: string; + placeholder: string | undefined; readonly onDidChangeValue: Event; From 6fb14fddace8dbbfb9b47db916c3521e89312242 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sat, 7 Mar 2020 19:26:05 +0100 Subject: [PATCH 076/137] update labels --- .../contrib/userDataSync/browser/userDataSyncView.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts index fef03371c14..b189b51863d 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncView.ts @@ -51,7 +51,7 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { private registerBackupView(container: ViewContainer, remote: boolean): void { const id = `workbench.views.sync.${remote ? 'remote' : 'local'}BackupView`; - const name = remote ? localize('remote title', "Backup (Remote)") : localize('local title', "Backup (Local)"); + const name = remote ? localize('remote title', "Remote Backup") : localize('local title', "Local Backup"); const contextKey = new RawContextKey(`showUserDataSync${remote ? 'Remote' : 'Local'}BackupView`, false); const viewEnablementContext = contextKey.bindTo(this.contextKeyService); const treeView = this.instantiationService.createInstance(TreeView, id, name); @@ -83,8 +83,8 @@ export class UserDataSyncViewContribution implements IWorkbenchContribution { super({ id: `workbench.actions.showSync${remote ? 'Remote' : 'Local'}BackupView`, title: remote ? - { value: localize('workbench.action.showSyncRemoteBackup', "Show Backup (Remote)"), original: `Show Backup (Remote)` } - : { value: localize('workbench.action.showSyncLocalBackup', "Show Backup (Local)"), original: `Show Backup (Local)` }, + { value: localize('workbench.action.showSyncRemoteBackup', "Show Remote Backup"), original: `Show Remote Backup` } + : { value: localize('workbench.action.showSyncLocalBackup', "Show Local Backup"), original: `Show Local Backup` }, category: { value: localize('sync', "Sync"), original: `Sync` }, menu: { id: MenuId.CommandPalette, From 1edef2f2a173aec5372188b6e78eb956a9371d85 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 8 Mar 2020 08:11:28 +0100 Subject: [PATCH 077/137] quick access - improved help grouping --- .../quickAccess/standaloneHelpQuickAccess.ts | 2 +- .../standaloneQuickInputServiceImpl.ts | 5 ++++- .../quickinput/browser/helpQuickAccess.ts | 20 +++++++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts b/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts index d521022ee81..94deb2ba64e 100644 --- a/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts +++ b/src/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.ts @@ -11,5 +11,5 @@ import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuic Registry.as(Extensions.Quickaccess).defaultProvider = { ctor: HelpQuickAccessProvider, prefix: '', - helpEntries: [{ description: QuickHelpNLS.helpQuickAccessActionLabel, needsEditor: false }] + helpEntries: [{ description: QuickHelpNLS.helpQuickAccessActionLabel, needsEditor: true }] }; diff --git a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts index 20342263dc2..81574dce34b 100644 --- a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts +++ b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts @@ -145,7 +145,10 @@ export class QuickInputEditorContribution implements IEditorContribution { readonly widget = new QuickInputEditorWidget(this.editor); - constructor(private editor: ICodeEditor) { } + constructor(private editor: ICodeEditor, @IQuickInputService quickInputService: IQuickInputService) { + // TODO@ben remove me - only for testing + once(editor.onDidFocusEditorText)(() => quickInputService.quickAccess.show('')); + } dispose(): void { this.widget.dispose(); diff --git a/src/vs/platform/quickinput/browser/helpQuickAccess.ts b/src/vs/platform/quickinput/browser/helpQuickAccess.ts index 9742ff6a23a..0d4601edb17 100644 --- a/src/vs/platform/quickinput/browser/helpQuickAccess.ts +++ b/src/vs/platform/quickinput/browser/helpQuickAccess.ts @@ -35,12 +35,20 @@ export class HelpQuickAccessProvider implements IQuickAccessProvider { // Fill in all providers separated by editor/global scope const { editorProviders, globalProviders } = this.getQuickAccessProviders(); - picker.items = [ - { label: localize('globalCommands', "global commands"), type: 'separator' }, - ...globalProviders, - { label: localize('editorCommands', "editor commands"), type: 'separator' }, - ...editorProviders - ]; + picker.items = editorProviders.length === 0 || globalProviders.length === 0 ? + + // Without groups + [ + ...(editorProviders.length === 0 ? globalProviders : editorProviders) + ] : + + // With groups + [ + { label: localize('globalCommands', "global commands"), type: 'separator' }, + ...globalProviders, + { label: localize('editorCommands', "editor commands"), type: 'separator' }, + ...editorProviders + ]; picker.show(); } From 49f3723a3a1a1dcd0cf71b90f8f919cf7da2bd95 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 8 Mar 2020 08:26:28 +0100 Subject: [PATCH 078/137] quick access - allow provide to return disposable and cancel token properly --- .../quickinput/browser/helpQuickAccess.ts | 8 ++- .../quickinput/browser/quickAccess.ts | 40 +++++++++----- .../platform/quickinput/common/quickAccess.ts | 12 +++-- .../browser/parts/quickopen/quickopen.ts | 12 ++--- .../test/browser/quickAccess.test.ts | 52 ++++++++++++++----- 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/src/vs/platform/quickinput/browser/helpQuickAccess.ts b/src/vs/platform/quickinput/browser/helpQuickAccess.ts index 0d4601edb17..d4a66d3556b 100644 --- a/src/vs/platform/quickinput/browser/helpQuickAccess.ts +++ b/src/vs/platform/quickinput/browser/helpQuickAccess.ts @@ -8,8 +8,7 @@ import { IQuickAccessProvider, IQuickAccessRegistry, Extensions } from 'vs/platf import { Registry } from 'vs/platform/registry/common/platform'; import { CancellationToken } from 'vs/base/common/cancellation'; import { localize } from 'vs/nls'; -import { DisposableStore } from 'vs/base/common/lifecycle'; -import { once } from 'vs/base/common/functional'; +import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; interface IHelpQuickAccessPickItem extends IQuickPickItem { prefix: string; @@ -21,9 +20,8 @@ export class HelpQuickAccessProvider implements IQuickAccessProvider { constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } - provide(picker: IQuickPick, token: CancellationToken): void { + provide(picker: IQuickPick, token: CancellationToken): IDisposable { const disposables = new DisposableStore(); - once(token.onCancellationRequested)(() => disposables.dispose()); // Open a picker with the selected value if picked disposables.add(picker.onDidAccept(() => { @@ -50,7 +48,7 @@ export class HelpQuickAccessProvider implements IQuickAccessProvider { ...editorProviders ]; - picker.show(); + return disposables; } private getQuickAccessProviders(): { editorProviders: IHelpQuickAccessPickItem[], globalProviders: IHelpQuickAccessPickItem[] } { diff --git a/src/vs/platform/quickinput/browser/quickAccess.ts b/src/vs/platform/quickinput/browser/quickAccess.ts index f58d550fa5c..66f3ba390e8 100644 --- a/src/vs/platform/quickinput/browser/quickAccess.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -10,7 +10,6 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { once } from 'vs/base/common/functional'; -import { Event } from 'vs/base/common/event'; export class QuickAccessController extends Disposable implements IQuickAccessController { @@ -27,23 +26,40 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon } show(value = ''): void { + const disposables = new DisposableStore(); // Hide any previous picker if any - this.lastActivePicker?.dispose(); + this.lastActivePicker?.hide(); // Find provider for the value to show const [provider, prefix] = this.getOrInstantiateProvider(value); // Create a picker for the provider to use with the initial value // and adjust the filtering to exclude the prefix from filtering - const picker = this.lastActivePicker = this.quickInputService.createQuickPick(); + const picker = disposables.add(this.quickInputService.createQuickPick()); picker.value = value; picker.valueSelection = [value.length, value.length]; picker.filterValue = (value: string) => value.substring(prefix.length); - // Cleanup when picker hides or gets disposed - const disposables = new DisposableStore(); - once(Event.any(picker.onDidHide, picker.onDispose))(() => disposables.dispose()); + // Remember as last active picker and clean up once picker get's disposed + this.lastActivePicker = picker; + disposables.add(toDisposable(() => { + if (picker === this.lastActivePicker) { + this.lastActivePicker = undefined; + } + })); + + // Create a cancellation token source that is valid as long as the + // picker has not been closed without picking an item + const cts = disposables.add(new CancellationTokenSource()); + once(picker.onDidHide)(() => { + if (picker.selectedItems.length === 0) { + cts.cancel(); + } + + // Start to dispose once picker hides + disposables.dispose(); + }); // Whenever the value changes, check if the provider has // changed and if so - re-create the picker from the beginning @@ -54,13 +70,13 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon } })); - // Create a cancellation token source that is valid - // as long as the picker has not been closed - const cts = new CancellationTokenSource(); - disposables.add(toDisposable(() => cts.dispose(true))); + // Ask provider to fill the picker as needed + disposables.add(provider.provide(picker, cts.token)); - // Finally ask provider to fill the picker as needed - provider.provide(picker, cts.token); + // Finally, show the picker. This is important because a provider + // may not call this and then our disposables would leak that rely + // on the onDidHide event. + picker.show(); } private getOrInstantiateProvider(value: string): [IQuickAccessProvider, string /* prefix */] { diff --git a/src/vs/platform/quickinput/common/quickAccess.ts b/src/vs/platform/quickinput/common/quickAccess.ts index ac45cc1c104..de79e148ff3 100644 --- a/src/vs/platform/quickinput/common/quickAccess.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -24,12 +24,16 @@ export interface IQuickAccessProvider { /** * Called whenever a prefix was typed into quick pick that matches the provider. * - * @param picker the picker to use for showing provider results. + * @param picker the picker to use for showing provider results. The picker is + * automatically shown after the method returns, no need to call `show()`. * @param token providers have to check the cancellation token everytime after - * a long running operation because it could be that the picker has been closed - * or changed meanwhile. + * a long running operation or from event handlers because it could be that the + * picker has been closed or changed meanwhile. The token can be used to find out + * that the picker was closed without picking an entry (e.g. was canceled by the user). + * @return a disposable that will automatically be disposed when the picker + * closes or is replaced by another picker. */ - provide(picker: IQuickPick, token: CancellationToken): void; + provide(picker: IQuickPick, token: CancellationToken): IDisposable; } export interface IQuickAccessProviderHelp { diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index 6317058023a..d13c217727d 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -11,11 +11,11 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IQuickAccessRegistry, Extensions as QuickinputExtensions, IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; +import { IQuickAccessProvider, IQuickAccessRegistry, Extensions as QuickInputExtensions } from 'vs/platform/quickinput/common/quickAccess'; import { CancellationToken } from 'vs/base/common/cancellation'; const inQuickOpenKey = 'inQuickOpen'; @@ -209,19 +209,19 @@ export class LegacyQuickInputQuickOpenController extends Disposable { Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); class SampleQuickAccessProvider implements IQuickAccessProvider { - provide(picker: IQuickPick, token: CancellationToken): void { + provide(picker: IQuickPick, token: CancellationToken): IDisposable { picker.items = [ { label: 'Hello World' }, { label: 'Lorem Ipsum' }, { label: 'Something Else' } ]; - picker.show(); + return Disposable.None; } } -const quickAccessRegistry = Registry.as(QuickinputExtensions.Quickaccess); -['', '>', '@', ':', 'edt', 'edt active', 'edt mru', 'view'].forEach(prefix => { +const quickAccessRegistry = Registry.as(QuickInputExtensions.Quickaccess); +[''/*, '>', '@', ':', 'edt', 'edt active', 'edt mru', 'view'*/].forEach(prefix => { const provider = { ctor: SampleQuickAccessProvider, prefix, diff --git a/src/vs/workbench/test/browser/quickAccess.test.ts b/src/vs/workbench/test/browser/quickAccess.test.ts index da960ecb035..94ffc5ac658 100644 --- a/src/vs/workbench/test/browser/quickAccess.test.ts +++ b/src/vs/workbench/test/browser/quickAccess.test.ts @@ -10,7 +10,7 @@ import { IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quic import { CancellationToken } from 'vs/base/common/cancellation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { timeout } from 'vs/base/common/async'; suite('QuickAccess', () => { @@ -20,61 +20,66 @@ suite('QuickAccess', () => { let provider1Called = false; let provider1Canceled = false; + let provider1Disposed = false; let provider2Called = false; let provider2Canceled = false; + let provider2Disposed = false; let provider3Called = false; let provider3Canceled = false; + let provider3Disposed = false; let provider4Called = false; let provider4Canceled = false; + let provider4Disposed = false; class TestProvider1 implements IQuickAccessProvider { - provide(picker: IQuickPick, token: CancellationToken) { + provide(picker: IQuickPick, token: CancellationToken): IDisposable { assert.ok(picker); provider1Called = true; token.onCancellationRequested(() => provider1Canceled = true); - picker.show(); + return toDisposable(() => provider1Disposed = true); } } class TestProvider2 implements IQuickAccessProvider { - provide(picker: IQuickPick, token: CancellationToken) { + provide(picker: IQuickPick, token: CancellationToken): IDisposable { assert.ok(picker); provider2Called = true; token.onCancellationRequested(() => provider2Canceled = true); - // Not calling picker show explicitly to test bad provider - // picker.show(); + return toDisposable(() => provider2Disposed = true); } } class TestProvider3 implements IQuickAccessProvider { - constructor(@IQuickInputService private readonly quickInputService: IQuickInputService) { } + constructor(@IQuickInputService private readonly quickInputService: IQuickInputService, disposables: DisposableStore) { } - async provide(picker: IQuickPick, token: CancellationToken) { + provide(picker: IQuickPick, token: CancellationToken): IDisposable { assert.ok(picker); provider3Called = true; token.onCancellationRequested(() => provider3Canceled = true); - picker.show(); - // bring up provider #4 - await timeout(0); - this.quickInputService.quickAccess.show(providerDescriptor4.prefix); + setTimeout(() => this.quickInputService.quickAccess.show(providerDescriptor4.prefix)); + + return toDisposable(() => provider3Disposed = true); } } class TestProvider4 implements IQuickAccessProvider { - provide(picker: IQuickPick, token: CancellationToken) { + provide(picker: IQuickPick, token: CancellationToken): IDisposable { assert.ok(picker); provider4Called = true; token.onCancellationRequested(() => provider4Canceled = true); - picker.show(); + // hide without picking + setTimeout(() => picker.hide()); + + return toDisposable(() => provider4Disposed = true); } } @@ -124,6 +129,10 @@ suite('QuickAccess', () => { assert.equal(provider2Canceled, false); assert.equal(provider3Canceled, false); assert.equal(provider4Canceled, false); + assert.equal(provider1Disposed, false); + assert.equal(provider2Disposed, false); + assert.equal(provider3Disposed, false); + assert.equal(provider4Disposed, false); provider1Called = false; accessor.quickInputService.quickAccess.show('test something'); @@ -135,8 +144,13 @@ suite('QuickAccess', () => { assert.equal(provider2Canceled, false); assert.equal(provider3Canceled, false); assert.equal(provider4Canceled, false); + assert.equal(provider1Disposed, true); + assert.equal(provider2Disposed, false); + assert.equal(provider3Disposed, false); + assert.equal(provider4Disposed, false); provider2Called = false; provider1Canceled = false; + provider1Disposed = false; accessor.quickInputService.quickAccess.show('usedefault'); assert.equal(provider1Called, false); @@ -147,12 +161,22 @@ suite('QuickAccess', () => { assert.equal(provider2Canceled, true); assert.equal(provider3Canceled, false); assert.equal(provider4Canceled, false); + assert.equal(provider1Disposed, false); + assert.equal(provider2Disposed, true); + assert.equal(provider3Disposed, false); + assert.equal(provider4Disposed, false); await timeout(1); assert.equal(provider3Canceled, true); + assert.equal(provider3Disposed, true); assert.equal(provider4Called, true); + await timeout(1); + + assert.equal(provider4Canceled, true); + assert.equal(provider4Disposed, true); + disposables.dispose(); registry.defaultProvider = defaultProvider; }); From de2426aa081174fb5c3818793b3ea777255d34c9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 8 Mar 2020 09:05:25 +0100 Subject: [PATCH 079/137] quick access - implement "Go to Line" --- src/vs/editor/contrib/quickAccess/gotoLine.ts | 206 ++++++++++++++++++ .../editor/contrib/quickAccess/quickAccess.ts | 104 +++++++++ src/vs/editor/editor.main.ts | 1 + .../standaloneGotoLineQuickAccess.ts | 31 +++ .../browser/codeEditor.contribution.ts | 1 + .../quickaccess/gotoLineQuickAccess.ts | 45 ++++ 6 files changed, 388 insertions(+) create mode 100644 src/vs/editor/contrib/quickAccess/gotoLine.ts create mode 100644 src/vs/editor/contrib/quickAccess/quickAccess.ts create mode 100644 src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts create mode 100644 src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts diff --git a/src/vs/editor/contrib/quickAccess/gotoLine.ts b/src/vs/editor/contrib/quickAccess/gotoLine.ts new file mode 100644 index 00000000000..83d98fbfc77 --- /dev/null +++ b/src/vs/editor/contrib/quickAccess/gotoLine.ts @@ -0,0 +1,206 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { IQuickPick, IQuickPickItem, IKeyMods } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { DisposableStore, toDisposable, IDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { once } from 'vs/base/common/functional'; +import { IEditor, ScrollType, IDiffEditor } from 'vs/editor/common/editorCommon'; +import { ITextModel } from 'vs/editor/common/model'; +import { isDiffEditor } from 'vs/editor/browser/editorBrowser'; +import { IRange } from 'vs/editor/common/core/range'; +import { withNullAsUndefined } from 'vs/base/common/types'; +import { AbstractEditorQuickAccessProvider } from 'vs/editor/contrib/quickAccess/quickAccess'; +import { IPosition } from 'vs/editor/common/core/position'; + +export const GOTO_LINE_PREFIX = ':'; + +interface IGotoLineQuickPickItem extends IQuickPickItem, Partial { } + +export abstract class AbstractGotoLineQuickAccessProvider extends AbstractEditorQuickAccessProvider { + + provide(picker: IQuickPick, token: CancellationToken): IDisposable { + const disposables = new DisposableStore(); + + // Disable filtering, we control the results + picker.filterValue = () => ''; + + // Provide based on current active editor + let pickerDisposable = this.doProvide(picker, token); + disposables.add(toDisposable(() => pickerDisposable.dispose())); + + // Re-create whenever the active editor changes + disposables.add(this.onDidActiveTextEditorControlChange(() => { + pickerDisposable.dispose(); + pickerDisposable = this.doProvide(picker, token); + })); + + return disposables; + } + + private doProvide(picker: IQuickPick, token: CancellationToken): IDisposable { + + // With text control + if (this.activeTextEditorControl) { + return this.doProvideWithTextEditor(this.activeTextEditorControl, picker, token); + } + + // Without text control + return this.doProvideWithoutTextEditor(picker); + } + + private doProvideWithoutTextEditor(picker: IQuickPick): IDisposable { + const label = localize('cannotRunGotoLine', "Open a text file first to go to a line."); + picker.items = [{ label }]; + picker.ariaLabel = label; + + return Disposable.None; + } + + private doProvideWithTextEditor(editor: IEditor, picker: IQuickPick, token: CancellationToken): IDisposable { + const disposables = new DisposableStore(); + + // Restore any view state if this picker was closed + // without actually going to a line + const lastKnownEditorViewState = withNullAsUndefined(editor.saveViewState()); + once(token.onCancellationRequested)(() => { + if (lastKnownEditorViewState) { + editor.restoreViewState(lastKnownEditorViewState); + } + }); + + // Goto line once picked + disposables.add(picker.onDidAccept(() => { + const [item] = picker.selectedItems; + if (item) { + if (!this.isValidLineNumber(editor, item.lineNumber)) { + return; + } + + this.gotoLine(editor, this.toRange(item.lineNumber, item.column), picker.keyMods); + + picker.hide(); + } + })); + + // React to picker changes + const updatePickerAndEditor = () => { + const position = this.parsePosition(editor, picker.value.trim().substr(GOTO_LINE_PREFIX.length)); + const label = this.getPickLabel(editor, position.lineNumber, position.column); + + // Picker + picker.items = [{ + lineNumber: position.lineNumber, + column: position.column, + label + }]; + + // ARIA Label + picker.ariaLabel = label; + + // Clear decorations for invalid range + if (!this.isValidLineNumber(editor, position.lineNumber)) { + this.clearDecorations(editor); + return; + } + + // Reveal + const range = this.toRange(position.lineNumber, position.column); + editor.revealRangeInCenter(range, ScrollType.Smooth); + + // Decorate + this.addDecorations(editor, range); + }; + updatePickerAndEditor(); + disposables.add(picker.onDidChangeValue(() => updatePickerAndEditor())); + + // Clean up decorations on dispose + disposables.add(toDisposable(() => this.clearDecorations(editor))); + + return disposables; + } + + private toRange(lineNumber = 1, column = 1): IRange { + return { + startLineNumber: lineNumber, + startColumn: column, + endLineNumber: lineNumber, + endColumn: column + }; + } + + private parsePosition(editor: IEditor, value: string): IPosition { + + // Support line-col formats of `line,col`, `line:col`, `line#col` + const numbers = value.split(/,|:|#/).map(part => parseInt(part, 10)).filter(part => !isNaN(part)); + const endLine = this.lineCount(editor) + 1; + + return { + lineNumber: numbers[0] > 0 ? numbers[0] : endLine + numbers[0], + column: numbers[1] + }; + } + + private getPickLabel(editor: IEditor, lineNumber: number, column: number | undefined): string { + + // Location valid: indicate this as picker label + if (this.isValidLineNumber(editor, lineNumber)) { + if (this.isValidColumn(editor, lineNumber, column)) { + return localize('gotoLineColumnLabel', "Go to line {0} and column {1}.", lineNumber, column); + } + + return localize('gotoLineLabel', "Go to line {0}.", lineNumber); + } + + // Location invalid: show generic label + const position = editor.getPosition() || { lineNumber: 1, column: 1 }; + const lineCount = this.lineCount(editor); + if (lineCount > 1) { + return localize('gotoLineLabelEmptyWithLimit', "Current Line: {0}, Column: {1}. Type a line number between 1 and {2} to navigate to.", position.lineNumber, position.column, lineCount); + } + + return localize('gotoLineLabelEmpty', "Current Line: {0}, Column: {1}. Type a line number to navigate to.", position.lineNumber, position.column); + } + + private isValidLineNumber(editor: IEditor, lineNumber: number | undefined): boolean { + if (!lineNumber || typeof lineNumber !== 'number') { + return false; + } + + return lineNumber > 0 && lineNumber <= this.lineCount(editor); + } + + private isValidColumn(editor: IEditor, lineNumber: number, column: number | undefined): boolean { + if (!column || typeof column !== 'number') { + return false; + } + + const model = this.getModel(editor); + if (!model) { + return false; + } + + const positionCandidate = { lineNumber, column }; + + return model.validatePosition(positionCandidate).equals(positionCandidate); + } + + private lineCount(editor: IEditor): number { + return this.getModel(editor)?.getLineCount() ?? 0; + } + + private getModel(editor: IEditor | IDiffEditor): ITextModel | undefined { + return isDiffEditor(editor) ? + editor.getModel()?.modified : + editor.getModel() as ITextModel; + } + + protected gotoLine(editor: IEditor, range: IRange, keyMods: IKeyMods): void { + editor.setSelection(range); + editor.revealRangeInCenter(range, ScrollType.Smooth); + editor.focus(); + } +} diff --git a/src/vs/editor/contrib/quickAccess/quickAccess.ts b/src/vs/editor/contrib/quickAccess/quickAccess.ts new file mode 100644 index 00000000000..3b315010d9c --- /dev/null +++ b/src/vs/editor/contrib/quickAccess/quickAccess.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; +import { IEditor } from 'vs/editor/common/editorCommon'; +import { IModelDeltaDecoration, OverviewRulerLane } from 'vs/editor/common/model'; +import { IRange } from 'vs/editor/common/core/range'; +import { themeColorFromId } from 'vs/platform/theme/common/themeService'; +import { overviewRulerRangeHighlight } from 'vs/editor/common/view/editorColorRegistry'; +import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { Event } from 'vs/base/common/event'; + +interface IEditorLineDecoration { + rangeHighlightId: string; + overviewRulerDecorationId: string; +} + +/** + * A reusable quick access provider for the editor with support for adding decorations. + */ +export abstract class AbstractEditorQuickAccessProvider implements IQuickAccessProvider { + + /** + * Subclasses to provide an event when the active editor control changes. + */ + abstract readonly onDidActiveTextEditorControlChange: Event; + + /** + * Subclasses to provide the current active editor control. + */ + abstract activeTextEditorControl: IEditor | undefined; + + /** + * Subclasses to implement the quick access picker. + */ + abstract provide(picker: IQuickPick, token: CancellationToken): IDisposable; + + + //#region Decorations Utils + + private rangeHighlightDecorationId: IEditorLineDecoration | undefined = undefined; + + protected addDecorations(editor: IEditor, range: IRange): void { + editor.changeDecorations(changeAccessor => { + + // Reset old decorations if any + const deleteDecorations: string[] = []; + if (this.rangeHighlightDecorationId) { + deleteDecorations.push(this.rangeHighlightDecorationId.overviewRulerDecorationId); + deleteDecorations.push(this.rangeHighlightDecorationId.rangeHighlightId); + + this.rangeHighlightDecorationId = undefined; + } + + // Add new decorations for the range + const newDecorations: IModelDeltaDecoration[] = [ + + // highlight the entire line on the range + { + range, + options: { + className: 'rangeHighlight', + isWholeLine: true + } + }, + + // also add overview ruler highlight + { + range, + options: { + overviewRuler: { + color: themeColorFromId(overviewRulerRangeHighlight), + position: OverviewRulerLane.Full + } + } + } + ]; + + const [rangeHighlightId, overviewRulerDecorationId] = changeAccessor.deltaDecorations(deleteDecorations, newDecorations); + + this.rangeHighlightDecorationId = { rangeHighlightId, overviewRulerDecorationId }; + }); + } + + protected clearDecorations(editor: IEditor): void { + const rangeHighlightDecorationId = this.rangeHighlightDecorationId; + if (rangeHighlightDecorationId) { + editor.changeDecorations(changeAccessor => { + changeAccessor.deltaDecorations([ + rangeHighlightDecorationId.overviewRulerDecorationId, + rangeHighlightDecorationId.rangeHighlightId + ], []); + }); + + this.rangeHighlightDecorationId = undefined; + } + } + + //#endregion +} diff --git a/src/vs/editor/editor.main.ts b/src/vs/editor/editor.main.ts index 0868614ed38..875233ba7a8 100644 --- a/src/vs/editor/editor.main.ts +++ b/src/vs/editor/editor.main.ts @@ -11,6 +11,7 @@ import 'vs/editor/standalone/browser/quickOpen/gotoLine'; import 'vs/editor/standalone/browser/quickOpen/quickCommand'; import 'vs/editor/standalone/browser/quickOpen/quickOutline'; import 'vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess'; +import 'vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess'; import 'vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch'; import 'vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast'; diff --git a/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts b/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts new file mode 100644 index 00000000000..d513431044b --- /dev/null +++ b/src/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { AbstractGotoLineQuickAccessProvider, GOTO_LINE_PREFIX } from 'vs/editor/contrib/quickAccess/gotoLine'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { withNullAsUndefined } from 'vs/base/common/types'; +import { GoToLineNLS } from 'vs/editor/common/standaloneStrings'; +import { Event } from 'vs/base/common/event'; + +export class StandaloneGotoLineQuickAccessProvider extends AbstractGotoLineQuickAccessProvider { + + readonly onDidActiveTextEditorControlChange = Event.None; + + constructor(@ICodeEditorService private readonly editorService: ICodeEditorService) { + super(); + } + + get activeTextEditorControl() { + return withNullAsUndefined(this.editorService.getFocusedCodeEditor()); + } +} + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ + ctor: StandaloneGotoLineQuickAccessProvider, + prefix: GOTO_LINE_PREFIX, + helpEntries: [{ description: GoToLineNLS.gotoLineActionLabel, needsEditor: true }] +}); diff --git a/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts b/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts index eae8927c912..ddcd8ff16b4 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/codeEditor.contribution.ts @@ -9,6 +9,7 @@ import './diffEditorHelper'; import './inspectKeybindings'; import './largeFileOptimizations'; import './inspectEditorTokens/inspectEditorTokens'; +import './quickaccess/gotoLineQuickAccess'; import './saveParticipants'; import './toggleColumnSelection'; import './toggleMinimap'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts new file mode 100644 index 00000000000..73075d46e98 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; +import { IEditor } from 'vs/editor/common/editorCommon'; +import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { IRange } from 'vs/editor/common/core/range'; +import { AbstractGotoLineQuickAccessProvider, GOTO_LINE_PREFIX } from 'vs/editor/contrib/quickAccess/gotoLine'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; + +export class GotoLineQuickAccessProvider extends AbstractGotoLineQuickAccessProvider { + + readonly onDidActiveTextEditorControlChange = this.editorService.onDidActiveEditorChange; + + constructor(@IEditorService private readonly editorService: IEditorService) { + super(); + } + + get activeTextEditorControl() { + return this.editorService.activeTextEditorControl; + } + + protected gotoLine(editor: IEditor, range: IRange, keyMods: IKeyMods): void { + + // Check for sideBySide use + if (keyMods.ctrlCmd && this.editorService.activeEditor) { + this.editorService.openEditor(this.editorService.activeEditor, { selection: range, pinned: keyMods.alt }, SIDE_GROUP); + } + + // Otherwise let parent handle it + else { + super.gotoLine(editor, range, keyMods); + } + } +} + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ + ctor: GotoLineQuickAccessProvider, + prefix: GOTO_LINE_PREFIX, + helpEntries: [{ description: localize('gotoLineQuickAccess', "Go to Line"), needsEditor: true }] +}); From aaaefeb05e6867a3431f1242a57278bef75804f6 Mon Sep 17 00:00:00 2001 From: Gustavo Sampaio Date: Sun, 8 Mar 2020 09:05:23 -0300 Subject: [PATCH 080/137] PR review --- .../contrib/codelens/codelensController.ts | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 6bf5613c964..56f1c1c1b46 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -3,25 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - -import * as dom from 'vs/base/browser/dom'; -import { CancelablePromise, createCancelablePromise, disposableTimeout, RunOnceScheduler } from 'vs/base/common/async'; +import { CancelablePromise, RunOnceScheduler, createCancelablePromise, disposableTimeout } from 'vs/base/common/async'; import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors'; -import { hash } from 'vs/base/common/hash'; -import { DisposableStore, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { toDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { StableEditorScrollState } from 'vs/editor/browser/core/editorState'; -import { IActiveCodeEditor, ICodeEditor, IViewZoneChangeAccessor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; -import { Command, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { ICodeEditor, MouseTargetType, IViewZoneChangeAccessor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { registerEditorContribution, EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; -import { CodeLens, CodeLensProviderRegistry } from 'vs/editor/common/modes'; -import { CodeLensItem, CodeLensModel, getCodeLensData } from 'vs/editor/contrib/codelens/codelens'; -import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; -import { CodeLensHelper, CodeLensWidget } from 'vs/editor/contrib/codelens/codelensWidget'; +import { CodeLensProviderRegistry, CodeLens } from 'vs/editor/common/modes'; +import { CodeLensModel, getCodeLensData, CodeLensItem } from 'vs/editor/contrib/codelens/codelens'; +import { CodeLensWidget, CodeLensHelper } from 'vs/editor/contrib/codelens/codelensWidget'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; +import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import * as dom from 'vs/base/browser/dom'; +import { hash } from 'vs/base/common/hash'; import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; export class CodeLensContribution implements IEditorContribution { @@ -411,18 +409,14 @@ export class CodeLensContribution implements IEditorContribution { } } -export class ShowLensesInCurrentLineCommand extends Command { - public runCommand(accessor: ServicesAccessor, args: any): void | Promise { +export class ShowLensesInCurrentLineCommand extends EditorCommand { + public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Promise { const quickInputService = accessor.get(IQuickInputService); const commandService = accessor.get(ICommandService); const notificationService = accessor.get(INotificationService); - const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor(); - if (!focusedEditor?.getSelection()?.isEmpty()) { - return; - } - const lineNumber = focusedEditor.getSelection()?.positionLineNumber; - const codelensController = focusedEditor.getContribution(CodeLensContribution.ID) as CodeLensContribution; + const lineNumber = editor.getSelection()?.positionLineNumber; + const codelensController = editor.getContribution(CodeLensContribution.ID) as CodeLensContribution; const activeLensesWidgets = codelensController.getLenses().filter(lens => lens.getLineNumber() === lineNumber); From 4c0a275957f3814f8692e7616a011b8a93f2d245 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 8 Mar 2020 19:46:32 +0100 Subject: [PATCH 081/137] #92038 move from get*Actions to menu actions --- .../contrib/markers/browser/constants.ts | 1 + .../contrib/markers/browser/markersView.ts | 155 +++++++++++------- .../markers/browser/markersViewActions.ts | 125 +++++++------- 3 files changed, 164 insertions(+), 117 deletions(-) diff --git a/src/vs/workbench/contrib/markers/browser/constants.ts b/src/vs/workbench/contrib/markers/browser/constants.ts index 6a06908d88a..ca720e8509c 100644 --- a/src/vs/workbench/contrib/markers/browser/constants.ts +++ b/src/vs/workbench/contrib/markers/browser/constants.ts @@ -21,6 +21,7 @@ export default { MARKER_SHOW_QUICK_FIX: 'problems.action.showQuickFixes', TOGGLE_MARKERS_VIEW_ACTION_ID: 'workbench.actions.view.toggleProblems', + MarkersViewSmallLayoutContextKey: new RawContextKey(`problemsView.smallLayout`, false), MarkerViewFocusContextKey: new RawContextKey('problemsViewFocus', false), MarkerFocusContextKey: new RawContextKey('problemFocus', false), MarkerViewFilterFocusContextKey: new RawContextKey('problemsFilterFocus', false), diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index aa7d6318e91..23f2e38d80d 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -13,7 +13,7 @@ import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/ import Constants from 'vs/workbench/contrib/markers/browser/constants'; import { Marker, ResourceMarkers, RelatedInformation, MarkerChangesEvent } from 'vs/workbench/contrib/markers/browser/markersModel'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { MarkersFilterActionViewItem, MarkersFilterAction, IMarkersFilterActionChangeEvent, IMarkerFilterController } from 'vs/workbench/contrib/markers/browser/markersViewActions'; +import { MarkersFilterActionViewItem, MarkersFilters, IMarkersFiltersChangeEvent, IMarkerFilterController } from 'vs/workbench/contrib/markers/browser/markersViewActions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import Messages from 'vs/workbench/contrib/markers/browser/messages'; import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations'; @@ -22,7 +22,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IMarkersWorkbenchService } from 'vs/workbench/contrib/markers/browser/markers'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { localize } from 'vs/nls'; -import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService, ContextKeyEqualsExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Iterator } from 'vs/base/common/iterator'; import { ITreeElement, ITreeNode, ITreeContextMenuEvent, ITreeRenderer } from 'vs/base/browser/ui/tree/tree'; import { Relay, Event, Emitter } from 'vs/base/common/event'; @@ -34,7 +34,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { FilterData, Filter, VirtualDelegate, ResourceMarkersRenderer, MarkerRenderer, RelatedInformationRenderer, TreeElement, MarkersTreeAccessibilityProvider, MarkersViewModel, ResourceDragAndDrop } from 'vs/workbench/contrib/markers/browser/markersTreeViewer'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { Separator, ActionViewItem, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; +import { IMenuService, MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { domEvent } from 'vs/base/browser/event'; @@ -75,22 +75,26 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private filterActionBar: ActionBar | undefined; private messageBoxContainer: HTMLElement | undefined; private ariaLabelElement: HTMLElement | undefined; - private readonly collapseAllAction: IAction; - private readonly filterAction: MarkersFilterAction; + readonly filters: MarkersFilters; private readonly panelState: MementoObject; - private panelFoucusContextKey: IContextKey; + private readonly panelFoucusContextKey: IContextKey; - private _onDidFilter = this._register(new Emitter()); - readonly onDidFilter: Event = this._onDidFilter.event; + private _onDidChangeFilterStats = this._register(new Emitter<{ total: number, filtered: number }>()); + readonly onDidChangeFilterStats: Event<{ total: number, filtered: number }> = this._onDidChangeFilterStats.event; private cachedFilterStats: { total: number; filtered: number; } | undefined = undefined; private currentResourceGotAddedToMarkersData: boolean = false; readonly markersViewModel: MarkersViewModel; - private isSmallLayout: boolean = false; + private readonly smallLayoutContextKey: IContextKey; + private get smallLayout(): boolean { return !!this.smallLayoutContextKey.get(); } + private set smallLayout(smallLayout: boolean) { this.smallLayoutContextKey.set(smallLayout); } readonly onDidChangeVisibility = this.onDidChangeBodyVisibility; + private readonly _onDidFocusFilter: Emitter = this._register(new Emitter()); + readonly onDidFocusFilter: Event = this._onDidFocusFilter.event; + constructor( options: IViewPaneOptions, @IInstantiationService instantiationService: IInstantiationService, @@ -109,7 +113,8 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { @IThemeService themeService: IThemeService, ) { super({ ...(options as IViewPaneOptions), id: Constants.MARKERS_VIEW_ID, ariaHeaderLabel: Messages.MARKERS_PANEL_TITLE_PROBLEMS }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); - this.panelFoucusContextKey = Constants.MarkerViewFocusContextKey.bindTo(contextKeyService); + this.smallLayoutContextKey = Constants.MarkersViewSmallLayoutContextKey.bindTo(this.contextKeyService); + this.panelFoucusContextKey = Constants.MarkerViewFocusContextKey.bindTo(this.contextKeyService); this.panelState = new Memento(Constants.MARKERS_VIEW_STORAGE_ID, storageService).getMemento(StorageScope.WORKSPACE); this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState['multiline'])); this._register(this.markersViewModel.onDidChange(marker => this.onDidChangeViewState(marker))); @@ -119,15 +124,16 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { this.rangeHighlightDecorations = this._register(this.instantiationService.createInstance(RangeHighlightDecorations)); // actions - this.collapseAllAction = this._register(new Action('vs.tree.collapse', localize('collapseAll', "Collapse All"), 'monaco-tree-action codicon-collapse-all', true, async () => this.collapseAll())); - this.filterAction = this._register(this.instantiationService.createInstance(MarkersFilterAction, { + this.regiserActions(); + this.filters = this._register(new MarkersFilters({ filterText: this.panelState['filter'] || '', filterHistory: this.panelState['filterHistory'] || [], showErrors: this.panelState['showErrors'] !== false, showWarnings: this.panelState['showWarnings'] !== false, showInfos: this.panelState['showInfos'] !== false, excludedFiles: !!this.panelState['useFilesExclude'], - activeFile: !!this.panelState['activeFile'] + activeFile: !!this.panelState['activeFile'], + layout: new dom.Dimension(0, 0) })); } @@ -157,7 +163,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } })); - this.filterActionBar!.push(this.filterAction); + this.filterActionBar!.push(new Action(`workbench.actions.treeView.${this.id}.filter`)); this.renderContent(); } @@ -166,22 +172,21 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } public layoutBody(height: number, width: number): void { - const wasSmallLayout = this.isSmallLayout; - this.isSmallLayout = width < 600 && height > 100; - if (this.isSmallLayout !== wasSmallLayout) { - this.updateActions(); + const wasSmallLayout = this.smallLayout; + this.smallLayout = width < 600 && height > 100; + if (this.smallLayout !== wasSmallLayout) { if (this.filterActionBar) { - dom.toggleClass(this.filterActionBar.getContainer(), 'hide', !this.isSmallLayout); + dom.toggleClass(this.filterActionBar.getContainer(), 'hide', !this.smallLayout); } } - const contentHeight = this.isSmallLayout ? height - 44 : height; + const contentHeight = this.smallLayout ? height - 44 : height; if (this.tree) { this.tree.layout(contentHeight, width); } if (this.messageBoxContainer) { this.messageBoxContainer.style.height = `${contentHeight}px`; } - this.filterAction.layout(this.isSmallLayout ? width : width - 200); + this.filters.layout = new dom.Dimension(this.smallLayout ? width : width - 200, height); } public focus(): void { @@ -197,14 +202,44 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } public focusFilter(): void { - this.filterAction.focus(); + this._onDidFocusFilter.fire(); } - public getActions(): IAction[] { - if (this.isSmallLayout) { - return [this.collapseAllAction]; - } - return [this.filterAction, this.collapseAllAction]; + private regiserActions(): void { + const that = this; + this._register(registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.actions.treeView.${that.id}.collapseAll`, + title: localize('collapseAll', "Collapse All"), + menu: { + id: MenuId.ViewTitle, + when: ContextKeyEqualsExpr.create('view', that.id), + group: 'navigation', + order: Number.MAX_SAFE_INTEGER, + }, + icon: { id: 'codicon/collapse-all' } + }); + } + async run(): Promise { + return that.collapseAll(); + } + })); + this._register(registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.actions.treeView.${that.id}.filter`, + title: localize('filter', "Filter"), + menu: { + id: MenuId.ViewTitle, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.id), Constants.MarkersViewSmallLayoutContextKey.negate()), + group: 'navigation', + order: 1, + }, + }); + } + async run(): Promise { } + })); } public showQuickFixes(marker: Marker): void { @@ -279,7 +314,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { const { total, filtered } = this.getFilterStats(); this.tree.toggleVisibility(total === 0 || filtered === 0); this.renderMessage(); - this._onDidFilter.fire(); + this._onDidChangeFilterStats.fire(this.getFilterStats()); } } @@ -292,7 +327,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { return; } let resourceMarkers: ResourceMarkers[] = []; - if (this.filterAction.activeFile) { + if (this.filters.activeFile) { if (this.currentActiveResource) { const activeResourceMarkers = this.markersWorkbenchService.markersModel.getResourceMarkers(this.currentActiveResource); if (activeResourceMarkers) { @@ -307,11 +342,11 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private updateFilter() { this.cachedFilterStats = undefined; - this.filter.options = new FilterOptions(this.filterAction.filterText, this.getFilesExcludeExpressions(), this.filterAction.showWarnings, this.filterAction.showErrors, this.filterAction.showInfos); + this.filter.options = new FilterOptions(this.filters.filterText, this.getFilesExcludeExpressions(), this.filters.showWarnings, this.filters.showErrors, this.filters.showInfos); if (this.tree) { this.tree.refilter(); } - this._onDidFilter.fire(); + this._onDidChangeFilterStats.fire(this.getFilterStats()); const { total, filtered } = this.getFilterStats(); if (this.tree) { @@ -321,7 +356,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } private getFilesExcludeExpressions(): { root: URI, expression: IExpression }[] | IExpression { - if (!this.filterAction.excludedFiles) { + if (!this.filters.excludedFiles) { return []; } @@ -338,7 +373,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private createFilterActionBar(parent: HTMLElement): void { this.filterActionBar = this._register(new ActionBar(parent, { actionViewItemProvider: action => this.getActionViewItem(action) })); dom.addClass(this.filterActionBar.getContainer(), 'markers-panel-filter-container'); - dom.toggleClass(this.filterActionBar.getContainer(), 'hide', !this.isSmallLayout); + dom.toggleClass(this.filterActionBar.getContainer(), 'hide', !this.smallLayout); } private createMessageBox(parent: HTMLElement): void { @@ -416,7 +451,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { this._register(this.tree.onContextMenu(this.onContextMenu, this)); this._register(this.configurationService.onDidChangeConfiguration(e => { - if (this.filterAction.excludedFiles && e.affectsConfiguration('files.exclude')) { + if (this.filters.excludedFiles && e.affectsConfiguration('files.exclude')) { this.updateFilter(); } })); @@ -424,7 +459,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { // move focus to input, whenever a key is pressed in the panel container this._register(domEvent(parent, 'keydown')(e => { if (this.keybindingService.mightProducePrintableCharacter(new StandardKeyboardEvent(e))) { - this.filterAction.focus(); + this.focusFilter(); } })); @@ -462,7 +497,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { if (this.tree) { this._register(this.tree.onDidChangeSelection(() => this.onSelected())); } - this._register(this.filterAction.onDidChange((event: IMarkersFilterActionChangeEvent) => { + this._register(this.filters.onDidChange((event: IMarkersFiltersChangeEvent) => { this.reportFilteringUsed(); if (event.activeFile) { this.refreshPanel(); @@ -508,7 +543,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private onActiveEditorChanged(): void { this.setCurrentActiveEditor(); - if (this.filterAction.activeFile) { + if (this.filters.activeFile) { this.refreshPanel(); } this.autoReveal(); @@ -552,7 +587,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { if (filtered === 0) { this.messageBoxContainer.style.display = 'block'; this.messageBoxContainer.setAttribute('tabIndex', '0'); - if (this.filterAction.activeFile) { + if (this.filters.activeFile) { this.renderFilterMessageForActiveFile(this.messageBoxContainer); } else { if (total > 0) { @@ -611,16 +646,16 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } private clearFilters(): void { - this.filterAction.filterText = ''; - this.filterAction.excludedFiles = false; - this.filterAction.showErrors = true; - this.filterAction.showWarnings = true; - this.filterAction.showInfos = true; + this.filters.filterText = ''; + this.filters.excludedFiles = false; + this.filters.showErrors = true; + this.filters.showWarnings = true; + this.filters.showInfos = true; } private autoReveal(focus: boolean = false): void { // No need to auto reveal if active file filter is on - if (this.filterAction.activeFile || !this.tree) { + if (this.filters.activeFile || !this.tree) { return; } let autoReveal = this.configurationService.getValue('problems.autoReveal'); @@ -749,16 +784,12 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } public getActionViewItem(action: IAction): IActionViewItem | undefined { - if (action.id === MarkersFilterAction.ID) { - return this.instantiationService.createInstance(MarkersFilterActionViewItem, this.filterAction, this); + if (action.id === `workbench.actions.treeView.${this.id}.filter`) { + return this.instantiationService.createInstance(MarkersFilterActionViewItem, action, this); } return super.getActionViewItem(action); } - getFilterOptions(): FilterOptions { - return this.filter.options; - } - getFilterStats(): { total: number; filtered: number; } { if (!this.cachedFilterStats) { this.cachedFilterStats = this.computeFilterStats(); @@ -790,11 +821,11 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private reportFilteringUsed(): void { const data = { - errors: this.filterAction.showErrors, - warnings: this.filterAction.showWarnings, - infos: this.filterAction.showInfos, - activeFile: this.filterAction.activeFile, - excludedFiles: this.filterAction.excludedFiles, + errors: this.filters.showErrors, + warnings: this.filters.showWarnings, + infos: this.filters.showInfos, + activeFile: this.filters.activeFile, + excludedFiles: this.filters.excludedFiles, }; /* __GDPR__ "problems.filter" : { @@ -809,13 +840,13 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } saveState(): void { - this.panelState['filter'] = this.filterAction.filterText; - this.panelState['filterHistory'] = this.filterAction.filterHistory; - this.panelState['showErrors'] = this.filterAction.showErrors; - this.panelState['showWarnings'] = this.filterAction.showWarnings; - this.panelState['showInfos'] = this.filterAction.showInfos; - this.panelState['useFilesExclude'] = this.filterAction.excludedFiles; - this.panelState['activeFile'] = this.filterAction.activeFile; + this.panelState['filter'] = this.filters.filterText; + this.panelState['filterHistory'] = this.filters.filterHistory; + this.panelState['showErrors'] = this.filters.showErrors; + this.panelState['showWarnings'] = this.filters.showWarnings; + this.panelState['showInfos'] = this.filters.showInfos; + this.panelState['useFilesExclude'] = this.filters.excludedFiles; + this.panelState['activeFile'] = this.filters.activeFile; this.panelState['multiline'] = this.markersViewModel.multiline; super.saveState(); diff --git a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts index 839661e78e9..abe04813ce6 100644 --- a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts +++ b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts @@ -5,7 +5,7 @@ import { Delayer } from 'vs/base/common/async'; import * as DOM from 'vs/base/browser/dom'; -import { Action, IActionChangeEvent, IAction, IActionRunner } from 'vs/base/common/actions'; +import { Action, IAction, IActionRunner } from 'vs/base/common/actions'; import { HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { KeyCode } from 'vs/base/common/keyCodes'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -14,7 +14,7 @@ import Messages from 'vs/workbench/contrib/markers/browser/messages'; import Constants from 'vs/workbench/contrib/markers/browser/constants'; import { IThemeService, registerThemingParticipant, ICssStyleCollector, IColorTheme } from 'vs/platform/theme/common/themeService'; import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; -import { toDisposable } from 'vs/base/common/lifecycle'; +import { toDisposable, Disposable } from 'vs/base/common/lifecycle'; import { BaseActionViewItem, ActionViewItem, ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { badgeBackground, badgeForeground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground } from 'vs/platform/theme/common/colorRegistry'; import { localize } from 'vs/nls'; @@ -23,7 +23,6 @@ import { ContextScopedHistoryInputBox } from 'vs/platform/browser/contextScopedH import { Marker } from 'vs/workbench/contrib/markers/browser/markersModel'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Event, Emitter } from 'vs/base/common/event'; -import { FilterOptions } from 'vs/workbench/contrib/markers/browser/markersFilterOptions'; import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdown'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { IViewsService } from 'vs/workbench/common/views'; @@ -44,16 +43,17 @@ export class ShowProblemsPanelAction extends Action { } } -export interface IMarkersFilterActionChangeEvent extends IActionChangeEvent { +export interface IMarkersFiltersChangeEvent { filterText?: boolean; excludedFiles?: boolean; showWarnings?: boolean; showErrors?: boolean; showInfos?: boolean; activeFile?: boolean; + layout?: boolean; } -export interface IMarkersFilterActionOptions { +export interface IMarkersFiltersOptions { filterText: string; filterHistory: string[]; showErrors: boolean; @@ -61,17 +61,16 @@ export interface IMarkersFilterActionOptions { showInfos: boolean; excludedFiles: boolean; activeFile: boolean; + layout: DOM.Dimension; } -export class MarkersFilterAction extends Action { +export class MarkersFilters extends Disposable { - public static readonly ID: string = 'workbench.actions.problems.filter'; + private readonly _onDidChange: Emitter = this._register(new Emitter()); + readonly onDidChange: Event = this._onDidChange.event; - private readonly _onFocus: Emitter = this._register(new Emitter()); - readonly onFocus: Event = this._onFocus.event; - - constructor(options: IMarkersFilterActionOptions) { - super(MarkersFilterAction.ID, Messages.MARKERS_PANEL_ACTION_TOOLTIP_FILTER, 'markers-panel-action-filter', true); + constructor(options: IMarkersFiltersOptions) { + super(); this._filterText = options.filterText; this._showErrors = options.showErrors; this._showWarnings = options.showWarnings; @@ -79,6 +78,7 @@ export class MarkersFilterAction extends Action { this._excludedFiles = options.excludedFiles; this._activeFile = options.activeFile; this.filterHistory = options.filterHistory; + this._layout = options.layout; } private _filterText: string; @@ -88,7 +88,7 @@ export class MarkersFilterAction extends Action { set filterText(filterText: string) { if (this._filterText !== filterText) { this._filterText = filterText; - this._onDidChange.fire({ filterText: true }); + this._onDidChange.fire({ filterText: true }); } } @@ -101,7 +101,7 @@ export class MarkersFilterAction extends Action { set excludedFiles(filesExclude: boolean) { if (this._excludedFiles !== filesExclude) { this._excludedFiles = filesExclude; - this._onDidChange.fire({ excludedFiles: true }); + this._onDidChange.fire({ excludedFiles: true }); } } @@ -112,7 +112,7 @@ export class MarkersFilterAction extends Action { set activeFile(activeFile: boolean) { if (this._activeFile !== activeFile) { this._activeFile = activeFile; - this._onDidChange.fire({ activeFile: true }); + this._onDidChange.fire({ activeFile: true }); } } @@ -123,7 +123,7 @@ export class MarkersFilterAction extends Action { set showWarnings(showWarnings: boolean) { if (this._showWarnings !== showWarnings) { this._showWarnings = showWarnings; - this._onDidChange.fire({ showWarnings: true }); + this._onDidChange.fire({ showWarnings: true }); } } @@ -134,7 +134,7 @@ export class MarkersFilterAction extends Action { set showErrors(showErrors: boolean) { if (this._showErrors !== showErrors) { this._showErrors = showErrors; - this._onDidChange.fire({ showErrors: true }); + this._onDidChange.fire({ showErrors: true }); } } @@ -145,35 +145,33 @@ export class MarkersFilterAction extends Action { set showInfos(showInfos: boolean) { if (this._showInfos !== showInfos) { this._showInfos = showInfos; - this._onDidChange.fire({ showInfos: true }); + this._onDidChange.fire({ showInfos: true }); } } - focus(): void { - this._onFocus.fire(); + private _layout: DOM.Dimension = new DOM.Dimension(0, 0); + get layout(): DOM.Dimension { + return this._layout; } - - layout(width: number): void { - if (width > 600) { - this.class = 'markers-panel-action-filter grow'; - } else if (width < 400) { - this.class = 'markers-panel-action-filter small'; - } else { - this.class = 'markers-panel-action-filter'; + set layout(layout: DOM.Dimension) { + if (this._layout.width !== layout.width || this._layout.height !== layout.height) { + this._layout = layout; + this._onDidChange.fire({ layout: true }); } } } export interface IMarkerFilterController { - onDidFilter: Event; - getFilterOptions(): FilterOptions; + readonly onDidFocusFilter: Event; + readonly filters: MarkersFilters; + readonly onDidChangeFilterStats: Event<{ total: number, filtered: number }>; getFilterStats(): { total: number, filtered: number }; } class FiltersDropdownMenuActionViewItem extends DropdownMenuActionViewItem { constructor( - action: IAction, private filterAction: MarkersFilterAction, actionRunner: IActionRunner, + action: IAction, private filters: MarkersFilters, actionRunner: IActionRunner, @IContextMenuService contextMenuService: IContextMenuService ) { super(action, @@ -194,53 +192,53 @@ class FiltersDropdownMenuActionViewItem extends DropdownMenuActionViewItem { private getActions(): IAction[] { return [ { - checked: this.filterAction.showErrors, + checked: this.filters.showErrors, class: undefined, enabled: true, id: 'showErrors', label: Messages.MARKERS_PANEL_FILTER_LABEL_SHOW_ERRORS, - run: async () => this.filterAction.showErrors = !this.filterAction.showErrors, + run: async () => this.filters.showErrors = !this.filters.showErrors, tooltip: '', dispose: () => null }, { - checked: this.filterAction.showWarnings, + checked: this.filters.showWarnings, class: undefined, enabled: true, id: 'showWarnings', label: Messages.MARKERS_PANEL_FILTER_LABEL_SHOW_WARNINGS, - run: async () => this.filterAction.showWarnings = !this.filterAction.showWarnings, + run: async () => this.filters.showWarnings = !this.filters.showWarnings, tooltip: '', dispose: () => null }, { - checked: this.filterAction.showInfos, + checked: this.filters.showInfos, class: undefined, enabled: true, id: 'showInfos', label: Messages.MARKERS_PANEL_FILTER_LABEL_SHOW_INFOS, - run: async () => this.filterAction.showInfos = !this.filterAction.showInfos, + run: async () => this.filters.showInfos = !this.filters.showInfos, tooltip: '', dispose: () => null }, new Separator(), { - checked: this.filterAction.activeFile, + checked: this.filters.activeFile, class: undefined, enabled: true, id: 'activeFile', label: Messages.MARKERS_PANEL_FILTER_LABEL_ACTIVE_FILE, - run: async () => this.filterAction.activeFile = !this.filterAction.activeFile, + run: async () => this.filters.activeFile = !this.filters.activeFile, tooltip: '', dispose: () => null }, { - checked: this.filterAction.excludedFiles, + checked: this.filters.excludedFiles, class: undefined, enabled: true, id: 'useFilesExclude', label: Messages.MARKERS_PANEL_FILTER_LABEL_EXCLUDED_FILES, - run: async () => this.filterAction.excludedFiles = !this.filterAction.excludedFiles, + run: async () => this.filters.excludedFiles = !this.filters.excludedFiles, tooltip: '', dispose: () => null }, @@ -263,7 +261,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { private readonly filtersAction: IAction; constructor( - readonly action: MarkersFilterAction, + action: IAction, private filterController: IMarkerFilterController, @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextViewService private readonly contextViewService: IContextViewService, @@ -274,10 +272,10 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { this.focusContextKey = Constants.MarkerViewFilterFocusContextKey.bindTo(contextKeyService); this.delayedFilterUpdate = new Delayer(200); this._register(toDisposable(() => this.delayedFilterUpdate.cancel())); - this._register(action.onFocus(() => this.focus())); + this._register(filterController.onDidFocusFilter(() => this.focus())); this.filtersAction = new Action('markersFiltersAction', Messages.MARKERS_PANEL_ACTION_TOOLTIP_MORE_FILTERS, 'markers-filters codicon-filter'); this.filtersAction.checked = this.hasFiltersChanged(); - this._register(action.onDidChange(() => this.filtersAction.checked = this.hasFiltersChanged())); + this._register(filterController.filters.onDidChange(e => this.onDidFiltersChange(e))); } render(container: HTMLElement): void { @@ -285,7 +283,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { DOM.addClass(this.container, 'markers-panel-action-filter-container'); this.element = DOM.append(this.container, DOM.$('')); - this.element.className = this.action.class || ''; + this.element.className = this.class; this.createInput(this.element); this.createControls(this.element); this.updateClass(); @@ -299,23 +297,30 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { } } + private onDidFiltersChange(e: IMarkersFiltersChangeEvent): void { + this.filtersAction.checked = this.hasFiltersChanged(); + if (e.layout) { + this.updateClass(); + } + } + private hasFiltersChanged(): boolean { - return !this.action.showErrors || !this.action.showWarnings || !this.action.showInfos || this.action.excludedFiles || this.action.activeFile; + return !this.filterController.filters.showErrors || !this.filterController.filters.showWarnings || !this.filterController.filters.showInfos || this.filterController.filters.excludedFiles || this.filterController.filters.activeFile; } private createInput(container: HTMLElement): void { this.filterInputBox = this._register(this.instantiationService.createInstance(ContextScopedHistoryInputBox, container, this.contextViewService, { placeholder: Messages.MARKERS_PANEL_FILTER_PLACEHOLDER, ariaLabel: Messages.MARKERS_PANEL_FILTER_ARIA_LABEL, - history: this.action.filterHistory + history: this.filterController.filters.filterHistory })); this.filterInputBox.inputElement.setAttribute('aria-labelledby', 'markers-panel-arialabel'); this._register(attachInputBoxStyler(this.filterInputBox, this.themeService)); - this.filterInputBox.value = this.action.filterText; + this.filterInputBox.value = this.filterController.filters.filterText; this._register(this.filterInputBox.onDidChange(filter => this.delayedFilterUpdate.trigger(() => this.onDidInputChange(this.filterInputBox!)))); - this._register(this.action.onDidChange((event: IMarkersFilterActionChangeEvent) => { + this._register(this.filterController.filters.onDidChange((event: IMarkersFiltersChangeEvent) => { if (event.filterText) { - this.filterInputBox!.value = this.action.filterText; + this.filterInputBox!.value = this.filterController.filters.filterText; } })); this._register(DOM.addStandardDisposableListener(this.filterInputBox.inputElement, DOM.EventType.KEY_DOWN, (e: any) => this.onInputKeyDown(e, this.filterInputBox!))); @@ -349,14 +354,14 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { filterBadge.style.color = foreground; })); this.updateBadge(); - this._register(this.filterController.onDidFilter(() => this.updateBadge())); + this._register(this.filterController.onDidChangeFilterStats(() => this.updateBadge())); } private createFilters(container: HTMLElement): void { const actionbar = this._register(new ActionBar(container, { actionViewItemProvider: action => { if (action.id === this.filtersAction.id) { - return this.instantiationService.createInstance(FiltersDropdownMenuActionViewItem, action, this.action, this.actionRunner); + return this.instantiationService.createInstance(FiltersDropdownMenuActionViewItem, action, this.filterController.filters, this.actionRunner); } return undefined; } @@ -366,8 +371,8 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { private onDidInputChange(inputbox: HistoryInputBox) { inputbox.addToHistory(); - this.action.filterText = inputbox.value; - this.action.filterHistory = inputbox.getHistory(); + this.filterController.filters.filterText = inputbox.value; + this.filterController.filters.filterHistory = inputbox.getHistory(); } private updateBadge(): void { @@ -410,11 +415,21 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { protected updateClass(): void { if (this.element && this.container) { - this.element.className = this.action.class || ''; + this.element.className = this.class; DOM.toggleClass(this.container, 'grow', DOM.hasClass(this.element, 'grow')); this.adjustInputBox(); } } + + protected get class(): string { + if (this.filterController.filters.layout.width > 600) { + return 'markers-panel-action-filter grow'; + } else if (this.filterController.filters.layout.width < 400) { + return 'markers-panel-action-filter small'; + } else { + return 'markers-panel-action-filter'; + } + } } export class QuickFixAction extends Action { From c9e1f43c2725c692481a01a732592a05e93c9306 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 8 Mar 2020 20:42:06 +0100 Subject: [PATCH 082/137] :lipstick: --- .../workbench/browser/parts/views/treeView.ts | 8 ++-- .../search/browser/search.contribution.ts | 4 +- .../contrib/search/browser/searchViewlet.ts | 42 ------------------- 3 files changed, 6 insertions(+), 48 deletions(-) delete mode 100644 src/vs/workbench/contrib/search/browser/searchViewlet.ts diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 93485f37d59..1016d6e3582 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -294,7 +294,7 @@ export class TreeView extends Disposable implements ITreeView { private registerActions() { const that = this; - registerAction2(class extends Action2 { + this._register(registerAction2(class extends Action2 { constructor() { super({ id: `workbench.actions.treeView.${that.id}.refresh`, @@ -311,8 +311,8 @@ export class TreeView extends Disposable implements ITreeView { async run(): Promise { return that.refresh(); } - }); - registerAction2(class extends Action2 { + })); + this._register(registerAction2(class extends Action2 { constructor() { super({ id: `workbench.actions.treeView.${that.id}.collapseAll`, @@ -331,7 +331,7 @@ export class TreeView extends Disposable implements ITreeView { return new CollapseAllAction(that.tree, true).run(); } } - }); + })); } setVisibility(isVisible: boolean): void { diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 950b1f164ba..3d9deddf982 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -52,9 +52,9 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { ExplorerViewPaneContainer } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { assertType, assertIsDefined } from 'vs/base/common/types'; -import { SearchViewPaneContainer } from 'vs/workbench/contrib/search/browser/searchViewlet'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { SearchEditor } from 'vs/workbench/contrib/searchEditor/browser/searchEditor'; +import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; registerSingleton(ISearchWorkbenchService, SearchWorkbenchService, true); registerSingleton(ISearchHistoryService, SearchHistoryService, true); @@ -499,7 +499,7 @@ class ShowAllSymbolsAction extends Action { const viewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: VIEWLET_ID, name: nls.localize('name', "Search"), - ctorDescriptor: new SyncDescriptor(SearchViewPaneContainer), + ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]), hideIfEmpty: true, icon: 'codicon-search', order: 1 diff --git a/src/vs/workbench/contrib/search/browser/searchViewlet.ts b/src/vs/workbench/contrib/search/browser/searchViewlet.ts deleted file mode 100644 index 2754b71d7b8..00000000000 --- a/src/vs/workbench/contrib/search/browser/searchViewlet.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { VIEWLET_ID, VIEW_ID } from 'vs/workbench/services/search/common/search'; -import { SearchView } from 'vs/workbench/contrib/search/browser/searchView'; -import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; -import { IViewDescriptorService } from 'vs/workbench/common/views'; - - -export class SearchViewPaneContainer extends ViewPaneContainer { - - constructor( - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService protected contextService: IWorkspaceContextService, - @IStorageService protected storageService: IStorageService, - @IConfigurationService configurationService: IConfigurationService, - @IInstantiationService protected instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService, - @IViewDescriptorService viewDescriptorService: IViewDescriptorService - ) { - super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); - } - - getSearchView(): SearchView | undefined { - const view = super.getView(VIEW_ID); - return view ? view as SearchView : undefined; - } -} From 45fa807a8a92ae54e701a40b48b067e6fa596994 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Sun, 8 Mar 2020 14:34:03 -0700 Subject: [PATCH 083/137] Add command to open search editor to side Closes #92025 --- .../contrib/searchEditor/browser/constants.ts | 1 + .../browser/searchEditor.contribution.ts | 6 ++++- .../browser/searchEditorActions.ts | 22 ++++++++++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/searchEditor/browser/constants.ts b/src/vs/workbench/contrib/searchEditor/browser/constants.ts index 7de8978e745..f4083a25baa 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/constants.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/constants.ts @@ -7,6 +7,7 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; export const OpenInEditorCommandId = 'search.action.openInEditor'; export const OpenNewEditorCommandId = 'search.action.openNewEditor'; +export const OpenNewEditorToSideCommandId = 'search.action.openNewEditorToSide'; export const ToggleSearchEditorCaseSensitiveCommandId = 'toggleSearchEditorCaseSensitive'; export const ToggleSearchEditorWholeWordCommandId = 'toggleSearchEditorWholeWord'; diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts index 63948369b3a..0758c2d315f 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts @@ -24,7 +24,7 @@ import { Extensions as EditorInputExtensions, IEditorInputFactory, IEditorInputF import * as SearchConstants from 'vs/workbench/contrib/search/common/constants'; import * as SearchEditorConstants from 'vs/workbench/contrib/searchEditor/browser/constants'; import { SearchEditor } from 'vs/workbench/contrib/searchEditor/browser/searchEditor'; -import { OpenResultsInEditorAction, OpenSearchEditorAction, toggleSearchEditorCaseSensitiveCommand, toggleSearchEditorContextLinesCommand, toggleSearchEditorRegexCommand, toggleSearchEditorWholeWordCommand, selectAllSearchEditorMatchesCommand, RerunSearchEditorSearchAction } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; +import { OpenResultsInEditorAction, OpenSearchEditorAction, toggleSearchEditorCaseSensitiveCommand, toggleSearchEditorContextLinesCommand, toggleSearchEditorRegexCommand, toggleSearchEditorWholeWordCommand, selectAllSearchEditorMatchesCommand, RerunSearchEditorSearchAction, OpenSearchEditorToSideAction } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; import { getOrMakeSearchEditorInput, SearchEditorInput } from 'vs/workbench/contrib/searchEditor/browser/searchEditorInput'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -183,6 +183,10 @@ registry.registerWorkbenchAction( SyncActionDescriptor.create(OpenSearchEditorAction, OpenSearchEditorAction.ID, OpenSearchEditorAction.LABEL), 'Search Editor: Open New Search Editor', category); +registry.registerWorkbenchAction( + SyncActionDescriptor.create(OpenSearchEditorToSideAction, OpenSearchEditorToSideAction.ID, OpenSearchEditorToSideAction.LABEL), + 'Search Editor: Open New Search Editor to Side', category); + registry.registerWorkbenchAction(SyncActionDescriptor.create(RerunSearchEditorSearchAction, RerunSearchEditorSearchAction.ID, RerunSearchEditorSearchAction.LABEL, { mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_R } }, ContextKeyExpr.and(SearchEditorConstants.InSearchEditor)), 'Search Editor: Rerun', category); diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts index cc291cefbbd..866e604fc5f 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts @@ -19,7 +19,7 @@ import * as Constants from 'vs/workbench/contrib/searchEditor/browser/constants' import { SearchEditor } from 'vs/workbench/contrib/searchEditor/browser/searchEditor'; import { getOrMakeSearchEditorInput, SearchEditorInput } from 'vs/workbench/contrib/searchEditor/browser/searchEditorInput'; import { serializeSearchResultForEditor } from 'vs/workbench/contrib/searchEditor/browser/searchEditorSerialization'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ISearchConfigurationProperties } from 'vs/workbench/services/search/common/search'; export const toggleSearchEditorCaseSensitiveCommand = (accessor: ServicesAccessor) => { @@ -87,6 +87,22 @@ export class OpenSearchEditorAction extends Action { } } +export class OpenSearchEditorToSideAction extends Action { + + static readonly ID: string = Constants.OpenNewEditorToSideCommandId; + static readonly LABEL = localize('search.openNewEditorToSide', "Open New Search Editor to Side"); + + constructor(id: string, label: string, + @IInstantiationService private readonly instantiationService: IInstantiationService, + ) { + super(id, label, 'codicon-new-file'); + } + + async run() { + await this.instantiationService.invokeFunction(openNewSearchEditor, true); + } +} + export class OpenResultsInEditorAction extends Action { static readonly ID: string = Constants.OpenInEditorCommandId; @@ -135,7 +151,7 @@ export class RerunSearchEditorSearchAction extends Action { } const openNewSearchEditor = - async (accessor: ServicesAccessor) => { + async (accessor: ServicesAccessor, toSide = false) => { const editorService = accessor.get(IEditorService); const telemetryService = accessor.get(ITelemetryService); const instantiationService = accessor.get(IInstantiationService); @@ -166,7 +182,7 @@ const openNewSearchEditor = telemetryService.publicLog2('searchEditor/openNewSearchEditor'); const input = instantiationService.invokeFunction(getOrMakeSearchEditorInput, { config: { query: selected } }); - const editor = await editorService.openEditor(input, { pinned: true }) as SearchEditor; + const editor = await editorService.openEditor(input, { pinned: true }, toSide ? SIDE_GROUP : ACTIVE_GROUP) as SearchEditor; if (selected && configurationService.getValue('search').searchOnType) { editor.triggerSearch(); From b980d895f728f417d45c2af20d0f8860f3c3485a Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Sun, 8 Mar 2020 15:06:25 -0700 Subject: [PATCH 084/137] Add keybindings to change number of context lines Close #92172 --- .../contrib/search/browser/searchWidget.ts | 9 ++++++++- .../contrib/searchEditor/browser/constants.ts | 3 +++ .../browser/searchEditor.contribution.ts | 20 ++++++++++++++++++- .../searchEditor/browser/searchEditor.ts | 6 +++++- .../browser/searchEditorActions.ts | 8 ++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchWidget.ts b/src/vs/workbench/contrib/search/browser/searchWidget.ts index 428becff1e7..706c368d91a 100644 --- a/src/vs/workbench/contrib/search/browser/searchWidget.ts +++ b/src/vs/workbench/contrib/search/browser/searchWidget.ts @@ -634,10 +634,17 @@ export class SearchWidget extends Widget { this._onSearchSubmit.fire({ triggeredOnType, delay }); } - contextLines() { + getContextLines() { return this.showContextCheckbox.checked ? +this.contextLinesInput.value : 0; } + modifyContextLines(increase: boolean) { + const current = +this.contextLinesInput.value; + const modified = current + (increase ? 1 : -1); + this.showContextCheckbox.checked = modified !== 0; + this.contextLinesInput.value = '' + modified; + } + toggleContextLines() { this.showContextCheckbox.checked = !this.showContextCheckbox.checked; this.onContextLinesChanged(); diff --git a/src/vs/workbench/contrib/searchEditor/browser/constants.ts b/src/vs/workbench/contrib/searchEditor/browser/constants.ts index f4083a25baa..39c264c57c9 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/constants.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/constants.ts @@ -13,6 +13,9 @@ export const ToggleSearchEditorCaseSensitiveCommandId = 'toggleSearchEditorCaseS export const ToggleSearchEditorWholeWordCommandId = 'toggleSearchEditorWholeWord'; export const ToggleSearchEditorRegexCommandId = 'toggleSearchEditorRegex'; export const ToggleSearchEditorContextLinesCommandId = 'toggleSearchEditorContextLines'; +export const IncreaseSearchEditorContextLinesCommandId = 'increaseSearchEditorContextLines'; +export const DecreaseSearchEditorContextLinesCommandId = 'decreaseSearchEditorContextLines'; + export const RerunSearchEditorSearchCommandId = 'rerunSearchEditorSearch'; export const CleanSearchEditorStateCommandId = 'cleanSearchEditorState'; export const SelectAllSearchEditorMatchesCommandId = 'selectAllSearchEditorMatches'; diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts index 0758c2d315f..e74e02bdbab 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts @@ -24,7 +24,7 @@ import { Extensions as EditorInputExtensions, IEditorInputFactory, IEditorInputF import * as SearchConstants from 'vs/workbench/contrib/search/common/constants'; import * as SearchEditorConstants from 'vs/workbench/contrib/searchEditor/browser/constants'; import { SearchEditor } from 'vs/workbench/contrib/searchEditor/browser/searchEditor'; -import { OpenResultsInEditorAction, OpenSearchEditorAction, toggleSearchEditorCaseSensitiveCommand, toggleSearchEditorContextLinesCommand, toggleSearchEditorRegexCommand, toggleSearchEditorWholeWordCommand, selectAllSearchEditorMatchesCommand, RerunSearchEditorSearchAction, OpenSearchEditorToSideAction } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; +import { OpenResultsInEditorAction, OpenSearchEditorAction, toggleSearchEditorCaseSensitiveCommand, toggleSearchEditorContextLinesCommand, toggleSearchEditorRegexCommand, toggleSearchEditorWholeWordCommand, selectAllSearchEditorMatchesCommand, RerunSearchEditorSearchAction, OpenSearchEditorToSideAction, modifySearchEditorContextLinesCommand } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; import { getOrMakeSearchEditorInput, SearchEditorInput } from 'vs/workbench/contrib/searchEditor/browser/searchEditorInput'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -151,6 +151,24 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_L } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: SearchEditorConstants.IncreaseSearchEditorContextLinesCommandId, + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + handler: (accessor: ServicesAccessor) => modifySearchEditorContextLinesCommand(accessor, true), + primary: KeyMod.Alt | KeyCode.KEY_L, + mac: { primary: KeyMod.Alt | KeyCode.US_EQUAL } +}); + +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: SearchEditorConstants.DecreaseSearchEditorContextLinesCommandId, + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + handler: (accessor: ServicesAccessor) => modifySearchEditorContextLinesCommand(accessor, false), + primary: KeyMod.Alt | KeyCode.KEY_L, + mac: { primary: KeyMod.Alt | KeyCode.US_MINUS } +}); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: SearchEditorConstants.SelectAllSearchEditorMatchesCommandId, weight: KeybindingWeight.WorkbenchContrib, diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index 61717d14936..382284e12ee 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -295,6 +295,10 @@ export class SearchEditor extends BaseTextEditor { this.queryEditorWidget.toggleContextLines(); } + modifyContextLines(increase: boolean) { + this.queryEditorWidget.modifyContextLines(increase); + } + toggleQueryDetails() { this.toggleIncludesExcludes(); } @@ -421,7 +425,7 @@ export class SearchEditor extends BaseTextEditor { private readConfigFromWidget() { return { caseSensitive: this.queryEditorWidget.searchInput.getCaseSensitive(), - contextLines: this.queryEditorWidget.contextLines(), + contextLines: this.queryEditorWidget.getContextLines(), excludes: this.inputPatternExcludes.getValue(), includes: this.inputPatternIncludes.getValue(), query: this.queryEditorWidget.searchInput.getValue(), diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts index 866e604fc5f..29d36746319 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts @@ -54,6 +54,14 @@ export const toggleSearchEditorContextLinesCommand = (accessor: ServicesAccessor } }; +export const modifySearchEditorContextLinesCommand = (accessor: ServicesAccessor, increase: boolean) => { + const editorService = accessor.get(IEditorService); + const input = editorService.activeEditor; + if (input instanceof SearchEditorInput) { + (editorService.activeEditorPane as SearchEditor).modifyContextLines(increase); + } +}; + export const selectAllSearchEditorMatchesCommand = (accessor: ServicesAccessor) => { const editorService = accessor.get(IEditorService); const input = editorService.activeEditor; From 7edc0a4edb51ca4cfdda86a6e47a621c51802d8d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 09:48:49 +0100 Subject: [PATCH 085/137] quick access - implement view handler --- .../quickinput/browser/quickInputList.ts | 12 +- .../parts/quickinput/common/quickInput.ts | 10 +- src/vs/editor/contrib/quickAccess/gotoLine.ts | 4 +- .../browser/quickAccess.contribution.ts | 7 + .../quickaccess/browser/viewQuickAccess.ts | 205 ++++++++++++++++++ 5 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index bc730ff2a9b..1e758f0d9b1 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -33,9 +33,12 @@ interface IListElement { readonly index: number; readonly item: IQuickPickItem; readonly saneLabel: string; + readonly saneAriaLabel: string; readonly saneDescription?: string; readonly saneDetail?: string; - readonly saneAriaLabel: string; + readonly labelHighlights?: IMatch[]; + readonly descriptionHighlights?: IMatch[]; + readonly detailHighlights?: IMatch[]; readonly checked: boolean; readonly separator?: IQuickPickSeparator; readonly fireButtonTriggered: (event: IQuickPickItemButtonEvent) => void; @@ -45,9 +48,9 @@ class ListElement implements IListElement { index!: number; item!: IQuickPickItem; saneLabel!: string; + saneAriaLabel!: string; saneDescription?: string; saneDetail?: string; - saneAriaLabel!: string; hidden = false; private readonly _onChecked = new Emitter(); onChecked = this._onChecked.event; @@ -375,9 +378,12 @@ export class QuickInputList { index, item, saneLabel, + saneAriaLabel, saneDescription, saneDetail, - saneAriaLabel, + labelHighlights: item.highlights?.label, + descriptionHighlights: item.highlights?.description, + detailHighlights: item.highlights?.detail, checked: false, separator: previous && previous.type === 'separator' ? previous : undefined, fireButtonTriggered diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index 3ad4be0a5f1..9defebaeb77 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -7,15 +7,23 @@ import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IMatch } from 'vs/base/common/filters'; + +export interface IQuickPickItemHighlights { + label?: IMatch[]; + description?: IMatch[]; + detail?: IMatch[]; +} export interface IQuickPickItem { type?: 'item'; id?: string; label: string; + ariaLabel?: string; description?: string; detail?: string; - ariaLabel?: string; iconClasses?: string[]; + highlights?: IQuickPickItemHighlights; buttons?: IQuickInputButton[]; picked?: boolean; alwaysShow?: boolean; diff --git a/src/vs/editor/contrib/quickAccess/gotoLine.ts b/src/vs/editor/contrib/quickAccess/gotoLine.ts index 83d98fbfc77..941c3f654f9 100644 --- a/src/vs/editor/contrib/quickAccess/gotoLine.ts +++ b/src/vs/editor/contrib/quickAccess/gotoLine.ts @@ -25,8 +25,8 @@ export abstract class AbstractGotoLineQuickAccessProvider extends AbstractEditor provide(picker: IQuickPick, token: CancellationToken): IDisposable { const disposables = new DisposableStore(); - // Disable filtering, we control the results - picker.filterValue = () => ''; + // Disable filtering & sorting, we control the results + picker.matchOnLabel = picker.matchOnDescription = picker.matchOnDetail = picker.sortByLabel = false; // Provide based on current active editor let pickerDisposable = this.doProvide(picker, token); diff --git a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts index f5a304b7bed..90b796901d8 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts @@ -7,9 +7,16 @@ import { localize } from 'vs/nls'; import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuickAccess'; +import { ViewQuickAccessProvider, VIEW_QUICK_ACCESS_PREFIX } from 'vs/workbench/contrib/quickaccess/browser/viewQuickAccess'; Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ ctor: HelpQuickAccessProvider, prefix: '?', helpEntries: [{ description: localize('helpQuickAccess', "Show all Quick Access Providers"), needsEditor: false }] }); + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ + ctor: ViewQuickAccessProvider, + prefix: VIEW_QUICK_ACCESS_PREFIX, + helpEntries: [{ description: localize('viewQuickAccess', "Open View"), needsEditor: false }] +}); diff --git a/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts b/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts new file mode 100644 index 00000000000..d61f2cf75a0 --- /dev/null +++ b/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts @@ -0,0 +1,205 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IQuickPick, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import { IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IViewDescriptorService, IViewsService, ViewContainer, IViewsRegistry, Extensions as ViewExtensions, IViewContainersRegistry } from 'vs/workbench/common/views'; +import { IOutputService } from 'vs/workbench/contrib/output/common/output'; +import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; +import { matchesFuzzy } from 'vs/base/common/filters'; +import { fuzzyContains } from 'vs/base/common/strings'; +import { withNullAsUndefined } from 'vs/base/common/types'; + +export const VIEW_QUICK_ACCESS_PREFIX = 'view '; + +interface IViewQuickPickItem extends IQuickPickItem { + containerLabel: string; + run: () => Promise; +} + +export class ViewQuickAccessProvider implements IQuickAccessProvider { + + constructor( + @IViewletService private readonly viewletService: IViewletService, + @IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService, + @IViewsService private readonly viewsService: IViewsService, + @IOutputService private readonly outputService: IOutputService, + @ITerminalService private readonly terminalService: ITerminalService, + @IPanelService private readonly panelService: IPanelService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + ) { + } + + provide(picker: IQuickPick, token: CancellationToken): IDisposable { + const disposables = new DisposableStore(); + + // Disable filtering & sorting, we control the results + picker.matchOnLabel = picker.matchOnDescription = picker.matchOnDetail = picker.sortByLabel = false; + + // Add all view items + picker.items = this.getViewPickItems(''); + + // Filter on type + disposables.add(picker.onDidChangeValue(value => { + picker.items = this.getViewPickItems(value.trim().substr(VIEW_QUICK_ACCESS_PREFIX.length)); + })); + + // Open the picked view on accept + disposables.add(picker.onDidAccept(() => { + const [item] = picker.selectedItems; + if (item) { + picker.hide(); + item.run(); + } + })); + + return disposables; + } + + private getViewPickItems(filter: string): Array { + const filteredViewEntries = this.doGetViewPickItems().filter(entry => { + if (!filter) { + return true; + } + + // Match fuzzy on label + entry.highlights = { label: withNullAsUndefined(matchesFuzzy(filter, entry.label, true)) }; + + // Return if we have a match on label or container + return entry.highlights.label || fuzzyContains(entry.containerLabel, filter); + }); + + // Map entries to container labels + const mapEntryToContainer = new Map(); + for (const entry of filteredViewEntries) { + if (!mapEntryToContainer.has(entry.label)) { + mapEntryToContainer.set(entry.label, entry.containerLabel); + } + } + + const filteredViewEntriesWithSeparators: Array = []; + + // Add separators for containers + let lastContainer: string | undefined = undefined; + for (const entry of filteredViewEntries) { + if (lastContainer !== entry.containerLabel) { + lastContainer = entry.containerLabel; + + // When the entry container has a parent container, set container + // label as Parent / Child. For example, `Views / Explorer`. + let separatorLabel: string; + if (mapEntryToContainer.has(lastContainer)) { + separatorLabel = `${mapEntryToContainer.get(lastContainer)} / ${lastContainer}`; + } else { + separatorLabel = lastContainer; + } + + filteredViewEntriesWithSeparators.push({ type: 'separator', label: separatorLabel }); + + } + + filteredViewEntriesWithSeparators.push(entry); + } + + return filteredViewEntriesWithSeparators; + } + + private doGetViewPickItems(): Array { + const viewEntries: Array = []; + + const getViewEntriesForViewlet = (viewlet: ViewletDescriptor, viewContainer: ViewContainer): IViewQuickPickItem[] => { + const views = Registry.as(ViewExtensions.ViewsRegistry).getViews(viewContainer); + const result: IViewQuickPickItem[] = []; + for (const view of views) { + if (this.contextKeyService.contextMatchesRules(view.when)) { + result.push({ + label: view.name, + containerLabel: viewlet.name, + run: () => this.viewsService.openView(view.id, true) + }); + } + } + + return result; + }; + + // Viewlets + const viewlets = this.viewletService.getViewlets(); + for (const viewlet of viewlets) { + if (this.includeViewlet(viewlet)) { + viewEntries.push({ + label: viewlet.name, + containerLabel: localize('views', "Side Bar"), + run: () => this.viewletService.openViewlet(viewlet.id, true) + }); + } + } + + // Panels + const panels = this.panelService.getPanels(); + for (const panel of panels) { + viewEntries.push({ + label: panel.name, + containerLabel: localize('panels', "Panel"), + run: () => this.panelService.openPanel(panel.id, true) + }); + } + + // Viewlet Views + for (const viewlet of viewlets) { + const viewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).get(viewlet.id); + if (viewContainer) { + viewEntries.push(...getViewEntriesForViewlet(viewlet, viewContainer)); + } + } + + // Terminals + this.terminalService.terminalTabs.forEach((tab, tabIndex) => { + tab.terminalInstances.forEach((terminal, terminalIndex) => { + viewEntries.push({ + label: localize('terminalTitle', "{0}: {1}", `${tabIndex + 1}.${terminalIndex + 1}`, terminal.title), + containerLabel: localize('terminals', "Terminal"), + run: async () => { + await this.terminalService.showPanel(true); + + return this.terminalService.setActiveInstance(terminal); + } + }); + }); + }); + + // Output Channels + const channels = this.outputService.getChannelDescriptors(); + for (const channel of channels) { + viewEntries.push({ + label: channel.log ? localize('logChannel', "Log ({0})", channel.label) : channel.label, + containerLabel: localize('channels', "Output"), + run: () => this.outputService.showChannel(channel.id) + }); + } + + // Add generic ARIA label + viewEntries.forEach(entry => entry.ariaLabel = localize('entryAriaLabel', "{0}, view picker", entry.label)); + + return viewEntries; + } + + private includeViewlet(viewlet: ViewletDescriptor): boolean { + const viewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).get(viewlet.id); + if (viewContainer?.hideIfEmpty) { + return this.viewDescriptorService.getViewDescriptors(viewContainer).activeViewDescriptors.length > 0; + } + + return true; + } +} From 74376da8e57a55487617b217e8777a7c83d8df67 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 9 Mar 2020 09:54:36 +0100 Subject: [PATCH 086/137] Opener service: do not throw since there is a chance that the commandService will actually activate the extension. fixes #92125 --- src/vs/editor/browser/services/openerService.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 4dfb0035522..0390927a4c4 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -11,7 +11,7 @@ import { Schemas } from 'vs/base/common/network'; import { normalizePath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; +import { ICommandService } from 'vs/platform/commands/common/commands'; import { IOpener, IOpenerService, IValidator, IExternalUriResolver, OpenOptions, ResolveExternalUriOptions, IResolvedExternalUri, IExternalOpener, matchesScheme } from 'vs/platform/opener/common/opener'; import { EditorOpenContext } from 'vs/platform/editor/common/editor'; @@ -28,9 +28,6 @@ class CommandOpener implements IOpener { if (typeof target === 'string') { target = URI.parse(target); } - if (!CommandsRegistry.getCommand(target.path)) { - throw new Error(`command '${target.path}' NOT known`); - } // execute as command let args: any = []; try { From cc4beafccd2f3fe1042c78a5ae66f7903972fb79 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 9 Mar 2020 10:31:42 +0100 Subject: [PATCH 087/137] Saying "command is" in the keyboard shortcuts list is inefficient fixes #92212 --- .../workbench/contrib/preferences/browser/keybindingsEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts index bdd7e5e3b26..17bc4b85e9c 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts @@ -953,7 +953,7 @@ class CommandColumn extends Column { } private getAriaLabel(keybindingItemEntry: IKeybindingItemEntry): string { - return localize('commandAriaLabel', "Command is {0}.", keybindingItemEntry.keybindingItem.commandLabel ? keybindingItemEntry.keybindingItem.commandLabel : keybindingItemEntry.keybindingItem.command); + return keybindingItemEntry.keybindingItem.commandLabel ? keybindingItemEntry.keybindingItem.commandLabel : keybindingItemEntry.keybindingItem.command; } } From 2502f01cb4b12a872c8103f56f43684b6653c267 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 9 Mar 2020 10:36:05 +0100 Subject: [PATCH 088/137] Welcome views show to often in custom views --- .../workbench/browser/parts/views/treeView.ts | 28 ++++++++++++++++--- src/vs/workbench/common/views.ts | 3 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 1016d6e3582..7ccbdb8997e 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -85,7 +85,7 @@ export class TreeViewPane extends ViewPane { } shouldShowWelcome(): boolean { - return (this.treeView.dataProvider === undefined) && (this.treeView.message === undefined); + return ((this.treeView.dataProvider === undefined) || !!this.treeView.dataProvider.isTreeEmpty) && (this.treeView.message === undefined); } layoutBody(height: number, width: number): void { @@ -217,15 +217,35 @@ export class TreeView extends Disposable implements ITreeView { if (dataProvider) { this._dataProvider = new class implements ITreeViewDataProvider { + private _isEmpty: boolean = true; + private _onDidChangeEmpty: Emitter = new Emitter(); + public onDidChangeEmpty: Event = this._onDidChangeEmpty.event; + + get isTreeEmpty(): boolean { + return this._isEmpty; + } + async getChildren(node: ITreeItem): Promise { + let children: ITreeItem[]; if (node && node.children) { - return Promise.resolve(node.children); + children = node.children; + } else { + children = await (node instanceof Root ? dataProvider.getChildren() : dataProvider.getChildren(node)); + node.children = children; + } + if (node instanceof Root) { + const oldEmpty = this._isEmpty; + this._isEmpty = children.length === 0; + if (oldEmpty !== this._isEmpty) { + this._onDidChangeEmpty.fire(); + } } - const children = await (node instanceof Root ? dataProvider.getChildren() : dataProvider.getChildren(node)); - node.children = children; return children; } }; + if (this._dataProvider.onDidChangeEmpty) { + this._register(this._dataProvider.onDidChangeEmpty(() => this._onDidChangeWelcomeState.fire())); + } this.updateMessage(); this.refresh(); } else { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index dbd8958dc5c..14564a51d3b 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -573,7 +573,8 @@ export interface ITreeItem { } export interface ITreeViewDataProvider { - + readonly isTreeEmpty?: boolean; + onDidChangeEmpty?: Event; getChildren(element?: ITreeItem): Promise; } From 66e66600f16ce1b88ea53a194d89176350efafdd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 10:39:09 +0100 Subject: [PATCH 089/137] quick access - prepare for merge to master --- .../parts/quickinput/browser/quickInput.ts | 7 ++-- .../standaloneQuickInputServiceImpl.ts | 5 +-- .../browser/parts/quickopen/quickopen.ts | 35 ++----------------- .../browser/quickAccess.contribution.ts | 18 ++++++++-- .../browser/quickAccessCommands.ts | 28 +++++++++++++++ .../test/browser/quickAccess.test.ts | 3 ++ .../test/browser/workbenchTestServices.ts | 2 +- 7 files changed, 54 insertions(+), 44 deletions(-) create mode 100644 src/vs/workbench/contrib/quickaccess/browser/quickAccessCommands.ts diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index db75187e82e..002c1df9a51 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -129,10 +129,6 @@ type Visibilities = { class QuickInput extends Disposable implements IQuickInput { - private readonly onDidTriggerButtonEmitter = this._register(new Emitter()); - private readonly onDidHideEmitter = this._register(new Emitter()); - private readonly onDisposeEmitter = this._register(new Emitter()); - private _title: string | undefined; private _description: string | undefined; private _steps: number | undefined; @@ -144,6 +140,9 @@ class QuickInput extends Disposable implements IQuickInput { private _ignoreFocusOut = false; private _buttons: IQuickInputButton[] = []; private buttonsUpdated = false; + private readonly onDidTriggerButtonEmitter = this._register(new Emitter()); + private readonly onDidHideEmitter = this._register(new Emitter()); + private readonly onDisposeEmitter = this._register(new Emitter()); protected readonly visibleDisposables = this._register(new DisposableStore()); diff --git a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts index 81574dce34b..20342263dc2 100644 --- a/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts +++ b/src/vs/editor/standalone/browser/quickInput/standaloneQuickInputServiceImpl.ts @@ -145,10 +145,7 @@ export class QuickInputEditorContribution implements IEditorContribution { readonly widget = new QuickInputEditorWidget(this.editor); - constructor(private editor: ICodeEditor, @IQuickInputService quickInputService: IQuickInputService) { - // TODO@ben remove me - only for testing - once(editor.onDidFocusEditorText)(() => quickInputService.quickAccess.show('')); - } + constructor(private editor: ICodeEditor) { } dispose(): void { this.widget.dispose(); diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index d13c217727d..5f7373c0d3f 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -6,17 +6,15 @@ import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; -import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IQuickAccessProvider, IQuickAccessRegistry, Extensions as QuickInputExtensions } from 'vs/platform/quickinput/common/quickAccess'; -import { CancellationToken } from 'vs/base/common/cancellation'; const inQuickOpenKey = 'inQuickOpen'; export const InQuickOpenContextKey = new RawContextKey(inQuickOpenKey, false); @@ -167,8 +165,6 @@ export class LegacyQuickInputQuickOpenController extends Disposable { super(); this.registerListeners(); - - setTimeout(() => this.quickInputService.quickAccess.show('?'), 0); } private registerListeners(): void { @@ -207,30 +203,3 @@ export class LegacyQuickInputQuickOpenController extends Disposable { } Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); - -class SampleQuickAccessProvider implements IQuickAccessProvider { - provide(picker: IQuickPick, token: CancellationToken): IDisposable { - picker.items = [ - { label: 'Hello World' }, - { label: 'Lorem Ipsum' }, - { label: 'Something Else' } - ]; - - return Disposable.None; - } -} - -const quickAccessRegistry = Registry.as(QuickInputExtensions.Quickaccess); -[''/*, '>', '@', ':', 'edt', 'edt active', 'edt mru', 'view'*/].forEach(prefix => { - const provider = { - ctor: SampleQuickAccessProvider, - prefix, - helpEntries: [{ description: `Sample Provider with prefix ${prefix}`, needsEditor: prefix === '@' || prefix === ':' }] - }; - - if (!prefix) { - quickAccessRegistry.defaultProvider = provider; - } else { - quickAccessRegistry.registerQuickAccessProvider(provider); - } -}); diff --git a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts index 90b796901d8..7b097e5f77a 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts @@ -8,15 +8,29 @@ import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/ import { Registry } from 'vs/platform/registry/common/platform'; import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuickAccess'; import { ViewQuickAccessProvider, VIEW_QUICK_ACCESS_PREFIX } from 'vs/workbench/contrib/quickaccess/browser/viewQuickAccess'; +import { QUICK_ACCESS_COMMAND_ID } from 'vs/workbench/contrib/quickaccess/browser/quickAccessCommands'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; -Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ +const helpQuickAccessProvider = { ctor: HelpQuickAccessProvider, prefix: '?', helpEntries: [{ description: localize('helpQuickAccess', "Show all Quick Access Providers"), needsEditor: false }] -}); +}; + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider(helpQuickAccessProvider); +Registry.as(Extensions.Quickaccess).defaultProvider = helpQuickAccessProvider; Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ ctor: ViewQuickAccessProvider, prefix: VIEW_QUICK_ACCESS_PREFIX, helpEntries: [{ description: localize('viewQuickAccess', "Open View"), needsEditor: false }] }); + +MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: QUICK_ACCESS_COMMAND_ID, title: { + value: localize('openQuickAccess', "Open Quick Access"), original: 'Open Quick Access' + }, + category: localize('quickAccess', "Quick Access") + } +}); diff --git a/src/vs/workbench/contrib/quickaccess/browser/quickAccessCommands.ts b/src/vs/workbench/contrib/quickaccess/browser/quickAccessCommands.ts new file mode 100644 index 00000000000..23b2521b043 --- /dev/null +++ b/src/vs/workbench/contrib/quickaccess/browser/quickAccessCommands.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; + +export const QUICK_ACCESS_COMMAND_ID = 'workbench.action.openQuickAccess'; + +CommandsRegistry.registerCommand({ + id: QUICK_ACCESS_COMMAND_ID, + handler: async function (accessor: ServicesAccessor, prefix: string | null = null) { + const quickInputService = accessor.get(IQuickInputService); + + quickInputService.quickAccess.show(typeof prefix === 'string' ? prefix : undefined); + }, + description: { + description: `Quick access`, + args: [{ + name: 'prefix', + schema: { + 'type': 'string' + } + }] + } +}); diff --git a/src/vs/workbench/test/browser/quickAccess.test.ts b/src/vs/workbench/test/browser/quickAccess.test.ts index 94ffc5ac658..bd9990491e4 100644 --- a/src/vs/workbench/test/browser/quickAccess.test.ts +++ b/src/vs/workbench/test/browser/quickAccess.test.ts @@ -83,6 +83,7 @@ suite('QuickAccess', () => { } } + const defaultProviderDescriptor = { ctor: TestProvider1, prefix: '', helpEntries: [] }; const providerDescriptor1 = { ctor: TestProvider1, prefix: 'test', helpEntries: [] }; const providerDescriptor2 = { ctor: TestProvider2, prefix: 'test something', helpEntries: [] }; const providerDescriptor3 = { ctor: TestProvider3, prefix: 'default', helpEntries: [] }; @@ -95,6 +96,8 @@ suite('QuickAccess', () => { test('registry', () => { const registry = (Registry.as(Extensions.Quickaccess)); + registry.defaultProvider = defaultProviderDescriptor; + const initialSize = registry.getQuickAccessProviders().length; const disposable = registry.registerQuickAccessProvider(providerDescriptor1); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index ef9c609850a..0caf68b4e03 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -102,12 +102,12 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IDiffEditor } from 'vs/editor/common/editorCommon'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; +import { IListService } from 'vs/platform/list/browser/listService'; export import TestTextResourcePropertiesService = CommonWorkbenchTestServices.TestTextResourcePropertiesService; export import TestContextService = CommonWorkbenchTestServices.TestContextService; export import TestStorageService = CommonWorkbenchTestServices.TestStorageService; export import TestWorkingCopyService = CommonWorkbenchTestServices.TestWorkingCopyService; -import { IListService } from 'vs/platform/list/browser/listService'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); From 617e61ce27481d6c24bb2a6b3ae681ace4906323 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 10:44:28 +0100 Subject: [PATCH 090/137] tests - add test remote path service --- .../test/browser/workbenchTestServices.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 0caf68b4e03..3cf8910a9cb 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -64,7 +64,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { isLinux } from 'vs/base/common/platform'; +import { isLinux, isWindows } from 'vs/base/common/platform'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { Part } from 'vs/workbench/browser/part'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -103,6 +103,7 @@ import { IDiffEditor } from 'vs/editor/common/editorCommon'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; import { IListService } from 'vs/platform/list/browser/listService'; +import { win32, posix } from 'vs/base/common/path'; export import TestTextResourcePropertiesService = CommonWorkbenchTestServices.TestTextResourcePropertiesService; export import TestContextService = CommonWorkbenchTestServices.TestContextService; @@ -133,6 +134,7 @@ export function workbenchInstantiationService(overrides?: { textFileService?: (i instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService)); instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService)); instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IRemotePathService, new TestRemotePathService(TestEnvironmentService)); const layoutService = new TestLayoutService(); instantiationService.stub(IWorkbenchLayoutService, layoutService); instantiationService.stub(IDialogService, new TestDialogService()); @@ -1084,3 +1086,18 @@ export class TestListService implements IListService { return Disposable.None; } } + +export class TestRemotePathService implements IRemotePathService { + + _serviceBrand: undefined; + + constructor(@IWorkbenchEnvironmentService private readonly environmentService: IEnvironmentService) { } + + get path() { return Promise.resolve(isWindows ? win32 : posix); } + + get userHome() { return Promise.resolve(URI.file(this.environmentService.userHome)); } + + async fileURI(path: string): Promise { + return URI.file(path); + } +} From e9d2dc18954c7024b2ff3410e7b21eafad850234 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 9 Mar 2020 10:45:40 +0100 Subject: [PATCH 091/137] Give default tasks value for configuration (#92084) Fixes #91911 --- .../services/configuration/common/configuration.ts | 2 ++ .../common/configurationEditingService.ts | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 888f442d2fe..630086370ba 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -40,3 +40,5 @@ export interface IConfigurationCache { remove(key: ConfigurationKey): Promise; } + +export const TASKS_DEFAULT = '{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": []\n}'; diff --git a/src/vs/workbench/services/configuration/common/configurationEditingService.ts b/src/vs/workbench/services/configuration/common/configurationEditingService.ts index 6b15032cd5c..573b4f0f546 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditingService.ts @@ -20,7 +20,7 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IConfigurationService, IConfigurationOverrides, keyFromOverrideIdentifier } from 'vs/platform/configuration/common/configuration'; -import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY, USER_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY, USER_STANDALONE_CONFIGURATIONS, TASKS_DEFAULT } from 'vs/workbench/services/configuration/common/configuration'; import { IFileService, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { OVERRIDE_PROPERTY_PATTERN, IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; @@ -434,10 +434,19 @@ export class ConfigurationEditingService { return setProperty(model.getValue(), jsonPath, value, { tabSize, insertSpaces, eol }); } + private defaultResourceValue(resource: URI): string { + const basename: string = resources.basename(resource); + const configurationValue: string = basename.substr(0, basename.length - resources.extname(resource).length); + switch (configurationValue) { + case TASKS_CONFIGURATION_KEY: return TASKS_DEFAULT; + default: return '{}'; + } + } + private async resolveModelReference(resource: URI): Promise> { const exists = await this.fileService.exists(resource); if (!exists) { - await this.textFileService.write(resource, '{}', { encoding: 'utf8' }); + await this.textFileService.write(resource, this.defaultResourceValue(resource), { encoding: 'utf8' }); } return this.textModelResolverService.createModelReference(resource); } From 1811122d95d8b9b9786b5ab8f352526694b95dcd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 10:52:54 +0100 Subject: [PATCH 092/137] tests - stop using import export --- .../test/electron-browser/extensionsActions.test.ts | 2 +- .../test/electron-browser/extensionsTipsService.test.ts | 3 ++- .../test/electron-browser/extensionsViews.test.ts | 3 ++- .../electron-browser/extensionsWorkbenchService.test.ts | 2 +- .../contrib/output/test/browser/outputLinkProvider.test.ts | 2 +- .../contrib/search/test/browser/queryBuilder.test.ts | 3 ++- .../contrib/search/test/browser/searchViewlet.test.ts | 2 +- .../search/test/electron-browser/queryBuilder.test.ts | 2 +- .../electron-browser/configurationResolverService.test.ts | 3 ++- .../services/editor/test/browser/editorService.test.ts | 3 ++- .../services/editor/test/browser/editorsObserver.test.ts | 3 ++- .../test/electron-browser/browserKeyboardMapper.test.ts | 2 +- .../test/electron-browser/keybindingEditing.test.ts | 3 ++- src/vs/workbench/services/label/test/browser/label.test.ts | 3 ++- .../test/browser/api/mainThreadDocumentsAndEditors.test.ts | 3 ++- .../workbench/test/browser/api/mainThreadEditors.test.ts | 3 ++- src/vs/workbench/test/browser/part.test.ts | 3 ++- .../workbench/test/browser/parts/editor/baseEditor.test.ts | 3 ++- .../test/browser/parts/editor/breadcrumbModel.test.ts | 2 +- .../test/browser/parts/editor/editorGroups.test.ts | 3 ++- .../test/browser/parts/editor/editorModel.test.ts | 2 +- src/vs/workbench/test/browser/workbenchTestServices.ts | 7 +------ .../electron-browser/quickopen.perf.integrationTest.ts | 3 ++- .../electron-browser/textsearch.perf.integrationTest.ts | 3 ++- .../test/electron-browser/workbenchTestServices.ts | 3 ++- 25 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index b7d2136893e..b455f29a5c0 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -27,7 +27,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; import { TestSharedProcessService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts index 5242e47633c..d8a87bcbf64 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -22,7 +22,8 @@ import { Emitter } from 'vs/base/common/event'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { TestContextService, TestLifecycleService, productService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestLifecycleService, productService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; import { TestSharedProcessService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index 7334f11625f..8347fcae927 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -27,7 +27,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { TestContextService, TestMenuService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestMenuService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestSharedProcessService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; @@ -46,6 +46,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IMenuService } from 'vs/platform/actions/common/actions'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('ExtensionsListView Tests', () => { diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 6d22875244d..f04352be125 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -27,7 +27,6 @@ import { IPager } from 'vs/base/common/paging'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestSharedProcessService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; @@ -41,6 +40,7 @@ import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('ExtensionsWorkbenchServiceTest', () => { diff --git a/src/vs/workbench/contrib/output/test/browser/outputLinkProvider.test.ts b/src/vs/workbench/contrib/output/test/browser/outputLinkProvider.test.ts index ce131747b3c..a53b8c389e7 100644 --- a/src/vs/workbench/contrib/output/test/browser/outputLinkProvider.test.ts +++ b/src/vs/workbench/contrib/output/test/browser/outputLinkProvider.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform'; import { OutputLinkComputer } from 'vs/workbench/contrib/output/common/outputLinkComputer'; -import { TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; function toOSPath(p: string): string { if (isMacintosh || isLinux) { diff --git a/src/vs/workbench/contrib/search/test/browser/queryBuilder.test.ts b/src/vs/workbench/contrib/search/test/browser/queryBuilder.test.ts index 621cf435ac4..09b44564799 100644 --- a/src/vs/workbench/contrib/search/test/browser/queryBuilder.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/queryBuilder.test.ts @@ -13,8 +13,9 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/ import { IFolderQuery, IPatternInfo, QueryType, ITextQuery, IFileQuery } from 'vs/workbench/services/search/common/search'; import { IWorkspaceContextService, toWorkspaceFolder, Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { ISearchPathsInfo, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder'; -import { TestContextService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; import { isWindows } from 'vs/base/common/platform'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; const DEFAULT_EDITOR_CONFIG = {}; const DEFAULT_USER_CONFIG = { useRipgrep: true, useIgnoreFiles: true, useGlobalIgnoreFiles: true }; diff --git a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts index a1c96e21aa2..c8f8bbbccac 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchViewlet.test.ts @@ -13,8 +13,8 @@ import { IFileMatch, ITextSearchMatch, OneLineRange, QueryType, SearchSortOrder import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { FileMatch, Match, searchMatchComparer, SearchResult } from 'vs/workbench/contrib/search/common/searchModel'; -import { TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; import { isWindows } from 'vs/base/common/platform'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('Search - Viewlet', () => { let instantiation: TestInstantiationService; diff --git a/src/vs/workbench/contrib/search/test/electron-browser/queryBuilder.test.ts b/src/vs/workbench/contrib/search/test/electron-browser/queryBuilder.test.ts index 5222422e2b4..6f1e394203f 100644 --- a/src/vs/workbench/contrib/search/test/electron-browser/queryBuilder.test.ts +++ b/src/vs/workbench/contrib/search/test/electron-browser/queryBuilder.test.ts @@ -8,9 +8,9 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IWorkspaceContextService, toWorkspaceFolder, Workspace } from 'vs/platform/workspace/common/workspace'; import { ISearchPathsInfo, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder'; -import { TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { assertEqualSearchPathResults, getUri, patternsToIExpression, globalGlob, fixPath } from 'vs/workbench/contrib/search/test/browser/queryBuilder.test'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; const DEFAULT_EDITOR_CONFIG = {}; const DEFAULT_USER_CONFIG = { useRipgrep: true, useIgnoreFiles: true, useGlobalIgnoreFiles: true }; diff --git a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts index d8844b3636b..91e52e14ed3 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts @@ -12,7 +12,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { BaseConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { TestEditorService, TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestWindowConfiguration } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -22,6 +22,7 @@ import * as Types from 'vs/base/common/types'; import { EditorType } from 'vs/editor/common/editorCommon'; import { Selection } from 'vs/editor/common/core/selection'; import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; const mockLineNumber = 10; class TestEditorServiceWithActiveEditor extends TestEditorService { diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index fec64ea2b21..90f3c5fee04 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorInput, EditorsOrder, SideBySideEditorInput } from 'vs/workbench/common/editor'; -import { workbenchInstantiationService, TestStorageService, TestServiceAccessor, registerTestEditor, TestFileEditorInput } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService, TestServiceAccessor, registerTestEditor, TestFileEditorInput } from 'vs/workbench/test/browser/workbenchTestServices'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { EditorService, DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService'; @@ -27,6 +27,7 @@ import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry'; import { UntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel'; import { NullFileSystemProvider } from 'vs/platform/files/test/common/nullFileSystemProvider'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; +import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; const TEST_EDITOR_ID = 'MyTestEditorForEditorService'; const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorService'; diff --git a/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts b/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts index c0e0d8a1921..c0d0d905221 100644 --- a/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { EditorOptions, IEditorInputFactoryRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; -import { workbenchInstantiationService, TestStorageService, TestFileEditorInput, registerTestEditor, TestEditorPart } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService, TestFileEditorInput, registerTestEditor, TestEditorPart } from 'vs/workbench/test/browser/workbenchTestServices'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; @@ -16,6 +16,7 @@ import { WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { EditorsObserver } from 'vs/workbench/browser/parts/editor/editorsObserver'; import { timeout } from 'vs/base/common/async'; +import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; const TEST_EDITOR_ID = 'MyTestEditorForEditorsObserver'; const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorsObserver'; diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/browserKeyboardMapper.test.ts index 93aec7997a5..0405c4f0556 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/browserKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/browserKeyboardMapper.test.ts @@ -12,8 +12,8 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/ import { INotificationService } from 'vs/platform/notification/common/notification'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { TestStorageService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; +import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) { diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index 822ef2faced..fc22f855180 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -38,7 +38,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor import { KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; -import { TestBackupFileService, TestContextService, TestEditorGroupsService, TestEditorService, TestLifecycleService, TestTextResourcePropertiesService, TestWorkingCopyService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestBackupFileService, TestEditorGroupsService, TestEditorService, TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; @@ -54,6 +54,7 @@ import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbe import { WorkingCopyFileService, IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; +import { TestTextResourcePropertiesService, TestContextService, TestWorkingCopyService } from 'vs/workbench/test/common/workbenchTestServices'; class TestEnvironmentService extends NativeWorkbenchEnvironmentService { diff --git a/src/vs/workbench/services/label/test/browser/label.test.ts b/src/vs/workbench/services/label/test/browser/label.test.ts index b9afd8221e9..897da308f9a 100644 --- a/src/vs/workbench/services/label/test/browser/label.test.ts +++ b/src/vs/workbench/services/label/test/browser/label.test.ts @@ -4,12 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { TestEnvironmentService, TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { URI } from 'vs/base/common/uri'; import { sep } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('URI Label', () => { diff --git a/src/vs/workbench/test/browser/api/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/test/browser/api/mainThreadDocumentsAndEditors.test.ts index 4101a887f69..09a1e6a56a9 100644 --- a/src/vs/workbench/test/browser/api/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/browser/api/mainThreadDocumentsAndEditors.test.ts @@ -13,7 +13,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol'; import { createTestCodeEditor, TestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { mock } from 'vs/workbench/test/browser/api/mock'; -import { TestEditorService, TestEditorGroupsService, TestTextResourcePropertiesService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; import { ITextModel } from 'vs/editor/common/model'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -25,6 +25,7 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; +import { TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; suite('MainThreadDocumentsAndEditors', () => { diff --git a/src/vs/workbench/test/browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/browser/api/mainThreadEditors.test.ts index 0d96189e4c9..2dc9e4ca630 100644 --- a/src/vs/workbench/test/browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/browser/api/mainThreadEditors.test.ts @@ -19,7 +19,7 @@ import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { IModelService } from 'vs/editor/common/services/modelService'; import { EditOperation } from 'vs/editor/common/core/editOperation'; -import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; import { BulkEditService } from 'vs/workbench/services/bulkEdit/browser/bulkEditService'; import { NullLogService, ILogService } from 'vs/platform/log/common/log'; import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; @@ -47,6 +47,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { TestTextResourcePropertiesService, TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('MainThreadEditors', () => { diff --git a/src/vs/workbench/test/browser/part.test.ts b/src/vs/workbench/test/browser/part.test.ts index 63946bb4257..a2bd94ea0ec 100644 --- a/src/vs/workbench/test/browser/part.test.ts +++ b/src/vs/workbench/test/browser/part.test.ts @@ -8,8 +8,9 @@ import { Part } from 'vs/workbench/browser/part'; import * as Types from 'vs/base/common/types'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { append, $, hide } from 'vs/base/browser/dom'; -import { TestStorageService, TestLayoutService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestLayoutService } from 'vs/workbench/test/browser/workbenchTestServices'; import { StorageScope } from 'vs/platform/storage/common/storage'; +import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; class SimplePart extends Part { diff --git a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts index d5d30e62aae..635c4c865fe 100644 --- a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts @@ -11,7 +11,7 @@ import * as Platform from 'vs/platform/registry/common/platform'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; -import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService, TestStorageService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { URI } from 'vs/base/common/uri'; @@ -19,6 +19,7 @@ import { IEditorRegistry, Extensions, EditorDescriptor } from 'vs/workbench/brow import { CancellationToken } from 'vs/base/common/cancellation'; import { IEditorModel } from 'vs/platform/editor/common/editor'; import { dispose } from 'vs/base/common/lifecycle'; +import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; const NullThemeService = new TestThemeService(); diff --git a/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts b/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts index d74c28ef6c4..067919112c6 100644 --- a/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/breadcrumbModel.test.ts @@ -7,9 +7,9 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel'; -import { TestContextService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { FileKind } from 'vs/platform/files/common/files'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; suite('Breadcrumb Model', function () { diff --git a/src/vs/workbench/test/browser/parts/editor/editorGroups.test.ts b/src/vs/workbench/test/browser/parts/editor/editorGroups.test.ts index 2eb866b7a4a..f8e3f5e90a5 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorGroups.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorGroups.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { EditorGroup, ISerializedEditorGroup, EditorCloseEvent } from 'vs/workbench/common/editor/editorGroup'; import { Extensions as EditorExtensions, IEditorInputFactoryRegistry, EditorInput, IFileEditorInput, IEditorInputFactory, CloseDirection, EditorsOrder } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; -import { TestLifecycleService, TestContextService, TestStorageService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -21,6 +21,7 @@ import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtil import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { TestContextService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; function inst(): IInstantiationService { let inst = new TestInstantiationService(); diff --git a/src/vs/workbench/test/browser/parts/editor/editorModel.test.ts b/src/vs/workbench/test/browser/parts/editor/editorModel.test.ts index d0c2abb5eea..e74010b7c6e 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorModel.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorModel.test.ts @@ -17,13 +17,13 @@ import { ITextBufferFactory } from 'vs/editor/common/model'; import { URI } from 'vs/base/common/uri'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService'; -import { TestTextResourcePropertiesService } from 'vs/workbench/test/browser/workbenchTestServices'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; class MyEditorModel extends EditorModel { } class MyTextEditorModel extends BaseTextEditorModel { diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 3cf8910a9cb..2e064554f57 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -81,7 +81,6 @@ import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbe import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { BrowserTextFileService } from 'vs/workbench/services/textfile/browser/browserTextFileService'; -import * as CommonWorkbenchTestServices from 'vs/workbench/test/common/workbenchTestServices'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService'; @@ -104,11 +103,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; import { IListService } from 'vs/platform/list/browser/listService'; import { win32, posix } from 'vs/base/common/path'; - -export import TestTextResourcePropertiesService = CommonWorkbenchTestServices.TestTextResourcePropertiesService; -export import TestContextService = CommonWorkbenchTestServices.TestContextService; -export import TestStorageService = CommonWorkbenchTestServices.TestStorageService; -export import TestWorkingCopyService = CommonWorkbenchTestServices.TestWorkingCopyService; +import { TestWorkingCopyService, TestContextService, TestStorageService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); diff --git a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts index 4af6351e22c..da6aef2e37e 100644 --- a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts @@ -28,7 +28,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { LocalSearchService } from 'vs/workbench/services/search/node/searchService'; import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import { TestContextService, TestEditorGroupsService, TestEditorService, TestTextResourcePropertiesService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; @@ -39,6 +39,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { TestContextService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; namespace Timer { export interface ITimerEvent { diff --git a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts index be6ef9e5492..91558016763 100644 --- a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts @@ -17,7 +17,7 @@ import * as minimist from 'vscode-minimist'; import * as path from 'vs/base/common/path'; import { LocalSearchService } from 'vs/workbench/services/search/node/searchService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { TestContextService, TestEditorService, TestEditorGroupsService, TestTextResourcePropertiesService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorService, TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { URI } from 'vs/base/common/uri'; @@ -42,6 +42,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { TestTextResourcePropertiesService, TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; // declare var __dirname: string; diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index 233a0930623..8ee0f138984 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestLifecycleService, TestFilesConfigurationService, TestContextService, TestFileService, TestFileDialogService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestLifecycleService, TestFilesConfigurationService, TestFileService, TestFileDialogService } from 'vs/workbench/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { NativeWorkbenchEnvironmentService, INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService'; @@ -38,6 +38,7 @@ import { NodeTestBackupFileService } from 'vs/workbench/services/backup/test/ele import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { INativeWindowConfiguration } from 'vs/platform/windows/node/window'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; export const TestWindowConfiguration: INativeWindowConfiguration = { windowId: 0, From a12ae5fcad1ae6d269d8beeed63bb1a581d39ad5 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 9 Mar 2020 10:43:55 +0100 Subject: [PATCH 093/137] use view focus context key --- src/vs/workbench/contrib/markers/browser/constants.ts | 1 - .../contrib/markers/browser/markers.contribution.ts | 4 ++-- src/vs/workbench/contrib/markers/browser/markersView.ts | 5 ----- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/markers/browser/constants.ts b/src/vs/workbench/contrib/markers/browser/constants.ts index ca720e8509c..bc94f9ee415 100644 --- a/src/vs/workbench/contrib/markers/browser/constants.ts +++ b/src/vs/workbench/contrib/markers/browser/constants.ts @@ -22,7 +22,6 @@ export default { TOGGLE_MARKERS_VIEW_ACTION_ID: 'workbench.actions.view.toggleProblems', MarkersViewSmallLayoutContextKey: new RawContextKey(`problemsView.smallLayout`, false), - MarkerViewFocusContextKey: new RawContextKey('problemsViewFocus', false), MarkerFocusContextKey: new RawContextKey('problemFocus', false), MarkerViewFilterFocusContextKey: new RawContextKey('problemsFilterFocus', false), RelatedInformationFocusContextKey: new RawContextKey('relatedInformationFocus', false) diff --git a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts index 30e05092dfe..444dc9267c9 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts @@ -28,7 +28,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar'; import { IMarkerService, MarkerStatistics } from 'vs/platform/markers/common/markers'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation, IViewsRegistry, IViewsService, getVisbileViewContextKey } from 'vs/workbench/common/views'; +import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation, IViewsRegistry, IViewsService, getVisbileViewContextKey, FocusedViewContext } from 'vs/workbench/common/views'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; @@ -211,7 +211,7 @@ registerAction2(class extends Action2 { id: Constants.MARKERS_VIEW_FOCUS_FILTER, title: localize('focusProblemsFilter', "Focus problems filter"), keybinding: { - when: Constants.MarkerViewFocusContextKey, + when: FocusedViewContext.isEqualTo(Constants.MARKERS_VIEW_ID), weight: KeybindingWeight.WorkbenchContrib, primary: KeyMod.CtrlCmd | KeyCode.KEY_F } diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index 23f2e38d80d..5f5278f78c2 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -78,7 +78,6 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { readonly filters: MarkersFilters; private readonly panelState: MementoObject; - private readonly panelFoucusContextKey: IContextKey; private _onDidChangeFilterStats = this._register(new Emitter<{ total: number, filtered: number }>()); readonly onDidChangeFilterStats: Event<{ total: number, filtered: number }> = this._onDidChangeFilterStats.event; @@ -114,7 +113,6 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { ) { super({ ...(options as IViewPaneOptions), id: Constants.MARKERS_VIEW_ID, ariaHeaderLabel: Messages.MARKERS_PANEL_TITLE_PROBLEMS }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.smallLayoutContextKey = Constants.MarkersViewSmallLayoutContextKey.bindTo(this.contextKeyService); - this.panelFoucusContextKey = Constants.MarkerViewFocusContextKey.bindTo(this.contextKeyService); this.panelState = new Memento(Constants.MARKERS_VIEW_STORAGE_ID, storageService).getMemento(StorageScope.WORKSPACE); this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState['multiline'])); this._register(this.markersViewModel.onDidChange(marker => this.onDidChangeViewState(marker))); @@ -152,9 +150,6 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { this.updateFilter(); - this._register(this.onDidFocus(() => this.panelFoucusContextKey.set(true))); - this._register(this.onDidBlur(() => this.panelFoucusContextKey.set(false))); - this._register(this.onDidChangeVisibility(visible => { if (visible) { this.refreshPanel(); From 23c1f6c2ce6a27da6e8af05606b281fe0977368b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 9 Mar 2020 10:58:15 +0100 Subject: [PATCH 094/137] fix test --- .../test/common/synchronizer.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/userDataSync/test/common/synchronizer.test.ts b/src/vs/platform/userDataSync/test/common/synchronizer.test.ts index 14c69ca7bc1..b2fa135d413 100644 --- a/src/vs/platform/userDataSync/test/common/synchronizer.test.ts +++ b/src/vs/platform/userDataSync/test/common/synchronizer.test.ts @@ -68,7 +68,7 @@ suite('TestSynchronizer', () => { teardown(() => disposableStore.clear()); test('status is syncing', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); const actual: SyncStatus[] = []; disposableStore.add(testObject.onDidChangeStatus(status => actual.push(status))); @@ -85,7 +85,7 @@ suite('TestSynchronizer', () => { }); test('status is set correctly when sync is finished', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); testObject.syncBarrier.open(); const actual: SyncStatus[] = []; @@ -97,7 +97,7 @@ suite('TestSynchronizer', () => { }); test('status is set correctly when sync has conflicts', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); testObject.syncResult = { status: SyncStatus.HasConflicts }; testObject.syncBarrier.open(); @@ -110,7 +110,7 @@ suite('TestSynchronizer', () => { }); test('status is set correctly when sync has errors', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); testObject.syncResult = { error: true }; testObject.syncBarrier.open(); @@ -127,7 +127,7 @@ suite('TestSynchronizer', () => { }); test('sync should not run if syncing already', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); const promise = Event.toPromise(testObject.onDoSyncCall.event); testObject.sync(); @@ -144,7 +144,7 @@ suite('TestSynchronizer', () => { }); test('sync should not run if disabled', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); client.instantiationService.get(IUserDataSyncEnablementService).setResourceEnablement(testObject.resourceKey, false); const actual: SyncStatus[] = []; @@ -157,7 +157,7 @@ suite('TestSynchronizer', () => { }); test('sync should not run if there are conflicts', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); testObject.syncResult = { status: SyncStatus.HasConflicts }; testObject.syncBarrier.open(); await testObject.sync(); @@ -171,7 +171,7 @@ suite('TestSynchronizer', () => { }); test('request latest data on precondition failure', async () => { - const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings); + const testObject: TestSynchroniser = client.instantiationService.createInstance(TestSynchroniser, SyncSource.Settings, 'settings'); // Sync once testObject.syncBarrier.open(); await testObject.sync(); From c45be8b90934306b193520ac902e890201687707 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 9 Mar 2020 11:24:52 +0100 Subject: [PATCH 095/137] fix #92237 --- src/vs/workbench/browser/parts/panel/panelActions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index 7cb981e9583..1501c87bcce 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -74,7 +74,6 @@ class FocusPanelAction extends Action { // Show panel if (!this.layoutService.isVisible(Parts.PANEL_PART)) { this.layoutService.setPanelHidden(false); - return; } // Focus into active panel From 8d46ea6c3a21bf459a4ecc2a0b66c423f3aaabfe Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 9 Mar 2020 11:34:55 +0100 Subject: [PATCH 096/137] Missing layout call (fixes #92250) --- src/vs/base/parts/quickinput/browser/quickInputList.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index 1e758f0d9b1..3df8daffc60 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -486,6 +486,7 @@ export class QuickInputList { filter(query: string) { if (!(this.sortByLabel || this.matchOnLabel || this.matchOnDescription || this.matchOnDetail)) { + this.list.layout(); return; } query = query.trim(); From 0b3510db7dbfcb749feece4d849ddcfcbc1bbe43 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 9 Mar 2020 11:42:54 +0100 Subject: [PATCH 097/137] views: aria header label compute from title fixes #91602 --- src/vs/base/browser/ui/splitview/paneview.ts | 7 ++++--- src/vs/workbench/browser/parts/views/treeView.ts | 2 +- src/vs/workbench/browser/parts/views/viewPaneContainer.ts | 1 - src/vs/workbench/contrib/comments/browser/commentsView.ts | 2 +- src/vs/workbench/contrib/debug/browser/breakpointsView.ts | 4 ++-- src/vs/workbench/contrib/debug/browser/callStackView.ts | 4 ++-- .../workbench/contrib/debug/browser/loadedScriptsView.ts | 4 ++-- src/vs/workbench/contrib/debug/browser/repl.ts | 2 +- src/vs/workbench/contrib/debug/browser/variablesView.ts | 4 ++-- .../contrib/debug/browser/watchExpressionsView.ts | 4 ++-- src/vs/workbench/contrib/debug/browser/welcomeView.ts | 4 ++-- .../contrib/extensions/browser/extensionsViews.ts | 2 +- src/vs/workbench/contrib/files/browser/views/emptyView.ts | 4 ++-- .../workbench/contrib/files/browser/views/explorerView.ts | 2 +- .../contrib/files/browser/views/openEditorsView.ts | 7 ++----- src/vs/workbench/contrib/markers/browser/markersView.ts | 2 +- src/vs/workbench/contrib/search/browser/searchView.ts | 4 ++-- 17 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/paneview.ts b/src/vs/base/browser/ui/splitview/paneview.ts index 037ffdce27b..8d310aefee9 100644 --- a/src/vs/base/browser/ui/splitview/paneview.ts +++ b/src/vs/base/browser/ui/splitview/paneview.ts @@ -15,12 +15,13 @@ import { Color, RGBA } from 'vs/base/common/color'; import { SplitView, IView } from './splitview'; import { isFirefox } from 'vs/base/browser/browser'; import { DataTransfers } from 'vs/base/browser/dnd'; +import { localize } from 'vs/nls'; export interface IPaneOptions { - ariaHeaderLabel?: string; minimumBodySize?: number; maximumBodySize?: number; expanded?: boolean; + title: string; } export interface IPaneStyles { @@ -116,10 +117,10 @@ export abstract class Pane extends Disposable implements IView { width: number = 0; - constructor(options: IPaneOptions = {}) { + constructor(options: IPaneOptions) { super(); this._expanded = typeof options.expanded === 'undefined' ? true : !!options.expanded; - this.ariaHeaderLabel = options.ariaHeaderLabel || ''; + this.ariaHeaderLabel = localize('viewSection', "{0} Section", options.title); this._minimumBodySize = typeof options.minimumBodySize === 'number' ? options.minimumBodySize : 120; this._maximumBodySize = typeof options.maximumBodySize === 'number' ? options.maximumBodySize : Number.POSITIVE_INFINITY; diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 7ccbdb8997e..1624e9274c9 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -60,7 +60,7 @@ export class TreeViewPane extends ViewPane { @IThemeService themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title, titleMenuId: MenuId.ViewTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super({ ...(options as IViewPaneOptions), titleMenuId: MenuId.ViewTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); const { treeView } = (Registry.as(Extensions.ViewsRegistry).getView(options.id)); this.treeView = treeView; this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this)); diff --git a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts index 06161af0a38..4ad5250ccf6 100644 --- a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts +++ b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts @@ -53,7 +53,6 @@ export interface IPaneColors extends IColorMapping { export interface IViewPaneOptions extends IPaneOptions { id: string; - title: string; showActionsAlways?: boolean; titleMenuId?: MenuId; } diff --git a/src/vs/workbench/contrib/comments/browser/commentsView.ts b/src/vs/workbench/contrib/comments/browser/commentsView.ts index 31d066a3e35..3a60d76d637 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsView.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsView.ts @@ -55,7 +55,7 @@ export class CommentsPanel extends ViewPane { @ICommentService private readonly commentService: ICommentService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), id: COMMENTS_VIEW_ID, ariaHeaderLabel: COMMENTS_VIEW_TITLE }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); } public renderBody(container: HTMLElement): void { diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 8d8aaabded6..cbecd41545e 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -28,7 +28,7 @@ import { attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { ILabelService } from 'vs/platform/label/common/label'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Gesture } from 'vs/base/browser/touch'; @@ -74,7 +74,7 @@ export class BreakpointsView extends ViewPane { @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.minimumBodySize = this.maximumBodySize = getExpandedBodySize(this.debugService.getModel()); this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange())); diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index d8af8fb5a29..77086ba5fc7 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -18,7 +18,7 @@ import { IAction, Action } from 'vs/base/common/actions'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { ILabelService } from 'vs/platform/label/common/label'; import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; @@ -104,7 +104,7 @@ export class CallStackView extends ViewPane { @IThemeService themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.callStackItemType = CONTEXT_CALLSTACK_ITEM_TYPE.bindTo(contextKeyService); this.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService); diff --git a/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts b/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts index 4bfd98599aa..5df627acdb2 100644 --- a/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { normalize, isAbsolute, posix } from 'vs/base/common/path'; -import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -430,7 +430,7 @@ export class LoadedScriptsView extends ViewPane { @IThemeService themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService); } diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 0f54aa901c9..56022d9f636 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -113,7 +113,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), id: REPL_VIEW_ID, ariaHeaderLabel: localize('debugConsole', "Debug Console") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.history = new HistoryNavigator(JSON.parse(this.storageService.get(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE, '[]')), 50); codeEditorService.registerDecorationType(DECORATION_KEY, {}); diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index 2c40b45a4e2..6011bdbd99a 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -17,7 +17,7 @@ import { IAction, Action } from 'vs/base/common/actions'; import { CopyValueAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { ITreeRenderer, ITreeNode, ITreeMouseEvent, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree'; @@ -61,7 +61,7 @@ export class VariablesView extends ViewPane { @IThemeService themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); // Use scheduler to prevent unnecessary flashing this.onFocusStackFrameScheduler = new RunOnceScheduler(async () => { diff --git a/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts b/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts index 1be23a91b3e..0dbd60fc37c 100644 --- a/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts +++ b/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts @@ -18,7 +18,7 @@ import { IAction, Action } from 'vs/base/common/actions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { renderExpressionValue, renderViewTree, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData } from 'vs/workbench/contrib/debug/browser/baseDebugView'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService'; @@ -58,7 +58,7 @@ export class WatchExpressionsView extends ViewPane { @IThemeService themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.onWatchExpressionsUpdatedScheduler = new RunOnceScheduler(() => { this.needsRefresh = false; diff --git a/src/vs/workbench/contrib/debug/browser/welcomeView.ts b/src/vs/workbench/contrib/debug/browser/welcomeView.ts index eb23cb4cd14..333c01000bd 100644 --- a/src/vs/workbench/contrib/debug/browser/welcomeView.ts +++ b/src/vs/workbench/contrib/debug/browser/welcomeView.ts @@ -13,7 +13,7 @@ import { localize } from 'vs/nls'; import { StartAction, ConfigureAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { IDebugService } from 'vs/workbench/contrib/debug/common/debug'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IViewDescriptorService, IViewsRegistry, Extensions } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -52,7 +52,7 @@ export class WelcomeView extends ViewPane { @IStorageService storageSevice: IStorageService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Welcome Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.debugStartLanguageContext = CONTEXT_DEBUG_START_LANGUAGE.bindTo(contextKeyService); this.debuggerInterestedContext = CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR.bindTo(contextKeyService); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 856cb6f48c5..9b53fb17a6f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -114,7 +114,7 @@ export class ExtensionsListView extends ViewPane { @IMenuService private readonly menuService: IMenuService, @IOpenerService openerService: IOpenerService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title, showActionsAlways: true }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super({ ...(options as IViewPaneOptions), showActionsAlways: true }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.server = options.server; } diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index f5de88ae4eb..042b938fef1 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -11,7 +11,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { ResourcesDropHandler, DragAndDropObserver } from 'vs/workbench/browser/dnd'; import { listDropBackground } from 'vs/platform/theme/common/colorRegistry'; import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; @@ -40,7 +40,7 @@ export class EmptyView extends ViewPane { @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('explorerSection', "Explorer Section: No Folder Opened") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this._register(this.contextService.onDidChangeWorkbenchState(() => this.refreshTitle())); this._register(this.labelService.onDidChangeFormatters(() => this.refreshTitle())); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 2a72ae6c655..733a9b62ed1 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -172,7 +172,7 @@ export class ExplorerView extends ViewPane { @IFileService private readonly fileService: IFileService, @IOpenerService openerService: IOpenerService, ) { - super({ ...(options as IViewPaneOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Explorer Section: {0}", labelService.getWorkspaceLabel(contextService.getWorkspace())) }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.resourceContext = instantiationService.createInstance(ResourceContextKey); this._register(this.resourceContext); diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index ff9ec14a6af..1c22f7201cd 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -34,7 +34,7 @@ import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions' import { DirtyEditorContext, OpenEditorsGroupContext, ReadonlyEditorContext } from 'vs/workbench/contrib/files/browser/fileCommands'; import { ResourceContextKey } from 'vs/workbench/common/resources'; import { ResourcesDropHandler, fillResourceDataTransfers, CodeDataTransfers, containsDragType } from 'vs/workbench/browser/dnd'; -import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IDragAndDropData, DataTransfers } from 'vs/base/browser/dnd'; import { memoize } from 'vs/base/common/decorators'; @@ -84,10 +84,7 @@ export class OpenEditorsView extends ViewPane { @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService, @IOpenerService openerService: IOpenerService, ) { - super({ - ...(options as IViewPaneOptions), - ariaHeaderLabel: nls.localize({ key: 'openEditosrSection', comment: ['Open is an adjective'] }, "Open Editors Section"), - }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.structuralRefreshDelay = 0; this.listRefreshScheduler = new RunOnceScheduler(() => { diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index 5f5278f78c2..6bff6ff3832 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -111,7 +111,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { @IOpenerService openerService: IOpenerService, @IThemeService themeService: IThemeService, ) { - super({ ...(options as IViewPaneOptions), id: Constants.MARKERS_VIEW_ID, ariaHeaderLabel: Messages.MARKERS_PANEL_TITLE_PROBLEMS }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.smallLayoutContextKey = Constants.MarkersViewSmallLayoutContextKey.bindTo(this.contextKeyService); this.panelState = new Memento(Constants.MARKERS_VIEW_STORAGE_ID, storageService).getMemento(StorageScope.WORKSPACE); this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState['multiline'])); diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index e00d561e775..c82dcac7c67 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -34,7 +34,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ResourceNavigator, WorkbenchObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IProgressService, IProgressStep, IProgress } from 'vs/platform/progress/common/progress'; -import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, VIEW_ID, SearchSortOrder, SearchCompletionExitCode } from 'vs/workbench/services/search/common/search'; +import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, SearchSortOrder, SearchCompletionExitCode } from 'vs/workbench/services/search/common/search'; import { ISearchHistoryService, ISearchHistoryValues } from 'vs/workbench/contrib/search/common/searchHistoryService'; import { diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, editorFindMatchHighlight, editorFindMatchHighlightBorder, listActiveSelectionForeground, foreground } from 'vs/platform/theme/common/colorRegistry'; import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -179,7 +179,7 @@ export class SearchView extends ViewPane { @ITelemetryService telemetryService: ITelemetryService, ) { - super({ ...options, id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); this.container = dom.$('.search-view'); From 97984f6a52a64e164fd2e03cb8c7bf6283a4eff0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 9 Mar 2020 12:12:05 +0100 Subject: [PATCH 098/137] Fix #92189 --- .../contrib/markers/browser/constants.ts | 1 + .../markers/browser/markers.contribution.ts | 19 +++++++++++++++++++ .../contrib/markers/browser/markersView.ts | 7 +++++++ .../markers/browser/markersViewActions.ts | 10 +++++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/markers/browser/constants.ts b/src/vs/workbench/contrib/markers/browser/constants.ts index bc94f9ee415..6714a443377 100644 --- a/src/vs/workbench/contrib/markers/browser/constants.ts +++ b/src/vs/workbench/contrib/markers/browser/constants.ts @@ -14,6 +14,7 @@ export default { RELATED_INFORMATION_COPY_MESSAGE_ACTION_ID: 'problems.action.copyRelatedInformationMessage', FOCUS_PROBLEMS_FROM_FILTER: 'problems.action.focusProblemsFromFilter', MARKERS_VIEW_FOCUS_FILTER: 'problems.action.focusFilter', + MARKERS_VIEW_CLEAR_FILTER_TEXT: 'problems.action.clearFilterText', MARKERS_VIEW_SHOW_MULTILINE_MESSAGE: 'problems.action.showMultilineMessage', MARKERS_VIEW_SHOW_SINGLELINE_MESSAGE: 'problems.action.showSinglelineMessage', MARKER_OPEN_SIDE_ACTION_ID: 'problems.action.openToSide', diff --git a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts index 444dc9267c9..2620461b323 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts @@ -259,6 +259,25 @@ registerAction2(class extends Action2 { } } }); +registerAction2(class extends Action2 { + constructor() { + super({ + id: Constants.MARKERS_VIEW_CLEAR_FILTER_TEXT, + title: localize('clearFiltersText', "Clear filters text"), + category: localize('problems', "Problems"), + keybinding: { + when: Constants.MarkerViewFilterFocusContextKey, + weight: KeybindingWeight.WorkbenchContrib, + } + }); + } + run(accessor: ServicesAccessor) { + const markersView = accessor.get(IViewsService).getActiveViewWithId(Constants.MARKERS_VIEW_ID); + if (markersView) { + markersView.clearFilterText(); + } + } +}); async function copyMarker(viewsService: IViewsService, clipboardService: IClipboardService) { const markersView = viewsService.getActiveViewWithId(Constants.MARKERS_VIEW_ID); diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index 6bff6ff3832..d19f41ae6f6 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -94,6 +94,9 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private readonly _onDidFocusFilter: Emitter = this._register(new Emitter()); readonly onDidFocusFilter: Event = this._onDidFocusFilter.event; + private readonly _onDidClearFilterText: Emitter = this._register(new Emitter()); + readonly onDidClearFilterText: Event = this._onDidClearFilterText.event; + constructor( options: IViewPaneOptions, @IInstantiationService instantiationService: IInstantiationService, @@ -200,6 +203,10 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { this._onDidFocusFilter.fire(); } + public clearFilterText(): void { + this._onDidClearFilterText.fire(); + } + private regiserActions(): void { const that = this; this._register(registerAction2(class extends Action2 { diff --git a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts index abe04813ce6..0f424cd9e16 100644 --- a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts +++ b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts @@ -163,6 +163,7 @@ export class MarkersFilters extends Disposable { export interface IMarkerFilterController { readonly onDidFocusFilter: Event; + readonly onDidClearFilterText: Event; readonly filters: MarkersFilters; readonly onDidChangeFilterStats: Event<{ total: number, filtered: number }>; getFilterStats(): { total: number, filtered: number }; @@ -273,6 +274,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { this.delayedFilterUpdate = new Delayer(200); this._register(toDisposable(() => this.delayedFilterUpdate.cancel())); this._register(filterController.onDidFocusFilter(() => this.focus())); + this._register(filterController.onDidClearFilterText(() => this.clearFilterText())); this.filtersAction = new Action('markersFiltersAction', Messages.MARKERS_PANEL_ACTION_TOOLTIP_MORE_FILTERS, 'markers-filters codicon-filter'); this.filtersAction.checked = this.hasFiltersChanged(); this._register(filterController.filters.onDidChange(e => this.onDidFiltersChange(e))); @@ -297,6 +299,12 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { } } + private clearFilterText(): void { + if (this.filterInputBox) { + this.filterInputBox.value = ''; + } + } + private onDidFiltersChange(e: IMarkersFiltersChangeEvent): void { this.filtersAction.checked = this.hasFiltersChanged(); if (e.layout) { @@ -404,7 +412,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { private onInputKeyDown(event: StandardKeyboardEvent, filterInputBox: HistoryInputBox) { let handled = false; if (event.equals(KeyCode.Escape)) { - filterInputBox.value = ''; + this.clearFilterText(); handled = true; } if (handled) { From 9bfe24741027fb34a753555ba603618058aebd42 Mon Sep 17 00:00:00 2001 From: Gustavo Sampaio Date: Mon, 9 Mar 2020 09:22:57 -0300 Subject: [PATCH 099/137] PR review --- .../contrib/codelens/codelensController.ts | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 56f1c1c1b46..0a1538a6455 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -422,7 +422,6 @@ export class ShowLensesInCurrentLineCommand extends EditorCommand { const commandArguments: Map = new Map(); - const picker = quickInputService.createQuickPick(); const items: (IQuickPickItem | IQuickPickSeparator)[] = []; activeLensesWidgets.forEach(widget => { @@ -437,23 +436,15 @@ export class ShowLensesInCurrentLineCommand extends EditorCommand { }); }); - picker.items = items; - picker.canSelectMany = false; - picker.onDidAccept(_ => { - const selectedItems = picker.selectedItems; - if (selectedItems.length === 1) { - const id = selectedItems[0].id!; + // We dont want an empty picker + if (!items.length) { + return; + } - if (!id) { - picker.hide(); - return; - } - - commandService.executeCommand(id, ...(commandArguments.get(id) || [])).catch(err => notificationService.error(err)); - } - picker.hide(); + quickInputService.pick(items, { canPickMany: false }).then(item => { + const id = item.id!; + commandService.executeCommand(id, ...(commandArguments.get(id) || [])).catch(err => notificationService.error(err)); }); - picker.show(); } } From 413f1fe096f651bc0b53d94aa12bc250a8d9f004 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 13:37:14 +0100 Subject: [PATCH 100/137] quick access - placeholder & contextkey support --- src/vs/platform/quickinput/browser/quickAccess.ts | 10 ++++++---- src/vs/platform/quickinput/common/quickAccess.ts | 7 +++++++ .../browser/quickaccess/gotoLineQuickAccess.ts | 1 + .../browser/quickAccess.contribution.ts | 14 +++++++++----- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/quickinput/browser/quickAccess.ts b/src/vs/platform/quickinput/browser/quickAccess.ts index 66f3ba390e8..377db89fbd3 100644 --- a/src/vs/platform/quickinput/browser/quickAccess.ts +++ b/src/vs/platform/quickinput/browser/quickAccess.ts @@ -32,14 +32,16 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon this.lastActivePicker?.hide(); // Find provider for the value to show - const [provider, prefix] = this.getOrInstantiateProvider(value); + const [provider, descriptor] = this.getOrInstantiateProvider(value); // Create a picker for the provider to use with the initial value // and adjust the filtering to exclude the prefix from filtering const picker = disposables.add(this.quickInputService.createQuickPick()); + picker.placeholder = descriptor.placeholder; picker.value = value; picker.valueSelection = [value.length, value.length]; - picker.filterValue = (value: string) => value.substring(prefix.length); + picker.contextKey = descriptor.contextKey; + picker.filterValue = (value: string) => value.substring(descriptor.prefix.length); // Remember as last active picker and clean up once picker get's disposed this.lastActivePicker = picker; @@ -79,7 +81,7 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon picker.show(); } - private getOrInstantiateProvider(value: string): [IQuickAccessProvider, string /* prefix */] { + private getOrInstantiateProvider(value: string): [IQuickAccessProvider, IQuickAccessProviderDescriptor] { const providerDescriptor = this.registry.getQuickAccessProvider(value) || this.registry.defaultProvider; let provider = this.mapProviderToDescriptor.get(providerDescriptor); @@ -88,6 +90,6 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon this.mapProviderToDescriptor.set(providerDescriptor, provider); } - return [provider, providerDescriptor.prefix]; + return [provider, providerDescriptor]; } } diff --git a/src/vs/platform/quickinput/common/quickAccess.ts b/src/vs/platform/quickinput/common/quickAccess.ts index de79e148ff3..be8fba3f311 100644 --- a/src/vs/platform/quickinput/common/quickAccess.ts +++ b/src/vs/platform/quickinput/common/quickAccess.ts @@ -67,6 +67,13 @@ export interface IQuickAccessProviderDescriptor { */ readonly prefix: string; + /** + * A placeholder to use for the input field when the provider is active. + * This will also be read out by screen readers and thus helps for + * accessibility. + */ + readonly placeholder?: string; + /** * Documentation for the provider in the quick access help. */ diff --git a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts index 73075d46e98..6404881f956 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoLineQuickAccess.ts @@ -41,5 +41,6 @@ export class GotoLineQuickAccessProvider extends AbstractGotoLineQuickAccessProv Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ ctor: GotoLineQuickAccessProvider, prefix: GOTO_LINE_PREFIX, + placeholder: localize('gotoLineQuickAccessPlaceholder', "Type the line number and optional column to go to (e.g. 42:5 for line 42 and column 5)."), helpEntries: [{ description: localize('gotoLineQuickAccess', "Go to Line"), needsEditor: true }] }); diff --git a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts index 7b097e5f77a..5d30386f4ea 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts @@ -4,25 +4,29 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; +import { IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuickAccess'; import { ViewQuickAccessProvider, VIEW_QUICK_ACCESS_PREFIX } from 'vs/workbench/contrib/quickaccess/browser/viewQuickAccess'; import { QUICK_ACCESS_COMMAND_ID } from 'vs/workbench/contrib/quickaccess/browser/quickAccessCommands'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; -const helpQuickAccessProvider = { +const helpQuickAccessProvider: IQuickAccessProviderDescriptor = { ctor: HelpQuickAccessProvider, prefix: '?', + placeholder: localize('helpQuickAccessPlaceholder', "Type '?' to get help on the actions you can take from here."), helpEntries: [{ description: localize('helpQuickAccess', "Show all Quick Access Providers"), needsEditor: false }] }; -Registry.as(Extensions.Quickaccess).registerQuickAccessProvider(helpQuickAccessProvider); -Registry.as(Extensions.Quickaccess).defaultProvider = helpQuickAccessProvider; +const registry = Registry.as(Extensions.Quickaccess); -Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ +registry.defaultProvider = helpQuickAccessProvider; +registry.registerQuickAccessProvider(helpQuickAccessProvider); + +registry.registerQuickAccessProvider({ ctor: ViewQuickAccessProvider, prefix: VIEW_QUICK_ACCESS_PREFIX, + placeholder: localize('viewQuickAccessPlaceholder', "Type the name of a view, output channel or terminal to open."), helpEntries: [{ description: localize('viewQuickAccess', "Open View"), needsEditor: false }] }); From eeda7a1fb10fea1a7314039c6272fdc2899f282a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 9 Mar 2020 13:53:43 +0100 Subject: [PATCH 101/137] add icon registry --- extensions/vscode-colorize-tests/package.json | 3 +- .../producticons/test-product-icon-theme.json | 13 +- src/vs/platform/theme/common/iconRegistry.ts | 543 ++++++++++++++++++ .../themes/browser/productIconThemeData.ts | 31 - .../themes/common/productIconThemeSchema.ts | 18 +- 5 files changed, 559 insertions(+), 49 deletions(-) create mode 100644 src/vs/platform/theme/common/iconRegistry.ts diff --git a/extensions/vscode-colorize-tests/package.json b/extensions/vscode-colorize-tests/package.json index e2c15b2f67b..0f3815b2b65 100644 --- a/extensions/vscode-colorize-tests/package.json +++ b/extensions/vscode-colorize-tests/package.json @@ -60,7 +60,8 @@ { "id": "Test Product Icons", "label": "The Test Product Icon Theme", - "path": "./producticons/test-product-icon-theme.json" + "path": "./producticons/test-product-icon-theme.json", + "_watch": true } ] } diff --git a/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json b/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json index 6c908a223e2..dc076aef5f9 100644 --- a/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json +++ b/extensions/vscode-colorize-tests/producticons/test-product-icon-theme.json @@ -27,10 +27,17 @@ "fontCharacter": "\\e063" }, "settings-gear": { - "fontCharacter": "\\e035" + "fontCharacter": "\\e030" }, - "settings-files": { - "fontCharacter": "\\e006;" + "files": { + "fontCharacter": "\\e056" + }, + "extensions": { + "fontCharacter": "\\e015" + }, + "debug-alt-2": { + "fontCharacter": "\\e072" } + } } diff --git a/src/vs/platform/theme/common/iconRegistry.ts b/src/vs/platform/theme/common/iconRegistry.ts new file mode 100644 index 00000000000..42b1d589352 --- /dev/null +++ b/src/vs/platform/theme/common/iconRegistry.ts @@ -0,0 +1,543 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as platform from 'vs/platform/registry/common/platform'; +import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; +import { ThemeIcon } from 'vs/platform/theme/common/themeService'; +import { Event, Emitter } from 'vs/base/common/event'; +import { localize } from 'vs/nls'; + +// ------ API types + + +// color registry +export const Extensions = { + IconContribution: 'base.contributions.icons' +}; + +export interface IconDefaults { + font?: string; + character: string; +} + +export interface IconContribution { + id: string; + description: string; + deprecationMessage?: string; + defaults: IconDefaults; +} + +export interface IIconRegistry { + + readonly onDidChangeSchema: Event; + + /** + * Register a icon to the registry. + * @param id The icon id + * @param defaults The default values + * @description the description + */ + registerIcon(id: string, defaults: IconDefaults, description: string): ThemeIcon; + + /** + * Register a icon to the registry. + */ + deregisterIcon(id: string): void; + + /** + * Get all icon contributions + */ + getIcons(): IconContribution[]; + + /** + * JSON schema for an object to assign icon values to one of the color contributions. + */ + getIconSchema(): IJSONSchema; + + /** + * JSON schema to for a reference to a icon contribution. + */ + getIconReferenceSchema(): IJSONSchema; + +} + +class IconRegistry implements IIconRegistry { + + private readonly _onDidChangeSchema = new Emitter(); + readonly onDidChangeSchema: Event = this._onDidChangeSchema.event; + + private iconsById: { [key: string]: IconContribution }; + private iconSchema: IJSONSchema & { properties: IJSONSchemaMap } = { type: 'object', properties: {} }; + private iconReferenceSchema: IJSONSchema & { enum: string[], enumDescriptions: string[] } = { type: 'string', enum: [], enumDescriptions: [] }; + + constructor() { + this.iconsById = {}; + } + + public registerIcon(id: string, defaults: IconDefaults, description: string, deprecationMessage?: string): ThemeIcon { + let iconContribution: IconContribution = { id, description, defaults, deprecationMessage }; + this.iconsById[id] = iconContribution; + let propertySchema: IJSONSchema = { type: 'object', description, properties: { font: { type: 'string' }, fontCharacter: { type: 'string' } }, defaultSnippets: [{ body: { fontCharacter: '\\\\e030' } }] }; + if (deprecationMessage) { + propertySchema.deprecationMessage = deprecationMessage; + } + this.iconSchema.properties[id] = propertySchema; + this.iconReferenceSchema.enum.push(id); + this.iconReferenceSchema.enumDescriptions.push(description); + + this._onDidChangeSchema.fire(); + return { id }; + } + + + public deregisterIcon(id: string): void { + delete this.iconsById[id]; + delete this.iconSchema.properties[id]; + const index = this.iconReferenceSchema.enum.indexOf(id); + if (index !== -1) { + this.iconReferenceSchema.enum.splice(index, 1); + this.iconReferenceSchema.enumDescriptions.splice(index, 1); + } + this._onDidChangeSchema.fire(); + } + + public getIcons(): IconContribution[] { + return Object.keys(this.iconsById).map(id => this.iconsById[id]); + } + + public getIconSchema(): IJSONSchema { + return this.iconSchema; + } + + public getIconReferenceSchema(): IJSONSchema { + return this.iconReferenceSchema; + } + + public toString() { + let sorter = (a: string, b: string) => { + let cat1 = a.indexOf('.') === -1 ? 0 : 1; + let cat2 = b.indexOf('.') === -1 ? 0 : 1; + if (cat1 !== cat2) { + return cat1 - cat2; + } + return a.localeCompare(b); + }; + + return Object.keys(this.iconsById).sort(sorter).map(k => `- \`${k}\`: ${this.iconsById[k].description}`).join('\n'); + } + +} + +const iconRegistry = new IconRegistry(); +platform.Registry.add(Extensions.IconContribution, iconRegistry); + +export function registerIcon(id: string, defaults: IconDefaults, description: string, deprecationMessage?: string): ThemeIcon { + return iconRegistry.registerIcon(id, defaults, description, deprecationMessage); +} + +export function getIconRegistry(): IIconRegistry { + return iconRegistry; +} + +registerIcon('add', { character: '\ea60' }, localize('add', '')); +registerIcon('plus', { character: '\ea60' }, localize('plus', '')); +registerIcon('gist-new', { character: '\ea60' }, localize('gist-new', '')); +registerIcon('repo-create', { character: '\ea60' }, localize('repo-create', '')); +registerIcon('lightbulb', { character: '\ea61' }, localize('lightbulb', '')); +registerIcon('light-bulb', { character: '\ea61' }, localize('light-bulb', '')); +registerIcon('repo', { character: '\ea62' }, localize('repo', '')); +registerIcon('repo-delete', { character: '\ea62' }, localize('repo-delete', '')); +registerIcon('gist-fork', { character: '\ea63' }, localize('gist-fork', '')); +registerIcon('repo-forked', { character: '\ea63' }, localize('repo-forked', '')); +registerIcon('git-pull-request', { character: '\ea64' }, localize('git-pull-request', '')); +registerIcon('git-pull-request-abandoned', { character: '\ea64' }, localize('git-pull-request-abandoned', '')); +registerIcon('record-keys', { character: '\ea65' }, localize('record-keys', '')); +registerIcon('keyboard', { character: '\ea65' }, localize('keyboard', '')); +registerIcon('tag', { character: '\ea66' }, localize('tag', '')); +registerIcon('tag-add', { character: '\ea66' }, localize('tag-add', '')); +registerIcon('tag-remove', { character: '\ea66' }, localize('tag-remove', '')); +registerIcon('person', { character: '\ea67' }, localize('person', '')); +registerIcon('person-add', { character: '\ea67' }, localize('person-add', '')); +registerIcon('person-follow', { character: '\ea67' }, localize('person-follow', '')); +registerIcon('person-outline', { character: '\ea67' }, localize('person-outline', '')); +registerIcon('person-filled', { character: '\ea67' }, localize('person-filled', '')); +registerIcon('git-branch', { character: '\ea68' }, localize('git-branch', '')); +registerIcon('git-branch-create', { character: '\ea68' }, localize('git-branch-create', '')); +registerIcon('git-branch-delete', { character: '\ea68' }, localize('git-branch-delete', '')); +registerIcon('source-control', { character: '\ea68' }, localize('source-control', '')); +registerIcon('mirror', { character: '\ea69' }, localize('mirror', '')); +registerIcon('mirror-public', { character: '\ea69' }, localize('mirror-public', '')); +registerIcon('star', { character: '\ea6a' }, localize('star', '')); +registerIcon('star-add', { character: '\ea6a' }, localize('star-add', '')); +registerIcon('star-delete', { character: '\ea6a' }, localize('star-delete', '')); +registerIcon('star-empty', { character: '\ea6a' }, localize('star-empty', '')); +registerIcon('comment', { character: '\ea6b' }, localize('comment', '')); +registerIcon('comment-add', { character: '\ea6b' }, localize('comment-add', '')); +registerIcon('alert', { character: '\ea6c' }, localize('alert', '')); +registerIcon('warning', { character: '\ea6c' }, localize('warning', '')); +registerIcon('search', { character: '\ea6d' }, localize('search', '')); +registerIcon('search-save', { character: '\ea6d' }, localize('search-save', '')); +registerIcon('log-out', { character: '\ea6e' }, localize('log-out', '')); +registerIcon('sign-out', { character: '\ea6e' }, localize('sign-out', '')); +registerIcon('log-in', { character: '\ea6f' }, localize('log-in', '')); +registerIcon('sign-in', { character: '\ea6f' }, localize('sign-in', '')); +registerIcon('eye', { character: '\ea70' }, localize('eye', '')); +registerIcon('eye-unwatch', { character: '\ea70' }, localize('eye-unwatch', '')); +registerIcon('eye-watch', { character: '\ea70' }, localize('eye-watch', '')); +registerIcon('circle-filled', { character: '\ea71' }, localize('circle-filled', '')); +registerIcon('primitive-dot', { character: '\ea71' }, localize('primitive-dot', '')); +registerIcon('close-dirty', { character: '\ea71' }, localize('close-dirty', '')); +registerIcon('debug-breakpoint', { character: '\ea71' }, localize('debug-breakpoint', '')); +registerIcon('debug-breakpoint-disabled', { character: '\ea71' }, localize('debug-breakpoint-disabled', '')); +registerIcon('debug-hint', { character: '\ea71' }, localize('debug-hint', '')); +registerIcon('primitive-square', { character: '\ea72' }, localize('primitive-square', '')); +registerIcon('edit', { character: '\ea73' }, localize('edit', '')); +registerIcon('pencil', { character: '\ea73' }, localize('pencil', '')); +registerIcon('info', { character: '\ea74' }, localize('info', '')); +registerIcon('issue-opened', { character: '\ea74' }, localize('issue-opened', '')); +registerIcon('gist-private', { character: '\ea75' }, localize('gist-private', '')); +registerIcon('git-fork-private', { character: '\ea75' }, localize('git-fork-private', '')); +registerIcon('lock', { character: '\ea75' }, localize('lock', '')); +registerIcon('mirror-private', { character: '\ea75' }, localize('mirror-private', '')); +registerIcon('close', { character: '\ea76' }, localize('close', '')); +registerIcon('remove-close', { character: '\ea76' }, localize('remove-close', '')); +registerIcon('x', { character: '\ea76' }, localize('x', '')); +registerIcon('repo-sync', { character: '\ea77' }, localize('repo-sync', '')); +registerIcon('sync', { character: '\ea77' }, localize('sync', '')); +registerIcon('clone', { character: '\ea78' }, localize('clone', '')); +registerIcon('desktop-download', { character: '\ea78' }, localize('desktop-download', '')); +registerIcon('beaker', { character: '\ea79' }, localize('beaker', '')); +registerIcon('microscope', { character: '\ea79' }, localize('microscope', '')); +registerIcon('vm', { character: '\ea7a' }, localize('vm', '')); +registerIcon('device-desktop', { character: '\ea7a' }, localize('device-desktop', '')); +registerIcon('file', { character: '\ea7b' }, localize('file', '')); +registerIcon('file-text', { character: '\ea7b' }, localize('file-text', '')); +registerIcon('more', { character: '\ea7c' }, localize('more', '')); +registerIcon('ellipsis', { character: '\ea7c' }, localize('ellipsis', '')); +registerIcon('kebab-horizontal', { character: '\ea7c' }, localize('kebab-horizontal', '')); +registerIcon('mail-reply', { character: '\ea7d' }, localize('mail-reply', '')); +registerIcon('reply', { character: '\ea7d' }, localize('reply', '')); +registerIcon('organization', { character: '\ea7e' }, localize('organization', '')); +registerIcon('organization-filled', { character: '\ea7e' }, localize('organization-filled', '')); +registerIcon('organization-outline', { character: '\ea7e' }, localize('organization-outline', '')); +registerIcon('new-file', { character: '\ea7f' }, localize('new-file', '')); +registerIcon('file-add', { character: '\ea7f' }, localize('file-add', '')); +registerIcon('new-folder', { character: '\ea80' }, localize('new-folder', '')); +registerIcon('file-directory-create', { character: '\ea80' }, localize('file-directory-create', '')); +registerIcon('trash', { character: '\ea81' }, localize('trash', '')); +registerIcon('trashcan', { character: '\ea81' }, localize('trashcan', '')); +registerIcon('history', { character: '\ea82' }, localize('history', '')); +registerIcon('clock', { character: '\ea82' }, localize('clock', '')); +registerIcon('folder', { character: '\ea83' }, localize('folder', '')); +registerIcon('file-directory', { character: '\ea83' }, localize('file-directory', '')); +registerIcon('symbol-folder', { character: '\ea83' }, localize('symbol-folder', '')); +registerIcon('logo-github', { character: '\ea84' }, localize('logo-github', '')); +registerIcon('mark-github', { character: '\ea84' }, localize('mark-github', '')); +registerIcon('github', { character: '\ea84' }, localize('github', '')); +registerIcon('terminal', { character: '\ea85' }, localize('terminal', '')); +registerIcon('console', { character: '\ea85' }, localize('console', '')); +registerIcon('repl', { character: '\ea85' }, localize('repl', '')); +registerIcon('zap', { character: '\ea86' }, localize('zap', '')); +registerIcon('symbol-event', { character: '\ea86' }, localize('symbol-event', '')); +registerIcon('error', { character: '\ea87' }, localize('error', '')); +registerIcon('stop', { character: '\ea87' }, localize('stop', '')); +registerIcon('variable', { character: '\ea88' }, localize('variable', '')); +registerIcon('symbol-variable', { character: '\ea88' }, localize('symbol-variable', '')); +registerIcon('array', { character: '\ea8a' }, localize('array', '')); +registerIcon('symbol-array', { character: '\ea8a' }, localize('symbol-array', '')); +registerIcon('symbol-module', { character: '\ea8b' }, localize('symbol-module', '')); +registerIcon('symbol-package', { character: '\ea8b' }, localize('symbol-package', '')); +registerIcon('symbol-namespace', { character: '\ea8b' }, localize('symbol-namespace', '')); +registerIcon('symbol-object', { character: '\ea8b' }, localize('symbol-object', '')); +registerIcon('symbol-method', { character: '\ea8c' }, localize('symbol-method', '')); +registerIcon('symbol-function', { character: '\ea8c' }, localize('symbol-function', '')); +registerIcon('symbol-constructor', { character: '\ea8c' }, localize('symbol-constructor', '')); +registerIcon('symbol-boolean', { character: '\ea8f' }, localize('symbol-boolean', '')); +registerIcon('symbol-null', { character: '\ea8f' }, localize('symbol-null', '')); +registerIcon('symbol-numeric', { character: '\ea90' }, localize('symbol-numeric', '')); +registerIcon('symbol-number', { character: '\ea90' }, localize('symbol-number', '')); +registerIcon('symbol-structure', { character: '\ea91' }, localize('symbol-structure', '')); +registerIcon('symbol-struct', { character: '\ea91' }, localize('symbol-struct', '')); +registerIcon('symbol-parameter', { character: '\ea92' }, localize('symbol-parameter', '')); +registerIcon('symbol-type-parameter', { character: '\ea92' }, localize('symbol-type-parameter', '')); +registerIcon('symbol-key', { character: '\ea93' }, localize('symbol-key', '')); +registerIcon('symbol-text', { character: '\ea93' }, localize('symbol-text', '')); +registerIcon('symbol-reference', { character: '\ea94' }, localize('symbol-reference', '')); +registerIcon('go-to-file', { character: '\ea94' }, localize('go-to-file', '')); +registerIcon('symbol-enum', { character: '\ea95' }, localize('symbol-enum', '')); +registerIcon('symbol-value', { character: '\ea95' }, localize('symbol-value', '')); +registerIcon('symbol-ruler', { character: '\ea96' }, localize('symbol-ruler', '')); +registerIcon('symbol-unit', { character: '\ea96' }, localize('symbol-unit', '')); +registerIcon('activate-breakpoints', { character: '\ea97' }, localize('activate-breakpoints', '')); +registerIcon('archive', { character: '\ea98' }, localize('archive', '')); +registerIcon('arrow-both', { character: '\ea99' }, localize('arrow-both', '')); +registerIcon('arrow-down', { character: '\ea9a' }, localize('arrow-down', '')); +registerIcon('arrow-left', { character: '\ea9b' }, localize('arrow-left', '')); +registerIcon('arrow-right', { character: '\ea9c' }, localize('arrow-right', '')); +registerIcon('arrow-small-down', { character: '\ea9d' }, localize('arrow-small-down', '')); +registerIcon('arrow-small-left', { character: '\ea9e' }, localize('arrow-small-left', '')); +registerIcon('arrow-small-right', { character: '\ea9f' }, localize('arrow-small-right', '')); +registerIcon('arrow-small-up', { character: '\eaa0' }, localize('arrow-small-up', '')); +registerIcon('arrow-up', { character: '\eaa1' }, localize('arrow-up', '')); +registerIcon('bell', { character: '\eaa2' }, localize('bell', '')); +registerIcon('bold', { character: '\eaa3' }, localize('bold', '')); +registerIcon('book', { character: '\eaa4' }, localize('book', '')); +registerIcon('bookmark', { character: '\eaa5' }, localize('bookmark', '')); +registerIcon('debug-breakpoint-conditional-unverified', { character: '\eaa6' }, localize('debug-breakpoint-conditional-unverified', '')); +registerIcon('debug-breakpoint-conditional', { character: '\eaa7' }, localize('debug-breakpoint-conditional', '')); +registerIcon('debug-breakpoint-conditional-disabled', { character: '\eaa7' }, localize('debug-breakpoint-conditional-disabled', '')); +registerIcon('debug-breakpoint-data-unverified', { character: '\eaa8' }, localize('debug-breakpoint-data-unverified', '')); +registerIcon('debug-breakpoint-data', { character: '\eaa9' }, localize('debug-breakpoint-data', '')); +registerIcon('debug-breakpoint-data-disabled', { character: '\eaa9' }, localize('debug-breakpoint-data-disabled', '')); +registerIcon('debug-breakpoint-log-unverified', { character: '\eaaa' }, localize('debug-breakpoint-log-unverified', '')); +registerIcon('debug-breakpoint-log', { character: '\eaab' }, localize('debug-breakpoint-log', '')); +registerIcon('debug-breakpoint-log-disabled', { character: '\eaab' }, localize('debug-breakpoint-log-disabled', '')); +registerIcon('briefcase', { character: '\eaac' }, localize('briefcase', '')); +registerIcon('broadcast', { character: '\eaad' }, localize('broadcast', '')); +registerIcon('browser', { character: '\eaae' }, localize('browser', '')); +registerIcon('bug', { character: '\eaaf' }, localize('bug', '')); +registerIcon('calendar', { character: '\eab0' }, localize('calendar', '')); +registerIcon('case-sensitive', { character: '\eab1' }, localize('case-sensitive', '')); +registerIcon('check', { character: '\eab2' }, localize('check', '')); +registerIcon('checklist', { character: '\eab3' }, localize('checklist', '')); +registerIcon('chevron-down', { character: '\eab4' }, localize('chevron-down', '')); +registerIcon('chevron-left', { character: '\eab5' }, localize('chevron-left', '')); +registerIcon('chevron-right', { character: '\eab6' }, localize('chevron-right', '')); +registerIcon('chevron-up', { character: '\eab7' }, localize('chevron-up', '')); +registerIcon('chrome-close', { character: '\eab8' }, localize('chrome-close', '')); +registerIcon('chrome-maximize', { character: '\eab9' }, localize('chrome-maximize', '')); +registerIcon('chrome-minimize', { character: '\eaba' }, localize('chrome-minimize', '')); +registerIcon('chrome-restore', { character: '\eabb' }, localize('chrome-restore', '')); +registerIcon('circle-outline', { character: '\eabc' }, localize('circle-outline', '')); +registerIcon('debug-breakpoint-unverified', { character: '\eabc' }, localize('debug-breakpoint-unverified', '')); +registerIcon('circle-slash', { character: '\eabd' }, localize('circle-slash', '')); +registerIcon('circuit-board', { character: '\eabe' }, localize('circuit-board', '')); +registerIcon('clear-all', { character: '\eabf' }, localize('clear-all', '')); +registerIcon('clippy', { character: '\eac0' }, localize('clippy', '')); +registerIcon('close-all', { character: '\eac1' }, localize('close-all', '')); +registerIcon('cloud-download', { character: '\eac2' }, localize('cloud-download', '')); +registerIcon('cloud-upload', { character: '\eac3' }, localize('cloud-upload', '')); +registerIcon('code', { character: '\eac4' }, localize('code', '')); +registerIcon('collapse-all', { character: '\eac5' }, localize('collapse-all', '')); +registerIcon('color-mode', { character: '\eac6' }, localize('color-mode', '')); +registerIcon('comment-discussion', { character: '\eac7' }, localize('comment-discussion', '')); +registerIcon('compare-changes', { character: '\eac8' }, localize('compare-changes', '')); +registerIcon('credit-card', { character: '\eac9' }, localize('credit-card', '')); +registerIcon('dash', { character: '\eacc' }, localize('dash', '')); +registerIcon('dashboard', { character: '\eacd' }, localize('dashboard', '')); +registerIcon('database', { character: '\eace' }, localize('database', '')); +registerIcon('debug-continue', { character: '\eacf' }, localize('debug-continue', '')); +registerIcon('debug-disconnect', { character: '\ead0' }, localize('debug-disconnect', '')); +registerIcon('debug-pause', { character: '\ead1' }, localize('debug-pause', '')); +registerIcon('debug-restart', { character: '\ead2' }, localize('debug-restart', '')); +registerIcon('debug-start', { character: '\ead3' }, localize('debug-start', '')); +registerIcon('debug-step-into', { character: '\ead4' }, localize('debug-step-into', '')); +registerIcon('debug-step-out', { character: '\ead5' }, localize('debug-step-out', '')); +registerIcon('debug-step-over', { character: '\ead6' }, localize('debug-step-over', '')); +registerIcon('debug-stop', { character: '\ead7' }, localize('debug-stop', '')); +registerIcon('debug', { character: '\ead8' }, localize('debug', '')); +registerIcon('device-camera-video', { character: '\ead9' }, localize('device-camera-video', '')); +registerIcon('device-camera', { character: '\eada' }, localize('device-camera', '')); +registerIcon('device-mobile', { character: '\eadb' }, localize('device-mobile', '')); +registerIcon('diff-added', { character: '\eadc' }, localize('diff-added', '')); +registerIcon('diff-ignored', { character: '\eadd' }, localize('diff-ignored', '')); +registerIcon('diff-modified', { character: '\eade' }, localize('diff-modified', '')); +registerIcon('diff-removed', { character: '\eadf' }, localize('diff-removed', '')); +registerIcon('diff-renamed', { character: '\eae0' }, localize('diff-renamed', '')); +registerIcon('diff', { character: '\eae1' }, localize('diff', '')); +registerIcon('discard', { character: '\eae2' }, localize('discard', '')); +registerIcon('editor-layout', { character: '\eae3' }, localize('editor-layout', '')); +registerIcon('empty-window', { character: '\eae4' }, localize('empty-window', '')); +registerIcon('exclude', { character: '\eae5' }, localize('exclude', '')); +registerIcon('extensions', { character: '\eae6' }, localize('extensions', '')); +registerIcon('eye-closed', { character: '\eae7' }, localize('eye-closed', '')); +registerIcon('file-binary', { character: '\eae8' }, localize('file-binary', '')); +registerIcon('file-code', { character: '\eae9' }, localize('file-code', '')); +registerIcon('file-media', { character: '\eaea' }, localize('file-media', '')); +registerIcon('file-pdf', { character: '\eaeb' }, localize('file-pdf', '')); +registerIcon('file-submodule', { character: '\eaec' }, localize('file-submodule', '')); +registerIcon('file-symlink-directory', { character: '\eaed' }, localize('file-symlink-directory', '')); +registerIcon('file-symlink-file', { character: '\eaee' }, localize('file-symlink-file', '')); +registerIcon('file-zip', { character: '\eaef' }, localize('file-zip', '')); +registerIcon('files', { character: '\eaf0' }, localize('files', '')); +registerIcon('filter', { character: '\eaf1' }, localize('filter', '')); +registerIcon('flame', { character: '\eaf2' }, localize('flame', '')); +registerIcon('fold-down', { character: '\eaf3' }, localize('fold-down', '')); +registerIcon('fold-up', { character: '\eaf4' }, localize('fold-up', '')); +registerIcon('fold', { character: '\eaf5' }, localize('fold', '')); +registerIcon('folder-active', { character: '\eaf6' }, localize('folder-active', '')); +registerIcon('folder-opened', { character: '\eaf7' }, localize('folder-opened', '')); +registerIcon('gear', { character: '\eaf8' }, localize('gear', '')); +registerIcon('gift', { character: '\eaf9' }, localize('gift', '')); +registerIcon('gist-secret', { character: '\eafa' }, localize('gist-secret', '')); +registerIcon('gist', { character: '\eafb' }, localize('gist', '')); +registerIcon('git-commit', { character: '\eafc' }, localize('git-commit', '')); +registerIcon('git-compare', { character: '\eafd' }, localize('git-compare', '')); +registerIcon('git-merge', { character: '\eafe' }, localize('git-merge', '')); +registerIcon('github-action', { character: '\eaff' }, localize('github-action', '')); +registerIcon('github-alt', { character: '\eb00' }, localize('github-alt', '')); +registerIcon('globe', { character: '\eb01' }, localize('globe', '')); +registerIcon('grabber', { character: '\eb02' }, localize('grabber', '')); +registerIcon('graph', { character: '\eb03' }, localize('graph', '')); +registerIcon('gripper', { character: '\eb04' }, localize('gripper', '')); +registerIcon('heart', { character: '\eb05' }, localize('heart', '')); +registerIcon('home', { character: '\eb06' }, localize('home', '')); +registerIcon('horizontal-rule', { character: '\eb07' }, localize('horizontal-rule', '')); +registerIcon('hubot', { character: '\eb08' }, localize('hubot', '')); +registerIcon('inbox', { character: '\eb09' }, localize('inbox', '')); +registerIcon('issue-closed', { character: '\eb0a' }, localize('issue-closed', '')); +registerIcon('issue-reopened', { character: '\eb0b' }, localize('issue-reopened', '')); +registerIcon('issues', { character: '\eb0c' }, localize('issues', '')); +registerIcon('italic', { character: '\eb0d' }, localize('italic', '')); +registerIcon('jersey', { character: '\eb0e' }, localize('jersey', '')); +registerIcon('json', { character: '\eb0f' }, localize('json', '')); +registerIcon('kebab-vertical', { character: '\eb10' }, localize('kebab-vertical', '')); +registerIcon('key', { character: '\eb11' }, localize('key', '')); +registerIcon('law', { character: '\eb12' }, localize('law', '')); +registerIcon('lightbulb-autofix', { character: '\eb13' }, localize('lightbulb-autofix', '')); +registerIcon('link-external', { character: '\eb14' }, localize('link-external', '')); +registerIcon('link', { character: '\eb15' }, localize('link', '')); +registerIcon('list-ordered', { character: '\eb16' }, localize('list-ordered', '')); +registerIcon('list-unordered', { character: '\eb17' }, localize('list-unordered', '')); +registerIcon('live-share', { character: '\eb18' }, localize('live-share', '')); +registerIcon('loading', { character: '\eb19' }, localize('loading', '')); +registerIcon('location', { character: '\eb1a' }, localize('location', '')); +registerIcon('mail-read', { character: '\eb1b' }, localize('mail-read', '')); +registerIcon('mail', { character: '\eb1c' }, localize('mail', '')); +registerIcon('markdown', { character: '\eb1d' }, localize('markdown', '')); +registerIcon('megaphone', { character: '\eb1e' }, localize('megaphone', '')); +registerIcon('mention', { character: '\eb1f' }, localize('mention', '')); +registerIcon('milestone', { character: '\eb20' }, localize('milestone', '')); +registerIcon('mortar-board', { character: '\eb21' }, localize('mortar-board', '')); +registerIcon('move', { character: '\eb22' }, localize('move', '')); +registerIcon('multiple-windows', { character: '\eb23' }, localize('multiple-windows', '')); +registerIcon('mute', { character: '\eb24' }, localize('mute', '')); +registerIcon('no-newline', { character: '\eb25' }, localize('no-newline', '')); +registerIcon('note', { character: '\eb26' }, localize('note', '')); +registerIcon('octoface', { character: '\eb27' }, localize('octoface', '')); +registerIcon('open-preview', { character: '\eb28' }, localize('open-preview', '')); +registerIcon('package', { character: '\eb29' }, localize('package', '')); +registerIcon('paintcan', { character: '\eb2a' }, localize('paintcan', '')); +registerIcon('pin', { character: '\eb2b' }, localize('pin', '')); +registerIcon('play', { character: '\eb2c' }, localize('play', '')); +registerIcon('run', { character: '\eb2c' }, localize('run', '')); +registerIcon('plug', { character: '\eb2d' }, localize('plug', '')); +registerIcon('preserve-case', { character: '\eb2e' }, localize('preserve-case', '')); +registerIcon('preview', { character: '\eb2f' }, localize('preview', '')); +registerIcon('project', { character: '\eb30' }, localize('project', '')); +registerIcon('pulse', { character: '\eb31' }, localize('pulse', '')); +registerIcon('question', { character: '\eb32' }, localize('question', '')); +registerIcon('quote', { character: '\eb33' }, localize('quote', '')); +registerIcon('radio-tower', { character: '\eb34' }, localize('radio-tower', '')); +registerIcon('reactions', { character: '\eb35' }, localize('reactions', '')); +registerIcon('references', { character: '\eb36' }, localize('references', '')); +registerIcon('refresh', { character: '\eb37' }, localize('refresh', '')); +registerIcon('regex', { character: '\eb38' }, localize('regex', '')); +registerIcon('remote-explorer', { character: '\eb39' }, localize('remote-explorer', '')); +registerIcon('remote', { character: '\eb3a' }, localize('remote', '')); +registerIcon('remove', { character: '\eb3b' }, localize('remove', '')); +registerIcon('replace-all', { character: '\eb3c' }, localize('replace-all', '')); +registerIcon('replace', { character: '\eb3d' }, localize('replace', '')); +registerIcon('repo-clone', { character: '\eb3e' }, localize('repo-clone', '')); +registerIcon('repo-force-push', { character: '\eb3f' }, localize('repo-force-push', '')); +registerIcon('repo-pull', { character: '\eb40' }, localize('repo-pull', '')); +registerIcon('repo-push', { character: '\eb41' }, localize('repo-push', '')); +registerIcon('report', { character: '\eb42' }, localize('report', '')); +registerIcon('request-changes', { character: '\eb43' }, localize('request-changes', '')); +registerIcon('rocket', { character: '\eb44' }, localize('rocket', '')); +registerIcon('root-folder-opened', { character: '\eb45' }, localize('root-folder-opened', '')); +registerIcon('root-folder', { character: '\eb46' }, localize('root-folder', '')); +registerIcon('rss', { character: '\eb47' }, localize('rss', '')); +registerIcon('ruby', { character: '\eb48' }, localize('ruby', '')); +registerIcon('save-all', { character: '\eb49' }, localize('save-all', '')); +registerIcon('save-as', { character: '\eb4a' }, localize('save-as', '')); +registerIcon('save', { character: '\eb4b' }, localize('save', '')); +registerIcon('screen-full', { character: '\eb4c' }, localize('screen-full', '')); +registerIcon('screen-normal', { character: '\eb4d' }, localize('screen-normal', '')); +registerIcon('search-stop', { character: '\eb4e' }, localize('search-stop', '')); +registerIcon('server', { character: '\eb50' }, localize('server', '')); +registerIcon('settings-gear', { character: '\eb51' }, localize('settings-gear', '')); +registerIcon('settings', { character: '\eb52' }, localize('settings', '')); +registerIcon('shield', { character: '\eb53' }, localize('shield', '')); +registerIcon('smiley', { character: '\eb54' }, localize('smiley', '')); +registerIcon('sort-precedence', { character: '\eb55' }, localize('sort-precedence', '')); +registerIcon('split-horizontal', { character: '\eb56' }, localize('split-horizontal', '')); +registerIcon('split-vertical', { character: '\eb57' }, localize('split-vertical', '')); +registerIcon('squirrel', { character: '\eb58' }, localize('squirrel', '')); +registerIcon('star-full', { character: '\eb59' }, localize('star-full', '')); +registerIcon('star-half', { character: '\eb5a' }, localize('star-half', '')); +registerIcon('symbol-class', { character: '\eb5b' }, localize('symbol-class', '')); +registerIcon('symbol-color', { character: '\eb5c' }, localize('symbol-color', '')); +registerIcon('symbol-constant', { character: '\eb5d' }, localize('symbol-constant', '')); +registerIcon('symbol-enum-member', { character: '\eb5e' }, localize('symbol-enum-member', '')); +registerIcon('symbol-field', { character: '\eb5f' }, localize('symbol-field', '')); +registerIcon('symbol-file', { character: '\eb60' }, localize('symbol-file', '')); +registerIcon('symbol-interface', { character: '\eb61' }, localize('symbol-interface', '')); +registerIcon('symbol-keyword', { character: '\eb62' }, localize('symbol-keyword', '')); +registerIcon('symbol-misc', { character: '\eb63' }, localize('symbol-misc', '')); +registerIcon('symbol-operator', { character: '\eb64' }, localize('symbol-operator', '')); +registerIcon('symbol-property', { character: '\eb65' }, localize('symbol-property', '')); +registerIcon('wrench', { character: '\eb65' }, localize('wrench', '')); +registerIcon('wrench-subaction', { character: '\eb65' }, localize('wrench-subaction', '')); +registerIcon('symbol-snippet', { character: '\eb66' }, localize('symbol-snippet', '')); +registerIcon('tasklist', { character: '\eb67' }, localize('tasklist', '')); +registerIcon('telescope', { character: '\eb68' }, localize('telescope', '')); +registerIcon('text-size', { character: '\eb69' }, localize('text-size', '')); +registerIcon('three-bars', { character: '\eb6a' }, localize('three-bars', '')); +registerIcon('thumbsdown', { character: '\eb6b' }, localize('thumbsdown', '')); +registerIcon('thumbsup', { character: '\eb6c' }, localize('thumbsup', '')); +registerIcon('tools', { character: '\eb6d' }, localize('tools', '')); +registerIcon('triangle-down', { character: '\eb6e' }, localize('triangle-down', '')); +registerIcon('triangle-left', { character: '\eb6f' }, localize('triangle-left', '')); +registerIcon('triangle-right', { character: '\eb70' }, localize('triangle-right', '')); +registerIcon('triangle-up', { character: '\eb71' }, localize('triangle-up', '')); +registerIcon('twitter', { character: '\eb72' }, localize('twitter', '')); +registerIcon('unfold', { character: '\eb73' }, localize('unfold', '')); +registerIcon('unlock', { character: '\eb74' }, localize('unlock', '')); +registerIcon('unmute', { character: '\eb75' }, localize('unmute', '')); +registerIcon('unverified', { character: '\eb76' }, localize('unverified', '')); +registerIcon('verified', { character: '\eb77' }, localize('verified', '')); +registerIcon('versions', { character: '\eb78' }, localize('versions', '')); +registerIcon('vm-active', { character: '\eb79' }, localize('vm-active', '')); +registerIcon('vm-outline', { character: '\eb7a' }, localize('vm-outline', '')); +registerIcon('vm-running', { character: '\eb7b' }, localize('vm-running', '')); +registerIcon('watch', { character: '\eb7c' }, localize('watch', '')); +registerIcon('whitespace', { character: '\eb7d' }, localize('whitespace', '')); +registerIcon('whole-word', { character: '\eb7e' }, localize('whole-word', '')); +registerIcon('window', { character: '\eb7f' }, localize('window', '')); +registerIcon('word-wrap', { character: '\eb80' }, localize('word-wrap', '')); +registerIcon('zoom-in', { character: '\eb81' }, localize('zoom-in', '')); +registerIcon('zoom-out', { character: '\eb82' }, localize('zoom-out', '')); +registerIcon('list-filter', { character: '\eb83' }, localize('list-filter', '')); +registerIcon('list-flat', { character: '\eb84' }, localize('list-flat', '')); +registerIcon('list-selection', { character: '\eb85' }, localize('list-selection', '')); +registerIcon('selection', { character: '\eb85' }, localize('selection', '')); +registerIcon('list-tree', { character: '\eb86' }, localize('list-tree', '')); +registerIcon('debug-breakpoint-function-unverified', { character: '\eb87' }, localize('debug-breakpoint-function-unverified', '')); +registerIcon('debug-breakpoint-function', { character: '\eb88' }, localize('debug-breakpoint-function', '')); +registerIcon('debug-breakpoint-function-disabled', { character: '\eb88' }, localize('debug-breakpoint-function-disabled', '')); +registerIcon('debug-stackframe-active', { character: '\eb89' }, localize('debug-stackframe-active', '')); +registerIcon('debug-stackframe-dot', { character: '\eb8a' }, localize('debug-stackframe-dot', '')); +registerIcon('debug-stackframe', { character: '\eb8b' }, localize('debug-stackframe', '')); +registerIcon('debug-stackframe-focused', { character: '\eb8b' }, localize('debug-stackframe-focused', '')); +registerIcon('debug-breakpoint-unsupported', { character: '\eb8c' }, localize('debug-breakpoint-unsupported', '')); +registerIcon('symbol-string', { character: '\eb8d' }, localize('symbol-string', '')); +registerIcon('debug-reverse-continue', { character: '\eb8e' }, localize('debug-reverse-continue', '')); +registerIcon('debug-step-back', { character: '\eb8f' }, localize('debug-step-back', '')); +registerIcon('debug-restart-frame', { character: '\eb90' }, localize('debug-restart-frame', '')); +registerIcon('debug-alternate', { character: '\eb91' }, localize('debug-alternate', '')); +registerIcon('call-incoming', { character: '\eb92' }, localize('call-incoming', '')); +registerIcon('call-outgoing', { character: '\eb93' }, localize('call-outgoing', '')); +registerIcon('menu', { character: '\eb94' }, localize('menu', '')); +registerIcon('expand-all', { character: '\eb95' }, localize('expand-all', '')); +registerIcon('feedback', { character: '\eb96' }, localize('feedback', '')); +registerIcon('group-by-ref-type', { character: '\eb97' }, localize('group-by-ref-type', '')); +registerIcon('ungroup-by-ref-type', { character: '\eb98' }, localize('ungroup-by-ref-type', '')); +registerIcon('bell-dot', { character: '\f101' }, localize('bell-dot', '')); +registerIcon('debug-alt-2', { character: '\f102' }, localize('debug-alt-2', '')); +registerIcon('debug-alt', { character: '\f103' }, localize('debug-alt', '')); + + +// setTimeout(_ => console.log(colorRegistry.toString()), 5000); diff --git a/src/vs/workbench/services/themes/browser/productIconThemeData.ts b/src/vs/workbench/services/themes/browser/productIconThemeData.ts index 8b200a513cf..a189eb6823f 100644 --- a/src/vs/workbench/services/themes/browser/productIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/productIconThemeData.ts @@ -203,34 +203,3 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i result.content = cssRules.join('\n'); return result; } - -/* -@font-face { - font-family: "codicon"; - src: url("./codicon.ttf?b5dd8f5aa953889dc1f4c9fa9b44d3dd") format("truetype"); -} - -.codicon[class*='codicon-'] { - font: normal normal normal 16px/1 codicon; - display: inline-block; - text-decoration: none; - text-rendering: auto; - text-align: center; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - user-select: none; - -webkit-user-select: none; - -ms-user-select: none; -} - - -.codicon-add:before { content: "\ea60" } -.codicon-plus:before { content: "\ea60" } -.codicon-gist-new:before { content: "\ea60" } -.codicon-repo-create:before { content: "\ea60" } -.codicon-lightbulb:before { content: "\ea61" } -.codicon-light-bulb:before { content: "\ea61" } -.codicon-repo:before { content: "\ea62" } -.codicon-repo-delete:before { content: "\ea62" } -.codicon-gist-fork:before { content: "\ea63" } -*/ diff --git a/src/vs/workbench/services/themes/common/productIconThemeSchema.ts b/src/vs/workbench/services/themes/common/productIconThemeSchema.ts index 29fe708a8e9..69d1b32d8f5 100644 --- a/src/vs/workbench/services/themes/common/productIconThemeSchema.ts +++ b/src/vs/workbench/services/themes/common/productIconThemeSchema.ts @@ -7,6 +7,8 @@ import * as nls from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as JSONExtensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; + const schemaId = 'vscode://schemas/product-icon-theme'; const schema: IJSONSchema = { @@ -67,20 +69,8 @@ const schema: IJSONSchema = { iconDefinitions: { type: 'object', description: nls.localize('schema.iconDefinitions', 'Assocation of icon name to a font character.'), - additionalProperties: { - type: 'object', - description: nls.localize('schema.iconDefinition', 'An icon definition. The object key is the icon name.'), - properties: { - fontCharacter: { - type: 'string', - description: nls.localize('schema.fontCharacter', 'The character in the font to use.') - }, - fontId: { - type: 'string', - description: nls.localize('schema.fontId', 'When using a font: The id of the font. If not set, defaults to the first font definition.') - } - } - } + properties: getIconRegistry().getIconSchema().properties, + additionalProperties: false } } }; From 39cddc9315ac6e0eb1b9b36bd7157e00c377f845 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 9 Mar 2020 13:57:37 +0100 Subject: [PATCH 102/137] range decorations should check for code editor explicitly --- src/vs/workbench/browser/parts/editor/rangeDecorations.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/rangeDecorations.ts b/src/vs/workbench/browser/parts/editor/rangeDecorations.ts index 8c45a102a63..98304f2366b 100644 --- a/src/vs/workbench/browser/parts/editor/rangeDecorations.ts +++ b/src/vs/workbench/browser/parts/editor/rangeDecorations.ts @@ -10,7 +10,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IRange } from 'vs/editor/common/core/range'; import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { TrackedRangeStickiness, IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; export interface IRangeHighlightDecoration { @@ -41,9 +41,9 @@ export class RangeHighlightDecorations extends Disposable { this.rangeHighlightDecorationId = null; } - highlightRange(range: IRangeHighlightDecoration, editor?: ICodeEditor) { + highlightRange(range: IRangeHighlightDecoration, editor?: any) { editor = editor ? editor : this.getEditor(range); - if (editor) { + if (isCodeEditor(editor)) { this.doHighlightRange(editor, range); } } From ffbb280a36607e3fea73577e616d006a92f6fb5b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 9 Mar 2020 14:51:44 +0100 Subject: [PATCH 103/137] Fixes #68024 --- src/bootstrap-fork.js | 3 +++ src/bootstrap.js | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index e0c6cf34c56..7239ae52837 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -8,6 +8,9 @@ const bootstrap = require('./bootstrap'); +// Remove global paths from the node module lookup +bootstrap.removeGlobalNodeModuleLookupPaths(); + // Enable ASAR in our forked processes bootstrap.enableASARSupport(); diff --git a/src/bootstrap.js b/src/bootstrap.js index b035adc9f41..cc63fc39422 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -53,6 +53,29 @@ exports.injectNodeModuleLookupPath = function (injectPath) { }; //#endregion +//#region Remove global paths from the node lookup paths + +exports.removeGlobalNodeModuleLookupPaths = function() { + // @ts-ignore + const Module = require('module'); + // @ts-ignore + const globalPaths = Module.globalPaths; + + // @ts-ignore + const originalResolveLookupPaths = Module._resolveLookupPaths; + + // @ts-ignore + Module._resolveLookupPaths = function (moduleName, parent) { + const paths = originalResolveLookupPaths(moduleName, parent); + let commonSuffixLength = 0; + while (commonSuffixLength < paths.length && paths[paths.length - 1 - commonSuffixLength] === globalPaths[globalPaths.length - 1 - commonSuffixLength]) { + commonSuffixLength++; + } + return paths.slice(0, paths.length - commonSuffixLength); + }; +}; +//#endregion + //#region Add support for using node_modules.asar /** * @param {string=} nodeModulesPath From 6077d6446ffbafe0157d30666524c36d7b466c8d Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 9 Mar 2020 15:22:51 +0100 Subject: [PATCH 104/137] workbench theme service polish --- .../themes/browser/workbenchThemeService.ts | 47 +++++++------------ .../services/themes/common/colorThemeData.ts | 7 +++ 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index c9a8b794e6c..a13360a9451 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -125,22 +125,17 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (!themeData || themeData.baseTheme !== containerBaseTheme) { themeData = ColorThemeData.createUnloadedTheme(containerBaseTheme); } - themeData.setCustomColors(this.settings.colorCustomizations); - themeData.setCustomTokenColors(this.settings.tokenColorCustomizations); - themeData.setCustomTokenStyleRules(this.settings.tokenStylesCustomizations); - this.updateDynamicCSSRules(themeData); + themeData.setCustomizations(this.settings); this.applyTheme(themeData, undefined, true); const fileIconData = FileIconThemeData.fromStorageData(this.storageService); if (fileIconData) { - _applyRules(fileIconData.styleSheetContent!, fileIconThemeRulesClassName); - this.doSetFileIconTheme(fileIconData); + this.applyAndSetFileIconTheme(fileIconData); } const productIconData = ProductIconThemeData.fromStorageData(this.storageService); if (productIconData) { - _applyRules(productIconData.styleSheetContent!, productIconThemeRulesClassName); - this.doSetProductIconTheme(productIconData); + this.applyAndSetProductIconTheme(productIconData); } this.initialize().then(undefined, errors.onUnexpectedError).then(_ => { @@ -386,15 +381,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.currentColorTheme.clearCaches(); // the loaded theme is identical to the perisisted theme. Don't need to send an event. this.currentColorTheme = themeData; - themeData.setCustomColors(this.settings.colorCustomizations); - themeData.setCustomTokenColors(this.settings.tokenColorCustomizations); - themeData.setCustomTokenStyleRules(this.settings.tokenStylesCustomizations); + themeData.setCustomizations(this.settings); return Promise.resolve(themeData); } - themeData.setCustomColors(this.settings.colorCustomizations); - themeData.setCustomTokenColors(this.settings.tokenColorCustomizations); - themeData.setCustomTokenStyleRules(this.settings.tokenStylesCustomizations); - this.updateDynamicCSSRules(themeData); + themeData.setCustomizations(this.settings); return this.applyTheme(themeData, settingsTarget); }, error => { return Promise.reject(new Error(nls.localize('error.cannotloadtheme', "Unable to load {0}: {1}", themeData.location!.toString(), error.message))); @@ -404,10 +394,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { private async reloadCurrentColorTheme() { await this.currentColorTheme.reload(this.extensionResourceLoaderService); - this.currentColorTheme.setCustomColors(this.settings.colorCustomizations); - this.currentColorTheme.setCustomTokenColors(this.settings.tokenColorCustomizations); - this.currentColorTheme.setCustomTokenStyleRules(this.settings.tokenStylesCustomizations); - this.updateDynamicCSSRules(this.currentColorTheme); + this.currentColorTheme.setCustomizations(this.settings); this.applyTheme(this.currentColorTheme, undefined, false); } @@ -436,6 +423,8 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } private applyTheme(newTheme: ColorThemeData, settingsTarget: ConfigurationTarget | undefined | 'auto', silent = false): Promise { + this.updateDynamicCSSRules(newTheme); + if (this.currentColorTheme.id) { removeClasses(this.container, this.currentColorTheme.id); } else { @@ -516,9 +505,8 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { const newThemeData = (await this.fileIconThemeRegistry.findThemeById(iconTheme)) || FileIconThemeData.noIconTheme; await newThemeData.ensureLoaded(this.fileService); - _applyRules(newThemeData.styleSheetContent!, fileIconThemeRulesClassName); - this.doSetFileIconTheme(newThemeData); + this.applyAndSetFileIconTheme(newThemeData); // remember theme data for a quick restore if (newThemeData.isLoaded && (!newThemeData.location || !getRemoteAuthority(newThemeData.location))) { @@ -531,8 +519,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { private async reloadCurrentFileIconTheme() { await this.currentFileIconTheme.reload(this.fileService); - _applyRules(this.currentFileIconTheme.styleSheetContent!, fileIconThemeRulesClassName); - this.doSetFileIconTheme(this.currentFileIconTheme); + this.applyAndSetFileIconTheme(this.currentFileIconTheme); } public async restoreFileIconTheme(): Promise { @@ -547,7 +534,9 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return false; } - private doSetFileIconTheme(iconThemeData: FileIconThemeData): void { + private applyAndSetFileIconTheme(iconThemeData: FileIconThemeData): void { + _applyRules(iconThemeData.styleSheetContent!, fileIconThemeRulesClassName); + this.currentFileIconTheme = iconThemeData; if (iconThemeData.id) { @@ -582,9 +571,8 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { const newThemeData = await this.productIconThemeRegistry.findThemeById(iconTheme) || ProductIconThemeData.defaultTheme; await newThemeData.ensureLoaded(this.fileService); - _applyRules(newThemeData.styleSheetContent!, fileIconThemeRulesClassName); - this.doSetProductIconTheme(newThemeData); + this.applyAndSetProductIconTheme(newThemeData); // remember theme data for a quick restore if (newThemeData.isLoaded && (!newThemeData.location || !getRemoteAuthority(newThemeData.location))) { @@ -597,8 +585,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { private async reloadCurrentProductIconTheme() { await this.currentProductIconTheme.reload(this.fileService); - _applyRules(this.currentProductIconTheme.styleSheetContent!, productIconThemeRulesClassName); - this.doSetProductIconTheme(this.currentProductIconTheme); + this.applyAndSetProductIconTheme(this.currentProductIconTheme); } public async restoreProductIconTheme(): Promise { @@ -613,7 +600,9 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return false; } - private doSetProductIconTheme(iconThemeData: ProductIconThemeData): void { + private applyAndSetProductIconTheme(iconThemeData: ProductIconThemeData): void { + _applyRules(this.currentProductIconTheme.styleSheetContent!, productIconThemeRulesClassName); + this.currentProductIconTheme = iconThemeData; this.productIconThemeWatcher.update(iconThemeData); diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index 18dcea74f29..ca5fb5e9e3d 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -24,6 +24,7 @@ import { MatcherWithPriority, Matcher, createMatchers } from 'vs/workbench/servi import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; import { CharCode } from 'vs/base/common/charCode'; import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; +import { ThemeConfiguration } from 'vs/workbench/services/themes/common/themeConfiguration'; let colorRegistry = Registry.as(ColorRegistryExtensions.ColorContribution); @@ -312,6 +313,12 @@ export class ColorThemeData implements IWorkbenchColorTheme { return this.customColorMap.hasOwnProperty(colorId) || this.colorMap.hasOwnProperty(colorId); } + public setCustomizations(settings: ThemeConfiguration) { + this.setCustomColors(settings.colorCustomizations); + this.setCustomTokenColors(settings.tokenColorCustomizations); + this.setCustomTokenStyleRules(settings.tokenStylesCustomizations); + } + public setCustomColors(colors: IColorCustomizations) { this.customColorMap = {}; this.overwriteCustomColors(colors); From b8de2acee012d7ed791006d2070a2684c2c375c6 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 9 Mar 2020 15:33:12 +0100 Subject: [PATCH 105/137] product icon theme update fix --- .../themes/browser/workbenchThemeService.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index a13360a9451..47a3e6a33be 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -219,14 +219,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.onColorThemeChange.event; } - public get onDidFileIconThemeChange(): Event { - return this.onFileIconThemeChange.event; - } - - public get onDidProductIconThemeChange(): Event { - return this.onProductIconThemeChange.event; - } - private initialize(): Promise<[IWorkbenchColorTheme | null, IWorkbenchFileIconTheme | null, IWorkbenchProductIconTheme | null]> { const extDevLocs = this.environmentService.extensionDevelopmentLocationURI; const extDevLoc = extDevLocs && extDevLocs.length === 1 ? extDevLocs[0] : undefined; // in dev mode, switch to a theme provided by the extension under dev. @@ -496,6 +488,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.currentFileIconTheme; } + public get onDidFileIconThemeChange(): Event { + return this.onFileIconThemeChange.event; + } + + public async setFileIconTheme(iconTheme: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { iconTheme = iconTheme || ''; if (iconTheme === this.currentFileIconTheme.id && this.currentFileIconTheme.isLoaded) { @@ -535,10 +532,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } private applyAndSetFileIconTheme(iconThemeData: FileIconThemeData): void { - _applyRules(iconThemeData.styleSheetContent!, fileIconThemeRulesClassName); - this.currentFileIconTheme = iconThemeData; + _applyRules(iconThemeData.styleSheetContent!, fileIconThemeRulesClassName); + if (iconThemeData.id) { addClasses(this.container, fileIconsEnabledClass); } else { @@ -562,6 +559,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { return this.currentProductIconTheme; } + public get onDidProductIconThemeChange(): Event { + return this.onProductIconThemeChange.event; + } + public async setProductIconTheme(iconTheme: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise { iconTheme = iconTheme || ''; if (iconTheme === this.currentProductIconTheme.id && this.currentProductIconTheme.isLoaded) { @@ -601,10 +602,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } private applyAndSetProductIconTheme(iconThemeData: ProductIconThemeData): void { - _applyRules(this.currentProductIconTheme.styleSheetContent!, productIconThemeRulesClassName); this.currentProductIconTheme = iconThemeData; + _applyRules(iconThemeData.styleSheetContent!, productIconThemeRulesClassName); + this.productIconThemeWatcher.update(iconThemeData); if (iconThemeData.id) { From 36996caea047bc07208ebf191207efd5d8e94476 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 9 Mar 2020 16:48:26 +0100 Subject: [PATCH 106/137] Clear font info when displays are added, removed or changed --- src/vs/code/electron-main/window.ts | 2 ++ src/vs/workbench/electron-browser/window.ts | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 7e4ddbbe0a3..de0a7dff13a 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -392,6 +392,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.setFullScreen(false); this.setFullScreen(true); } + + this.sendWhenReady('vscode:displayChanged'); }, 100)); const displayChangedListener = () => simpleFullScreenScheduler.schedule(); diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 55ee4b0f1cb..6f7117b9068 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -62,6 +62,7 @@ import { IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/servi import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { Event } from 'vs/base/common/event'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService'; +import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; export class NativeWindow extends Disposable { @@ -179,6 +180,10 @@ export class NativeWindow extends Disposable { this.notificationService.info(message); }); + ipc.on('vscode:displayChanged', (event: IpcEvent) => { + clearAllFontInfos(); + }); + // Fullscreen Events ipc.on('vscode:enterFullScreen', async () => { await this.lifecycleService.when(LifecyclePhase.Ready); From 4b716ca5337b5b06f28b5f36c9e8ad257a0ed746 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 16:57:13 +0100 Subject: [PATCH 107/137] quick access - implement editors picker --- .../quickinput/browser/quickInputList.ts | 1 + .../parts/quickinput/common/quickInput.ts | 1 + .../parts/quickopen/browser/quickOpenModel.ts | 8 +- .../parts/quickopen/common/quickOpenScorer.ts | 10 +- .../parts/editor/editor.contribution.ts | 29 +++ .../browser/parts/editor/editorQuickAccess.ts | 199 ++++++++++++++++++ .../parts/quickopen/quickOpenController.ts | 4 +- .../browser/quickAccess.contribution.ts | 20 +- .../quickaccess/browser/viewQuickAccess.ts | 14 +- 9 files changed, 258 insertions(+), 28 deletions(-) create mode 100644 src/vs/workbench/browser/parts/editor/editorQuickAccess.ts diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index 3df8daffc60..c816f564689 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -147,6 +147,7 @@ class ListElementRenderer implements IListRenderer { - getItemLabel(entry: QuickOpenEntry): string | null { - return types.withUndefinedAsNull(entry.getLabel()); + getItemLabel(entry: QuickOpenEntry): string | undefined { + return entry.getLabel(); } - getItemDescription(entry: QuickOpenEntry): string | null { - return types.withUndefinedAsNull(entry.getDescription()); + getItemDescription(entry: QuickOpenEntry): string | undefined { + return entry.getDescription(); } getItemPath(entry: QuickOpenEntry): string | undefined { diff --git a/src/vs/base/parts/quickopen/common/quickOpenScorer.ts b/src/vs/base/parts/quickopen/common/quickOpenScorer.ts index 21cb08caace..9e988f42e46 100644 --- a/src/vs/base/parts/quickopen/common/quickOpenScorer.ts +++ b/src/vs/base/parts/quickopen/common/quickOpenScorer.ts @@ -285,15 +285,15 @@ export interface IItemAccessor { /** * Just the label of the item to score on. */ - getItemLabel(item: T): string | null; + getItemLabel(item: T): string | undefined; /** - * The optional description of the item to score on. Can be null. + * The optional description of the item to score on. */ - getItemDescription(item: T): string | null; + getItemDescription(item: T): string | undefined; /** - * If the item is a file, the path of the file to score on. Can be null. + * If the item is a file, the path of the file to score on. */ getItemPath(file: T): string | undefined; } @@ -376,7 +376,7 @@ function createMatches(offsets: undefined | number[]): IMatch[] { return ret; } -function doScoreItem(label: string, description: string | null, path: string | undefined, query: IPreparedQuery, fuzzy: boolean): IItemScore { +function doScoreItem(label: string, description: string | undefined, path: string | undefined, query: IPreparedQuery, fuzzy: boolean): IItemScore { // 1.) treat identity matches on full path highest if (path && (isLinux ? query.original === path : equalsIgnoreCase(query.original, path))) { diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index f5fff985bed..bc2a05ab0cf 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -56,6 +56,8 @@ import { IFilesConfigurationService } from 'vs/workbench/services/filesConfigura import { EditorAutoSave } from 'vs/workbench/browser/parts/editor/editorAutoSave'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; +import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/platform/quickinput/common/quickAccess'; +import { ActiveGroupEditorsByMostRecentlyUsedQuickAccess, AllEditorsByAppearanceQuickAccess, AllEditorsByMostRecentlyUsedQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess'; // Register String Editor Registry.as(EditorExtensions.Editors).registerEditor( @@ -359,6 +361,33 @@ Registry.as(QuickOpenExtensions.Quickopen).registerQuickOpen ) ); +// Register Editor Quick Access +const quickAccessRegistry = Registry.as(QuickAccessExtensions.Quickaccess); + +quickAccessRegistry.registerQuickAccessProvider({ + ctor: ActiveGroupEditorsByMostRecentlyUsedQuickAccess, + prefix: ActiveGroupEditorsByMostRecentlyUsedQuickAccess.PREFIX, + contextKey: editorPickerContextKey, + placeholder: nls.localize('editorQuickAccessPlaceholder', "Type the name of an editor to open it."), + helpEntries: [{ description: nls.localize('activeGroupEditorsByMostRecentlyUsedQuickAccess', "Show Editors in Active Group by Most Recently Used."), needsEditor: false }] +}); + +quickAccessRegistry.registerQuickAccessProvider({ + ctor: AllEditorsByAppearanceQuickAccess, + prefix: AllEditorsByAppearanceQuickAccess.PREFIX, + contextKey: editorPickerContextKey, + placeholder: nls.localize('editorQuickAccessPlaceholder', "Type the name of an editor to open it."), + helpEntries: [{ description: nls.localize('allEditorsByAppearanceQuickAccess', "Show All Opened Editors By Appearance"), needsEditor: false }] +}); + +quickAccessRegistry.registerQuickAccessProvider({ + ctor: AllEditorsByMostRecentlyUsedQuickAccess, + prefix: AllEditorsByMostRecentlyUsedQuickAccess.PREFIX, + contextKey: editorPickerContextKey, + placeholder: nls.localize('editorQuickAccessPlaceholder', "Type the name of an editor to open it."), + helpEntries: [{ description: nls.localize('allEditorsByMostRecentlyUsedQuickAccess', "Show All Opened Editors By Most Recently Used"), needsEditor: false }] +}); + // Register Editor Actions const category = nls.localize('view', "View"); registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenNextEditor, OpenNextEditor.ID, OpenNextEditor.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.PageDown, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_CLOSE_SQUARE_BRACKET] } }), 'View: Open Next Editor', category); diff --git a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts new file mode 100644 index 00000000000..a665f9a13aa --- /dev/null +++ b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts @@ -0,0 +1,199 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { IQuickPick, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import { IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; +import { IEditorGroupsService, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { EditorsOrder, IEditorIdentifier, toResource, SideBySideEditor } from 'vs/workbench/common/editor'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; +import { prepareQuery, IPreparedQuery, ScorerCache, scoreItem, compareItemsByScore, IItemAccessor } from 'vs/base/parts/quickopen/common/quickOpenScorer'; + +interface IEditorQuickPickItem extends IQuickPickItem, IEditorIdentifier { } + +export abstract class BaseEditorQuickAccessProvider implements IQuickAccessProvider { + + protected abstract readonly prefix: string; + + private editorQuickPickScoringAccessor = new class implements IItemAccessor { + getItemLabel(entry: IEditorQuickPickItem): string | undefined { + return entry.label; + } + + getItemDescription(entry: IEditorQuickPickItem): string | undefined { + return entry.description; + } + + getItemPath(entry: IEditorQuickPickItem): string | undefined { + return toResource(entry.editor, { supportSideBySide: SideBySideEditor.MASTER })?.fsPath; + } + }; + + constructor( + @IEditorGroupsService protected readonly editorGroupService: IEditorGroupsService, + @IEditorService protected readonly editorService: IEditorService, + @IModelService private readonly modelService: IModelService, + @IModeService private readonly modeService: IModeService + ) { + } + + provide(picker: IQuickPick, token: CancellationToken): IDisposable { + const disposables = new DisposableStore(); + + // Disable filtering & sorting, we control the results + picker.matchOnLabel = picker.matchOnDescription = picker.matchOnDetail = picker.sortByLabel = false; + + // Add all view items & filter on type + const scorerCache = Object.create(null); + const updatePickerItems = () => picker.items = this.getEditorPickItems(prepareQuery(picker.value.trim().substr(this.prefix.length)), scorerCache); + disposables.add(picker.onDidChangeValue(() => updatePickerItems())); + updatePickerItems(); + + // Open the picked view on accept + disposables.add(picker.onDidAccept(() => { + const [item] = picker.selectedItems; + if (item) { + picker.hide(); + this.editorGroupService.getGroup(item.groupId)?.openEditor(item.editor); + } + })); + + return disposables; + } + + private getEditorPickItems(query: IPreparedQuery, scorerCache: ScorerCache): Array { + const filteredEditorEntries = this.doGetEditorPickItems().filter(entry => { + if (!query.value) { + return true; + } + + // Score on label and description + const itemScore = scoreItem(entry, query, true, this.editorQuickPickScoringAccessor, scorerCache); + if (!itemScore.score) { + return false; + } + + // Apply highlights + entry.highlights = { label: itemScore.labelMatch, description: itemScore.descriptionMatch }; + + return true; + }); + + // Sorting + if (query.value) { + const groups = this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE).map(group => group.id); + filteredEditorEntries.sort((entryA, entryB) => { + if (entryA.groupId !== entryB.groupId) { + return groups.indexOf(entryA.groupId) - groups.indexOf(entryB.groupId); // older groups first + } + + return compareItemsByScore(entryA, entryB, query, true, this.editorQuickPickScoringAccessor, scorerCache); + }); + } + + // Grouping (for more than one group) + const filteredEditorEntriesWithSeparators: Array = []; + if (this.editorGroupService.count > 1) { + let lastGroupId: number | undefined = undefined; + for (const entry of filteredEditorEntries) { + if (typeof lastGroupId !== 'number' || lastGroupId !== entry.groupId) { + const group = this.editorGroupService.getGroup(entry.groupId); + if (group) { + filteredEditorEntriesWithSeparators.push({ type: 'separator', label: group.label }); + } + lastGroupId = entry.groupId; + } + + filteredEditorEntriesWithSeparators.push(entry); + } + } else { + filteredEditorEntriesWithSeparators.push(...filteredEditorEntries); + } + + return filteredEditorEntriesWithSeparators; + } + + private doGetEditorPickItems(): Array { + return this.doGetEditors().map(({ editor, groupId }) => ({ + editor, + groupId, + label: editor.isDirty() && !editor.isSaving() ? `$(circle-filled) ${editor.getName()}` : editor.getName(), + ariaLabel: localize('entryAriaLabel', "{0}, editor picker", editor.getName()), + description: editor.getDescription(), + iconClasses: getIconClasses(this.modelService, this.modeService, toResource(editor, { supportSideBySide: SideBySideEditor.MASTER })), + italic: !this.editorGroupService.getGroup(groupId)?.isPinned(editor) + })); + } + + protected abstract doGetEditors(): IEditorIdentifier[]; +} + +//#region Active Editor Group Editors by Most Recently Used + +export class ActiveGroupEditorsByMostRecentlyUsedQuickAccess extends BaseEditorQuickAccessProvider { + + static PREFIX = 'edt active '; + + readonly prefix = ActiveGroupEditorsByMostRecentlyUsedQuickAccess.PREFIX; + + protected doGetEditors(): IEditorIdentifier[] { + const group = this.editorGroupService.activeGroup; + + return group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).map(editor => ({ editor, groupId: group.id })); + } +} + +//#endregion + + +//#region All Editors by Appearance + +export class AllEditorsByAppearanceQuickAccess extends BaseEditorQuickAccessProvider { + + static PREFIX = 'edt '; + + readonly prefix = AllEditorsByAppearanceQuickAccess.PREFIX; + + protected doGetEditors(): IEditorIdentifier[] { + const entries: IEditorIdentifier[] = []; + + for (const group of this.editorGroupService.getGroups(GroupsOrder.GRID_APPEARANCE)) { + for (const editor of group.getEditors(EditorsOrder.SEQUENTIAL)) { + entries.push({ editor, groupId: group.id }); + } + } + + return entries; + } +} + +//#endregion + + +//#region All Editors by Most Recently Used + +export class AllEditorsByMostRecentlyUsedQuickAccess extends BaseEditorQuickAccessProvider { + + static PREFIX = 'edt mru '; + + readonly prefix = AllEditorsByMostRecentlyUsedQuickAccess.PREFIX; + + protected doGetEditors(): IEditorIdentifier[] { + const entries: IEditorIdentifier[] = []; + + for (const editor of this.editorService.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE)) { + entries.push(editor); + } + + return entries; + } +} + +//#endregion diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 2cb29536098..a76cb4eb948 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -707,8 +707,8 @@ class EditorHistoryItemAccessorClass extends QuickOpenItemAccessorClass { super(); } - getItemDescription(entry: QuickOpenEntry): string | null { - return this.allowMatchOnDescription ? types.withUndefinedAsNull(entry.getDescription()) : null; + getItemDescription(entry: QuickOpenEntry): string | undefined { + return this.allowMatchOnDescription ? entry.getDescription() : undefined; } } diff --git a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts index 5d30386f4ea..8a03f8bd360 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/quickAccess.contribution.ts @@ -4,24 +4,28 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { IQuickAccessRegistry, Extensions, IQuickAccessProviderDescriptor } from 'vs/platform/quickinput/common/quickAccess'; +import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { Registry } from 'vs/platform/registry/common/platform'; import { HelpQuickAccessProvider } from 'vs/platform/quickinput/browser/helpQuickAccess'; import { ViewQuickAccessProvider, VIEW_QUICK_ACCESS_PREFIX } from 'vs/workbench/contrib/quickaccess/browser/viewQuickAccess'; import { QUICK_ACCESS_COMMAND_ID } from 'vs/workbench/contrib/quickaccess/browser/quickAccessCommands'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; -const helpQuickAccessProvider: IQuickAccessProviderDescriptor = { +const registry = Registry.as(Extensions.Quickaccess); + +registry.defaultProvider = { + ctor: HelpQuickAccessProvider, + prefix: '', + placeholder: localize('helpQuickAccessPlaceholder', "Type '?' to get help on the actions you can take from here."), + helpEntries: [{ description: localize('gotoFileQuickAccess', "Go to File"), needsEditor: false }] +}; + +registry.registerQuickAccessProvider({ ctor: HelpQuickAccessProvider, prefix: '?', placeholder: localize('helpQuickAccessPlaceholder', "Type '?' to get help on the actions you can take from here."), helpEntries: [{ description: localize('helpQuickAccess', "Show all Quick Access Providers"), needsEditor: false }] -}; - -const registry = Registry.as(Extensions.Quickaccess); - -registry.defaultProvider = helpQuickAccessProvider; -registry.registerQuickAccessProvider(helpQuickAccessProvider); +}); registry.registerQuickAccessProvider({ ctor: ViewQuickAccessProvider, diff --git a/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts b/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts index d61f2cf75a0..d19c973f300 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/viewQuickAccess.ts @@ -46,13 +46,10 @@ export class ViewQuickAccessProvider implements IQuickAccessProvider { // Disable filtering & sorting, we control the results picker.matchOnLabel = picker.matchOnDescription = picker.matchOnDetail = picker.sortByLabel = false; - // Add all view items - picker.items = this.getViewPickItems(''); - - // Filter on type - disposables.add(picker.onDidChangeValue(value => { - picker.items = this.getViewPickItems(value.trim().substr(VIEW_QUICK_ACCESS_PREFIX.length)); - })); + // Add all view items & filter on type + const updatePickerItems = () => picker.items = this.getViewPickItems(picker.value.trim().substr(VIEW_QUICK_ACCESS_PREFIX.length)); + disposables.add(picker.onDidChangeValue(() => updatePickerItems())); + updatePickerItems(); // Open the picked view on accept disposables.add(picker.onDidAccept(() => { @@ -87,9 +84,8 @@ export class ViewQuickAccessProvider implements IQuickAccessProvider { } } - const filteredViewEntriesWithSeparators: Array = []; - // Add separators for containers + const filteredViewEntriesWithSeparators: Array = []; let lastContainer: string | undefined = undefined; for (const entry of filteredViewEntries) { if (lastContainer !== entry.containerLabel) { From 238413181cd0114645a9759eb3fd74eb5d68bd1e Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 9 Mar 2020 17:13:02 +0100 Subject: [PATCH 108/137] Set flags for filtering before filtering (fixes #92277) --- src/vs/base/parts/quickinput/browser/quickInput.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 002c1df9a51..7defd5cf056 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -787,6 +787,10 @@ class QuickPick extends QuickInput implements IQuickPi if (this.ui.inputBox.ariaLabel !== this.ariaLabel) { this.ui.inputBox.ariaLabel = this.ariaLabel; } + this.ui.list.matchOnDescription = this.matchOnDescription; + this.ui.list.matchOnDetail = this.matchOnDetail; + this.ui.list.matchOnLabel = this.matchOnLabel; + this.ui.list.sortByLabel = this.sortByLabel; if (this.itemsUpdated) { this.itemsUpdated = false; this.ui.list.setElements(this.items); @@ -832,10 +836,6 @@ class QuickPick extends QuickInput implements IQuickPi } this.ui.customButton.label = this.customLabel || ''; this.ui.customButton.element.title = this.customHover || ''; - this.ui.list.matchOnDescription = this.matchOnDescription; - this.ui.list.matchOnDetail = this.matchOnDetail; - this.ui.list.matchOnLabel = this.matchOnLabel; - this.ui.list.sortByLabel = this.sortByLabel; this.ui.setComboboxAccessibility(true); } } From 1eee7ab4ea6df10a236fb9799c5ef63948df074a Mon Sep 17 00:00:00 2001 From: David Teller Date: Mon, 9 Mar 2020 18:10:06 +0100 Subject: [PATCH 109/137] Fixes #91913 : Exclude **/.hg/store/** from the file watcher (#91941) Watching these files can cause several hours of 200% CPU after even trivial `hg` operations (numbers based on local testing). Excluding these files seems to bring down the duration to a few seconds. --- src/vs/workbench/contrib/files/browser/files.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index f7107199951..f92fbd96463 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -305,7 +305,7 @@ configurationRegistry.registerConfiguration({ }, 'files.watcherExclude': { 'type': 'object', - 'default': platform.isWindows /* https://github.com/Microsoft/vscode/issues/23954 */ ? { '**/.git/objects/**': true, '**/.git/subtree-cache/**': true, '**/node_modules/*/**': true } : { '**/.git/objects/**': true, '**/.git/subtree-cache/**': true, '**/node_modules/**': true }, + 'default': platform.isWindows /* https://github.com/Microsoft/vscode/issues/23954 */ ? { '**/.git/objects/**': true, '**/.git/subtree-cache/**': true, '**/node_modules/*/**': true, '**/.hg/store/**': true } : { '**/.git/objects/**': true, '**/.git/subtree-cache/**': true, '**/node_modules/**': true, '**/.hg/store/**': true }, 'description': nls.localize('watcherExclude', "Configure glob patterns of file paths to exclude from file watching. Patterns must match on absolute paths (i.e. prefix with ** or the full path to match properly). Changing this setting requires a restart. When you experience Code consuming lots of cpu time on startup, you can exclude large folders to reduce the initial load."), 'scope': ConfigurationScope.RESOURCE }, From db36e74f62b1b2603906d4d2c892ab12cf632a12 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Mon, 9 Mar 2020 13:19:38 -0400 Subject: [PATCH 110/137] Only stringify array context values --- src/vs/platform/contextkey/browser/contextKeyService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/contextkey/browser/contextKeyService.ts b/src/vs/platform/contextkey/browser/contextKeyService.ts index 8724786b589..78f7843ea46 100644 --- a/src/vs/platform/contextkey/browser/contextKeyService.ts +++ b/src/vs/platform/contextkey/browser/contextKeyService.ts @@ -143,7 +143,9 @@ class ConfigAwareContextValuesContainer extends Context { value = configValue; break; default: - value = JSON.stringify(configValue); + if (Array.isArray(configValue)) { + value = JSON.stringify(configValue); + } } this._values.set(key, value); From ab35bc5093792169bc8aceb4a3c05fc77404bd63 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 9 Mar 2020 18:47:17 +0100 Subject: [PATCH 111/137] quick access - move quick open scorer to a more generic place --- .../quickOpenScorer.ts => common/fuzzyScorer.ts} | 6 ++++-- src/vs/base/parts/quickopen/browser/quickOpenModel.ts | 2 +- .../common/fuzzyScorer.test.ts} | 8 ++++---- src/vs/workbench/browser/parts/editor/editorPicker.ts | 2 +- .../browser/parts/editor/editorQuickAccess.ts | 10 ++++++++-- .../browser/parts/quickopen/quickOpenController.ts | 2 +- .../contrib/search/browser/openAnythingHandler.ts | 2 +- .../contrib/search/browser/openFileHandler.ts | 2 +- src/vs/workbench/services/search/node/fileSearch.ts | 2 +- .../workbench/services/search/node/rawSearchService.ts | 2 +- 10 files changed, 23 insertions(+), 15 deletions(-) rename src/vs/base/{parts/quickopen/common/quickOpenScorer.ts => common/fuzzyScorer.ts} (98%) rename src/vs/base/{parts/quickopen/test/common/quickOpenScorer.test.ts => test/common/fuzzyScorer.test.ts} (99%) diff --git a/src/vs/base/parts/quickopen/common/quickOpenScorer.ts b/src/vs/base/common/fuzzyScorer.ts similarity index 98% rename from src/vs/base/parts/quickopen/common/quickOpenScorer.ts rename to src/vs/base/common/fuzzyScorer.ts index 9e988f42e46..c43b4f20e85 100644 --- a/src/vs/base/parts/quickopen/common/quickOpenScorer.ts +++ b/src/vs/base/common/fuzzyScorer.ts @@ -311,7 +311,7 @@ export interface IPreparedQuery { } /** - * Helper function to prepare a search value for scoring in quick open by removing unwanted characters. + * Helper function to prepare a search value for scoring by removing unwanted characters. */ export function prepareQuery(original: string): IPreparedQuery { if (!original) { @@ -364,6 +364,7 @@ function createMatches(offsets: undefined | number[]): IMatch[] { if (!offsets) { return ret; } + let last: IMatch | undefined; for (const pos of offsets) { if (last && last.end === pos) { @@ -373,6 +374,7 @@ function createMatches(offsets: undefined | number[]): IMatch[] { ret.push(last); } } + return ret; } @@ -589,7 +591,7 @@ function compareByMatchLength(matchesA?: IMatch[], matchesB?: IMatch[]): number return matchLengthA === matchLengthB ? 0 : matchLengthB < matchLengthA ? 1 : -1; } -export function fallbackCompare(itemA: T, itemB: T, query: IPreparedQuery, accessor: IItemAccessor): number { +function fallbackCompare(itemA: T, itemB: T, query: IPreparedQuery, accessor: IItemAccessor): number { // check for label + description length and prefer shorter const labelA = accessor.getItemLabel(itemA) || ''; diff --git a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts index 579d870cd3a..68cc687c5a3 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts @@ -17,7 +17,7 @@ import { IQuickOpenStyles } from 'vs/base/parts/quickopen/browser/quickOpenWidge import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; import { OS } from 'vs/base/common/platform'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; -import { IItemAccessor } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { IItemAccessor } from 'vs/base/common/fuzzyScorer'; import { coalesce } from 'vs/base/common/arrays'; import { IMatch } from 'vs/base/common/filters'; diff --git a/src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts b/src/vs/base/test/common/fuzzyScorer.test.ts similarity index 99% rename from src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts rename to src/vs/base/test/common/fuzzyScorer.test.ts index a7bbe6fb2a0..43cb8756d3e 100644 --- a/src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts +++ b/src/vs/base/test/common/fuzzyScorer.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as scorer from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import * as scorer from 'vs/base/common/fuzzyScorer'; import { URI } from 'vs/base/common/uri'; import { basename, dirname, sep } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; @@ -49,14 +49,14 @@ function scoreItem(item: T, query: string, fuzzy: boolean, accessor: scorer.I return scorer.scoreItem(item, scorer.prepareQuery(query), fuzzy, accessor, cache); } -function compareItemsByScore(itemA: T, itemB: T, query: string, fuzzy: boolean, accessor: scorer.IItemAccessor, cache: scorer.ScorerCache, fallbackComparer = scorer.fallbackCompare): number { - return scorer.compareItemsByScore(itemA, itemB, scorer.prepareQuery(query), fuzzy, accessor, cache, fallbackComparer); +function compareItemsByScore(itemA: T, itemB: T, query: string, fuzzy: boolean, accessor: scorer.IItemAccessor, cache: scorer.ScorerCache, fallbackComparer?: (itemA: T, itemB: T, query: scorer.IPreparedQuery, accessor: scorer.IItemAccessor) => number): number { + return scorer.compareItemsByScore(itemA, itemB, scorer.prepareQuery(query), fuzzy, accessor, cache, fallbackComparer as any); } const NullAccessor = new NullAccessorClass(); let cache: scorer.ScorerCache = Object.create(null); -suite('Quick Open Scorer', () => { +suite('Fuzzy Scorer', () => { setup(() => { cache = Object.create(null); diff --git a/src/vs/workbench/browser/parts/editor/editorPicker.ts b/src/vs/workbench/browser/parts/editor/editorPicker.ts index 427a7bce430..10f2a7bc04e 100644 --- a/src/vs/workbench/browser/parts/editor/editorPicker.ts +++ b/src/vs/workbench/browser/parts/editor/editorPicker.ts @@ -16,7 +16,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IEditorGroupsService, IEditorGroup, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { toResource, SideBySideEditor, IEditorInput, EditorsOrder } from 'vs/workbench/common/editor'; -import { compareItemsByScore, scoreItem, ScorerCache, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { compareItemsByScore, scoreItem, ScorerCache, prepareQuery } from 'vs/base/common/fuzzyScorer'; import { CancellationToken } from 'vs/base/common/cancellation'; export class EditorPickerEntry extends QuickOpenEntryGroup { diff --git a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts index a665f9a13aa..8a8ae3937ae 100644 --- a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts +++ b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts @@ -14,7 +14,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; -import { prepareQuery, IPreparedQuery, ScorerCache, scoreItem, compareItemsByScore, IItemAccessor } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { prepareQuery, IPreparedQuery, ScorerCache, scoreItem, compareItemsByScore, IItemAccessor } from 'vs/base/common/fuzzyScorer'; +import { Schemas } from 'vs/base/common/network'; interface IEditorQuickPickItem extends IQuickPickItem, IEditorIdentifier { } @@ -32,7 +33,12 @@ export abstract class BaseEditorQuickAccessProvider implements IQuickAccessProvi } getItemPath(entry: IEditorQuickPickItem): string | undefined { - return toResource(entry.editor, { supportSideBySide: SideBySideEditor.MASTER })?.fsPath; + const resource = toResource(entry.editor, { supportSideBySide: SideBySideEditor.MASTER }); + if (resource?.scheme === Schemas.file) { + return resource?.fsPath; + } + + return resource?.path; } }; diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index a76cb4eb948..9da034ae867 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -38,7 +38,7 @@ import { quickInputBackground, quickInputForeground } from 'vs/platform/theme/co import { attachQuickOpenStyler } from 'vs/platform/theme/common/styler'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; -import { scoreItem, ScorerCache, compareItemsByScore, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { scoreItem, ScorerCache, compareItemsByScore, prepareQuery } from 'vs/base/common/fuzzyScorer'; import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { Schemas } from 'vs/base/common/network'; import { INotificationService } from 'vs/platform/notification/common/notification'; diff --git a/src/vs/workbench/contrib/search/browser/openAnythingHandler.ts b/src/vs/workbench/contrib/search/browser/openAnythingHandler.ts index 7b3f04acbd6..a91deb9962b 100644 --- a/src/vs/workbench/contrib/search/browser/openAnythingHandler.ts +++ b/src/vs/workbench/contrib/search/browser/openAnythingHandler.ts @@ -16,7 +16,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkbenchSearchConfiguration } from 'vs/workbench/contrib/search/common/search'; import { IRange } from 'vs/editor/common/core/range'; -import { compareItemsByScore, scoreItem, ScorerCache, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { compareItemsByScore, scoreItem, ScorerCache, prepareQuery } from 'vs/base/common/fuzzyScorer'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { CancellationToken } from 'vs/base/common/cancellation'; diff --git a/src/vs/workbench/contrib/search/browser/openFileHandler.ts b/src/vs/workbench/contrib/search/browser/openFileHandler.ts index 3c88120a110..5329b1f91ae 100644 --- a/src/vs/workbench/contrib/search/browser/openFileHandler.ts +++ b/src/vs/workbench/contrib/search/browser/openFileHandler.ts @@ -13,7 +13,7 @@ import { basename, dirname, toLocalResource } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { QuickOpenEntry, QuickOpenModel } from 'vs/base/parts/quickopen/browser/quickOpenModel'; import { IAutoFocus } from 'vs/base/parts/quickopen/common/quickOpen'; -import { IPreparedQuery, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { IPreparedQuery, prepareQuery } from 'vs/base/common/fuzzyScorer'; import { IRange } from 'vs/editor/common/core/range'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; import { IModelService } from 'vs/editor/common/services/modelService'; diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index e0465326652..563a66a3efc 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -22,7 +22,7 @@ import { URI } from 'vs/base/common/uri'; import { readdir } from 'vs/base/node/pfs'; import { IFileQuery, IFolderQuery, IProgressMessage, ISearchEngineStats, IRawFileMatch, ISearchEngine, ISearchEngineSuccess, isFilePatternMatch } from 'vs/workbench/services/search/common/search'; import { spawnRipgrepCmd } from './ripgrepFileSearch'; -import { prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { prepareQuery } from 'vs/base/common/fuzzyScorer'; interface IDirectoryEntry { base: string; diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index 51f5440de19..5055db9ed39 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -15,7 +15,7 @@ import * as objects from 'vs/base/common/objects'; import { StopWatch } from 'vs/base/common/stopwatch'; import * as strings from 'vs/base/common/strings'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer'; +import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/common/fuzzyScorer'; import { MAX_FILE_SIZE } from 'vs/base/node/pfs'; import { ICachedSearchStats, IFileQuery, IFileSearchStats, IFolderQuery, IProgressMessage, IRawFileQuery, IRawQuery, IRawTextQuery, ITextQuery, IFileSearchProgressItem, IRawFileMatch, IRawSearchService, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess, isFilePatternMatch } from 'vs/workbench/services/search/common/search'; import { Engine as FileSearchEngine } from 'vs/workbench/services/search/node/fileSearch'; From 849aadb72c43dffa8018ec23bca82e6c35d30b3c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 9 Mar 2020 19:08:09 +0100 Subject: [PATCH 112/137] #92038 Move output view from get*Actions to use menus --- .../browser/parts/views/viewMenuActions.ts | 4 +- .../output/browser/output.contribution.ts | 250 +++++++++++++--- .../contrib/output/browser/outputActions.ts | 269 ------------------ .../contrib/output/browser/outputView.ts | 94 +++++- .../workbench/contrib/output/common/output.ts | 7 +- 5 files changed, 291 insertions(+), 333 deletions(-) delete mode 100644 src/vs/workbench/contrib/output/browser/outputActions.ts diff --git a/src/vs/workbench/browser/parts/views/viewMenuActions.ts b/src/vs/workbench/browser/parts/views/viewMenuActions.ts index f55455a925e..3c0ad25bc70 100644 --- a/src/vs/workbench/browser/parts/views/viewMenuActions.ts +++ b/src/vs/workbench/browser/parts/views/viewMenuActions.ts @@ -36,7 +36,7 @@ export class ViewMenuActions extends Disposable { const updateActions = () => { this.primaryActions = []; this.secondaryActions = []; - this.titleActionsDisposable.value = createAndFillInActionBarActions(menu, undefined, { primary: this.primaryActions, secondary: this.secondaryActions }); + this.titleActionsDisposable.value = createAndFillInActionBarActions(menu, { shouldForwardArgs: true }, { primary: this.primaryActions, secondary: this.secondaryActions }); this._onDidChangeTitle.fire(); }; this._register(menu.onDidChange(updateActions)); @@ -45,7 +45,7 @@ export class ViewMenuActions extends Disposable { const contextMenu = this._register(this.menuService.createMenu(contextMenuId, scopedContextKeyService)); const updateContextMenuActions = () => { this.contextMenuActions = []; - this.titleActionsDisposable.value = createAndFillInActionBarActions(contextMenu, undefined, { primary: [], secondary: this.contextMenuActions }); + this.titleActionsDisposable.value = createAndFillInActionBarActions(contextMenu, { shouldForwardArgs: true }, { primary: [], secondary: this.contextMenuActions }); }; this._register(contextMenu.onDidChange(updateContextMenuActions)); updateContextMenuActions(); diff --git a/src/vs/workbench/contrib/output/browser/output.contribution.ts b/src/vs/workbench/contrib/output/browser/output.contribution.ts index fc1a2c61224..ea14e0d998b 100644 --- a/src/vs/workbench/contrib/output/browser/output.contribution.ts +++ b/src/vs/workbench/contrib/output/browser/output.contribution.ts @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; +import * as aria from 'vs/base/browser/ui/aria/aria'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; -import { MenuId, MenuRegistry, SyncActionDescriptor, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; +import { MenuId, MenuRegistry, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { OutputService, LogContentProvider } from 'vs/workbench/contrib/output/browser/outputServices'; -import { ToggleOutputAction, ClearOutputAction, OpenLogOutputFile, ShowLogsOutputChannelAction, OpenOutputLogFileAction } from 'vs/workbench/contrib/output/browser/outputActions'; -import { OUTPUT_MODE_ID, OUTPUT_MIME, OUTPUT_VIEW_ID, IOutputService, CONTEXT_IN_OUTPUT, LOG_SCHEME, LOG_MODE_ID, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT } from 'vs/workbench/contrib/output/common/output'; +import { OUTPUT_MODE_ID, OUTPUT_MIME, OUTPUT_VIEW_ID, IOutputService, CONTEXT_IN_OUTPUT, LOG_SCHEME, LOG_MODE_ID, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT, CONTEXT_OUTPUT_SCROLL_LOCK } from 'vs/workbench/contrib/output/common/output'; import { OutputViewPane } from 'vs/workbench/contrib/output/browser/outputView'; import { IEditorRegistry, Extensions as EditorExtensions, EditorDescriptor } from 'vs/workbench/browser/editor'; import { LogViewer, LogViewerInput } from 'vs/workbench/contrib/output/browser/logViewer'; @@ -21,9 +20,18 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWo import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { ViewContainer, IViewContainersRegistry, ViewContainerLocation, Extensions as ViewContainerExtensions, IViewsRegistry } from 'vs/workbench/common/views'; +import { ViewContainer, IViewContainersRegistry, ViewContainerLocation, Extensions as ViewContainerExtensions, IViewsRegistry, IViewsService } from 'vs/workbench/common/views'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IOutputChannelDescriptor, IFileOutputChannelDescriptor } from 'vs/workbench/services/output/common/output'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { assertIsDefined } from 'vs/base/common/types'; +import { TogglePanelAction } from 'vs/workbench/browser/panel'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ContextKeyEqualsExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; // Register Service registerSingleton(IOutputService, OutputService); @@ -43,18 +51,18 @@ ModesRegistry.registerLanguage({ }); // register output container +const toggleOutputAcitonId = 'workbench.action.output.toggleOutput'; +const toggleOutputActionKeybindings = { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_U, + linux: { + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_H) // On Ubuntu Ctrl+Shift+U is taken by some global OS command + } +}; const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: OUTPUT_VIEW_ID, name: nls.localize('output', "Output"), ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [OUTPUT_VIEW_ID, OUTPUT_VIEW_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]), - focusCommand: { - id: ToggleOutputAction.ID, keybindings: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_U, - linux: { - primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_H) // On Ubuntu Ctrl+Shift+U is taken by some global OS command - } - } - } + focusCommand: { id: toggleOutputAcitonId, keybindings: toggleOutputActionKeybindings } }, ViewContainerLocation.Panel); Registry.as(ViewContainerExtensions.ViewsRegistry).registerViews([{ @@ -86,62 +94,220 @@ class OutputContribution implements IWorkbenchContribution { Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(OutputContribution, LifecyclePhase.Restored); -// register toggle output action globally -const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); -actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleOutputAction, ToggleOutputAction.ID, ToggleOutputAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_U, - linux: { - primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_H) // On Ubuntu Ctrl+Shift+U is taken by some global OS command - } -}), 'View: Toggle Output', nls.localize('viewCategory', "View")); - -actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ClearOutputAction, ClearOutputAction.ID, ClearOutputAction.LABEL), - 'View: Clear Output', nls.localize('viewCategory', "View")); - -const devCategory = nls.localize('developer', "Developer"); -actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ShowLogsOutputChannelAction, ShowLogsOutputChannelAction.ID, ShowLogsOutputChannelAction.LABEL), 'Developer: Show Logs...', devCategory); -actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(OpenOutputLogFileAction, OpenOutputLogFileAction.ID, OpenOutputLogFileAction.LABEL), 'Developer: Open Log File...', devCategory); - -// Define clear command, contribute to editor context menu registerAction2(class extends Action2 { constructor() { super({ - id: 'editor.action.clearoutput', - title: { value: nls.localize('clearOutput.label', "Clear Output"), original: 'Clear Output' }, + id: `workbench.output.action.switchBetweenOutputs`, + title: nls.localize('switchToOutput.label', "Switch to Output"), menu: { - id: MenuId.EditorContext, - when: CONTEXT_IN_OUTPUT + id: MenuId.ViewTitle, + when: ContextKeyEqualsExpr.create('view', OUTPUT_VIEW_ID), + group: 'navigation', + order: 1 }, }); } - run(accessor: ServicesAccessor) { - const activeChannel = accessor.get(IOutputService).getActiveChannel(); + async run(accessor: ServicesAccessor, channelId: string): Promise { + accessor.get(IOutputService).showChannel(channelId); + } +}); +registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.output.action.clearOutput`, + title: { value: nls.localize('clearOutput.label', "Clear Output"), original: 'Clear Output' }, + category: nls.localize('viewCategory', "View"), + menu: [{ + id: MenuId.ViewTitle, + when: ContextKeyEqualsExpr.create('view', OUTPUT_VIEW_ID), + group: 'navigation', + order: 2 + }, { + id: MenuId.CommandPalette + }, { + id: MenuId.EditorContext, + when: CONTEXT_IN_OUTPUT + }], + icon: { id: 'codicon/clear-all' } + }); + } + async run(accessor: ServicesAccessor): Promise { + const outputService = accessor.get(IOutputService); + const activeChannel = outputService.getActiveChannel(); if (activeChannel) { activeChannel.clear(); + aria.status(nls.localize('outputCleared', "Output was cleared")); + } + } +}); +registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.output.action.turnOffAutoScroll`, + title: nls.localize('outputScrollOff', "Turn Auto Scrolling Off"), + menu: { + id: MenuId.ViewTitle, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', OUTPUT_VIEW_ID), CONTEXT_OUTPUT_SCROLL_LOCK.negate()), + group: 'navigation', + order: 3, + }, + icon: { id: 'codicon/unlock' } + }); + } + async run(accessor: ServicesAccessor): Promise { + const outputView = accessor.get(IViewsService).getActiveViewWithId(OUTPUT_VIEW_ID)!; + outputView.scrollLock = true; + } +}); +registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.output.action.turnOnAutoScroll`, + title: nls.localize('outputScrollOn', "Turn Auto Scrolling On"), + menu: { + id: MenuId.ViewTitle, + when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', OUTPUT_VIEW_ID), CONTEXT_OUTPUT_SCROLL_LOCK), + group: 'navigation', + order: 3, + }, + icon: { id: 'codicon/lock' }, + }); + } + async run(accessor: ServicesAccessor): Promise { + const outputView = accessor.get(IViewsService).getActiveViewWithId(OUTPUT_VIEW_ID)!; + outputView.scrollLock = false; + } +}); +registerAction2(class extends Action2 { + constructor() { + super({ + id: `workbench.action.openActiveLogOutputFile`, + title: { value: nls.localize('openActiveLogOutputFile', "Open Log Output File"), original: 'Open Log Output File' }, + menu: [{ + id: MenuId.ViewTitle, + when: ContextKeyEqualsExpr.create('view', OUTPUT_VIEW_ID), + group: 'navigation', + order: 4 + }, { + id: MenuId.CommandPalette, + when: CONTEXT_ACTIVE_LOG_OUTPUT, + }], + icon: { id: 'codicon/go-to-file' }, + precondition: CONTEXT_ACTIVE_LOG_OUTPUT + }); + } + async run(accessor: ServicesAccessor): Promise { + const outputService = accessor.get(IOutputService); + const editorService = accessor.get(IEditorService); + const instantiationService = accessor.get(IInstantiationService); + const logFileOutputChannelDescriptor = this.getLogFileOutputChannelDescriptor(outputService); + if (logFileOutputChannelDescriptor) { + await editorService.openEditor(instantiationService.createInstance(LogViewerInput, logFileOutputChannelDescriptor)); + } + } + private getLogFileOutputChannelDescriptor(outputService: IOutputService): IFileOutputChannelDescriptor | null { + const channel = outputService.getActiveChannel(); + if (channel) { + const descriptor = outputService.getChannelDescriptors().filter(c => c.id === channel.id)[0]; + if (descriptor && descriptor.file && descriptor.log) { + return descriptor; + } + } + return null; + } +}); + +// register toggle output action globally +registerAction2(class extends Action2 { + constructor() { + super({ + id: toggleOutputAcitonId, + title: { value: nls.localize('toggleOutput', "Toggle Output"), original: 'Toggle Output' }, + category: { value: nls.localize('viewCategory', "View"), original: 'View' }, + menu: { + id: MenuId.CommandPalette, + }, + keybinding: { + ...toggleOutputActionKeybindings, + ...{ + weight: KeybindingWeight.WorkbenchContrib, + when: undefined + } + }, + }); + } + async run(accessor: ServicesAccessor): Promise { + const panelService = accessor.get(IPanelService); + const layoutService = accessor.get(IWorkbenchLayoutService); + return new class ToggleOutputAction extends TogglePanelAction { + constructor() { + super(toggleOutputAcitonId, 'Toggle Output', OUTPUT_VIEW_ID, panelService, layoutService); + } + }().run(); + } +}); + +const devCategory = { value: nls.localize('developer', "Developer"), original: 'Developer' }; +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.action.showLogs', + title: { value: nls.localize('showLogs', "Show Logs..."), original: 'Show Logs...' }, + category: devCategory, + menu: { + id: MenuId.CommandPalette, + }, + }); + } + async run(accessor: ServicesAccessor): Promise { + const outputService = accessor.get(IOutputService); + const quickInputService = accessor.get(IQuickInputService); + const entries: { id: string, label: string }[] = outputService.getChannelDescriptors().filter(c => c.file && c.log) + .map(({ id, label }) => ({ id, label })); + + const entry = await quickInputService.pick(entries, { placeHolder: nls.localize('selectlog', "Select Log") }); + if (entry) { + return outputService.showChannel(entry.id); } } }); +interface IOutputChannelQuickPickItem extends IQuickPickItem { + channel: IOutputChannelDescriptor; +} + registerAction2(class extends Action2 { constructor() { super({ - id: 'workbench.action.openActiveLogOutputFile', - title: { value: nls.localize('openActiveLogOutputFile', "Open Active Log Output File"), original: 'Open Active Log Output File' }, + id: 'workbench.action.openLogFile', + title: { value: nls.localize('openLogFile', "Open Log File..."), original: 'Open Log File...' }, + category: devCategory, menu: { id: MenuId.CommandPalette, - when: CONTEXT_ACTIVE_LOG_OUTPUT }, }); } - run(accessor: ServicesAccessor) { - accessor.get(IInstantiationService).createInstance(OpenLogOutputFile).run(); + async run(accessor: ServicesAccessor): Promise { + const outputService = accessor.get(IOutputService); + const quickInputService = accessor.get(IQuickInputService); + const instantiationService = accessor.get(IInstantiationService); + const editorService = accessor.get(IEditorService); + + const entries: IOutputChannelQuickPickItem[] = outputService.getChannelDescriptors().filter(c => c.file && c.log) + .map(channel => ({ id: channel.id, label: channel.label, channel })); + + const entry = await quickInputService.pick(entries, { placeHolder: nls.localize('selectlogFile', "Select Log file") }); + if (entry) { + assertIsDefined(entry.channel.file); + await editorService.openEditor(instantiationService.createInstance(LogViewerInput, (entry.channel as IFileOutputChannelDescriptor))); + } } }); MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { group: '4_panels', command: { - id: ToggleOutputAction.ID, + id: toggleOutputAcitonId, title: nls.localize({ key: 'miToggleOutput', comment: ['&& denotes a mnemonic'] }, "&&Output") }, order: 1 diff --git a/src/vs/workbench/contrib/output/browser/outputActions.ts b/src/vs/workbench/contrib/output/browser/outputActions.ts deleted file mode 100644 index db610d418d1..00000000000 --- a/src/vs/workbench/contrib/output/browser/outputActions.ts +++ /dev/null @@ -1,269 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as nls from 'vs/nls'; -import * as aria from 'vs/base/browser/ui/aria/aria'; -import { IAction, Action } from 'vs/base/common/actions'; -import { IOutputChannelRegistry, Extensions as OutputExt, IOutputChannelDescriptor, IFileOutputChannelDescriptor } from 'vs/workbench/services/output/common/output'; -import { IOutputService, OUTPUT_VIEW_ID } from 'vs/workbench/contrib/output/common/output'; -import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; -import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { TogglePanelAction } from 'vs/workbench/browser/panel'; -import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { groupBy } from 'vs/base/common/arrays'; -import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { LogViewerInput } from 'vs/workbench/contrib/output/browser/logViewer'; -import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; -import { assertIsDefined } from 'vs/base/common/types'; - -export class ToggleOutputAction extends TogglePanelAction { - - static readonly ID = 'workbench.action.output.toggleOutput'; - static readonly LABEL = nls.localize('toggleOutput', "Toggle Output"); - - constructor( - id: string, label: string, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @IPanelService panelService: IPanelService, - ) { - super(id, label, OUTPUT_VIEW_ID, panelService, layoutService); - } -} - -export class ClearOutputAction extends Action { - - static readonly ID = 'workbench.output.action.clearOutput'; - static readonly LABEL = nls.localize('clearOutput', "Clear Output"); - - constructor( - id: string, label: string, - @IOutputService private readonly outputService: IOutputService - ) { - super(id, label, 'output-action codicon-clear-all'); - } - - run(): Promise { - const activeChannel = this.outputService.getActiveChannel(); - if (activeChannel) { - activeChannel.clear(); - aria.status(nls.localize('outputCleared', "Output was cleared")); - } - return Promise.resolve(true); - } -} - -// this action can be triggered in two ways: -// 1. user clicks the action icon, In which case the action toggles the lock state -// 2. user clicks inside the output view, which sets the lock, Or unsets it if they click the last line. -export class ToggleOrSetOutputScrollLockAction extends Action { - - static readonly ID = 'workbench.output.action.toggleOutputScrollLock'; - static readonly LABEL = nls.localize({ key: 'toggleOutputScrollLock', comment: ['Turn on / off automatic output scrolling'] }, "Toggle Output Scroll Lock"); - - constructor(id: string, label: string, @IOutputService private readonly outputService: IOutputService) { - super(id, label, 'output-action codicon-unlock'); - this._register(this.outputService.onActiveOutputChannel(channel => { - const activeChannel = this.outputService.getActiveChannel(); - if (activeChannel) { - this.setClassAndLabel(activeChannel.scrollLock); - } - })); - } - - run(newLockState?: boolean): Promise { - - const activeChannel = this.outputService.getActiveChannel(); - if (activeChannel) { - if (typeof (newLockState) === 'boolean') { - activeChannel.scrollLock = newLockState; - } - else { - activeChannel.scrollLock = !activeChannel.scrollLock; - } - this.setClassAndLabel(activeChannel.scrollLock); - } - - return Promise.resolve(true); - } - - private setClassAndLabel(locked: boolean) { - if (locked) { - this.class = 'output-action codicon-lock'; - this.label = nls.localize('outputScrollOn', "Turn Auto Scrolling On"); - } else { - this.class = 'output-action codicon-unlock'; - this.label = nls.localize('outputScrollOff', "Turn Auto Scrolling Off"); - } - } -} - -export class SwitchOutputAction extends Action { - - static readonly ID = 'workbench.output.action.switchBetweenOutputs'; - - constructor(@IOutputService private readonly outputService: IOutputService) { - super(SwitchOutputAction.ID, nls.localize('switchToOutput.label', "Switch to Output")); - - this.class = 'output-action switch-to-output'; - } - - run(channelId: string): Promise { - return this.outputService.showChannel(channelId); - } -} - -export class SwitchOutputActionViewItem extends SelectActionViewItem { - - private static readonly SEPARATOR = '─────────'; - - private outputChannels: IOutputChannelDescriptor[] = []; - private logChannels: IOutputChannelDescriptor[] = []; - - constructor( - action: IAction, - @IOutputService private readonly outputService: IOutputService, - @IThemeService themeService: IThemeService, - @IContextViewService contextViewService: IContextViewService - ) { - super(null, action, [], 0, contextViewService, { ariaLabel: nls.localize('outputChannels', 'Output Channels.') }); - - let outputChannelRegistry = Registry.as(OutputExt.OutputChannels); - this._register(outputChannelRegistry.onDidRegisterChannel(() => this.updateOtions())); - this._register(outputChannelRegistry.onDidRemoveChannel(() => this.updateOtions())); - this._register(this.outputService.onActiveOutputChannel(() => this.updateOtions())); - this._register(attachSelectBoxStyler(this.selectBox, themeService)); - - this.updateOtions(); - } - - protected getActionContext(option: string, index: number): string { - const channel = index < this.outputChannels.length ? this.outputChannels[index] : this.logChannels[index - this.outputChannels.length - 1]; - return channel ? channel.id : option; - } - - private updateOtions(): void { - const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => { - if (!c1.log && c2.log) { - return -1; - } - if (c1.log && !c2.log) { - return 1; - } - return 0; - }); - this.outputChannels = groups[0] || []; - this.logChannels = groups[1] || []; - const showSeparator = this.outputChannels.length && this.logChannels.length; - const separatorIndex = showSeparator ? this.outputChannels.length : -1; - const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionViewItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))]; - let selected = 0; - const activeChannel = this.outputService.getActiveChannel(); - if (activeChannel) { - selected = this.outputChannels.map(c => c.id).indexOf(activeChannel.id); - if (selected === -1) { - const logChannelIndex = this.logChannels.map(c => c.id).indexOf(activeChannel.id); - selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0; - } - } - this.setOptions(options.map((label, index) => { text: label, isDisabled: (index === separatorIndex ? true : false) }), Math.max(0, selected)); - } -} - -export class OpenLogOutputFile extends Action { - - static readonly ID = 'workbench.output.action.openLogOutputFile'; - static readonly LABEL = nls.localize('openInLogViewer', "Open Log File"); - - constructor( - @IOutputService private readonly outputService: IOutputService, - @IEditorService private readonly editorService: IEditorService, - @IInstantiationService private readonly instantiationService: IInstantiationService - ) { - super(OpenLogOutputFile.ID, OpenLogOutputFile.LABEL, 'output-action codicon-go-to-file'); - this._register(this.outputService.onActiveOutputChannel(this.update, this)); - this.update(); - } - - private update(): void { - this.enabled = !!this.getLogFileOutputChannelDescriptor(); - } - - async run(): Promise { - const logFileOutputChannelDescriptor = this.getLogFileOutputChannelDescriptor(); - if (logFileOutputChannelDescriptor) { - await this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, logFileOutputChannelDescriptor)); - } - } - - private getLogFileOutputChannelDescriptor(): IFileOutputChannelDescriptor | null { - const channel = this.outputService.getActiveChannel(); - if (channel) { - const descriptor = this.outputService.getChannelDescriptors().filter(c => c.id === channel.id)[0]; - if (descriptor && descriptor.file && descriptor.log) { - return descriptor; - } - } - return null; - } -} - -export class ShowLogsOutputChannelAction extends Action { - - static readonly ID = 'workbench.action.showLogs'; - static readonly LABEL = nls.localize('showLogs', "Show Logs..."); - - constructor(id: string, label: string, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @IOutputService private readonly outputService: IOutputService - ) { - super(id, label); - } - - async run(): Promise { - const entries: { id: string, label: string }[] = this.outputService.getChannelDescriptors().filter(c => c.file && c.log) - .map(({ id, label }) => ({ id, label })); - - const entry = await this.quickInputService.pick(entries, { placeHolder: nls.localize('selectlog', "Select Log") }); - if (entry) { - return this.outputService.showChannel(entry.id); - } - } -} - -interface IOutputChannelQuickPickItem extends IQuickPickItem { - channel: IOutputChannelDescriptor; -} - -export class OpenOutputLogFileAction extends Action { - - static readonly ID = 'workbench.action.openLogFile'; - static readonly LABEL = nls.localize('openLogFile', "Open Log File..."); - - constructor(id: string, label: string, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @IOutputService private readonly outputService: IOutputService, - @IEditorService private readonly editorService: IEditorService, - @IInstantiationService private readonly instantiationService: IInstantiationService - ) { - super(id, label); - } - - async run(): Promise { - const entries: IOutputChannelQuickPickItem[] = this.outputService.getChannelDescriptors().filter(c => c.file && c.log) - .map(channel => ({ id: channel.id, label: channel.label, channel })); - - const entry = await this.quickInputService.pick(entries, { placeHolder: nls.localize('selectlogFile', "Select Log file") }); - if (entry) { - assertIsDefined(entry.channel.file); - await this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, (entry.channel as IFileOutputChannelDescriptor))); - } - } -} diff --git a/src/vs/workbench/contrib/output/browser/outputView.ts b/src/vs/workbench/contrib/output/browser/outputView.ts index bcc70dcadcf..c7fbe8223f5 100644 --- a/src/vs/workbench/contrib/output/browser/outputView.ts +++ b/src/vs/workbench/contrib/output/browser/outputView.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import { IAction } from 'vs/base/common/actions'; -import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; +import { IActionViewItem, SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -13,11 +13,10 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { EditorInput, EditorOptions } from 'vs/workbench/common/editor'; import { AbstractTextResourceEditor } from 'vs/workbench/browser/parts/editor/textResourceEditor'; -import { OUTPUT_VIEW_ID, IOutputService, CONTEXT_IN_OUTPUT, IOutputChannel, CONTEXT_ACTIVE_LOG_OUTPUT } from 'vs/workbench/contrib/output/common/output'; -import { SwitchOutputAction, SwitchOutputActionViewItem, ClearOutputAction, ToggleOrSetOutputScrollLockAction, OpenLogOutputFile } from 'vs/workbench/contrib/output/browser/outputActions'; +import { OUTPUT_VIEW_ID, IOutputService, CONTEXT_IN_OUTPUT, IOutputChannel, CONTEXT_ACTIVE_LOG_OUTPUT, CONTEXT_OUTPUT_SCROLL_LOCK } from 'vs/workbench/contrib/output/common/output'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -26,10 +25,15 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IViewDescriptorService } from 'vs/workbench/common/views'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IOutputChannelDescriptor, IOutputChannelRegistry, Extensions } from 'vs/workbench/services/output/common/output'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler'; +import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; +import { groupBy } from 'vs/base/common/arrays'; export class OutputViewPane extends ViewPane { @@ -38,6 +42,10 @@ export class OutputViewPane extends ViewPane { private editorPromise: Promise | null = null; private actions: IAction[] | undefined; + private readonly scrollLockContextKey: IContextKey; + get scrollLock(): boolean { return !!this.scrollLockContextKey.get(); } + set scrollLock(scrollLock: boolean) { this.scrollLockContextKey.set(scrollLock); } + constructor( options: IViewPaneOptions, @IKeybindingService keybindingService: IKeybindingService, @@ -52,6 +60,7 @@ export class OutputViewPane extends ViewPane { @ITelemetryService telemetryService: ITelemetryService, ) { super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + this.scrollLockContextKey = CONTEXT_OUTPUT_SCROLL_LOCK.bindTo(this.contextKeyService); this.editor = instantiationService.createInstance(OutputEditor); this._register(this.editor.onTitleAreaUpdate(() => { this.updateTitle(this.editor.getTitle()); @@ -81,7 +90,7 @@ export class OutputViewPane extends ViewPane { const codeEditor = this.editor.getControl(); this._register(codeEditor.onDidChangeModelContent(() => { const activeChannel = this.outputService.getActiveChannel(); - if (activeChannel && !activeChannel.scrollLock) { + if (activeChannel && !this.scrollLock) { this.editor.revealLastLine(); } })); @@ -98,9 +107,7 @@ export class OutputViewPane extends ViewPane { if (model && this.actions) { const newPositionLine = e.position.lineNumber; const lastLine = model.getLineCount(); - const newLockState = lastLine !== newPositionLine; - const lockAction = this.actions.filter((action) => action.id === ToggleOrSetOutputScrollLockAction.ID)[0]; - lockAction.run(newLockState); + this.scrollLock = lastLine !== newPositionLine; } })); } @@ -112,10 +119,10 @@ export class OutputViewPane extends ViewPane { getActions(): IAction[] { if (!this.actions) { this.actions = [ - this._register(this.instantiationService.createInstance(SwitchOutputAction)), - this._register(this.instantiationService.createInstance(ClearOutputAction, ClearOutputAction.ID, ClearOutputAction.LABEL)), - this._register(this.instantiationService.createInstance(ToggleOrSetOutputScrollLockAction, ToggleOrSetOutputScrollLockAction.ID, ToggleOrSetOutputScrollLockAction.LABEL)), - this._register(this.instantiationService.createInstance(OpenLogOutputFile)) + // this._register(this.instantiationService.createInstance(SwitchOutputAction)), + // this._register(this.instantiationService.createInstance(ClearOutputAction, ClearOutputAction.ID, ClearOutputAction.LABEL)), + // this._register(this.instantiationService.createInstance(ToggleOrSetOutputScrollLockAction, ToggleOrSetOutputScrollLockAction.ID, ToggleOrSetOutputScrollLockAction.LABEL)), + // this._register(this.instantiationService.createInstance(OpenLogOutputFile)) ]; } return [...super.getActions(), ...this.actions]; @@ -126,13 +133,12 @@ export class OutputViewPane extends ViewPane { } getActionViewItem(action: IAction): IActionViewItem | undefined { - if (action.id === SwitchOutputAction.ID) { + if (action.id === 'workbench.output.action.switchBetweenOutputs') { return this.instantiationService.createInstance(SwitchOutputActionViewItem, action); } return super.getActionViewItem(action); } - private onDidChangeVisibility(visible: boolean): void { this.editor.setVisible(visible); let channel: IOutputChannel | undefined = undefined; @@ -268,3 +274,61 @@ export class OutputEditor extends AbstractTextResourceEditor { CONTEXT_IN_OUTPUT.bindTo(scopedContextKeyService).set(true); } } + +class SwitchOutputActionViewItem extends SelectActionViewItem { + + private static readonly SEPARATOR = '─────────'; + + private outputChannels: IOutputChannelDescriptor[] = []; + private logChannels: IOutputChannelDescriptor[] = []; + + constructor( + action: IAction, + @IOutputService private readonly outputService: IOutputService, + @IThemeService themeService: IThemeService, + @IContextViewService contextViewService: IContextViewService + ) { + super(null, action, [], 0, contextViewService, { ariaLabel: nls.localize('outputChannels', 'Output Channels.') }); + + let outputChannelRegistry = Registry.as(Extensions.OutputChannels); + this._register(outputChannelRegistry.onDidRegisterChannel(() => this.updateOtions())); + this._register(outputChannelRegistry.onDidRemoveChannel(() => this.updateOtions())); + this._register(this.outputService.onActiveOutputChannel(() => this.updateOtions())); + this._register(attachSelectBoxStyler(this.selectBox, themeService)); + + this.updateOtions(); + } + + protected getActionContext(option: string, index: number): string { + const channel = index < this.outputChannels.length ? this.outputChannels[index] : this.logChannels[index - this.outputChannels.length - 1]; + return channel ? channel.id : option; + } + + private updateOtions(): void { + const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => { + if (!c1.log && c2.log) { + return -1; + } + if (c1.log && !c2.log) { + return 1; + } + return 0; + }); + this.outputChannels = groups[0] || []; + this.logChannels = groups[1] || []; + const showSeparator = this.outputChannels.length && this.logChannels.length; + const separatorIndex = showSeparator ? this.outputChannels.length : -1; + const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionViewItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))]; + let selected = 0; + const activeChannel = this.outputService.getActiveChannel(); + if (activeChannel) { + selected = this.outputChannels.map(c => c.id).indexOf(activeChannel.id); + if (selected === -1) { + const logChannelIndex = this.logChannels.map(c => c.id).indexOf(activeChannel.id); + selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0; + } + } + this.setOptions(options.map((label, index) => { text: label, isDisabled: (index === separatorIndex ? true : false) }), Math.max(0, selected)); + } +} + diff --git a/src/vs/workbench/contrib/output/common/output.ts b/src/vs/workbench/contrib/output/common/output.ts index 238e2b7758f..483be2132b5 100644 --- a/src/vs/workbench/contrib/output/common/output.ts +++ b/src/vs/workbench/contrib/output/common/output.ts @@ -52,6 +52,8 @@ export const CONTEXT_IN_OUTPUT = new RawContextKey('inOutput', false); export const CONTEXT_ACTIVE_LOG_OUTPUT = new RawContextKey('activeLogOutput', false); +export const CONTEXT_OUTPUT_SCROLL_LOCK = new RawContextKey(`outputView.scrollLock`, false); + export const IOutputService = createDecorator(OUTPUT_SERVICE_ID); /** @@ -105,11 +107,6 @@ export interface IOutputChannel { */ label: string; - /** - * Returns the value indicating whether the channel has scroll locked. - */ - scrollLock: boolean; - /** * URI of the output channel. */ From 1876b51870e30e9ba8f35dc0dcfaf49a3799a8ef Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 9 Mar 2020 19:32:47 +0100 Subject: [PATCH 113/137] Explorer should show hidden files and their path if they are opened fixes #92090 --- .../files/browser/views/explorerView.ts | 38 ++++----- .../files/browser/views/explorerViewer.ts | 85 ++++++++++++++++--- 2 files changed, 91 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 733a9b62ed1..a349a0c5c76 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -354,6 +354,7 @@ export class ExplorerView extends ViewPane { private createTree(container: HTMLElement): void { this.filter = this.instantiationService.createInstance(FilesFilter); this._register(this.filter); + this._register(this.filter.onDidChange(() => this.refresh(true))); const explorerLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility }); this._register(explorerLabels); @@ -458,18 +459,7 @@ export class ExplorerView extends ViewPane { this.autoReveal = configuration?.explorer?.autoReveal; // Push down config updates to components of viewer - let needsRefresh = false; - if (this.filter) { - needsRefresh = this.filter.updateConfiguration(); - } - - if (event && !needsRefresh) { - needsRefresh = event.affectsConfiguration('explorer.decorations.colors') - || event.affectsConfiguration('explorer.decorations.badges'); - } - - // Refresh viewer as needed if this originates from a config event - if (event && needsRefresh) { + if (event && (event.affectsConfiguration('explorer.decorations.colors') || event.affectsConfiguration('explorer.decorations.badges'))) { this.refresh(true); } } @@ -672,19 +662,23 @@ export class ExplorerView extends ViewPane { } if (item && item.parent) { - if (reveal) { - if (item.isDisposed) { - return this.onSelectResource(resource, reveal, retry + 1); + try { + if (reveal) { + if (item.isDisposed) { + return this.onSelectResource(resource, reveal, retry + 1); + } + + // Don't scroll to the item if it's already visible + if (this.tree.getRelativeTop(item) === null) { + this.tree.reveal(item, 0.5); + } } - // Don't scroll to the item if it's already visible - if (this.tree.getRelativeTop(item) === null) { - this.tree.reveal(item, 0.5); - } + this.tree.setFocus([item]); + this.tree.setSelection([item]); + } catch (e) { + // Element might not be in the tree, silently fail } - - this.tree.setFocus([item]); - this.tree.setSelection([item]); } } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 9ae1935e2cd..107f5f1da8b 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -55,6 +55,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { isNumber } from 'vs/base/common/types'; import { domEvent } from 'vs/base/browser/event'; import { IEditableData } from 'vs/workbench/common/views'; +import { IEditorInput } from 'vs/workbench/common/editor'; export class ExplorerDelegate implements IListVirtualDelegate { @@ -472,28 +473,70 @@ interface CachedParsedExpression { parsed: glob.ParsedExpression; } +/** + * Respectes files.exclude setting in filtering out content from the explorer. + * Makes sure that visible editors are always shown in the explorer even if they are filtered out by settings. + */ export class FilesFilter implements ITreeFilter { private hiddenExpressionPerRoot: Map; - private workspaceFolderChangeListener: IDisposable; + private hiddenUris = new Set(); + private editorsAffectingFilter = new Set(); + private _onDidChange = new Emitter(); + private toDispose: IDisposable[] = []; constructor( @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IConfigurationService private readonly configurationService: IConfigurationService, - @IExplorerService private readonly explorerService: IExplorerService + @IExplorerService private readonly explorerService: IExplorerService, + @IEditorService private readonly editorService: IEditorService, ) { this.hiddenExpressionPerRoot = new Map(); - this.workspaceFolderChangeListener = this.contextService.onDidChangeWorkspaceFolders(() => this.updateConfiguration()); + this.toDispose.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateConfiguration())); + this.toDispose.push(this.configurationService.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('files.exclude')) { + this.updateConfiguration(); + } + })); + this.toDispose.push(this.editorService.onDidVisibleEditorsChange(() => { + const editors = this.editorService.visibleEditors; + let shouldFire = false; + this.hiddenUris.forEach(u => { + editors.forEach(e => { + if (e.resource && isEqualOrParent(e.resource, u)) { + // A filtered resource suddenly became visible since user opened an editor + shouldFire = true; + } + }); + }); + + this.editorsAffectingFilter.forEach(e => { + if (editors.indexOf(e) === -1) { + // Editor that was affecting filtering is no longer visible + shouldFire = true; + } + }); + if (shouldFire) { + this.editorsAffectingFilter.clear(); + this.hiddenUris.clear(); + this._onDidChange.fire(); + } + })); + this.updateConfiguration(); } - updateConfiguration(): boolean { - let needsRefresh = false; + get onDidChange(): Event { + return this._onDidChange.event; + } + + private updateConfiguration(): void { + let shouldFire = false; this.contextService.getWorkspace().folders.forEach(folder => { const configuration = this.configurationService.getValue({ resource: folder.uri }); const excludesConfig: glob.IExpression = configuration?.files?.exclude || Object.create(null); - if (!needsRefresh) { + if (!shouldFire) { const cached = this.hiddenExpressionPerRoot.get(folder.uri.toString()); - needsRefresh = !cached || !equals(cached.original, excludesConfig); + shouldFire = !cached || !equals(cached.original, excludesConfig); } const excludesConfigCopy = deepClone(excludesConfig); // do not keep the config, as it gets mutated under our hoods @@ -501,10 +544,25 @@ export class FilesFilter implements ITreeFilter { this.hiddenExpressionPerRoot.set(folder.uri.toString(), { original: excludesConfigCopy, parsed: glob.parse(excludesConfigCopy) }); }); - return needsRefresh; + if (shouldFire) { + this.editorsAffectingFilter.clear(); + this.hiddenUris.clear(); + this._onDidChange.fire(); + } } filter(stat: ExplorerItem, parentVisibility: TreeVisibility): TreeFilterResult { + const isVisible = this.isVisible(stat, parentVisibility); + if (isVisible) { + this.hiddenUris.delete(stat.resource); + } else { + this.hiddenUris.add(stat.resource); + } + + return isVisible; + } + + private isVisible(stat: ExplorerItem, parentVisibility: TreeVisibility): boolean { if (parentVisibility === TreeVisibility.Hidden) { return false; } @@ -515,14 +573,21 @@ export class FilesFilter implements ITreeFilter { // Hide those that match Hidden Patterns const cached = this.hiddenExpressionPerRoot.get(stat.root.resource.toString()); if (cached && cached.parsed(path.relative(stat.root.resource.path, stat.resource.path), stat.name, name => !!(stat.parent && stat.parent.getChild(name)))) { + const editors = this.editorService.visibleEditors; + const editor = editors.filter(e => e.resource && isEqualOrParent(e.resource, stat.resource)).pop(); + if (editor) { + this.editorsAffectingFilter.add(editor); + return true; // Show all opened files and their parents + } + return false; // hidden through pattern } return true; } - public dispose(): void { - dispose(this.workspaceFolderChangeListener); + dispose(): void { + dispose(this.toDispose); } } From 514f56425770f7232eb97f14750e3f880c8005e3 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 9 Mar 2020 10:35:43 -0700 Subject: [PATCH 114/137] Update auth provider ids in API documentation --- src/vs/vscode.proposed.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 442e2651a96..67c78abac58 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -43,7 +43,7 @@ declare module 'vscode' { export interface AuthenticationProvider { /** * Used as an identifier for extensions trying to work with a particular - * provider: 'Microsoft', 'GitHub', etc. id must be unique, registering + * provider: 'microsoft', 'github', etc. id must be unique, registering * another provider with the same id will fail. */ readonly id: string; From 5551d73be99006fbd1bdf95f259b625b7df707ab Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 9 Mar 2020 12:41:48 -0700 Subject: [PATCH 115/137] Add scope parameter to getSessions, fixes #91571 --- src/vs/vscode.proposed.d.ts | 6 +-- .../workbench/api/common/extHost.api.impl.ts | 4 +- .../api/common/extHostAuthentication.ts | 41 ++++++++++--------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 67c78abac58..b4c379c9227 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -50,7 +50,7 @@ declare module 'vscode' { readonly displayName: string; /** - * A [event](#Event) which fires when the array of sessions has changed, or data + * An [event](#Event) which fires when the array of sessions has changed, or data * within a session has changed. */ readonly onDidChangeSessions: Event; @@ -85,7 +85,7 @@ declare module 'vscode' { * registered, or if the user does not consent to sharing authentication information with * the extension. */ - export function getSessions(providerId: string): Thenable; + export function getSessions(providerId: string, scopes: string[]): Thenable; /** * Prompt a user to login to create a new authenticaiton session. Rejects if a provider with @@ -95,7 +95,7 @@ declare module 'vscode' { export function login(providerId: string, scopes: string[]): Thenable; /** - * A [event](#Event) which fires when the array of sessions has changed, or data + * An [event](#Event) which fires when the array of sessions has changed, or data * within a session has changed for a provider. Fires with the ids of the providers * that have had session data change. */ diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 409da2f66d3..143bc3bdf77 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -191,8 +191,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I hasProvider(providerId: string): boolean { return extHostAuthentication.hasProvider(providerId); }, - getSessions(providerId: string): Thenable { - return extHostAuthentication.getSessions(extension, providerId); + getSessions(providerId: string, scopes: string[]): Thenable { + return extHostAuthentication.getSessions(extension, providerId, scopes); }, login(providerId: string, scopes: string[]): Thenable { return extHostAuthentication.login(extension, providerId, scopes); diff --git a/src/vs/workbench/api/common/extHostAuthentication.ts b/src/vs/workbench/api/common/extHostAuthentication.ts index 88ce55c51ea..baa486b5c5c 100644 --- a/src/vs/workbench/api/common/extHostAuthentication.ts +++ b/src/vs/workbench/api/common/extHostAuthentication.ts @@ -28,32 +28,35 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape { return !!this._authenticationProviders.get(providerId); } - async getSessions(requestingExtension: IExtensionDescription, providerId: string): Promise { + async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise { const provider = this._authenticationProviders.get(providerId); if (!provider) { throw new Error(`No authentication provider with id '${providerId}' is currently registered.`); } - return (await provider.getSessions()).map(session => { - return { - id: session.id, - accountName: session.accountName, - scopes: session.scopes, - getAccessToken: async () => { - const isAllowed = await this._proxy.$getSessionsPrompt( - provider.id, - provider.displayName, - ExtensionIdentifier.toKey(requestingExtension.identifier), - requestingExtension.displayName || requestingExtension.name); + const orderedScopes = scopes.sort().join(' '); + return (await provider.getSessions()) + .filter(session => session.scopes.sort().join(' ') === orderedScopes) + .map(session => { + return { + id: session.id, + accountName: session.accountName, + scopes: session.scopes, + getAccessToken: async () => { + const isAllowed = await this._proxy.$getSessionsPrompt( + provider.id, + provider.displayName, + ExtensionIdentifier.toKey(requestingExtension.identifier), + requestingExtension.displayName || requestingExtension.name); - if (!isAllowed) { - throw new Error('User did not consent to token access.'); + if (!isAllowed) { + throw new Error('User did not consent to token access.'); + } + + return session.getAccessToken(); } - - return session.getAccessToken(); - } - }; - }); + }; + }); } async login(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise { From 72c700cf5419663c7bf833308233cc760709bcaf Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 9 Mar 2020 15:56:23 -0400 Subject: [PATCH 116/137] Added completion entry for @ts-expect-error directive (#92093) * Added completion entry for @ts-expect-error directive * Limited to relevant TS versions * You know what, it's more complicated, I'll just go with everything vs 3.9 --- .../features/directiveCommentCompletions.ts | 20 +++++++++++++++++-- .../src/utils/api.ts | 1 + .../editor/vs_code_editor_walkthrough.ts | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts index c0a222e47df..8a33a76a5a8 100644 --- a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts +++ b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import { ITypeScriptServiceClient } from '../typescriptService'; +import API from '../utils/api'; const localize = nls.loadMessageBundle(); @@ -33,11 +34,26 @@ const directives: Directive[] = [ } ]; +const directives390: Directive[] = [ + ...directives, + { + value: '@ts-expect-error', + description: localize( + 'ts-expect-error', + "Suppresses @ts-check errors on the next line of a file, expecting at least one to exist.") + } +]; + class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvider { + private readonly directives: Directive[]; constructor( private readonly client: ITypeScriptServiceClient, - ) { } + ) { + this.directives = client.apiVersion.gte(API.v390) + ? directives390 + : directives; + } public provideCompletionItems( document: vscode.TextDocument, @@ -53,7 +69,7 @@ class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvide const prefix = line.slice(0, position.character); const match = prefix.match(/^\s*\/\/+\s?(@[a-zA-Z\-]*)?$/); if (match) { - return directives.map(directive => { + return this.directives.map(directive => { const item = new vscode.CompletionItem(directive.value, vscode.CompletionItemKind.Snippet); item.detail = directive.description; item.range = new vscode.Range(position.line, Math.max(0, position.character - (match[1] ? match[1].length : 0)), position.line, position.character); diff --git a/extensions/typescript-language-features/src/utils/api.ts b/extensions/typescript-language-features/src/utils/api.ts index 25be4b5e516..1845285caa4 100644 --- a/extensions/typescript-language-features/src/utils/api.ts +++ b/extensions/typescript-language-features/src/utils/api.ts @@ -33,6 +33,7 @@ export default class API { public static readonly v350 = API.fromSimpleString('3.5.0'); public static readonly v380 = API.fromSimpleString('3.8.0'); public static readonly v381 = API.fromSimpleString('3.8.1'); + public static readonly v390 = API.fromSimpleString('3.9.0'); public static fromVersionString(versionString: string): API { let version = semver.valid(versionString); diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.ts index 252b682d8b8..6f7b6c61db3 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.ts @@ -174,7 +174,7 @@ let easy = true; easy = 42; ||| ->**Tip:** You can also enable the checks workspace or application wide by adding |"javascript.implicitProjectConfig.checkJs": true| to your workspace or user settings and explicitly ignoring files or lines using |// @ts-nocheck| and |// @ts-ignore|. Check out the docs on [JavaScript in VS Code](https://code.visualstudio.com/docs/languages/javascript) to learn more. +>**Tip:** You can also enable the checks workspace or application wide by adding |"javascript.implicitProjectConfig.checkJs": true| to your workspace or user settings and explicitly ignoring files or lines using |// @ts-nocheck| and |// @ts-expect-error|. Check out the docs on [JavaScript in VS Code](https://code.visualstudio.com/docs/languages/javascript) to learn more. ## Thanks! From 0b3e54edb1a26fbeba02441319b2ad544550dd72 Mon Sep 17 00:00:00 2001 From: Benno Date: Tue, 10 Mar 2020 03:56:54 +0800 Subject: [PATCH 117/137] update #91296 allow multiple workspace roots (#92082) * update #91296 allow multiple workspace roots * update #92082 --- .../markdown-language-features/src/features/preview.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index ad8edc1c2ad..2b71b348f4d 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -457,7 +457,10 @@ export class DynamicMarkdownPreview extends Disposable { const folder = vscode.workspace.getWorkspaceFolder(base); if (folder) { - baseRoots.push(folder.uri); + const workspaceRoots = vscode.workspace.workspaceFolders?.map(folder => folder.uri); + if (workspaceRoots) { + baseRoots.push(...workspaceRoots); + } } else if (!base.scheme || base.scheme === 'file') { baseRoots.push(vscode.Uri.file(path.dirname(base.fsPath))); } From 44d4fe895d473c255ed7599bac84181b57e42e83 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 9 Mar 2020 12:57:33 -0700 Subject: [PATCH 118/137] Allow using Command in StatusBarItem (#92046) Fixes #22353 StatusBarItem is one of the few places in our API where we only allow extensions to give us a command as a `string` instead of as `Command` object. This change updates the API to also allow passing in a `vscode.Command` (which also allows arguments!) --- src/vs/vscode.d.ts | 7 ++- .../api/browser/mainThreadStatusBar.ts | 3 +- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../workbench/api/common/extHostStatusBar.ts | 59 ++++++++++++++----- .../browser/parts/statusbar/statusbarPart.ts | 8 ++- .../workbench/contrib/scm/browser/activity.ts | 3 +- .../services/statusbar/common/statusbar.ts | 8 +-- 8 files changed, 59 insertions(+), 33 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 9e852eca701..6ba87f6803a 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4975,10 +4975,11 @@ declare module 'vscode' { color: string | ThemeColor | undefined; /** - * The identifier of a command to run on click. The command must be - * [known](#commands.getCommands). + * [`Command`](#Command) or identifier of a command to run on click. + * + * The command must be [known](#commands.getCommands). */ - command: string | undefined; + command: string | Command | undefined; /** * Shows the entry in the status bar. diff --git a/src/vs/workbench/api/browser/mainThreadStatusBar.ts b/src/vs/workbench/api/browser/mainThreadStatusBar.ts index 91a9ba1419f..fb733a38228 100644 --- a/src/vs/workbench/api/browser/mainThreadStatusBar.ts +++ b/src/vs/workbench/api/browser/mainThreadStatusBar.ts @@ -8,6 +8,7 @@ import { MainThreadStatusBarShape, MainContext, IExtHostContext } from '../commo import { ThemeColor } from 'vs/platform/theme/common/themeService'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { dispose } from 'vs/base/common/lifecycle'; +import { Command } from 'vs/editor/common/modes'; @extHostNamedCustomer(MainContext.MainThreadStatusBar) export class MainThreadStatusBar implements MainThreadStatusBarShape { @@ -24,7 +25,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape { this.entries.clear(); } - $setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: string | undefined, color: string | ThemeColor | undefined, alignment: MainThreadStatusBarAlignment, priority: number | undefined): void { + $setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, alignment: MainThreadStatusBarAlignment, priority: number | undefined): void { const entry: IStatusbarEntry = { text, tooltip, command, color }; if (typeof priority === 'undefined') { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 143bc3bdf77..39f0534293c 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -143,7 +143,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostClipboard = new ExtHostClipboard(rpcProtocol); const extHostMessageService = new ExtHostMessageService(rpcProtocol, extHostLogService); const extHostDialogs = new ExtHostDialogs(rpcProtocol); - const extHostStatusBar = new ExtHostStatusBar(rpcProtocol); + const extHostStatusBar = new ExtHostStatusBar(rpcProtocol, extHostCommands.converter); const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); // Register API-ish commands diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index a21449c9036..ec69c297aa0 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -533,7 +533,7 @@ export interface MainThreadQuickOpenShape extends IDisposable { } export interface MainThreadStatusBarShape extends IDisposable { - $setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: string | undefined, color: string | ThemeColor | undefined, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void; + $setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: ICommandDto | undefined, color: string | ThemeColor | undefined, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void; $dispose(id: number): void; } diff --git a/src/vs/workbench/api/common/extHostStatusBar.ts b/src/vs/workbench/api/common/extHostStatusBar.ts index 02c89a6e89e..d26ee3d7c86 100644 --- a/src/vs/workbench/api/common/extHostStatusBar.ts +++ b/src/vs/workbench/api/common/extHostStatusBar.ts @@ -5,11 +5,13 @@ import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/workbench/services/statusbar/common/statusbar'; import { StatusBarAlignment as ExtHostStatusBarAlignment, Disposable, ThemeColor } from './extHostTypes'; -import { StatusBarItem, StatusBarAlignment } from 'vscode'; -import { MainContext, MainThreadStatusBarShape, IMainContext } from './extHost.protocol'; +import type * as vscode from 'vscode'; +import { MainContext, MainThreadStatusBarShape, IMainContext, ICommandDto } from './extHost.protocol'; import { localize } from 'vs/nls'; +import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; +import { DisposableStore } from 'vs/base/common/lifecycle'; -export class ExtHostStatusBarEntry implements StatusBarItem { +export class ExtHostStatusBarEntry implements vscode.StatusBarItem { private static ID_GEN = 0; private _id: number; @@ -24,14 +26,20 @@ export class ExtHostStatusBarEntry implements StatusBarItem { private _text: string = ''; private _tooltip?: string; private _color?: string | ThemeColor; - private _command?: string; + private readonly _internalCommandRegistration = new DisposableStore(); + private _command?: { + readonly fromApi: string | vscode.Command, + readonly internal: ICommandDto, + }; private _timeoutHandle: any; private _proxy: MainThreadStatusBarShape; + private _commands: CommandsConverter; - constructor(proxy: MainThreadStatusBarShape, id: string, name: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) { + constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, id: string, name: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) { this._id = ExtHostStatusBarEntry.ID_GEN++; this._proxy = proxy; + this._commands = commands; this._statusId = id; this._statusName = name; this._alignment = alignment; @@ -42,7 +50,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem { return this._id; } - public get alignment(): StatusBarAlignment { + public get alignment(): vscode.StatusBarAlignment { return this._alignment; } @@ -62,8 +70,8 @@ export class ExtHostStatusBarEntry implements StatusBarItem { return this._color; } - public get command(): string | undefined { - return this._command; + public get command(): string | vscode.Command | undefined { + return this._command?.fromApi; } public set text(text: string) { @@ -81,8 +89,25 @@ export class ExtHostStatusBarEntry implements StatusBarItem { this.update(); } - public set command(command: string | undefined) { - this._command = command; + public set command(command: string | vscode.Command | undefined) { + if (this._command?.fromApi === command) { + return; + } + + this._internalCommandRegistration.clear(); + if (typeof command === 'string') { + this._command = { + fromApi: command, + internal: this._commands.toInternal({ title: '', command }, this._internalCommandRegistration), + }; + } else if (command) { + this._command = { + fromApi: command, + internal: this._commands.toInternal(command, this._internalCommandRegistration), + }; + } else { + this._command = undefined; + } this.update(); } @@ -109,7 +134,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem { this._timeoutHandle = undefined; // Set to status bar - this._proxy.$setEntry(this.id, this._statusId, this._statusName, this.text, this.tooltip, this.command, this.color, + this._proxy.$setEntry(this.id, this._statusId, this._statusName, this.text, this.tooltip, this._command?.internal, this.color, this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT, this._priority); }, 0); @@ -123,7 +148,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem { class StatusBarMessage { - private _item: StatusBarItem; + private _item: vscode.StatusBarItem; private _messages: { message: string }[] = []; constructor(statusBar: ExtHostStatusBar) { @@ -161,16 +186,18 @@ class StatusBarMessage { export class ExtHostStatusBar { - private _proxy: MainThreadStatusBarShape; + private readonly _proxy: MainThreadStatusBarShape; + private readonly _commands: CommandsConverter; private _statusMessage: StatusBarMessage; - constructor(mainContext: IMainContext) { + constructor(mainContext: IMainContext, commands: CommandsConverter) { this._proxy = mainContext.getProxy(MainContext.MainThreadStatusBar); + this._commands = commands; this._statusMessage = new StatusBarMessage(this); } - createStatusBarEntry(id: string, name: string, alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem { - return new ExtHostStatusBarEntry(this._proxy, id, name, alignment, priority); + createStatusBarEntry(id: string, name: string, alignment?: ExtHostStatusBarAlignment, priority?: number): vscode.StatusBarItem { + return new ExtHostStatusBarEntry(this._proxy, this._commands, id, name, alignment, priority); } setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): Disposable { diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index 4d140afcf29..b3a0df2c36b 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -34,6 +34,7 @@ import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { values } from 'vs/base/common/map'; import { assertIsDefined } from 'vs/base/common/types'; import { Emitter, Event } from 'vs/base/common/event'; +import { Command } from 'vs/editor/common/modes'; interface IPendingStatusbarEntry { id: string; @@ -702,7 +703,7 @@ class StatusbarEntryItem extends Disposable { const command = entry.command; if (command) { - this.commandListener.value = addDisposableListener(this.labelContainer, EventType.CLICK, () => this.executeCommand(command, entry.arguments)); + this.commandListener.value = addDisposableListener(this.labelContainer, EventType.CLICK, () => this.executeCommand(command)); removeClass(this.labelContainer, 'disabled'); } else { @@ -738,8 +739,9 @@ class StatusbarEntryItem extends Disposable { this.entry = entry; } - private async executeCommand(id: string, args?: unknown[]): Promise { - args = args || []; + private async executeCommand(command: string | Command): Promise { + const id = typeof command === 'string' ? command : command.id; + const args = typeof command === 'string' ? [] : command.arguments ?? []; // Maintain old behaviour of always focusing the editor here const activeTextEditorControl = this.editorService.activeTextEditorControl; diff --git a/src/vs/workbench/contrib/scm/browser/activity.ts b/src/vs/workbench/contrib/scm/browser/activity.ts index 150e3b562e7..13ed604bd7f 100644 --- a/src/vs/workbench/contrib/scm/browser/activity.ts +++ b/src/vs/workbench/contrib/scm/browser/activity.ts @@ -159,8 +159,7 @@ export class SCMStatusController implements IWorkbenchContribution { disposables.add(this.statusbarService.addEntry({ text: c.title, tooltip: `${label} - ${c.tooltip}`, - command: c.id, - arguments: c.arguments + command: c }, 'status.scm', localize('status.scm', "Source Control"), MainThreadStatusBarAlignment.LEFT, 10000)); } diff --git a/src/vs/workbench/services/statusbar/common/statusbar.ts b/src/vs/workbench/services/statusbar/common/statusbar.ts index 31f46524c9c..130101a530b 100644 --- a/src/vs/workbench/services/statusbar/common/statusbar.ts +++ b/src/vs/workbench/services/statusbar/common/statusbar.ts @@ -7,6 +7,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { IDisposable } from 'vs/base/common/lifecycle'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; import { Event } from 'vs/base/common/event'; +import { Command } from 'vs/editor/common/modes'; export const IStatusbarService = createDecorator('statusbarService'); @@ -45,12 +46,7 @@ export interface IStatusbarEntry { /** * An optional id of a command that is known to the workbench to execute on click */ - readonly command?: string; - - /** - * Optional arguments for the command. - */ - readonly arguments?: unknown[]; + readonly command?: string | Command; /** * Whether to show a beak above the status bar entry. From fadb2e6bd9374a682fe1c7cc543696a64bb542df Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 9 Mar 2020 22:14:29 +0100 Subject: [PATCH 119/137] Validate monospace assumptions --- .../browser/viewParts/lines/viewLine.ts | 45 ++++++++++++++++- .../browser/viewParts/lines/viewLines.ts | 49 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index 11a33fd32a3..9a7011dc1d4 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -42,6 +42,8 @@ const canUseFastRenderedViewLine = (function () { return true; })(); +let monospaceAssumptionsAreValid = true; + const alwaysRenderInlineSelection = (browser.isEdge); export class DomReadingContext { @@ -248,7 +250,7 @@ export class ViewLine implements IVisibleLine { sb.appendASCIIString(''); let renderedViewLine: IRenderedViewLine | null = null; - if (canUseFastRenderedViewLine && lineData.isBasicASCII && options.useMonospaceOptimizations && output.containsForeignElements === ForeignElementType.None) { + if (monospaceAssumptionsAreValid && canUseFastRenderedViewLine && lineData.isBasicASCII && options.useMonospaceOptimizations && output.containsForeignElements === ForeignElementType.None) { if (lineData.content.length < 300 && renderLineInput.lineTokens.getCount() < 100) { // Browser rounding errors have been observed in Chrome and IE, so using the fast // view line only for short lines. Please test before removing the length check... @@ -304,6 +306,29 @@ export class ViewLine implements IVisibleLine { return this._renderedViewLine.getWidthIsFast(); } + public needsMonospaceFontCheck(): boolean { + if (!this._renderedViewLine) { + return false; + } + return (this._renderedViewLine instanceof FastRenderedViewLine); + } + + public monospaceAssumptionsAreValid(): boolean { + if (!this._renderedViewLine) { + return monospaceAssumptionsAreValid; + } + if (this._renderedViewLine instanceof FastRenderedViewLine) { + return this._renderedViewLine.monospaceAssumptionsAreValid(); + } + return monospaceAssumptionsAreValid; + } + + public onMonospaceAssumptionsInvalidated(): void { + if (this._renderedViewLine && this._renderedViewLine instanceof FastRenderedViewLine) { + this._renderedViewLine = this._renderedViewLine.toSlowRenderedLine(); + } + } + public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): VisibleRanges | null { if (!this._renderedViewLine) { return null; @@ -382,6 +407,24 @@ class FastRenderedViewLine implements IRenderedViewLine { return true; } + public monospaceAssumptionsAreValid(): boolean { + if (!this.domNode) { + return monospaceAssumptionsAreValid; + } + const expectedWidth = this.getWidth(); + const actualWidth = (this.domNode.domNode.firstChild).offsetWidth; + if (Math.abs(expectedWidth - actualWidth) >= 2) { + // more than 2px off + console.warn(`monospace assumptions have been violated, therefore disabling monospace optimizations!`); + monospaceAssumptionsAreValid = false; + } + return monospaceAssumptionsAreValid; + } + + public toSlowRenderedLine(): RenderedViewLine { + return createRenderedLine(this.domNode, this.input, this._characterMapping, false, ForeignElementType.None); + } + public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null { const startPosition = this._getCharPosition(startColumn); const endPosition = this._getCharPosition(endColumn); diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index b938a5fd9fa..09ee4fb5516 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./viewLines'; +import * as platform from 'vs/base/common/platform'; import { FastDomNode } from 'vs/base/browser/fastDomNode'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Configuration } from 'vs/editor/browser/config/configuration'; @@ -106,6 +107,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, // --- width private _maxLineWidth: number; private readonly _asyncUpdateLineWidths: RunOnceScheduler; + private readonly _asyncCheckMonospaceFontAssumptions: RunOnceScheduler; private _horizontalRevealRequest: HorizontalRevealRequest | null; private readonly _lastRenderedData: LastRenderedData; @@ -140,6 +142,9 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, this._asyncUpdateLineWidths = new RunOnceScheduler(() => { this._updateLineWidthsSlow(); }, 200); + this._asyncCheckMonospaceFontAssumptions = new RunOnceScheduler(() => { + this._checkMonospaceFontAssumptions(); + }, 2000); this._lastRenderedData = new LastRenderedData(); @@ -148,6 +153,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, public dispose(): void { this._asyncUpdateLineWidths.dispose(); + this._asyncCheckMonospaceFontAssumptions.dispose(); super.dispose(); } @@ -513,6 +519,37 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, return allWidthsComputed; } + private _checkMonospaceFontAssumptions(): void { + // Problems with monospace assumptions are more apparent for longer lines, + // as small rounding errors start to sum up, so we will select the longest + // line for a closer inspection + let longestLineNumber = -1; + let longestWidth = -1; + const rendStartLineNumber = this._visibleLines.getStartLineNumber(); + const rendEndLineNumber = this._visibleLines.getEndLineNumber(); + for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { + const visibleLine = this._visibleLines.getVisibleLine(lineNumber); + if (visibleLine.needsMonospaceFontCheck()) { + const lineWidth = visibleLine.getWidth(); + if (lineWidth > longestWidth) { + longestWidth = lineWidth; + longestLineNumber = lineNumber; + } + } + } + + if (longestLineNumber === -1) { + return; + } + + if (!this._visibleLines.getVisibleLine(longestLineNumber).monospaceAssumptionsAreValid()) { + for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { + const visibleLine = this._visibleLines.getVisibleLine(lineNumber); + visibleLine.onMonospaceAssumptionsInvalidated(); + } + } + } + public prepareRender(): void { throw new Error('Not supported'); } @@ -571,6 +608,18 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, this._asyncUpdateLineWidths.schedule(); } + if (platform.isLinux && !this._asyncCheckMonospaceFontAssumptions.isScheduled()) { + const rendStartLineNumber = this._visibleLines.getStartLineNumber(); + const rendEndLineNumber = this._visibleLines.getEndLineNumber(); + for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { + const visibleLine = this._visibleLines.getVisibleLine(lineNumber); + if (visibleLine.needsMonospaceFontCheck()) { + this._asyncCheckMonospaceFontAssumptions.schedule(); + break; + } + } + } + // (3) handle scrolling this._linesContent.setLayerHinting(this._canUseLayerHinting); this._linesContent.setContain('strict'); From 990363f194984a2bc8c58d75909e61a51473b704 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Mon, 9 Mar 2020 14:34:49 -0700 Subject: [PATCH 120/137] Multiple Views Per Panel V0 (#92294) * multipanel start * revert to horizontal headers * prevent collapse * prevent collapse * remove patch, no longer necessary --- src/vs/base/browser/ui/splitview/paneview.ts | 32 ++++++++++++------- .../workbench/browser/parts/compositeBar.ts | 2 +- .../browser/parts/panel/media/panelpart.css | 26 +++++++-------- .../browser/parts/views/media/paneviewlet.css | 4 +++ .../browser/parts/views/viewPaneContainer.ts | 12 +++++-- 5 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/paneview.ts b/src/vs/base/browser/ui/splitview/paneview.ts index 8d310aefee9..dd943d0ed32 100644 --- a/src/vs/base/browser/ui/splitview/paneview.ts +++ b/src/vs/base/browser/ui/splitview/paneview.ts @@ -15,6 +15,7 @@ import { Color, RGBA } from 'vs/base/common/color'; import { SplitView, IView } from './splitview'; import { isFirefox } from 'vs/base/browser/browser'; import { DataTransfers } from 'vs/base/browser/dnd'; +import { Orientation } from 'vs/base/browser/ui/sash/sash'; import { localize } from 'vs/nls'; export interface IPaneOptions { @@ -49,6 +50,7 @@ export abstract class Pane extends Disposable implements IView { private body!: HTMLElement; protected _expanded: boolean; + protected _preventCollapse?: boolean; private expandedSize: number | undefined = undefined; private _headerVisible = true; @@ -184,20 +186,23 @@ export abstract class Pane extends Disposable implements IView { this.updateHeader(); - const onHeaderKeyDown = Event.chain(domEvent(this.header, 'keydown')) - .map(e => new StandardKeyboardEvent(e)); - this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space) - .event(() => this.setExpanded(!this.isExpanded()), null)); + if (!this._preventCollapse) { + const onHeaderKeyDown = Event.chain(domEvent(this.header, 'keydown')) + .map(e => new StandardKeyboardEvent(e)); - this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow) - .event(() => this.setExpanded(false), null)); + this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space) + .event(() => this.setExpanded(!this.isExpanded()), null)); - this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow) - .event(() => this.setExpanded(true), null)); + this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow) + .event(() => this.setExpanded(false), null)); - this._register(domEvent(this.header, 'click') - (() => this.setExpanded(!this.isExpanded()), null)); + this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow) + .event(() => this.setExpanded(true), null)); + + this._register(domEvent(this.header, 'click') + (() => this.setExpanded(!this.isExpanded()), null)); + } this.body = append(this.element, $('.pane-body')); this.renderBody(this.body); @@ -372,6 +377,7 @@ export class DefaultPaneDndController implements IPaneDndController { export interface IPaneViewOptions { dnd?: IPaneDndController; + orientation?: Orientation; } interface IPaneItem { @@ -387,6 +393,7 @@ export class PaneView extends Disposable { private paneItems: IPaneItem[] = []; private width: number = 0; private splitview: SplitView; + private orientation: Orientation; private animationTimer: number | undefined = undefined; private _onDidDrop = this._register(new Emitter<{ from: Pane, to: Pane }>()); @@ -398,8 +405,9 @@ export class PaneView extends Disposable { super(); this.dnd = options.dnd; + this.orientation = options.orientation ?? Orientation.VERTICAL; this.el = append(container, $('.monaco-pane-view')); - this.splitview = this._register(new SplitView(this.el)); + this.splitview = this._register(new SplitView(this.el, { orientation: this.orientation })); this.onDidSashChange = this.splitview.onDidSashChange; } @@ -472,7 +480,7 @@ export class PaneView extends Disposable { paneItem.pane.width = width; } - this.splitview.layout(height); + this.splitview.layout(this.orientation === Orientation.HORIZONTAL ? width : height); } private setupAnimation(): void { diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index f61a5326174..51c974473a4 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -81,7 +81,7 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop { if (targetCompositeId) { const destinationContainer = viewContainerRegistry.get(targetCompositeId); if (destinationContainer && !destinationContainer.rejectAddedViews) { - if (this.targetContainerLocation === ViewContainerLocation.Sidebar) { + if (this.targetContainerLocation === ViewContainerLocation.Sidebar || this.targetContainerLocation === ViewContainerLocation.Panel) { this.viewDescriptorService.moveViewsToContainer([viewDescriptor], destinationContainer); this.openComposite(targetCompositeId, true).then(composite => { if (composite) { diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index a5b9004ca72..b4f6d8b08bb 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -12,19 +12,19 @@ z-index: initial; } -.monaco-workbench .part.panel .title { +.monaco-workbench .part.panel .composite.title { height: 35px; display: flex; flex-direction: row; justify-content: space-between; } -.monaco-workbench .part.panel.bottom .title { +.monaco-workbench .part.panel.bottom .composite.title { border-top-width: 1px; border-top-style: solid; } -.monaco-workbench.noeditorarea .part.panel.bottom .title { +.monaco-workbench.noeditorarea .part.panel.bottom .composite.title { border-top-width: 0; /* no border when editor area is hiden */ } @@ -46,13 +46,13 @@ border-right-width: 0; /* no border when editor area is hiden */ } -.monaco-workbench .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label { +.monaco-workbench .part.panel > .composite.tit > .title-actions .monaco-action-bar .action-item .action-label { outline-offset: -2px; } /** Panel Switcher */ -.monaco-workbench .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.codicon-more { +.monaco-workbench .part.panel > .composite.tit > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.codicon-more { display: flex; align-items: center; justify-content: center; @@ -66,16 +66,16 @@ width: 100px; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar { line-height: 27px; /* matches panel titles in settings */ height: 35px; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:first-child { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .action-item:first-child { padding-left: 12px; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .action-item { text-transform: uppercase; padding-left: 10px; padding-right: 10px; @@ -85,24 +85,24 @@ display: flex; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item .action-label{ +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .action-item .action-label{ margin-right: 0; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:last-child { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .action-item:last-child { padding-right: 10px; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item.checked .action-label { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .action-item.checked .action-label { border-bottom: 1px solid; margin-right: 0; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .badge { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .badge { margin-left: 8px; } -.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .badge .badge-content { +.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar .badge .badge-content { padding: 3px 5px; border-radius: 11px; font-size: 11px; diff --git a/src/vs/workbench/browser/parts/views/media/paneviewlet.css b/src/vs/workbench/browser/parts/views/media/paneviewlet.css index fc7221b9eaa..9ec114b965a 100644 --- a/src/vs/workbench/browser/parts/views/media/paneviewlet.css +++ b/src/vs/workbench/browser/parts/views/media/paneviewlet.css @@ -19,3 +19,7 @@ -webkit-margin-before: 0; -webkit-margin-after: 0; } + +.monaco-pane-view .pane > .pane-header h3.title:first-child { + margin-left: 7px; +} diff --git a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts index 4ad5250ccf6..afc66e4979b 100644 --- a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts +++ b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts @@ -43,6 +43,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { Button } from 'vs/base/browser/ui/button/button'; import { Link } from 'vs/platform/opener/browser/link'; import { LocalSelectionTransfer } from 'vs/workbench/browser/dnd'; +import { Orientation } from 'vs/base/browser/ui/sash/sash'; export interface IPaneColors extends IColorMapping { dropBackground?: ColorIdentifier; @@ -210,6 +211,8 @@ export abstract class ViewPane extends Pane implements IView { this.title = options.title; this.showActionsAlways = !!options.showActionsAlways; this.focusedViewContextKey = FocusedViewContext.bindTo(contextKeyService); + this._preventCollapse = this.viewDescriptorService.getViewLocation(this.id) === ViewContainerLocation.Panel; + this._expanded = this._preventCollapse || this._expanded; this.menuActions = this._register(instantiationService.createInstance(ViewMenuActions, this.id, options.titleMenuId || MenuId.ViewTitle, MenuId.ViewTitleContext)); this._register(this.menuActions.onDidChangeTitle(() => this.updateActions())); @@ -265,7 +268,9 @@ export abstract class ViewPane extends Pane implements IView { protected renderHeader(container: HTMLElement): void { this.headerContainer = container; - this.renderTwisties(container); + if (!this._preventCollapse) { + this.renderTwisties(container); + } this.renderHeaderTitle(container, this.title); @@ -563,6 +568,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { } create(parent: HTMLElement): void { + const options = this.options as IPaneViewOptions; + options.orientation = this.viewDescriptorService.getViewContainerLocation(this.viewContainer) === ViewContainerLocation.Panel ? Orientation.HORIZONTAL : Orientation.VERTICAL; this.paneview = this._register(new PaneView(parent, this.options)); this._register(this.paneview.onDidDrop(({ from, to }) => this.movePane(from as ViewPane, to as ViewPane))); this._register(addDisposableListener(parent, EventType.CONTEXT_MENU, (e: MouseEvent) => this.showContextMenu(new StandardMouseEvent(e)))); @@ -836,8 +843,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { { id: viewDescriptor.id, title: viewDescriptor.name, - expanded: !collapsed, - minimumBodySize: this.viewDescriptorService.getViewContainerLocation(this.viewContainer) === ViewContainerLocation.Panel ? 0 : 120 + expanded: !collapsed }); pane.render(); From f20250c965233df0478f0a9b08750a41a8cc3ced Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 9 Mar 2020 13:57:49 -0700 Subject: [PATCH 121/137] Move version check into provideCompletionItems Handle TS version changes --- .../features/directiveCommentCompletions.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts index 8a33a76a5a8..cfa35571d1d 100644 --- a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts +++ b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts @@ -15,7 +15,7 @@ interface Directive { readonly description: string; } -const directives: Directive[] = [ +const tsDirectives: Directive[] = [ { value: '@ts-check', description: localize( @@ -34,8 +34,8 @@ const directives: Directive[] = [ } ]; -const directives390: Directive[] = [ - ...directives, +const tsDirectives390: Directive[] = [ + ...tsDirectives, { value: '@ts-expect-error', description: localize( @@ -45,15 +45,10 @@ const directives390: Directive[] = [ ]; class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvider { - private readonly directives: Directive[]; constructor( private readonly client: ITypeScriptServiceClient, - ) { - this.directives = client.apiVersion.gte(API.v390) - ? directives390 - : directives; - } + ) { } public provideCompletionItems( document: vscode.TextDocument, @@ -69,7 +64,11 @@ class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvide const prefix = line.slice(0, position.character); const match = prefix.match(/^\s*\/\/+\s?(@[a-zA-Z\-]*)?$/); if (match) { - return this.directives.map(directive => { + const directives = this.client.apiVersion.gte(API.v390) + ? tsDirectives390 + : tsDirectives; + + return directives.map(directive => { const item = new vscode.CompletionItem(directive.value, vscode.CompletionItemKind.Snippet); item.detail = directive.description; item.range = new vscode.Range(position.line, Math.max(0, position.character - (match[1] ? match[1].length : 0)), position.line, position.character); From a02ea6a1404a4ba2fe69715f08ffa427c86f9fa4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 9 Mar 2020 14:45:28 -0700 Subject: [PATCH 122/137] Preserve focus on custom editor rename Fixes #91862 --- src/vs/workbench/contrib/customEditor/browser/customEditors.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditors.ts b/src/vs/workbench/contrib/customEditor/browser/customEditors.ts index 4ea151ca353..30c7de0b5b8 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditors.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditors.ts @@ -326,6 +326,9 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ this.editorService.replaceEditors([{ editor: editor, replacement: replacement, + options: { + preserveFocus: true + } }], group); } } From f618e507fbeec9bc23e1a04cae63e767fb601b2d Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 9 Mar 2020 14:56:57 -0700 Subject: [PATCH 123/137] feat: enable appcenter support (#92295) * feat: update appcenter config (#92041) * fix: order of crash reporter initialization (#92044) * fix: create new guid for crash reporter (#92180) This id should never be sent to telemetry for GDPR reasons, hence we don't reuse any of existing persistent ids like instanceId etc. * chore: update distro --- package.json | 2 +- .../electron-main/electronMainService.ts | 5 ++- .../platform/product/common/productService.ts | 2 +- src/vs/platform/storage/node/storageIpc.ts | 12 ++++++- src/vs/platform/telemetry/common/telemetry.ts | 1 + src/vs/workbench/electron-browser/window.ts | 36 +++++++++++-------- 6 files changed, 39 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index ae6bcde9491..6fc79f7aba1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.44.0", - "distro": "25a85963f9a02a91afefd34ed1992872c800473a", + "distro": "07db0bb3dc2da82ce33f2871e0093df1b9085d06", "author": { "name": "Microsoft Corporation" }, diff --git a/src/vs/platform/electron/electron-main/electronMainService.ts b/src/vs/platform/electron/electron-main/electronMainService.ts index 27ef89f17e2..55e00cc725a 100644 --- a/src/vs/platform/electron/electron-main/electronMainService.ts +++ b/src/vs/platform/electron/electron-main/electronMainService.ts @@ -20,6 +20,7 @@ import { dirExists } from 'vs/base/node/pfs'; import { URI } from 'vs/base/common/uri'; import { ITelemetryData, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; export interface IElectronMainService extends AddFirstParameterToFunctions /* only methods, not events */, number | undefined /* window ID */> { } @@ -34,7 +35,8 @@ export class ElectronMainService implements IElectronMainService { @IDialogMainService private readonly dialogMainService: IDialogMainService, @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService, @IEnvironmentService private readonly environmentService: IEnvironmentService, - @ITelemetryService private readonly telemetryService: ITelemetryService + @ITelemetryService private readonly telemetryService: ITelemetryService, + @ILogService private readonly logService: ILogService ) { } @@ -392,6 +394,7 @@ export class ElectronMainService implements IElectronMainService { async startCrashReporter(windowId: number | undefined, options: CrashReporterStartOptions): Promise { crashReporter.start(options); + this.logService.trace('ElectronMainService#crashReporter', JSON.stringify(options)); } //#endregion diff --git a/src/vs/platform/product/common/productService.ts b/src/vs/platform/product/common/productService.ts index 798f9f42518..7624fe5f8d2 100644 --- a/src/vs/platform/product/common/productService.ts +++ b/src/vs/platform/product/common/productService.ts @@ -89,7 +89,7 @@ export interface IProductConfiguration { readonly checksums?: { [path: string]: string; }; readonly checksumFailMoreInfoUrl?: string; - readonly hockeyApp?: { + readonly appCenter?: { readonly 'win32-ia32': string; readonly 'win32-x64': string; readonly 'linux-x64': string; diff --git a/src/vs/platform/storage/node/storageIpc.ts b/src/vs/platform/storage/node/storageIpc.ts index a6f2367f355..94cc9a06577 100644 --- a/src/vs/platform/storage/node/storageIpc.ts +++ b/src/vs/platform/storage/node/storageIpc.ts @@ -12,7 +12,7 @@ import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; import { ILogService } from 'vs/platform/log/common/log'; import { generateUuid } from 'vs/base/common/uuid'; -import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey, currentSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; +import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey, currentSessionDateStorageKey, crashReporterIdStorageKey } from 'vs/platform/telemetry/common/telemetry'; type Key = string; type Value = string; @@ -54,6 +54,16 @@ export class GlobalStorageDatabaseChannel extends Disposable implements IServerC this.logService.error(error); } + // This is unique to the application instance and thereby + // should be written from the main process once. + // + // THIS SHOULD NEVER BE SENT TO TELEMETRY. + // + const crashReporterId = this.storageMainService.get(crashReporterIdStorageKey, undefined); + if (crashReporterId === undefined) { + this.storageMainService.store(crashReporterIdStorageKey, generateUuid()); + } + // Apply global telemetry values as part of the initialization // These are global across all windows and thereby should be // written from the main process once. diff --git a/src/vs/platform/telemetry/common/telemetry.ts b/src/vs/platform/telemetry/common/telemetry.ts index d1125e0ffb3..0bbc17972f5 100644 --- a/src/vs/platform/telemetry/common/telemetry.ts +++ b/src/vs/platform/telemetry/common/telemetry.ts @@ -45,3 +45,4 @@ export const instanceStorageKey = 'telemetry.instanceId'; export const currentSessionDateStorageKey = 'telemetry.currentSessionDate'; export const firstSessionDateStorageKey = 'telemetry.firstSessionDate'; export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; +export const crashReporterIdStorageKey = 'crashReporter.guid'; diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 6f7117b9068..776821d3cb4 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -6,14 +6,14 @@ import * as nls from 'vs/nls'; import { URI } from 'vs/base/common/uri'; import * as errors from 'vs/base/common/errors'; -import { equals, deepClone, assign } from 'vs/base/common/objects'; +import { equals, deepClone } from 'vs/base/common/objects'; import * as DOM from 'vs/base/browser/dom'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IAction } from 'vs/base/common/actions'; import { IFileService } from 'vs/platform/files/common/files'; import { toResource, IUntitledTextResourceEditorInput, SideBySideEditor, pathsToEditors } from 'vs/workbench/common/editor'; import { IEditorService, IResourceEditorInputType } from 'vs/workbench/services/editor/common/editorService'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ITelemetryService, crashReporterIdStorageKey } from 'vs/platform/telemetry/common/telemetry'; import { IWindowSettings, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest, IRunKeybindingInWindowRequest, getTitleBarStyle } from 'vs/platform/windows/common/windows'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; import { IWorkbenchThemeService, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; @@ -46,7 +46,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { MenubarControl } from '../browser/parts/titlebar/menubarControl'; import { ILabelService } from 'vs/platform/label/common/label'; import { IUpdateService } from 'vs/platform/update/common/update'; -import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IPreferencesService } from '../services/preferences/common/preferences'; import { IMenubarService, IMenubarData, IMenubarMenu, IMenubarKeybinding, IMenubarMenuItemSubmenu, IMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/node/menubar'; import { withNullAsUndefined, assertIsDefined } from 'vs/base/common/types'; @@ -104,7 +104,8 @@ export class NativeWindow extends Disposable { @ITunnelService private readonly tunnelService: ITunnelService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService, - @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService, + @IStorageService private readonly storageService: IStorageService, ) { super(); @@ -426,8 +427,8 @@ export class NativeWindow extends Disposable { this.updateTouchbarMenu(); // Crash reporter (if enabled) - if (!this.environmentService.disableCrashReporter && product.crashReporter && product.hockeyApp && this.configurationService.getValue('telemetry.enableCrashReporter')) { - this.setupCrashReporter(product.crashReporter.companyName, product.crashReporter.productName, product.hockeyApp); + if (!this.environmentService.disableCrashReporter && product.crashReporter && product.appCenter && this.configurationService.getValue('telemetry.enableCrashReporter')) { + this.setupCrashReporter(product.crashReporter.companyName, product.crashReporter.productName, product.appCenter); } } @@ -540,31 +541,36 @@ export class NativeWindow extends Disposable { } } - private async setupCrashReporter(companyName: string, productName: string, hockeyAppConfig: typeof product.hockeyApp): Promise { - if (!hockeyAppConfig) { + private async setupCrashReporter(companyName: string, productName: string, appCenterConfig: typeof product.appCenter): Promise { + if (!appCenterConfig) { return; } + const appCenterURL = isWindows ? appCenterConfig[process.arch === 'ia32' ? 'win32-ia32' : 'win32-x64'] + : isLinux ? appCenterConfig[`linux-x64`] : appCenterConfig.darwin; + const info = await this.telemetryService.getTelemetryInfo(); + const crashReporterId = this.storageService.get(crashReporterIdStorageKey, StorageScope.GLOBAL)!; + // base options with product info const options: CrashReporterStartOptions = { companyName, productName, - submitURL: isWindows ? hockeyAppConfig[process.arch === 'ia32' ? 'win32-ia32' : 'win32-x64'] : isLinux ? hockeyAppConfig[`linux-x64`] : hockeyAppConfig.darwin, + submitURL: appCenterURL.concat('&uid=', crashReporterId, '&iid=', crashReporterId, '&sid=', info.sessionId), extra: { vscode_version: product.version, vscode_commit: product.commit || '' } }; - // mixin telemetry info - const info = await this.telemetryService.getTelemetryInfo(); - assign(options.extra, { vscode_sessionId: info.sessionId }); + // start crash reporter in the main process first. + // On windows crashpad excepts a name pipe for the client to connect, + // this pipe is created by crash reporter initialization from the main process, + // changing this order of initialization will cause issues. + // For more info: https://chromium.googlesource.com/crashpad/crashpad/+/HEAD/doc/overview_design.md#normal-registration + await this.electronService.startCrashReporter(options); // start crash reporter right here crashReporter.start(deepClone(options)); - - // start crash reporter in the main process - return this.electronService.startCrashReporter(options); } private onAddFoldersRequest(request: IAddFoldersRequest): void { From 8cac8fc0f3ea1362b5f92da744f3e1f1b6097a02 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 9 Mar 2020 15:11:17 -0700 Subject: [PATCH 124/137] fix tests --- .../test/electron-browser/extensionsViews.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index 8347fcae927..9fd9263ac72 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -47,6 +47,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IMenuService } from 'vs/platform/actions/common/actions'; import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; +import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views'; suite('ExtensionsListView Tests', () => { @@ -138,6 +139,12 @@ suite('ExtensionsListView Tests', () => { instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage()); instantiationService.stubPromise(IExperimentService, 'getExperimentsByType', []); + instantiationService.stub(IViewDescriptorService, { + getViewLocation(): ViewContainerLocation { + return ViewContainerLocation.Sidebar; + } + }); + instantiationService.stub(IExtensionService, { getExtensions: (): Promise => { return Promise.resolve([ From adadbe271c086d8ceb029acb8fd1796c0e151fe1 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 9 Mar 2020 15:18:42 -0700 Subject: [PATCH 125/137] Add telemetry for trusted domains --- .../contrib/url/common/trustedDomains.ts | 73 ++++++++++++------- .../url/common/trustedDomainsValidator.ts | 28 ++++++- 2 files changed, 74 insertions(+), 27 deletions(-) diff --git a/src/vs/workbench/contrib/url/common/trustedDomains.ts b/src/vs/workbench/contrib/url/common/trustedDomains.ts index 7c28ccf7ce8..dc46dcaaadb 100644 --- a/src/vs/workbench/contrib/url/common/trustedDomains.ts +++ b/src/vs/workbench/contrib/url/common/trustedDomains.ts @@ -10,6 +10,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; const TRUSTED_DOMAINS_URI = URI.parse('trustedDomains:/Trusted Domains'); @@ -26,64 +27,86 @@ export const manageTrustedDomainSettingsCommand = { } }; +type ConfigureTrustedDomainChoice = 'trustDomain' | 'trustSubdomain' | 'trustAll' | 'manage'; +interface ConfigureTrustedDomainsQuickPickItem extends IQuickPickItem { + id: ConfigureTrustedDomainChoice; +} +type ConfigureTrustedDomainsChoiceClassification = { + choice: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; +}; + export async function configureOpenerTrustedDomainsHandler( trustedDomains: string[], domainToConfigure: string, quickInputService: IQuickInputService, storageService: IStorageService, - editorService: IEditorService + editorService: IEditorService, + telemetryService: ITelemetryService ) { const parsedDomainToConfigure = URI.parse(domainToConfigure); const toplevelDomainSegements = parsedDomainToConfigure.authority.split('.'); const domainEnd = toplevelDomainSegements.slice(toplevelDomainSegements.length - 2).join('.'); const topLevelDomain = '*.' + domainEnd; - const trustDomainAndOpenLinkItem: IQuickPickItem = { + const trustDomainAndOpenLinkItem: ConfigureTrustedDomainsQuickPickItem = { type: 'item', label: localize('trustedDomain.trustDomain', 'Trust {0}', domainToConfigure), - id: domainToConfigure, + id: 'trustDomain', picked: true }; - const trustSubDomainAndOpenLinkItem: IQuickPickItem = { + const trustSubDomainAndOpenLinkItem: ConfigureTrustedDomainsQuickPickItem = { type: 'item', label: localize('trustedDomain.trustSubDomain', 'Trust {0} and all its subdomains', domainEnd), - id: topLevelDomain + id: 'trustSubdomain' }; - const openAllLinksItem: IQuickPickItem = { + const openAllLinksItem: ConfigureTrustedDomainsQuickPickItem = { type: 'item', label: localize('trustedDomain.trustAllDomains', 'Trust all domains (disables link protection)'), - id: '*' + id: 'trustAll' }; - const manageTrustedDomainItem: IQuickPickItem = { + const manageTrustedDomainItem: ConfigureTrustedDomainsQuickPickItem = { type: 'item', label: localize('trustedDomain.manageTrustedDomains', 'Manage Trusted Domains'), id: 'manage' }; - const pickedResult = await quickInputService.pick( + const pickedResult = await quickInputService.pick( [trustDomainAndOpenLinkItem, trustSubDomainAndOpenLinkItem, openAllLinksItem, manageTrustedDomainItem], { activeItem: trustDomainAndOpenLinkItem } ); - if (pickedResult) { - if (pickedResult.id === 'manage') { - editorService.openEditor({ - resource: TRUSTED_DOMAINS_URI, - mode: 'jsonc' - }); - return trustedDomains; - } - if (pickedResult.id && trustedDomains.indexOf(pickedResult.id) === -1) { - storageService.remove('http.linkProtectionTrustedDomainsContent', StorageScope.GLOBAL); - storageService.store( - 'http.linkProtectionTrustedDomains', - JSON.stringify([...trustedDomains, pickedResult.id]), - StorageScope.GLOBAL - ); + if (pickedResult && pickedResult.id) { + telemetryService.publicLog2<{ choice: string }, ConfigureTrustedDomainsChoiceClassification>( + 'trustedDomains.configureTrustedDomainsQuickPickChoice', + { choice: pickedResult.id } + ); - return [...trustedDomains, pickedResult.id]; + switch (pickedResult.id) { + case 'manage': + editorService.openEditor({ + resource: TRUSTED_DOMAINS_URI, + mode: 'jsonc' + }); + return trustedDomains; + case 'trustDomain': + case 'trustSubdomain': + case 'trustAll': + const itemToTrust = pickedResult.id === 'trustDomain' + ? domainToConfigure + : pickedResult.id === 'trustSubdomain' ? topLevelDomain : '*'; + + if (trustedDomains.indexOf(itemToTrust) === -1) { + storageService.remove('http.linkProtectionTrustedDomainsContent', StorageScope.GLOBAL); + storageService.store( + 'http.linkProtectionTrustedDomains', + JSON.stringify([...trustedDomains, itemToTrust]), + StorageScope.GLOBAL + ); + + return [...trustedDomains, pickedResult.id]; + } } } diff --git a/src/vs/workbench/contrib/url/common/trustedDomainsValidator.ts b/src/vs/workbench/contrib/url/common/trustedDomainsValidator.ts index d8b03dc04d0..3862d4fb66d 100644 --- a/src/vs/workbench/contrib/url/common/trustedDomainsValidator.ts +++ b/src/vs/workbench/contrib/url/common/trustedDomainsValidator.ts @@ -19,7 +19,11 @@ import { } from 'vs/workbench/contrib/url/common/trustedDomains'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +type TrustedDomainsDialogActionClassification = { + action: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; +}; export class OpenerValidatorContributions implements IWorkbenchContribution { constructor( @@ -29,7 +33,8 @@ export class OpenerValidatorContributions implements IWorkbenchContribution { @IProductService private readonly _productService: IProductService, @IQuickInputService private readonly _quickInputService: IQuickInputService, @IEditorService private readonly _editorService: IEditorService, - @IClipboardService private readonly _clipboardService: IClipboardService + @IClipboardService private readonly _clipboardService: IClipboardService, + @ITelemetryService private readonly _telemetryService: ITelemetryService ) { this._openerService.registerValidator({ shouldOpen: r => this.validateLink(r) }); } @@ -88,20 +93,34 @@ export class OpenerValidatorContributions implements IWorkbenchContribution { // Open Link if (choice === 0) { + this._telemetryService.publicLog2<{ action: string }, TrustedDomainsDialogActionClassification>( + 'trustedDomains.dialogAction', + { action: 'open' } + ); return true; } // Copy Link else if (choice === 1) { + this._telemetryService.publicLog2<{ action: string }, TrustedDomainsDialogActionClassification>( + 'trustedDomains.dialogAction', + { action: 'copy' } + ); this._clipboardService.writeText(resource.toString(true)); } // Configure Trusted Domains else if (choice === 3) { + this._telemetryService.publicLog2<{ action: string }, TrustedDomainsDialogActionClassification>( + 'trustedDomains.dialogAction', + { action: 'configure' } + ); + const pickedDomains = await configureOpenerTrustedDomainsHandler( trustedDomains, domainToOpen, this._quickInputService, this._storageService, - this._editorService + this._editorService, + this._telemetryService ); // Trust all domains if (pickedDomains.indexOf('*') !== -1) { @@ -114,6 +133,11 @@ export class OpenerValidatorContributions implements IWorkbenchContribution { return false; } + this._telemetryService.publicLog2<{ action: string }, TrustedDomainsDialogActionClassification>( + 'trustedDomains.dialogAction', + { action: 'cancel' } + ); + return false; } } From 033a5d476f0bcaef47178231b946462eedb64916 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 9 Mar 2020 15:46:55 -0700 Subject: [PATCH 126/137] Add a `revert` method for custom editors Fixes #91700 For #77131 Having an explicit revert method is a helpful signal that the extension should reload the changes from disk --- src/vs/vscode.proposed.d.ts | 14 +++++++++++++- src/vs/workbench/api/common/extHostWebview.ts | 13 ++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index b4c379c9227..ee599836346 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1278,7 +1278,7 @@ declare module 'vscode' { /** * Undo a set of edits. * - * This is triggered when a user undoes an edit or when revert is called on a file. + * This is triggered when a user undoes an edit. * * @param edit Array of edits. Sorted from most recent to oldest. * @@ -1286,6 +1286,18 @@ declare module 'vscode' { */ undoEdits(edits: readonly EditType[]): Thenable; + /** + * Revert the file to its last saved state. + * + * @param change Added or applied edits. + * + * @return Thenable signaling that the change has completed. + */ + revert(change: { + readonly undoneEdits: readonly EditType[]; + readonly appliedEdits: readonly EditType[]; + }): Thenable; + /** * Back up the resource in its current state. * diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index bdb51f8977c..86588547cd2 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -303,23 +303,26 @@ class CustomDocument extends Disposable implements vscode.CustomDocument { }); } - /** @internal*/ _revert() { + /** @internal*/ async _revert() { const editing = this.getEditingCapability(); if (this.#currentEditIndex === this.#savePoint) { return true; } + + let undoneEdits: EditType[] = []; + let appliedEdits: EditType[] = []; if (this.#currentEditIndex >= this.#savePoint) { - const editsToUndo = this.#edits.slice(this.#savePoint, this.#currentEditIndex); - editing.undoEdits(editsToUndo.reverse()); + undoneEdits = this.#edits.slice(this.#savePoint, this.#currentEditIndex).reverse(); } else if (this.#currentEditIndex < this.#savePoint) { - const editsToRedo = this.#edits.slice(this.#currentEditIndex, this.#savePoint); - editing.applyEdits(editsToRedo); + appliedEdits = this.#edits.slice(this.#currentEditIndex, this.#savePoint); } this.#currentEditIndex = this.#savePoint; this.spliceEdits(); + await editing.revert({ undoneEdits, appliedEdits }); + this.updateState(); return true; } From ffcd280b5382e89571e16b17c7157de0ed925b7f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 9 Mar 2020 16:41:02 -0700 Subject: [PATCH 127/137] Improving documentation on webviews Fixes #91656 --- src/vs/vscode.d.ts | 28 ++++++++++++++++++++++++---- src/vs/vscode.proposed.d.ts | 29 +++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 6ba87f6803a..53826e67839 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -6325,7 +6325,7 @@ declare module 'vscode' { } /** - * A webview displays html content, like an iframe. + * Displays html content, similarly to an iframe. */ export interface Webview { /** @@ -6334,9 +6334,29 @@ declare module 'vscode' { options: WebviewOptions; /** - * Contents of the webview. + * HTML contents of the webview. * - * Should be a complete html document. + * This should be a complete, valid html document. Changing this property causes the webview to be reloaded. + * + * Webviews are sandboxed from normal extension process, so all communication with the webview must use + * message passing. To send a message from the extension to the webview, use [`postMessage`](#Webview.postMessage). + * To send message from the webview back to an extension, use the `acquireVsCodeApi` function inside the webview + * to get a handle to VS Code's api and then call `.postMessage()`: + * + * ```html + * + * ``` + * + * To load a resources from the workspace inside a webview, use the `[asWebviewUri](#Webview.asWebviewUri)` method + * and ensure the resource's directory is listed in [`WebviewOptions.localResourceRoots`](#WebviewOptions.localResourceRoots). + * + * Keep in mind that even though webviews are sandboxed, they still allow running scripts and loading arbitrary content, + * so extensions must follow all standard web security best practices when working with webviews. This includes + * properly sanitizing all untrusted input (including content from the workspace) and + * setting a [content security policy](https://aka.ms/vscode-api-webview-csp). */ html: string; @@ -6434,7 +6454,7 @@ declare module 'vscode' { iconPath?: Uri | { light: Uri; dark: Uri }; /** - * Webview belonging to the panel. + * [`Webview`](#Webview) belonging to the panel. */ readonly webview: Webview; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ee599836346..9adb13c95fc 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1320,10 +1320,10 @@ declare module 'vscode' { } /** - * Represents a custom document for a custom webview editor. + * Represents a custom document used by a `CustomEditorProvider`. * * Custom documents are only used within a given `CustomEditorProvider`. The lifecycle of a - * `CustomDocument` is managed by VS Code. When more more references remain to a given `CustomDocument` + * `CustomDocument` is managed by VS Code. When no more references remain to a given `CustomDocument`, * then it is disposed of. * * @param UserDataType Type of custom object that extensions can store on the document. @@ -1366,6 +1366,11 @@ declare module 'vscode' { /** * Resolve the model for a given resource. * + * `resolveCustomDocument` is called when the first editor for a given resource is opened, and the resolve document + * is passed to `resolveCustomEditor`. The resolved `CustomDocument` is re-used for subsequent editor opens. + * If all editors for a given resource are closed, the `CustomDocument` is disposed of. Opening an editor at + * this point will trigger another call to `resolveCustomDocument`. + * * @param document Document to resolve. * * @return The capabilities of the resolved document. @@ -1375,11 +1380,15 @@ declare module 'vscode' { /** * Resolve a webview editor for a given resource. * + * This is called when a user first opens a resource for a `CustomTextEditorProvider`, or if they reopen an + * existing editor using this `CustomTextEditorProvider`. + * * To resolve a webview editor, the provider must fill in its initial html content and hook up all - * the event listeners it is interested it. The provider should also take ownership of the passed in `WebviewPanel`. + * the event listeners it is interested it. The provider can also hold onto the `WebviewPanel` to use later, + * for example in a command. See [`WebviewPanel`](#WebviewPanel) for additional details * * @param document Document for the resource being resolved. - * @param webviewPanel Webview to resolve. The provider should take ownership of this webview. + * @param webviewPanel Webview to resolve. * * @return Thenable indicating that the webview editor has been resolved. */ @@ -1398,13 +1407,17 @@ declare module 'vscode' { */ export interface CustomTextEditorProvider { /** - * Resolve a webview editor for a given resource. + * Resolve a webview editor for a given text resource. + * + * This is called when a user first opens a resource for a `CustomTextEditorProvider`, or if they reopen an + * existing editor using this `CustomTextEditorProvider`. * * To resolve a webview editor, the provider must fill in its initial html content and hook up all - * the event listeners it is interested it. The provider should also take ownership of the passed in `WebviewPanel`. + * the event listeners it is interested it. The provider can also hold onto the `WebviewPanel` to use later, + * for example in a command. See [`WebviewPanel`](#WebviewPanel) for additional details. * - * @param document Resource being resolved. - * @param webviewPanel Webview to resolve. The provider should take ownership of this webview. + * @param document Document for the resource to resolve. + * @param webviewPanel Webview to resolve. * * @return Thenable indicating that the webview editor has been resolved. */ From b419081bbcc0524ababd3cbf1ef3ea3865778be8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 10 Mar 2020 07:58:04 +0100 Subject: [PATCH 128/137] reuse telemetry constants (#92099) --- src/vs/code/electron-main/app.ts | 14 +++++--------- .../telemetry/browser/workbenchCommonProperties.ts | 8 +------- src/vs/platform/telemetry/common/telemetry.ts | 2 ++ 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index cda40703e32..6bc5a5e62f6 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -26,7 +26,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IURLService } from 'vs/platform/url/common/url'; import { URLHandlerChannelClient, URLHandlerRouter } from 'vs/platform/url/common/urlIpc'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ITelemetryService, machineIdKey, trueMachineIdKey } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; @@ -79,10 +79,6 @@ import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv'; import { coalesce } from 'vs/base/common/arrays'; export class CodeApplication extends Disposable { - - private static readonly MACHINE_ID_KEY = 'telemetry.machineId'; - private static readonly TRUE_MACHINE_ID_KEY = 'telemetry.trueMachineId'; - private windowsMainService: IWindowsMainService | undefined; private dialogMainService: IDialogMainService | undefined; @@ -407,21 +403,21 @@ export class CodeApplication extends Disposable { // We cache the machineId for faster lookups on startup // and resolve it only once initially if not cached - let machineId = this.stateService.getItem(CodeApplication.MACHINE_ID_KEY); + let machineId = this.stateService.getItem(machineIdKey); if (!machineId) { machineId = await getMachineId(); - this.stateService.setItem(CodeApplication.MACHINE_ID_KEY, machineId); + this.stateService.setItem(machineIdKey, machineId); } // Check if machineId is hashed iBridge Device let trueMachineId: string | undefined; if (isMacintosh && machineId === '6c9d2bc8f91b89624add29c0abeae7fb42bf539fa1cdb2e3e57cd668fa9bcead') { - trueMachineId = this.stateService.getItem(CodeApplication.TRUE_MACHINE_ID_KEY); + trueMachineId = this.stateService.getItem(trueMachineIdKey); if (!trueMachineId) { trueMachineId = await getMachineId(); - this.stateService.setItem(CodeApplication.TRUE_MACHINE_ID_KEY, trueMachineId); + this.stateService.setItem(trueMachineIdKey, trueMachineId); } } diff --git a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts index b798518500b..ff1f99715e0 100644 --- a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts @@ -4,17 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; - -export const instanceStorageKey = 'telemetry.instanceId'; -export const currentSessionDateStorageKey = 'telemetry.currentSessionDate'; -export const firstSessionDateStorageKey = 'telemetry.firstSessionDate'; -export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; -export const machineIdKey = 'telemetry.machineId'; - import * as Platform from 'vs/base/common/platform'; import * as uuid from 'vs/base/common/uuid'; import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtils'; import { mixin } from 'vs/base/common/objects'; +import { firstSessionDateStorageKey, lastSessionDateStorageKey, machineIdKey } from 'vs/platform/telemetry/common/telemetry'; export async function resolveWorkbenchCommonProperties( storageService: IStorageService, diff --git a/src/vs/platform/telemetry/common/telemetry.ts b/src/vs/platform/telemetry/common/telemetry.ts index 0bbc17972f5..07ad8719c7e 100644 --- a/src/vs/platform/telemetry/common/telemetry.ts +++ b/src/vs/platform/telemetry/common/telemetry.ts @@ -45,4 +45,6 @@ export const instanceStorageKey = 'telemetry.instanceId'; export const currentSessionDateStorageKey = 'telemetry.currentSessionDate'; export const firstSessionDateStorageKey = 'telemetry.firstSessionDate'; export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; +export const machineIdKey = 'telemetry.machineId'; +export const trueMachineIdKey = 'telemetry.trueMachineId'; export const crashReporterIdStorageKey = 'crashReporter.guid'; From 365d341e9dea3cf24cc8806dc3db6efcf76aad66 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 10 Mar 2020 08:37:04 +0100 Subject: [PATCH 129/137] Fixes #65815 --- src/vs/editor/common/controller/cursorMoveCommands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/controller/cursorMoveCommands.ts b/src/vs/editor/common/controller/cursorMoveCommands.ts index 759ad0e19fd..8545cb2a485 100644 --- a/src/vs/editor/common/controller/cursorMoveCommands.ts +++ b/src/vs/editor/common/controller/cursorMoveCommands.ts @@ -411,7 +411,7 @@ export class CursorMoveCommands { let newViewState = MoveOperations.moveLeft(context.config, context.viewModel, cursor.viewState, inSelectionMode, noOfColumns); - if (noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) { + if (!cursor.viewState.hasSelection() && noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) { // moved over to the previous view line const newViewModelPosition = context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(newViewState.position); if (newViewModelPosition.lineNumber === cursor.modelState.position.lineNumber) { @@ -442,7 +442,7 @@ export class CursorMoveCommands { const cursor = cursors[i]; let newViewState = MoveOperations.moveRight(context.config, context.viewModel, cursor.viewState, inSelectionMode, noOfColumns); - if (noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) { + if (!cursor.viewState.hasSelection() && noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) { // moved over to the next view line const newViewModelPosition = context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(newViewState.position); if (newViewModelPosition.lineNumber === cursor.modelState.position.lineNumber) { From 2697ae50402a713965cf075054cc309378959a0c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 10 Mar 2020 08:39:32 +0100 Subject: [PATCH 130/137] web - guard against creating workbench more than once --- src/vs/workbench/workbench.web.api.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 9f18e7bf59d..8aa59dc7659 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -230,8 +230,17 @@ interface IWorkbenchConstructionOptions { * @param domElement the container to create the workbench in * @param options for setting up the workbench */ +let created = false; async function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise { + // Assert that the workbench is not created more than once. We currently + // do not support this and require a full context switch to clean-up. + if (created) { + throw new Error('Unable to create the VSCode workbench more than once.'); + } else { + created = true; + } + // Startup workbench await main(domElement, options); From 888c94400b48d96ee56efa94c62d1c9c3c4886cf Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 10 Mar 2020 09:19:38 +0100 Subject: [PATCH 131/137] Fixes #71134: Handle numpad on macOS --- .../keybinding/browser/keybindingService.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index 42dfc300992..1bd4e2d252e 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -11,7 +11,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { Keybinding, ResolvedKeybinding, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeybindingParser } from 'vs/base/common/keybindingParser'; -import { OS, OperatingSystem } from 'vs/base/common/platform'; +import { OS, OperatingSystem, isMacintosh } from 'vs/base/common/platform'; import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Extensions as ConfigExtensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; @@ -161,6 +161,18 @@ const NUMPAD_PRINTABLE_SCANCODES = [ ScanCode.NumpadDecimal ]; +const otherMacNumpadMapping = new Map(); +otherMacNumpadMapping.set(ScanCode.Numpad1, KeyCode.KEY_1); +otherMacNumpadMapping.set(ScanCode.Numpad2, KeyCode.KEY_2); +otherMacNumpadMapping.set(ScanCode.Numpad3, KeyCode.KEY_3); +otherMacNumpadMapping.set(ScanCode.Numpad4, KeyCode.KEY_4); +otherMacNumpadMapping.set(ScanCode.Numpad5, KeyCode.KEY_5); +otherMacNumpadMapping.set(ScanCode.Numpad6, KeyCode.KEY_6); +otherMacNumpadMapping.set(ScanCode.Numpad7, KeyCode.KEY_7); +otherMacNumpadMapping.set(ScanCode.Numpad8, KeyCode.KEY_8); +otherMacNumpadMapping.set(ScanCode.Numpad9, KeyCode.KEY_9); +otherMacNumpadMapping.set(ScanCode.Numpad0, KeyCode.KEY_0); + export class WorkbenchKeybindingService extends AbstractKeybindingService { private _keyboardMapper: IKeyboardMapper; @@ -589,6 +601,10 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { // NumLock is on or this is /, *, -, + on the numpad return true; } + if (isMacintosh && event.keyCode === otherMacNumpadMapping.get(code)) { + // on macOS, the numpad keys can also map to keys 1 - 0. + return true; + } return false; } From a5770c6c4396520dfbab0eb5180e4f1a0e80c034 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 10 Mar 2020 09:27:12 +0100 Subject: [PATCH 132/137] quick access - add a reusable quickPickItemScorerAccessor --- .../parts/quickinput/common/quickInput.ts | 27 +++++++++ .../browser/parts/editor/editorQuickAccess.ts | 56 ++++++++----------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index 9a844ac255f..7a7d14cb0c6 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -8,6 +8,8 @@ import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IMatch } from 'vs/base/common/filters'; +import { IItemAccessor } from 'vs/base/common/fuzzyScorer'; +import { Schemas } from 'vs/base/common/network'; export interface IQuickPickItemHighlights { label?: IMatch[]; @@ -272,3 +274,28 @@ export interface IQuickPickItemButtonContext extends I } export type QuickPickInput = T | IQuickPickSeparator; + + +//region Fuzzy Scorer Support + +export type IQuickPickItemWithResource = IQuickPickItem & { resource: URI | undefined }; + +export const quickPickItemScorerAccessor = new class implements IItemAccessor { + getItemLabel(entry: IQuickPickItemWithResource): string { + return entry.label; + } + + getItemDescription(entry: IQuickPickItemWithResource): string | undefined { + return entry.description; + } + + getItemPath(entry: IQuickPickItemWithResource): string | undefined { + if (entry.resource?.scheme === Schemas.file) { + return entry.resource.fsPath; + } + + return entry.resource?.path; + } +}; + +//#endregion diff --git a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts index 8a8ae3937ae..44b9bb08329 100644 --- a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts +++ b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { IQuickPick, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickPick, IQuickPickSeparator, quickPickItemScorerAccessor, IQuickPickItemWithResource } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { IQuickAccessProvider } from 'vs/platform/quickinput/common/quickAccess'; @@ -14,34 +14,17 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; -import { prepareQuery, IPreparedQuery, ScorerCache, scoreItem, compareItemsByScore, IItemAccessor } from 'vs/base/common/fuzzyScorer'; -import { Schemas } from 'vs/base/common/network'; +import { prepareQuery, IPreparedQuery, ScorerCache, scoreItem, compareItemsByScore } from 'vs/base/common/fuzzyScorer'; +import { URI } from 'vs/base/common/uri'; -interface IEditorQuickPickItem extends IQuickPickItem, IEditorIdentifier { } +interface IEditorQuickPickItem extends IQuickPickItemWithResource, IEditorIdentifier { + resource: URI | undefined; +} export abstract class BaseEditorQuickAccessProvider implements IQuickAccessProvider { protected abstract readonly prefix: string; - private editorQuickPickScoringAccessor = new class implements IItemAccessor { - getItemLabel(entry: IEditorQuickPickItem): string | undefined { - return entry.label; - } - - getItemDescription(entry: IEditorQuickPickItem): string | undefined { - return entry.description; - } - - getItemPath(entry: IEditorQuickPickItem): string | undefined { - const resource = toResource(entry.editor, { supportSideBySide: SideBySideEditor.MASTER }); - if (resource?.scheme === Schemas.file) { - return resource?.fsPath; - } - - return resource?.path; - } - }; - constructor( @IEditorGroupsService protected readonly editorGroupService: IEditorGroupsService, @IEditorService protected readonly editorService: IEditorService, @@ -81,7 +64,7 @@ export abstract class BaseEditorQuickAccessProvider implements IQuickAccessProvi } // Score on label and description - const itemScore = scoreItem(entry, query, true, this.editorQuickPickScoringAccessor, scorerCache); + const itemScore = scoreItem(entry, query, true, quickPickItemScorerAccessor, scorerCache); if (!itemScore.score) { return false; } @@ -100,7 +83,7 @@ export abstract class BaseEditorQuickAccessProvider implements IQuickAccessProvi return groups.indexOf(entryA.groupId) - groups.indexOf(entryB.groupId); // older groups first } - return compareItemsByScore(entryA, entryB, query, true, this.editorQuickPickScoringAccessor, scorerCache); + return compareItemsByScore(entryA, entryB, query, true, quickPickItemScorerAccessor, scorerCache); }); } @@ -127,15 +110,20 @@ export abstract class BaseEditorQuickAccessProvider implements IQuickAccessProvi } private doGetEditorPickItems(): Array { - return this.doGetEditors().map(({ editor, groupId }) => ({ - editor, - groupId, - label: editor.isDirty() && !editor.isSaving() ? `$(circle-filled) ${editor.getName()}` : editor.getName(), - ariaLabel: localize('entryAriaLabel', "{0}, editor picker", editor.getName()), - description: editor.getDescription(), - iconClasses: getIconClasses(this.modelService, this.modeService, toResource(editor, { supportSideBySide: SideBySideEditor.MASTER })), - italic: !this.editorGroupService.getGroup(groupId)?.isPinned(editor) - })); + return this.doGetEditors().map(({ editor, groupId }) => { + const resource = toResource(editor, { supportSideBySide: SideBySideEditor.MASTER }); + + return { + editor, + groupId, + resource, + label: editor.isDirty() && !editor.isSaving() ? `$(circle-filled) ${editor.getName()}` : editor.getName(), + ariaLabel: localize('entryAriaLabel', "{0}, editor picker", editor.getName()), + description: editor.getDescription(), + iconClasses: getIconClasses(this.modelService, this.modeService, resource), + italic: !this.editorGroupService.getGroup(groupId)?.isPinned(editor) + }; + }); } protected abstract doGetEditors(): IEditorIdentifier[]; From 9f802b22fc57c39ff6bd2c2878a1cb3e668c4e3f Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 10 Mar 2020 09:48:17 +0100 Subject: [PATCH 133/137] icon theme switches back to default on start --- .../workbench/services/themes/browser/workbenchThemeService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 47a3e6a33be..6f0d33b6f84 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -180,7 +180,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.fileIconThemeRegistry.onDidChange(async event => { updateFileIconThemeConfigurationSchemas(event.themes); - if (!await this.restoreFileIconTheme()) { // checks if theme from settings exists and is set + if (await this.restoreFileIconTheme()) { // checks if theme from settings exists and is set // restore theme if (this.currentFileIconTheme.id === DEFAULT_FILE_ICON_THEME_ID && !types.isUndefined(prevFileIconId) && await this.fileIconThemeRegistry.findThemeById(prevFileIconId)) { this.setFileIconTheme(prevFileIconId, 'auto'); From 0e10a3cbd14baf38f52899a2f61c8126c1a863da Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 10 Mar 2020 10:01:02 +0100 Subject: [PATCH 134/137] use editor action, some polish --- .../contrib/codelens/codelensController.ts | 89 +++++++++++-------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 0a1538a6455..84f1ac852c1 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -8,10 +8,10 @@ import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/err import { toDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { StableEditorScrollState } from 'vs/editor/browser/core/editorState'; import { ICodeEditor, MouseTargetType, IViewZoneChangeAccessor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; -import { registerEditorContribution, EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { registerEditorContribution, ServicesAccessor, registerEditorAction, EditorAction } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; -import { CodeLensProviderRegistry, CodeLens } from 'vs/editor/common/modes'; +import { CodeLensProviderRegistry, CodeLens, Command } from 'vs/editor/common/modes'; import { CodeLensModel, getCodeLensData, CodeLensItem } from 'vs/editor/contrib/codelens/codelens'; import { CodeLensWidget, CodeLensHelper } from 'vs/editor/contrib/codelens/codelensWidget'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -20,7 +20,9 @@ import { ICodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import * as dom from 'vs/base/browser/dom'; import { hash } from 'vs/base/common/hash'; -import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { localize } from 'vs/nls'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; export class CodeLensContribution implements IEditorContribution { @@ -404,52 +406,69 @@ export class CodeLensContribution implements IEditorContribution { }); } - public getLenses(): CodeLensWidget[] { + getLenses(): readonly CodeLensWidget[] { return this._lenses; } } -export class ShowLensesInCurrentLineCommand extends EditorCommand { - public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Promise { +registerEditorContribution(CodeLensContribution.ID, CodeLensContribution); + +registerEditorAction(class ShowLensesInCurrentLine extends EditorAction { + + constructor() { + super({ + id: 'codelens.showLensesInCurrentLine', + precondition: EditorContextKeys.hasCodeLensProvider, + label: localize('showLensOnLine', "Show Code Lens Command For Current Line"), + alias: 'Show Code Lens Commands For Current Line', + }); + } + + async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { + + if (!editor.hasModel()) { + return; + } + const quickInputService = accessor.get(IQuickInputService); const commandService = accessor.get(ICommandService); const notificationService = accessor.get(INotificationService); - const lineNumber = editor.getSelection()?.positionLineNumber; - const codelensController = editor.getContribution(CodeLensContribution.ID) as CodeLensContribution; + const lineNumber = editor.getSelection().positionLineNumber; + const codelensController = editor.getContribution(CodeLensContribution.ID); + const items: { label: string, command: Command }[] = []; - const activeLensesWidgets = codelensController.getLenses().filter(lens => lens.getLineNumber() === lineNumber); - - const commandArguments: Map = new Map(); - - const items: (IQuickPickItem | IQuickPickSeparator)[] = []; - - activeLensesWidgets.forEach(widget => { - widget.getItems().forEach(codelens => { - const command = codelens.symbol.command; - if (!command) { - return; + for (let lens of codelensController.getLenses()) { + if (lens.getLineNumber() === lineNumber) { + for (let item of lens.getItems()) { + const { command } = item.symbol; + if (command) { + items.push({ + label: command.title, + command: command + }); + } } - items.push({ id: command.id, label: command.title }); + } + } - commandArguments.set(command.id, command.arguments); - }); - }); - - // We dont want an empty picker - if (!items.length) { + if (items.length === 0) { + // We dont want an empty picker return; } - quickInputService.pick(items, { canPickMany: false }).then(item => { - const id = item.id!; - commandService.executeCommand(id, ...(commandArguments.get(id) || [])).catch(err => notificationService.error(err)); - }); + const item = await quickInputService.pick(items, { canPickMany: false }); + if (!item) { + // Nothing picked + return; + } + + try { + await commandService.executeCommand(item.command.id, ...(item.command.arguments || [])); + } catch (err) { + notificationService.error(err); + } } +}); -} -registerEditorContribution(CodeLensContribution.ID, CodeLensContribution); - -const showLensesInCurrentLineCommand = new ShowLensesInCurrentLineCommand({ id: 'codelens.showLensesInCurrentLine', precondition: undefined }); -showLensesInCurrentLineCommand.register(); From c91e2b62d707edb5913767726e853e50a0ed3aa3 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 10 Mar 2020 10:11:48 +0100 Subject: [PATCH 135/137] debug integration: make sure to clear out session on retry --- .../src/singlefolder-tests/debug.test.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/debug.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/debug.test.ts index 0bf0eb23934..be3509a2bfa 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/debug.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/debug.test.ts @@ -39,14 +39,23 @@ suite('Debug', function () { this.retries(2); test('start debugging', async function () { - assert.equal(debug.activeDebugSession, undefined); let stoppedEvents = 0; let variablesReceived: () => void; let initializedReceived: () => void; let configurationDoneReceived: () => void; + const toDispose: Disposable[] = []; + if (debug.activeDebugSession) { + // We are re-running due to flakyness, make sure to clear out state + let sessionTerminatedRetry: () => void; + toDispose.push(debug.onDidTerminateDebugSession(() => { + sessionTerminatedRetry(); + })); + const sessionTerminatedPromise = new Promise(resolve => sessionTerminatedRetry = resolve); + await commands.executeCommand('workbench.action.debug.stop'); + await sessionTerminatedPromise; + } const firstVariablesRetrieved = new Promise(resolve => variablesReceived = resolve); - const toDispose: Disposable[] = []; toDispose.push(debug.registerDebugAdapterTrackerFactory('*', { createDebugAdapterTracker: () => ({ onDidSendMessage: m => { From 539a102fba1212f89ccbc9b04d91440e87d025b1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 10 Mar 2020 10:35:02 +0100 Subject: [PATCH 136/137] expose `joinPaths` as proposed API, https://github.com/microsoft/vscode/issues/90208 --- src/vs/vscode.proposed.d.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 9adb13c95fc..75ab9e81145 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1807,5 +1807,21 @@ declare module 'vscode' { readonly code?: string; } - ////#endregion + //#endregion + + + //#region https://github.com/microsoft/vscode/issues/90208 + + export namespace Uri { + + /** + * + * @param base + * @param pathFragments + * @returns A new uri + */ + export function joinPaths(base: Uri, ...pathFragments: string[]): Uri; + } + + //#endregion } From 12a725842b49806f43a09762de849a9ff8676a5d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 10 Mar 2020 10:38:02 +0100 Subject: [PATCH 137/137] fix outDir to enable tsc-selfhosting, https://github.com/microsoft/vscode/issues/91503 --- src/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tsconfig.json b/src/tsconfig.json index 9419d9af0f4..5a2784b630f 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -4,7 +4,7 @@ "removeComments": false, "preserveConstEnums": true, "sourceMap": false, - "outDir": "../out", + "outDir": "../out/vs", "target": "es2017", "types": [ "keytar",