diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 34edacfa967..addf36f4339 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -3,7 +3,7 @@ name: Bug report
about: Create a report to help us improve
---
-
+
diff --git a/.github/calendar.yml b/.github/calendar.yml
index 9b86376e5a0..307c3db379a 100644
--- a/.github/calendar.yml
+++ b/.github/calendar.yml
@@ -29,5 +29,7 @@
'2018-08-27 18:00, US/Pacific': 'endgame',
'2018-09-05 12:00, US/Pacific': 'development', # 1.27.0 released
'2018-09-24 18:00, US/Pacific': 'endgame',
-# '2018-10-03 12:00, US/Pacific': 'development', # 1.28.0 released
+ '2018-10-08 09:00, US/Pacific': 'development', # 1.28.0 released
+ '2018-10-29 18:00, US/Pacific': 'endgame',
+ # '2018-11-07 09:00, US/Pacific': 'development', # 1.29.0 released
}
diff --git a/.github/classifier.yml b/.github/classifier.yml
index eba4910f445..07b85720764 100644
--- a/.github/classifier.yml
+++ b/.github/classifier.yml
@@ -15,7 +15,7 @@
css-less-scss: [ aeschli ],
debug-console: [],
debug: {
- assignees: [ isidorn ],
+ assignees: [ weinand ],
assignLabel: false
},
diff-editor: [],
@@ -78,10 +78,10 @@
formatting: [],
git: [ joaomoreno ],
grammar: [],
- hot-exit: [ Tyriar ],
+ hot-exit: [],
html: [ aeschli ],
install-update: [],
- integrated-terminal: [ Tyriar ],
+ integrated-terminal: [],
integration-test: [],
intellisense-config: [],
issue-reporter: [ RMacfarlane ],
diff --git a/.github/commands.yml b/.github/commands.yml
index ba6ab0e86e4..95a3df06c5b 100644
--- a/.github/commands.yml
+++ b/.github/commands.yml
@@ -46,6 +46,7 @@
{
type: 'comment',
name: 'duplicate',
+ allowUsers: ['cleidigh', 'usernamehw'],
action: 'updateLabels',
addLabel: '*duplicate'
},
@@ -59,18 +60,21 @@
{
type: 'comment',
name: 'confirm',
+ allowUsers: ['cleidigh', 'usernamehw'],
action: 'updateLabels',
addLabel: 'confirmed'
},
{
type: 'comment',
name: 'findDuplicates',
+ allowUsers: ['cleidigh', 'usernamehw'],
action: 'comment',
comment: "Potential duplicates:\n${potentialDuplicates}"
},
{
type: 'comment',
name: 'needsMoreInfo',
+ allowUsers: ['cleidigh', 'usernamehw'],
action: 'updateLabels',
addLabel: 'needs more info',
comment: "Thanks for creating this issue! We figured it's missing some basic information or in some other way doesn't follow our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines. Please take the time to review these and update the issue.\n\nHappy Coding!"
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 73b99e84fbb..a117e3ed45d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -147,7 +147,7 @@
},
"urlFilter": "*workbench.html*",
"runtimeArgs": [
- "--inspect=5875"
+ "--inspect=5875", "--no-cached-data"
],
"smartStep": true,
"skipFiles": [
@@ -155,6 +155,19 @@
],
"webRoot": "${workspaceFolder}"
},
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Launch VS Code (Main Process)",
+ "runtimeExecutable": "${workspaceFolder}/scripts/code.sh",
+ "runtimeArgs": [
+ "--no-cached-data"
+ ],
+ "smartStep": true,
+ "outFiles": [
+ "${workspaceFolder}/out/**/*.js"
+ ]
+ },
{
"type": "node",
"request": "launch",
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e8df189e775..3edd3534df9 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -21,7 +21,8 @@
"out-vscode/**": true,
"i18n/**": true,
"extensions/**/out/**": true,
- "test/smoke/out/**": true
+ "test/smoke/out/**": true,
+ "src/vs/base/test/node/uri.test.data.txt": true
},
"tslint.enable": true,
"lcov.path": [
@@ -42,5 +43,4 @@
"emmet.excludeLanguages": [],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.quoteStyle": "single"
-
}
\ No newline at end of file
diff --git a/.vscode/shared.code-snippets b/.vscode/shared.code-snippets
index 7ea5b3c14dc..6d6690a0282 100644
--- a/.vscode/shared.code-snippets
+++ b/.vscode/shared.code-snippets
@@ -5,8 +5,8 @@
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
- "JavaScript, TypeScript Copyright Header": {
- "scope": "javascript,typescript",
+ "MSFT Copyright Header": {
+ "scope": "javascript,typescript,css",
"prefix": [
"header",
"stub",
@@ -18,8 +18,6 @@
" * Licensed under the MIT License. See License.txt in the project root for license information.",
" *--------------------------------------------------------------------------------------------*/",
"",
- "'use strict';",
- "",
"$0"
],
"description": "Insert Copyright Statement"
@@ -33,25 +31,8 @@
"prefix": "emitter",
"description": "Add emitter and event properties",
"body": [
- "private _onDid$1 = new Emitter<$2>();",
+ "private readonly _onDid$1 = new Emitter<$2>();",
"readonly onDid$1: Event<$2> = this._onDid$1.event;"
],
- },
- "CSS Copyright Header": {
- "scope": "css",
- "prefix": [
- "header",
- "stub",
- "copyright"
- ],
- "body": [
- "/*---------------------------------------------------------------------------------------------",
- " * Copyright (c) Microsoft Corporation. All rights reserved.",
- " * Licensed under the MIT License. See License.txt in the project root for license information.",
- " *--------------------------------------------------------------------------------------------*/",
- "",
- "$0"
- ],
- "description": "Insert Copyright Statement"
}
}
diff --git a/.yarnrc b/.yarnrc
index 55749a8a0a7..8e1ac6b6cac 100644
--- a/.yarnrc
+++ b/.yarnrc
@@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
-target "2.0.11"
+target "2.0.12"
runtime "electron"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b1650a08e2e..7775753e8bc 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -101,4 +101,3 @@ please see [How to Contribute](https://github.com/Microsoft/vscode/wiki/How-to-C
# Thank You!
Your contributions to open source, large or small, make great projects like this possible. Thank you for taking the time to contribute.
-
diff --git a/OSSREADME.json b/OSSREADME.json
index c59395867eb..0f988151200 100644
--- a/OSSREADME.json
+++ b/OSSREADME.json
@@ -51,7 +51,7 @@
},
{
"name": "electron",
- "version": "2.0.11",
+ "version": "2.0.12",
"license": "MIT",
"repositoryURL": "https://github.com/electron/electron",
"isProd": true
diff --git a/README.md b/README.md
index f9b64ff7a21..a7294e71b9b 100644
--- a/README.md
+++ b/README.md
@@ -5,17 +5,16 @@
[](https://github.com/Microsoft/vscode/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Abug)
[](https://gitter.im/Microsoft/vscode)
-[VS Code](https://code.visualstudio.com) is a new type of tool that combines the simplicity of
-a code editor with what developers need for their core edit-build-debug cycle. Code
-provides comprehensive editing and debugging support, an extensibility model, and lightweight integration with existing tools.
+[VS Code](https://code.visualstudio.com) is a type of tool that combines the simplicity of
+a code editor with what developers need for their core edit-build-debug cycle. It provides comprehensive editing and debugging support, an extensibility model, and lightweight integration with existing tools.
-VS Code is updated monthly with new features and bug fixes. You can download it for Windows, macOS, and Linux on [VS Code's website](https://code.visualstudio.com/Download). To get the latest releases every day, you can install the [Insiders version of VS Code](https://code.visualstudio.com/insiders). This builds from the master branch and is updated at least daily.
+VS Code is updated monthly with new features and bug fixes. You can download it for Windows, macOS, and Linux on [VS Code's website](https://code.visualstudio.com/Download). To get the latest releases every day, you can install the [Insiders version of VS Code](https://code.visualstudio.com/insiders). This builds from the master branch and is updated daily at the very least.
-The [`vscode`](https://github.com/microsoft/vscode) repository is where we do development and there are many ways you can participate in the project, for example:
+The [`vscode`](https://github.com/microsoft/vscode) repository is where VS Code is developed and there are many ways you can participate in the project, for example:
* [Submit bugs and feature requests](https://github.com/microsoft/vscode/issues) and help us verify as they are checked in.
* Review [source code changes](https://github.com/microsoft/vscode/pulls).
@@ -38,15 +37,20 @@ Please also see our [Code of Conduct](CODE_OF_CONDUCT.md).
* Ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/vscode).
* Request a new feature on [GitHub](CONTRIBUTING.md).
-* Vote for [popular feature requests](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc).
+* Vote for [Popular Feature Requests](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc).
* File a bug in [GitHub Issues](https://github.com/Microsoft/vscode/issues).
-* [Tweet](https://twitter.com/code) us with other feedback.
+* [Tweet](https://twitter.com/code) us with any other feedback.
## Related Projects
-Many of the core components and extensions to Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug).
+Many of the core components and extensions to Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug) have their own repositories.
-For a complete list, please see the [Related Projects](https://github.com/Microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/Microsoft/vscode/wiki).
+For a complete list, please visit the [Related Projects](https://github.com/Microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/Microsoft/vscode/wiki).
+
+## Bundled Extensions
+
+Code ships with a set of extensions. These extensions are located in the [extensions](extensions) folder.
+These extensions include grammars and snippets for several languages. Extensions that provide rich language support (code completion, go to definition) for a language have the suffix 'language-features'. For example, the 'json' extension provides coloring for JSON and the 'json-language-features' provides rich language support for JSON.
## License
diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt
index ed7e5acda34..757d3800253 100644
--- a/ThirdPartyNotices.txt
+++ b/ThirdPartyNotices.txt
@@ -60,13 +60,12 @@ This project incorporates components from the projects listed below. The origina
53. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle)
54. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle)
55. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle)
-56. textmate/toml.tmbundle (https://github.com/textmate/toml.tmbundle)
-57. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle)
-58. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage)
-59. Unicode ()
-60. vscode-logfile-highlighter version 1.2.0 (https://github.com/emilast/vscode-logfile-highlighter)
-61. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
-62. Web Background Synchronization (https://github.com/WICG/BackgroundSync)
+56. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle)
+57. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage)
+58. Unicode ()
+59. vscode-logfile-highlighter version 1.2.0 (https://github.com/emilast/vscode-logfile-highlighter)
+60. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
+61. Web Background Synchronization (https://github.com/WICG/BackgroundSync)
%% atom/language-c NOTICES AND INFORMATION BEGIN HERE
@@ -1282,7 +1281,49 @@ END OF MagicStack/MagicPython NOTICES AND INFORMATION
%% marked NOTICES AND INFORMATION BEGIN HERE
=========================================
-Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)
+information
+
+## Contribution License Agreement
+
+If you contribute code to this project, you are implicitly allowing your code
+to be distributed under the MIT license. You are also implicitly verifying that
+all code is your original work. ``
+
+## Marked
+
+Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/)
+
+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.
+
+## Markdown
+
+Copyright © 2004, John Gruber
+http://daringfireball.net/
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+* Neither the name "Markdown" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
=========================================
END OF marked NOTICES AND INFORMATION
@@ -2180,20 +2221,6 @@ to the base-name name of the original file, and an extension of txt, html, or si
=========================================
END OF textmate/ruby.tmbundle NOTICES AND INFORMATION
-%% textmate/toml.tmbundle NOTICES AND INFORMATION BEGIN HERE
-=========================================
-Copyright (c) https://github.com/infininight and https://github.com/mojombo
-Permission to copy, use, modify, sell and distribute this
-software is granted. This software is provided "as is" without
-express or implied warranty, and with no claim as to its
-suitability for any purpose
-
-An exception is made for files in readable text which contain their own license information, or files where an accompanying
-file exists (in the same directory) with a "-license" suffix added to the base-name name of the original file, and an extension .
-of txt, html, or similar. For example "tidy" is accompanied by "tidy-license.txt".
-=========================================
-END OF textmate/toml.tmbundle NOTICES AND INFORMATION
-
%% textmate/yaml.tmbundle NOTICES AND INFORMATION BEGIN HERE
=========================================
Copyright (c) 2015 FichteFoll
diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json
index 0426994695a..e2cb847b634 100644
--- a/build/builtInExtensions.json
+++ b/build/builtInExtensions.json
@@ -1,7 +1,7 @@
[
{
"name": "ms-vscode.node-debug",
- "version": "1.28.2",
+ "version": "1.29.2",
"repo": "https://github.com/Microsoft/vscode-node-debug",
"metadata": {
"id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6",
@@ -16,7 +16,7 @@
},
{
"name": "ms-vscode.node-debug2",
- "version": "1.28.3",
+ "version": "1.29.5",
"repo": "https://github.com/Microsoft/vscode-node-debug2",
"metadata": {
"id": "36d19e17-7569-4841-a001-947eb18602b2",
@@ -28,5 +28,20 @@
},
"publisherDisplayName": "Microsoft"
}
+ },
+ {
+ "name": "ms-vscode.references-view",
+ "version": "0.0.8",
+ "repo": "https://github.com/Microsoft/vscode-reference-view",
+ "metadata": {
+ "id": "36d19e17-7569-4841-a001-947eb18602b2",
+ "publisherId": {
+ "publisherId": "5f5636e7-69ed-4afe-b5d6-8d231fb3d3ee",
+ "publisherName": "ms-vscode",
+ "displayName": "Microsoft",
+ "flags": "verified"
+ },
+ "publisherDisplayName": "Microsoft"
+ }
}
-]
\ No newline at end of file
+]
diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js
index 349a2b979e2..50258a98fb3 100644
--- a/build/gulpfile.vscode.linux.js
+++ b/build/gulpfile.vscode.linux.js
@@ -118,12 +118,12 @@ function prepareRpmPackage(arch) {
const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' })
.pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '-url-handler.desktop'));
- const desktops = es.merge(desktop, desktopUrlHandler)
- .pipe(replace('@@NAME_LONG@@', product.nameLong))
- .pipe(replace('@@NAME_SHORT@@', product.nameShort))
- .pipe(replace('@@NAME@@', product.applicationName))
- .pipe(replace('@@ICON@@', product.applicationName))
- .pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
+ const desktops = es.merge(desktop, desktopUrlHandler)
+ .pipe(replace('@@NAME_LONG@@', product.nameLong))
+ .pipe(replace('@@NAME_SHORT@@', product.nameShort))
+ .pipe(replace('@@NAME@@', product.applicationName))
+ .pipe(replace('@@ICON@@', product.applicationName))
+ .pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
@@ -172,6 +172,7 @@ function buildRpmPackage(arch) {
'cp "' + rpmOut + '/$(ls ' + rpmOut + ')" ' + destination + '/'
]);
}
+
function getSnapBuildPath(arch) {
return `.build/linux/snap/${arch}/${product.applicationName}-${arch}`;
}
@@ -192,17 +193,21 @@ function prepareSnapPackage(arch) {
.pipe(rename(`usr/share/pixmaps/${product.applicationName}.png`));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
- .pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; }));
+ .pipe(rename(function (p) { p.dirname = `usr/share/${product.applicationName}/${p.dirname}`; }));
const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
- .pipe(replace('@@VERSION@@', packageJson.version))
+ .pipe(replace('@@VERSION@@', `${packageJson.version}-${linuxPackageRevision}`))
.pipe(rename('snap/snapcraft.yaml'));
+ const snapUpdate = gulp.src('resources/linux/snap/snapUpdate.sh', { base: '.' })
+ .pipe(replace('@@NAME@@', product.applicationName))
+ .pipe(rename(`usr/share/${product.applicationName}/snapUpdate.sh`));
+
const electronLaunch = gulp.src('resources/linux/snap/electron-launch', { base: '.' })
.pipe(rename('electron-launch'));
- const all = es.merge(desktop, icon, code, snapcraft, electronLaunch);
+ const all = es.merge(desktop, icon, code, snapcraft, electronLaunch, snapUpdate);
return all.pipe(vfs.dest(destination));
};
@@ -210,11 +215,7 @@ function prepareSnapPackage(arch) {
function buildSnapPackage(arch) {
const snapBuildPath = getSnapBuildPath(arch);
- const snapFilename = `${product.applicationName}-${packageJson.version}-${linuxPackageRevision}-${arch}.snap`;
- return shell.task([
- `chmod +x ${snapBuildPath}/electron-launch`,
- `cd ${snapBuildPath} && snapcraft snap --output ../${snapFilename}`
- ]);
+ return shell.task(`cd ${snapBuildPath} && snapcraft build`);
}
gulp.task('clean-vscode-linux-ia32-deb', util.rimraf('.build/linux/deb/i386'));
diff --git a/build/lib/compilation.js b/build/lib/compilation.js
index fb311e14a01..9cc9846336a 100644
--- a/build/lib/compilation.js
+++ b/build/lib/compilation.js
@@ -11,7 +11,6 @@ const bom = require("gulp-bom");
const sourcemaps = require("gulp-sourcemaps");
const tsb = require("gulp-tsb");
const path = require("path");
-const ts = require("typescript");
const _ = require("underscore");
const monacodts = require("../monaco/api");
const nls = require("./nls");
@@ -89,7 +88,6 @@ function compileTask(src, out, build) {
.pipe(generator.stream)
.pipe(compile())
.pipe(gulp.dest(out));
- // .pipe(src !== 'src' ? es.through() : monacodtsTask(out, false));
};
}
exports.compileTask = compileTask;
@@ -110,87 +108,61 @@ exports.watchTask = watchTask;
const REPO_SRC_FOLDER = path.join(__dirname, '../../src');
class MonacoGenerator {
constructor(isWatch) {
+ this._executeSoonTimer = null;
this._isWatch = isWatch;
this.stream = es.through();
- this._inputFiles = monacodts.getIncludesInRecipe().map((moduleId) => {
- if (/\.d\.ts$/.test(moduleId)) {
- // This source file is already in .d.ts form
- return path.join(REPO_SRC_FOLDER, moduleId);
- }
- else {
- return path.join(REPO_SRC_FOLDER, `${moduleId}.ts`);
- }
- });
- // Install watchers
this._watchers = [];
- if (this._isWatch) {
- this._inputFiles.forEach((filePath) => {
- const watcher = fs.watch(filePath);
- watcher.addListener('change', () => {
- this._inputFileChanged[filePath] = true;
- // Avoid hitting empty files... :/
- setTimeout(() => this.execute(), 10);
- });
- this._watchers.push(watcher);
+ this._watchedFiles = {};
+ let onWillReadFile = (moduleId, filePath) => {
+ if (!this._isWatch) {
+ return;
+ }
+ if (this._watchedFiles[filePath]) {
+ return;
+ }
+ this._watchedFiles[filePath] = true;
+ const watcher = fs.watch(filePath);
+ watcher.addListener('change', () => {
+ this._declarationResolver.invalidateCache(moduleId);
+ this._executeSoon();
});
+ this._watchers.push(watcher);
+ };
+ this._fsProvider = new class extends monacodts.FSProvider {
+ readFileSync(moduleId, filePath) {
+ onWillReadFile(moduleId, filePath);
+ return super.readFileSync(moduleId, filePath);
+ }
+ };
+ this._declarationResolver = new monacodts.DeclarationResolver(this._fsProvider);
+ if (this._isWatch) {
const recipeWatcher = fs.watch(monacodts.RECIPE_PATH);
recipeWatcher.addListener('change', () => {
- this._recipeFileChanged = true;
- // Avoid hitting empty files... :/
- setTimeout(() => this.execute(), 10);
+ this._executeSoon();
});
this._watchers.push(recipeWatcher);
}
- this._inputFileChanged = {};
- this._inputFiles.forEach(file => this._inputFileChanged[file] = true);
- this._recipeFileChanged = true;
- this._dtsFilesContents = {};
- this._dtsFilesContents2 = {};
+ }
+ _executeSoon() {
+ if (this._executeSoonTimer !== null) {
+ clearTimeout(this._executeSoonTimer);
+ this._executeSoonTimer = null;
+ }
+ this._executeSoonTimer = setTimeout(() => {
+ this._executeSoonTimer = null;
+ this.execute();
+ }, 20);
}
dispose() {
this._watchers.forEach(watcher => watcher.close());
}
_run() {
- let somethingChanged = false;
- const setDTSFileContent = (file, contents) => {
- if (this._dtsFilesContents[file] === contents) {
- return;
- }
- this._dtsFilesContents[file] = contents;
- this._dtsFilesContents2[file] = ts.createSourceFile(file, contents, ts.ScriptTarget.ES5);
- somethingChanged = true;
- };
- const fileMap = {};
- this._inputFiles.forEach((inputFile) => {
- if (!this._inputFileChanged[inputFile]) {
- return;
- }
- this._inputFileChanged[inputFile] = false;
- const inputFileContents = fs.readFileSync(inputFile).toString();
- if (/\.d\.ts$/.test(inputFile)) {
- // This is a .d.ts file
- setDTSFileContent(inputFile, inputFileContents);
- return;
- }
- fileMap[inputFile] = inputFileContents;
- });
- if (Object.keys(fileMap).length > 0) {
- const service = ts.createLanguageService(new monacodts.TypeScriptLanguageServiceHost({}, fileMap, {}));
- Object.keys(fileMap).forEach((fileName) => {
- const output = service.getEmitOutput(fileName, true).outputFiles[0].text;
- const destFileName = fileName.replace(/\.ts$/, '.d.ts');
- setDTSFileContent(destFileName, output);
- });
+ let r = monacodts.run3(this._declarationResolver);
+ if (!r && !this._isWatch) {
+ // The build must always be able to generate the monaco.d.ts
+ throw new Error(`monaco.d.ts generation error - Cannot continue`);
}
- if (this._recipeFileChanged) {
- this._recipeFileChanged = false;
- somethingChanged = true;
- }
- if (!somethingChanged) {
- // Nothing changed
- return null;
- }
- return monacodts.run2('src', this._dtsFilesContents2);
+ return r;
}
_log(message, ...rest) {
util2.log(util2.colors.cyan('[monaco.d.ts]'), message, ...rest);
@@ -203,10 +175,10 @@ class MonacoGenerator {
return;
}
if (result.isTheSame) {
- this._log(`monaco.d.ts is unchanged - total time took ${Date.now() - startTime} ms`);
return;
}
fs.writeFileSync(result.filePath, result.content);
+ fs.writeFileSync(path.join(REPO_SRC_FOLDER, 'vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
this._log(`monaco.d.ts is changed - total time took ${Date.now() - startTime} ms`);
if (!this._isWatch) {
this.stream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts
index 30d03c069cb..393bc56bd16 100644
--- a/build/lib/compilation.ts
+++ b/build/lib/compilation.ts
@@ -12,7 +12,6 @@ import * as bom from 'gulp-bom';
import * as sourcemaps from 'gulp-sourcemaps';
import * as tsb from 'gulp-tsb';
import * as path from 'path';
-import * as ts from 'typescript';
import * as _ from 'underscore';
import * as monacodts from '../monaco/api';
import * as nls from './nls';
@@ -106,7 +105,6 @@ export function compileTask(src: string, out: string, build: boolean): () => Nod
.pipe(generator.stream)
.pipe(compile())
.pipe(gulp.dest(out));
- // .pipe(src !== 'src' ? es.through() : monacodtsTask(out, false));
};
}
@@ -136,57 +134,60 @@ const REPO_SRC_FOLDER = path.join(__dirname, '../../src');
class MonacoGenerator {
private readonly _isWatch: boolean;
public readonly stream: NodeJS.ReadWriteStream;
- /**
- * This list is never changed for the lifetime of this object.
- */
- private readonly _inputFiles: string[];
+
private readonly _watchers: fs.FSWatcher[];
-
- private _inputFileChanged: { [filePath: string]: boolean; };
- private _recipeFileChanged: boolean;
-
- private _dtsFilesContents: { [filePath: string]: string; };
- private _dtsFilesContents2: { [filePath: string]: ts.SourceFile; };
+ private readonly _watchedFiles: { [filePath: string]: boolean; };
+ private readonly _fsProvider: monacodts.FSProvider;
+ private readonly _declarationResolver: monacodts.DeclarationResolver;
constructor(isWatch: boolean) {
this._isWatch = isWatch;
this.stream = es.through();
- this._inputFiles = monacodts.getIncludesInRecipe().map((moduleId) => {
- if (/\.d\.ts$/.test(moduleId)) {
- // This source file is already in .d.ts form
- return path.join(REPO_SRC_FOLDER, moduleId);
- } else {
- return path.join(REPO_SRC_FOLDER, `${moduleId}.ts`);
- }
- });
-
- // Install watchers
this._watchers = [];
- if (this._isWatch) {
- this._inputFiles.forEach((filePath) => {
- const watcher = fs.watch(filePath);
- watcher.addListener('change', () => {
- this._inputFileChanged[filePath] = true;
- // Avoid hitting empty files... :/
- setTimeout(() => this.execute(), 10);
- });
- this._watchers.push(watcher);
- });
+ this._watchedFiles = {};
+ let onWillReadFile = (moduleId: string, filePath: string) => {
+ if (!this._isWatch) {
+ return;
+ }
+ if (this._watchedFiles[filePath]) {
+ return;
+ }
+ this._watchedFiles[filePath] = true;
+ const watcher = fs.watch(filePath);
+ watcher.addListener('change', () => {
+ this._declarationResolver.invalidateCache(moduleId);
+ this._executeSoon();
+ });
+ this._watchers.push(watcher);
+ };
+ this._fsProvider = new class extends monacodts.FSProvider {
+ public readFileSync(moduleId: string, filePath: string): Buffer {
+ onWillReadFile(moduleId, filePath);
+ return super.readFileSync(moduleId, filePath);
+ }
+ };
+ this._declarationResolver = new monacodts.DeclarationResolver(this._fsProvider);
+
+ if (this._isWatch) {
const recipeWatcher = fs.watch(monacodts.RECIPE_PATH);
recipeWatcher.addListener('change', () => {
- this._recipeFileChanged = true;
- // Avoid hitting empty files... :/
- setTimeout(() => this.execute(), 10);
+ this._executeSoon();
});
this._watchers.push(recipeWatcher);
}
+ }
- this._inputFileChanged = {};
- this._inputFiles.forEach(file => this._inputFileChanged[file] = true);
- this._recipeFileChanged = true;
- this._dtsFilesContents = {};
- this._dtsFilesContents2 = {};
+ private _executeSoonTimer: NodeJS.Timer | null = null;
+ private _executeSoon(): void {
+ if (this._executeSoonTimer !== null) {
+ clearTimeout(this._executeSoonTimer);
+ this._executeSoonTimer = null;
+ }
+ this._executeSoonTimer = setTimeout(() => {
+ this._executeSoonTimer = null;
+ this.execute();
+ }, 20);
}
public dispose(): void {
@@ -194,56 +195,12 @@ class MonacoGenerator {
}
private _run(): monacodts.IMonacoDeclarationResult | null {
- let somethingChanged = false;
-
- const setDTSFileContent = (file: string, contents: string): void => {
- if (this._dtsFilesContents[file] === contents) {
- return;
- }
- this._dtsFilesContents[file] = contents;
- this._dtsFilesContents2[file] = ts.createSourceFile(file, contents, ts.ScriptTarget.ES5);
- somethingChanged = true;
- };
-
- const fileMap: { [fileName: string]: string; } = {};
-
- this._inputFiles.forEach((inputFile) => {
- if (!this._inputFileChanged[inputFile]) {
- return;
- }
- this._inputFileChanged[inputFile] = false;
-
- const inputFileContents = fs.readFileSync(inputFile).toString();
- if (/\.d\.ts$/.test(inputFile)) {
- // This is a .d.ts file
- setDTSFileContent(inputFile, inputFileContents);
- return;
- }
-
- fileMap[inputFile] = inputFileContents;
- });
-
- if (Object.keys(fileMap).length > 0) {
- const service = ts.createLanguageService(new monacodts.TypeScriptLanguageServiceHost({}, fileMap, {}));
-
- Object.keys(fileMap).forEach((fileName) => {
- const output = service.getEmitOutput(fileName, true).outputFiles[0].text;
- const destFileName = fileName.replace(/\.ts$/, '.d.ts');
- setDTSFileContent(destFileName, output);
- });
+ let r = monacodts.run3(this._declarationResolver);
+ if (!r && !this._isWatch) {
+ // The build must always be able to generate the monaco.d.ts
+ throw new Error(`monaco.d.ts generation error - Cannot continue`);
}
-
- if (this._recipeFileChanged) {
- this._recipeFileChanged = false;
- somethingChanged = true;
- }
-
- if (!somethingChanged) {
- // Nothing changed
- return null;
- }
-
- return monacodts.run2('src', this._dtsFilesContents2);
+ return r;
}
private _log(message: any, ...rest: any[]): void {
@@ -258,11 +215,11 @@ class MonacoGenerator {
return;
}
if (result.isTheSame) {
- this._log(`monaco.d.ts is unchanged - total time took ${Date.now() - startTime} ms`);
return;
}
fs.writeFileSync(result.filePath, result.content);
+ fs.writeFileSync(path.join(REPO_SRC_FOLDER, 'vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
this._log(`monaco.d.ts is changed - total time took ${Date.now() - startTime} ms`);
if (!this._isWatch) {
this.stream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
diff --git a/build/lib/extensions.js b/build/lib/extensions.js
index 293c1f0c2ef..335b6b71671 100644
--- a/build/lib/extensions.js
+++ b/build/lib/extensions.js
@@ -36,10 +36,12 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
const result = es.through();
const packagedDependencies = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
- const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
- for (const key in webpackRootConfig.externals) {
- if (key in packageJsonConfig.dependencies) {
- packagedDependencies.push(key);
+ if (Array.isArray(packageJsonConfig.dependencies)) {
+ const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
+ for (const key in webpackRootConfig.externals) {
+ if (key in packageJsonConfig.dependencies) {
+ packagedDependencies.push(key);
+ }
}
}
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
@@ -68,8 +70,10 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json((data) => {
- // hardcoded entry point directory!
- data.main = data.main.replace('/out/', /dist/);
+ if (data.main) {
+ // hardcoded entry point directory!
+ data.main = data.main.replace('/out/', /dist/);
+ }
return data;
}))
.pipe(packageJsonFilter.restore);
diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts
index 7d3bc6630d1..07db5eac1c6 100644
--- a/build/lib/extensions.ts
+++ b/build/lib/extensions.ts
@@ -39,14 +39,15 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string |
const packagedDependencies: string[] = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
- const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
- for (const key in webpackRootConfig.externals) {
- if (key in packageJsonConfig.dependencies) {
- packagedDependencies.push(key);
+ if (Array.isArray(packageJsonConfig.dependencies)) {
+ const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
+ for (const key in webpackRootConfig.externals) {
+ if (key in packageJsonConfig.dependencies) {
+ packagedDependencies.push(key);
+ }
}
}
-
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
const files = fileNames
.map(fileName => path.join(extensionPath, fileName))
@@ -80,8 +81,10 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string |
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json((data: any) => {
- // hardcoded entry point directory!
- data.main = data.main.replace('/out/', /dist/);
+ if (data.main) {
+ // hardcoded entry point directory!
+ data.main = data.main.replace('/out/', /dist/);
+ }
return data;
}))
.pipe(packageJsonFilter.restore);
diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json
index 204ea6beea6..40d686c08cf 100644
--- a/build/lib/i18n.resources.json
+++ b/build/lib/i18n.resources.json
@@ -166,6 +166,10 @@
"name": "vs/workbench/services/bulkEdit",
"project": "vscode-workbench"
},
+ {
+ "name": "vs/workbench/services/commands",
+ "project": "vscode-workbench"
+ },
{
"name": "vs/workbench/services/configuration",
"project": "vscode-workbench"
diff --git a/build/lib/snapshotLoader.js b/build/lib/snapshotLoader.js
index 9a047e0f694..ee626a0f7f1 100644
--- a/build/lib/snapshotLoader.js
+++ b/build/lib/snapshotLoader.js
@@ -24,6 +24,7 @@ var snaps;
case 'linux':
loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`;
+ break;
default:
throw new Error('Unknown platform');
}
diff --git a/build/lib/snapshotLoader.ts b/build/lib/snapshotLoader.ts
index 3bc379697c8..40b06d67d05 100644
--- a/build/lib/snapshotLoader.ts
+++ b/build/lib/snapshotLoader.ts
@@ -30,6 +30,7 @@ namespace snaps {
case 'linux':
loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`;
+ break;
default:
throw new Error('Unknown platform');
diff --git a/build/lib/standalone.js b/build/lib/standalone.js
index c01e0f461f4..bc5f6d9decc 100644
--- a/build/lib/standalone.js
+++ b/build/lib/standalone.js
@@ -28,12 +28,22 @@ function writeFile(filePath, contents) {
}
function extractEditor(options) {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
- tsConfig.compilerOptions.noUnusedLocals = false;
- tsConfig.compilerOptions.preserveConstEnums = false;
- tsConfig.compilerOptions.declaration = false;
- delete tsConfig.compilerOptions.types;
+ let compilerOptions;
+ if (tsConfig.extends) {
+ compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
+ }
+ else {
+ compilerOptions = tsConfig.compilerOptions;
+ }
+ tsConfig.compilerOptions = compilerOptions;
+ compilerOptions.noUnusedLocals = false;
+ compilerOptions.preserveConstEnums = false;
+ compilerOptions.declaration = false;
+ compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
+ delete compilerOptions.types;
+ delete tsConfig.extends;
tsConfig.exclude = [];
- options.compilerOptions = tsConfig.compilerOptions;
+ options.compilerOptions = compilerOptions;
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts
index aba118ab529..c4b128542e7 100644
--- a/build/lib/standalone.ts
+++ b/build/lib/standalone.ts
@@ -32,13 +32,24 @@ function writeFile(filePath: string, contents: Buffer | string): void {
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
- tsConfig.compilerOptions.noUnusedLocals = false;
- tsConfig.compilerOptions.preserveConstEnums = false;
- tsConfig.compilerOptions.declaration = false;
- delete tsConfig.compilerOptions.types;
+ let compilerOptions: { [key: string]: any };
+ if (tsConfig.extends) {
+ compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
+ } else {
+ compilerOptions = tsConfig.compilerOptions;
+ }
+ tsConfig.compilerOptions = compilerOptions;
+
+ compilerOptions.noUnusedLocals = false;
+ compilerOptions.preserveConstEnums = false;
+ compilerOptions.declaration = false;
+ compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
+
+ delete compilerOptions.types;
+ delete tsConfig.extends;
tsConfig.exclude = [];
- options.compilerOptions = tsConfig.compilerOptions;
+ options.compilerOptions = compilerOptions;
let result = tss.shake(options);
for (let fileName in result) {
diff --git a/build/lib/treeshaking.js b/build/lib/treeshaking.js
index b8045415698..61cda44028a 100644
--- a/build/lib/treeshaking.js
+++ b/build/lib/treeshaking.js
@@ -70,7 +70,8 @@ function createTypeScriptLanguageService(options) {
const filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
- const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
+ const compilerOptions = ts.convertCompilerOptionsFromJson(options.compilerOptions, options.sourcesRoot).options;
+ const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, compilerOptions);
return ts.createLanguageService(host);
}
/**
diff --git a/build/lib/treeshaking.ts b/build/lib/treeshaking.ts
index 3439b1437ac..e84aa7effeb 100644
--- a/build/lib/treeshaking.ts
+++ b/build/lib/treeshaking.ts
@@ -126,7 +126,9 @@ function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.Langu
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
- const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
+ const compilerOptions = ts.convertCompilerOptionsFromJson(options.compilerOptions, options.sourcesRoot).options;
+
+ const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, compilerOptions);
return ts.createLanguageService(host);
}
diff --git a/build/lib/tslint/noNewBufferRule.js b/build/lib/tslint/noNewBufferRule.js
new file mode 100644
index 00000000000..ae9b02d457e
--- /dev/null
+++ b/build/lib/tslint/noNewBufferRule.js
@@ -0,0 +1,22 @@
+"use strict";
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+const ts = require("typescript");
+const Lint = require("tslint");
+class Rule extends Lint.Rules.AbstractRule {
+ apply(sourceFile) {
+ return this.applyWithWalker(new NewBufferRuleWalker(sourceFile, this.getOptions()));
+ }
+}
+exports.Rule = Rule;
+class NewBufferRuleWalker extends Lint.RuleWalker {
+ visitNewExpression(node) {
+ if (node.expression.kind === ts.SyntaxKind.Identifier && node.expression && node.expression.text === 'Buffer') {
+ this.addFailureAtNode(node, '`new Buffer` is deprecated. Consider Buffer.From or Buffer.alloc instead.');
+ }
+ super.visitNewExpression(node);
+ }
+}
diff --git a/build/lib/tslint/noNewBufferRule.ts b/build/lib/tslint/noNewBufferRule.ts
new file mode 100644
index 00000000000..7b0dd43e538
--- /dev/null
+++ b/build/lib/tslint/noNewBufferRule.ts
@@ -0,0 +1,23 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as ts from 'typescript';
+import * as Lint from 'tslint';
+
+export class Rule extends Lint.Rules.AbstractRule {
+ apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ return this.applyWithWalker(new NewBufferRuleWalker(sourceFile, this.getOptions()));
+ }
+}
+
+class NewBufferRuleWalker extends Lint.RuleWalker {
+ visitNewExpression(node: ts.NewExpression) {
+ if (node.expression.kind === ts.SyntaxKind.Identifier && node.expression && (node.expression as ts.Identifier).text === 'Buffer') {
+ this.addFailureAtNode(node, '`new Buffer` is deprecated. Consider Buffer.From or Buffer.alloc instead.');
+ }
+
+ super.visitNewExpression(node);
+ }
+}
\ No newline at end of file
diff --git a/build/lib/tslint/noUnexternalizedStringsRule.js b/build/lib/tslint/noUnexternalizedStringsRule.js
index 7cb407c8f19..f79421effc1 100644
--- a/build/lib/tslint/noUnexternalizedStringsRule.js
+++ b/build/lib/tslint/noUnexternalizedStringsRule.js
@@ -52,6 +52,12 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
visitSourceFile(node) {
super.visitSourceFile(node);
Object.keys(this.usedKeys).forEach(key => {
+ // Keys are quoted.
+ let identifier = key.substr(1, key.length - 2);
+ if (!NoUnexternalizedStringsRuleWalker.IDENTIFIER.test(identifier)) {
+ let occurrence = this.usedKeys[key][0];
+ this.addFailure(this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), `The key ${occurrence.key.getText()} doesn't conform to a valid localize identifier`));
+ }
const occurrences = this.usedKeys[key];
if (occurrences.length > 1) {
occurrences.forEach(occurrence => {
@@ -172,3 +178,4 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
}
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
+NoUnexternalizedStringsRuleWalker.IDENTIFIER = /^[_a-zA-Z0-9][ .\-_a-zA-Z0-9]*$/;
diff --git a/build/lib/tslint/noUnexternalizedStringsRule.ts b/build/lib/tslint/noUnexternalizedStringsRule.ts
index 91112582ff1..e8e8d001a00 100644
--- a/build/lib/tslint/noUnexternalizedStringsRule.ts
+++ b/build/lib/tslint/noUnexternalizedStringsRule.ts
@@ -81,9 +81,16 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
}
}
+ private static IDENTIFIER = /^[_a-zA-Z0-9][ .\-_a-zA-Z0-9]*$/;
protected visitSourceFile(node: ts.SourceFile): void {
super.visitSourceFile(node);
Object.keys(this.usedKeys).forEach(key => {
+ // Keys are quoted.
+ let identifier = key.substr(1, key.length - 2);
+ if (!NoUnexternalizedStringsRuleWalker.IDENTIFIER.test(identifier)) {
+ let occurrence = this.usedKeys[key][0];
+ this.addFailure(this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), `The key ${occurrence.key.getText()} doesn't conform to a valid localize identifier`));
+ }
const occurrences = this.usedKeys[key];
if (occurrences.length > 1) {
occurrences.forEach(occurrence => {
diff --git a/build/lib/util.ts b/build/lib/util.ts
index f5dc8cd84f2..4617cc83f2f 100644
--- a/build/lib/util.ts
+++ b/build/lib/util.ts
@@ -91,7 +91,7 @@ export function fixWin32DirectoryPermissions(): NodeJS.ReadWriteStream {
});
}
-export function setExecutableBit(pattern: string | string[]): NodeJS.ReadWriteStream {
+export function setExecutableBit(pattern?: string | string[]): NodeJS.ReadWriteStream {
const setBit = es.mapSync(f => {
f.stat.mode = /* 100755 */ 33261;
return f;
diff --git a/build/monaco/api.js b/build/monaco/api.js
index 8b131969081..716d1f56655 100644
--- a/build/monaco/api.js
+++ b/build/monaco/api.js
@@ -8,24 +8,13 @@ const fs = require("fs");
const ts = require("typescript");
const path = require("path");
const util = require("gulp-util");
+const dtsv = '2';
const tsfmt = require('../../tsfmt.json');
-function log(message, ...rest) {
- util.log(util.colors.cyan('[monaco.d.ts]'), message, ...rest);
-}
const SRC = path.join(__dirname, '../../src');
-const OUT_ROOT = path.join(__dirname, '../../');
exports.RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
-var CURRENT_PROCESSING_RULE = '';
function logErr(message, ...rest) {
- util.log(util.colors.red('[monaco.d.ts]'), 'WHILE HANDLING RULE: ', CURRENT_PROCESSING_RULE);
- util.log(util.colors.red('[monaco.d.ts]'), message, ...rest);
-}
-function moduleIdToPath(out, moduleId) {
- if (/\.d\.ts/.test(moduleId)) {
- return path.join(SRC, moduleId);
- }
- return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
+ util.log(util.colors.yellow(`[monaco.d.ts]`), message, ...rest);
}
function isDeclaration(a) {
return (a.kind === ts.SyntaxKind.InterfaceDeclaration
@@ -120,7 +109,7 @@ function isDefaultExport(declaration) {
return (hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword));
}
-function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage) {
+function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums) {
let result = getNodeText(sourceFile, declaration);
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
let interfaceDeclaration = declaration;
@@ -160,15 +149,115 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
+ if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
+ result = result.replace(/const enum/, 'enum');
+ enums.push(result);
+ }
return result;
}
-function format(text) {
+function format(text, endl) {
+ const REALLY_FORMAT = false;
+ text = preformat(text, endl);
+ if (!REALLY_FORMAT) {
+ return text;
+ }
// Parse the source text
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
// Get the formatting edits on the input sources
let edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
// Apply the edits on the input code
return applyEdits(text, edits);
+ function countParensCurly(text) {
+ let cnt = 0;
+ for (let i = 0; i < text.length; i++) {
+ if (text.charAt(i) === '(' || text.charAt(i) === '{') {
+ cnt++;
+ }
+ if (text.charAt(i) === ')' || text.charAt(i) === '}') {
+ cnt--;
+ }
+ }
+ return cnt;
+ }
+ function repeatStr(s, cnt) {
+ let r = '';
+ for (let i = 0; i < cnt; i++) {
+ r += s;
+ }
+ return r;
+ }
+ function preformat(text, endl) {
+ let lines = text.split(endl);
+ let inComment = false;
+ let inCommentDeltaIndent = 0;
+ let indent = 0;
+ for (let i = 0; i < lines.length; i++) {
+ let line = lines[i].replace(/\s$/, '');
+ let repeat = false;
+ let lineIndent = 0;
+ do {
+ repeat = false;
+ if (line.substring(0, 4) === ' ') {
+ line = line.substring(4);
+ lineIndent++;
+ repeat = true;
+ }
+ if (line.charAt(0) === '\t') {
+ line = line.substring(1);
+ lineIndent++;
+ repeat = true;
+ }
+ } while (repeat);
+ if (line.length === 0) {
+ continue;
+ }
+ if (inComment) {
+ if (/\*\//.test(line)) {
+ inComment = false;
+ }
+ lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line;
+ continue;
+ }
+ if (/\/\*/.test(line)) {
+ inComment = true;
+ inCommentDeltaIndent = indent - lineIndent;
+ lines[i] = repeatStr('\t', indent) + line;
+ continue;
+ }
+ const cnt = countParensCurly(line);
+ let shouldUnindentAfter = false;
+ let shouldUnindentBefore = false;
+ if (cnt < 0) {
+ if (/[({]/.test(line)) {
+ shouldUnindentAfter = true;
+ }
+ else {
+ shouldUnindentBefore = true;
+ }
+ }
+ else if (cnt === 0) {
+ shouldUnindentBefore = /^\}/.test(line);
+ }
+ let shouldIndentAfter = false;
+ if (cnt > 0) {
+ shouldIndentAfter = true;
+ }
+ else if (cnt === 0) {
+ shouldIndentAfter = /{$/.test(line);
+ }
+ if (shouldUnindentBefore) {
+ indent--;
+ }
+ lines[i] = repeatStr('\t', indent) + line;
+ if (shouldUnindentAfter) {
+ indent--;
+ }
+ if (shouldIndentAfter) {
+ indent++;
+ }
+ }
+ return lines.join(endl);
+ }
function getRuleProvider(options) {
// Share this between multiple formatters using the same options.
// This represents the bulk of the space the formatter uses.
@@ -215,6 +304,7 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
let usageCounter = 0;
let usageImports = [];
let usage = [];
+ let failed = false;
usage.push(`var a;`);
usage.push(`var b;`);
const generateUsageImport = (moduleId) => {
@@ -222,13 +312,24 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
return importName;
};
+ let enums = [];
+ let version = null;
lines.forEach(line => {
+ if (failed) {
+ return;
+ }
+ let m0 = line.match(/^\/\/dtsv=(\d+)$/);
+ if (m0) {
+ version = m0[1];
+ }
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
- CURRENT_PROCESSING_RULE = line;
let moduleId = m1[1];
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
+ logErr(`While handling ${line}`);
+ logErr(`Cannot find ${moduleId}`);
+ failed = true;
return;
}
const importName = generateUsageImport(moduleId);
@@ -241,19 +342,23 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
}
let declaration = getTopLevelDeclaration(sourceFile, typeName);
if (!declaration) {
- logErr('Cannot find type ' + typeName);
+ logErr(`While handling ${line}`);
+ logErr(`Cannot find ${typeName}`);
+ failed = true;
return;
}
- result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
+ result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
- CURRENT_PROCESSING_RULE = line;
let moduleId = m2[1];
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
+ logErr(`While handling ${line}`);
+ logErr(`Cannot find ${moduleId}`);
+ failed = true;
return;
}
const importName = generateUsageImport(moduleId);
@@ -284,92 +389,120 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
}
}
}
- result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
+ result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
result.push(line);
});
+ if (failed) {
+ return null;
+ }
+ if (version !== dtsv) {
+ if (!version) {
+ logErr(`gulp watch restart required. 'monaco.d.ts.recipe' is written before versioning was introduced.`);
+ }
+ else {
+ logErr(`gulp watch restart required. 'monaco.d.ts.recipe' v${version} does not match runtime v${dtsv}.`);
+ }
+ return null;
+ }
let resultTxt = result.join(endl);
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent {
- let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
- if (m1) {
- let moduleId = m1[1];
- result.push(moduleId);
- return;
- }
- let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
- if (m2) {
- let moduleId = m2[1];
- result.push(moduleId);
- return;
- }
- });
- return result;
-}
-exports.getIncludesInRecipe = getIncludesInRecipe;
-function getFilesToWatch(out) {
- return getIncludesInRecipe().map((moduleId) => moduleIdToPath(out, moduleId));
-}
-exports.getFilesToWatch = getFilesToWatch;
function _run(sourceFileGetter) {
- log('Starting monaco.d.ts generation');
- let recipe = fs.readFileSync(exports.RECIPE_PATH).toString();
- let [result, usageContent] = generateDeclarationFile(recipe, sourceFileGetter);
- let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
- log('Finished monaco.d.ts generation');
+ const recipe = fs.readFileSync(exports.RECIPE_PATH).toString();
+ const t = generateDeclarationFile(recipe, sourceFileGetter);
+ if (!t) {
+ return null;
+ }
+ const result = t.result;
+ const usageContent = t.usageContent;
+ const enums = t.enums;
+ const currentContent = fs.readFileSync(DECLARATION_PATH).toString();
const one = currentContent.replace(/\r\n/gm, '\n');
const other = result.replace(/\r\n/gm, '\n');
const isTheSame = (one === other);
return {
content: result,
usageContent: usageContent,
+ enums: enums,
filePath: DECLARATION_PATH,
isTheSame
};
}
-function run(out, inputFiles) {
- let SOURCE_FILE_MAP = {};
- const sourceFileGetter = (moduleId) => {
- if (!SOURCE_FILE_MAP[moduleId]) {
- let filePath = path.normalize(moduleIdToPath(out, moduleId));
- if (!inputFiles.hasOwnProperty(filePath)) {
- logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
+class FSProvider {
+ existsSync(filePath) {
+ return fs.existsSync(filePath);
+ }
+ readFileSync(_moduleId, filePath) {
+ return fs.readFileSync(filePath);
+ }
+}
+exports.FSProvider = FSProvider;
+class DeclarationResolver {
+ constructor(_fsProvider) {
+ this._fsProvider = _fsProvider;
+ this._sourceFileCache = Object.create(null);
+ }
+ invalidateCache(moduleId) {
+ this._sourceFileCache[moduleId] = null;
+ }
+ getDeclarationSourceFile(moduleId) {
+ if (!this._sourceFileCache[moduleId]) {
+ this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
+ }
+ return this._sourceFileCache[moduleId];
+ }
+ _getDeclarationSourceFile(moduleId) {
+ if (/\.d\.ts$/.test(moduleId)) {
+ const fileName = path.join(SRC, moduleId);
+ if (!this._fsProvider.existsSync(fileName)) {
return null;
}
- let fileContents = inputFiles[filePath];
- let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
- SOURCE_FILE_MAP[moduleId] = sourceFile;
+ const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
+ return ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5);
}
- return SOURCE_FILE_MAP[moduleId];
- };
+ const fileName = path.join(SRC, `${moduleId}.ts`);
+ if (!this._fsProvider.existsSync(fileName)) {
+ return null;
+ }
+ const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
+ const fileMap = {
+ 'file.ts': fileContents
+ };
+ const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
+ const text = service.getEmitOutput('file.ts', true).outputFiles[0].text;
+ return ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
+ }
+}
+exports.DeclarationResolver = DeclarationResolver;
+function run3(resolver) {
+ const sourceFileGetter = (moduleId) => resolver.getDeclarationSourceFile(moduleId);
return _run(sourceFileGetter);
}
-exports.run = run;
-function run2(out, sourceFileMap) {
- const sourceFileGetter = (moduleId) => {
- let filePath = path.normalize(moduleIdToPath(out, moduleId));
- return sourceFileMap[filePath];
- };
- return _run(sourceFileGetter);
-}
-exports.run2 = run2;
-function complainErrors() {
- logErr('Not running monaco.d.ts generation due to compile errors');
-}
-exports.complainErrors = complainErrors;
+exports.run3 = run3;
class TypeScriptLanguageServiceHost {
constructor(libs, files, compilerOptions) {
this._libs = libs;
@@ -415,28 +548,11 @@ class TypeScriptLanguageServiceHost {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
}
}
-exports.TypeScriptLanguageServiceHost = TypeScriptLanguageServiceHost;
function execute() {
- const OUTPUT_FILES = {};
- const SRC_FILES = {};
- const SRC_FILE_TO_EXPECTED_NAME = {};
- getIncludesInRecipe().forEach((moduleId) => {
- if (/\.d\.ts$/.test(moduleId)) {
- let fileName = path.join(SRC, moduleId);
- OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName).toString();
- return;
- }
- let fileName = path.join(SRC, moduleId) + '.ts';
- SRC_FILES[fileName] = fs.readFileSync(fileName).toString();
- SRC_FILE_TO_EXPECTED_NAME[fileName] = moduleIdToPath('src', moduleId);
- });
- const languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
- var t1 = Date.now();
- Object.keys(SRC_FILES).forEach((fileName) => {
- const emitOutput = languageService.getEmitOutput(fileName, true);
- OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
- });
- console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
- return run('src', OUTPUT_FILES);
+ let r = run3(new DeclarationResolver(new FSProvider()));
+ if (!r) {
+ throw new Error(`monaco.d.ts generation error - Cannot continue`);
+ }
+ return r;
}
exports.execute = execute;
diff --git a/build/monaco/api.ts b/build/monaco/api.ts
index 5b3fa8eb56f..d12b77787a0 100644
--- a/build/monaco/api.ts
+++ b/build/monaco/api.ts
@@ -8,34 +8,19 @@ import * as ts from 'typescript';
import * as path from 'path';
import * as util from 'gulp-util';
+const dtsv = '2';
+
const tsfmt = require('../../tsfmt.json');
-function log(message: any, ...rest: any[]): void {
- util.log(util.colors.cyan('[monaco.d.ts]'), message, ...rest);
-}
-
const SRC = path.join(__dirname, '../../src');
-const OUT_ROOT = path.join(__dirname, '../../');
export const RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
-var CURRENT_PROCESSING_RULE = '';
function logErr(message: any, ...rest: any[]): void {
- util.log(util.colors.red('[monaco.d.ts]'), 'WHILE HANDLING RULE: ', CURRENT_PROCESSING_RULE);
- util.log(util.colors.red('[monaco.d.ts]'), message, ...rest);
+ util.log(util.colors.yellow(`[monaco.d.ts]`), message, ...rest);
}
-function moduleIdToPath(out: string, moduleId: string): string {
- if (/\.d\.ts/.test(moduleId)) {
- return path.join(SRC, moduleId);
- }
- return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
-}
-
-export interface ISourceFileMap {
- [moduleId: string]: ts.SourceFile;
-}
-export type SourceFileGetter = (moduleId: string) => ts.SourceFile | null;
+type SourceFileGetter = (moduleId: string) => ts.SourceFile | null;
type TSTopLevelDeclaration = ts.InterfaceDeclaration | ts.EnumDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.ModuleDeclaration;
type TSTopLevelDeclare = TSTopLevelDeclaration | ts.VariableStatement;
@@ -152,7 +137,7 @@ function isDefaultExport(declaration: ts.InterfaceDeclaration | ts.ClassDeclarat
);
}
-function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[]): string {
+function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: string[]): string {
let result = getNodeText(sourceFile, declaration);
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
let interfaceDeclaration = declaration;
@@ -194,10 +179,22 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
+
+ if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
+ result = result.replace(/const enum/, 'enum');
+ enums.push(result);
+ }
+
return result;
}
-function format(text: string): string {
+function format(text: string, endl: string): string {
+ const REALLY_FORMAT = false;
+
+ text = preformat(text, endl);
+ if (!REALLY_FORMAT) {
+ return text;
+ }
// Parse the source text
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
@@ -208,6 +205,104 @@ function format(text: string): string {
// Apply the edits on the input code
return applyEdits(text, edits);
+ function countParensCurly(text: string): number {
+ let cnt = 0;
+ for (let i = 0; i < text.length; i++) {
+ if (text.charAt(i) === '(' || text.charAt(i) === '{') {
+ cnt++;
+ }
+ if (text.charAt(i) === ')' || text.charAt(i) === '}') {
+ cnt--;
+ }
+ }
+ return cnt;
+ }
+
+ function repeatStr(s: string, cnt: number): string {
+ let r = '';
+ for (let i = 0; i < cnt; i++) {
+ r += s;
+ }
+ return r;
+ }
+
+ function preformat(text: string, endl: string): string {
+ let lines = text.split(endl);
+ let inComment = false;
+ let inCommentDeltaIndent = 0;
+ let indent = 0;
+ for (let i = 0; i < lines.length; i++) {
+ let line = lines[i].replace(/\s$/, '');
+ let repeat = false;
+ let lineIndent = 0;
+ do {
+ repeat = false;
+ if (line.substring(0, 4) === ' ') {
+ line = line.substring(4);
+ lineIndent++;
+ repeat = true;
+ }
+ if (line.charAt(0) === '\t') {
+ line = line.substring(1);
+ lineIndent++;
+ repeat = true;
+ }
+ } while (repeat);
+
+ if (line.length === 0) {
+ continue;
+ }
+
+ if (inComment) {
+ if (/\*\//.test(line)) {
+ inComment = false;
+ }
+ lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line;
+ continue;
+ }
+
+ if (/\/\*/.test(line)) {
+ inComment = true;
+ inCommentDeltaIndent = indent - lineIndent;
+ lines[i] = repeatStr('\t', indent) + line;
+ continue;
+ }
+
+ const cnt = countParensCurly(line);
+ let shouldUnindentAfter = false;
+ let shouldUnindentBefore = false;
+ if (cnt < 0) {
+ if (/[({]/.test(line)) {
+ shouldUnindentAfter = true;
+ } else {
+ shouldUnindentBefore = true;
+ }
+ } else if (cnt === 0) {
+ shouldUnindentBefore = /^\}/.test(line);
+ }
+ let shouldIndentAfter = false;
+ if (cnt > 0) {
+ shouldIndentAfter = true;
+ } else if (cnt === 0) {
+ shouldIndentAfter = /{$/.test(line);
+ }
+
+ if (shouldUnindentBefore) {
+ indent--;
+ }
+
+ lines[i] = repeatStr('\t', indent) + line;
+
+ if (shouldUnindentAfter) {
+ indent--;
+ }
+ if (shouldIndentAfter) {
+ indent++;
+ }
+ }
+ return lines.join(endl);
+ }
+
function getRuleProvider(options: ts.FormatCodeSettings) {
// Share this between multiple formatters using the same options.
// This represents the bulk of the space the formatter uses.
@@ -252,7 +347,13 @@ function createReplacer(data: string): (str: string) => string {
};
}
-function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGetter): [string, string] {
+interface ITempResult {
+ result: string;
+ usageContent: string;
+ enums: string;
+}
+
+function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null {
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
let lines = recipe.split(endl);
@@ -262,6 +363,8 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
let usageImports: string[] = [];
let usage: string[] = [];
+ let failed = false;
+
usage.push(`var a;`);
usage.push(`var b;`);
@@ -271,14 +374,28 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
return importName;
};
+ let enums: string[] = [];
+ let version: string | null = null;
+
lines.forEach(line => {
+ if (failed) {
+ return;
+ }
+
+ let m0 = line.match(/^\/\/dtsv=(\d+)$/);
+ if (m0) {
+ version = m0[1];
+ }
+
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
- CURRENT_PROCESSING_RULE = line;
let moduleId = m1[1];
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
+ logErr(`While handling ${line}`);
+ logErr(`Cannot find ${moduleId}`);
+ failed = true;
return;
}
@@ -294,20 +411,24 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
}
let declaration = getTopLevelDeclaration(sourceFile, typeName);
if (!declaration) {
- logErr('Cannot find type ' + typeName);
+ logErr(`While handling ${line}`);
+ logErr(`Cannot find ${typeName}`);
+ failed = true;
return;
}
- result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
+ result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
- CURRENT_PROCESSING_RULE = line;
let moduleId = m2[1];
const sourceFile = sourceFileGetter(moduleId);
if (!sourceFile) {
+ logErr(`While handling ${line}`);
+ logErr(`Cannot find ${moduleId}`);
+ failed = true;
return;
}
@@ -341,7 +462,7 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
}
}
}
- result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
+ result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
});
return;
}
@@ -349,63 +470,66 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
result.push(line);
});
+ if (failed) {
+ return null;
+ }
+
+ if (version !== dtsv) {
+ if (!version) {
+ logErr(`gulp watch restart required. 'monaco.d.ts.recipe' is written before versioning was introduced.`);
+ } else {
+ logErr(`gulp watch restart required. 'monaco.d.ts.recipe' v${version} does not match runtime v${dtsv}.`);
+ }
+ return null;
+ }
+
let resultTxt = result.join(endl);
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent {
-
- let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
- if (m1) {
- let moduleId = m1[1];
- result.push(moduleId);
- return;
- }
-
- let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
- if (m2) {
- let moduleId = m2[1];
- result.push(moduleId);
- return;
- }
- });
-
- return result;
-}
-
-export function getFilesToWatch(out: string): string[] {
- return getIncludesInRecipe().map((moduleId) => moduleIdToPath(out, moduleId));
+ return {
+ result: resultTxt,
+ usageContent: `${usageImports.join('\n')}\n\n${usage.join('\n')}`,
+ enums: resultEnums
+ };
}
export interface IMonacoDeclarationResult {
content: string;
usageContent: string;
+ enums: string;
filePath: string;
isTheSame: boolean;
}
-function _run(sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult {
- log('Starting monaco.d.ts generation');
+function _run(sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult | null {
+ const recipe = fs.readFileSync(RECIPE_PATH).toString();
+ const t = generateDeclarationFile(recipe, sourceFileGetter);
+ if (!t) {
+ return null;
+ }
- let recipe = fs.readFileSync(RECIPE_PATH).toString();
- let [result, usageContent] = generateDeclarationFile(recipe, sourceFileGetter);
-
- let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
- log('Finished monaco.d.ts generation');
+ const result = t.result;
+ const usageContent = t.usageContent;
+ const enums = t.enums;
+ const currentContent = fs.readFileSync(DECLARATION_PATH).toString();
const one = currentContent.replace(/\r\n/gm, '\n');
const other = result.replace(/\r\n/gm, '\n');
const isTheSame = (one === other);
@@ -413,53 +537,75 @@ function _run(sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult {
return {
content: result,
usageContent: usageContent,
+ enums: enums,
filePath: DECLARATION_PATH,
isTheSame
};
}
-export function run(out: string, inputFiles: { [file: string]: string; }): IMonacoDeclarationResult {
+export class FSProvider {
+ public existsSync(filePath: string): boolean {
+ return fs.existsSync(filePath);
+ }
+ public readFileSync(_moduleId: string, filePath: string): Buffer {
+ return fs.readFileSync(filePath);
+ }
+}
- let SOURCE_FILE_MAP: { [moduleId: string]: ts.SourceFile; } = {};
- const sourceFileGetter = (moduleId: string): ts.SourceFile | null => {
- if (!SOURCE_FILE_MAP[moduleId]) {
- let filePath = path.normalize(moduleIdToPath(out, moduleId));
+export class DeclarationResolver {
- if (!inputFiles.hasOwnProperty(filePath)) {
- logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
+ private _sourceFileCache: { [moduleId: string]: ts.SourceFile | null; };
+
+ constructor(private readonly _fsProvider: FSProvider) {
+ this._sourceFileCache = Object.create(null);
+ }
+
+ public invalidateCache(moduleId: string): void {
+ this._sourceFileCache[moduleId] = null;
+ }
+
+ public getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
+ if (!this._sourceFileCache[moduleId]) {
+ this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
+ }
+ return this._sourceFileCache[moduleId];
+ }
+
+ private _getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
+ if (/\.d\.ts$/.test(moduleId)) {
+ const fileName = path.join(SRC, moduleId);
+ if (!this._fsProvider.existsSync(fileName)) {
return null;
}
-
- let fileContents = inputFiles[filePath];
- let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
-
- SOURCE_FILE_MAP[moduleId] = sourceFile;
+ const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
+ return ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5);
}
- return SOURCE_FILE_MAP[moduleId];
- };
+ const fileName = path.join(SRC, `${moduleId}.ts`);
+ if (!this._fsProvider.existsSync(fileName)) {
+ return null;
+ }
+ const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
+ const fileMap: IFileMap = {
+ 'file.ts': fileContents
+ };
+ const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
+ const text = service.getEmitOutput('file.ts', true).outputFiles[0].text;
+ return ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
+ }
+}
+export function run3(resolver: DeclarationResolver): IMonacoDeclarationResult | null {
+ const sourceFileGetter = (moduleId: string) => resolver.getDeclarationSourceFile(moduleId);
return _run(sourceFileGetter);
}
-export function run2(out: string, sourceFileMap: ISourceFileMap): IMonacoDeclarationResult {
- const sourceFileGetter = (moduleId: string): ts.SourceFile | null => {
- let filePath = path.normalize(moduleIdToPath(out, moduleId));
- return sourceFileMap[filePath];
- };
-
- return _run(sourceFileGetter);
-}
-
-export function complainErrors() {
- logErr('Not running monaco.d.ts generation due to compile errors');
-}
interface ILibMap { [libName: string]: string; }
interface IFileMap { [fileName: string]: string; }
-export class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
+class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
private readonly _libs: ILibMap;
private readonly _files: IFileMap;
@@ -513,30 +659,9 @@ export class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
}
export function execute(): IMonacoDeclarationResult {
-
- const OUTPUT_FILES: { [file: string]: string; } = {};
- const SRC_FILES: IFileMap = {};
- const SRC_FILE_TO_EXPECTED_NAME: { [filename: string]: string; } = {};
- getIncludesInRecipe().forEach((moduleId) => {
- if (/\.d\.ts$/.test(moduleId)) {
- let fileName = path.join(SRC, moduleId);
- OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName).toString();
- return;
- }
-
- let fileName = path.join(SRC, moduleId) + '.ts';
- SRC_FILES[fileName] = fs.readFileSync(fileName).toString();
- SRC_FILE_TO_EXPECTED_NAME[fileName] = moduleIdToPath('src', moduleId);
- });
-
- const languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
-
- var t1 = Date.now();
- Object.keys(SRC_FILES).forEach((fileName) => {
- const emitOutput = languageService.getEmitOutput(fileName, true);
- OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
- });
- console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
-
- return run('src', OUTPUT_FILES);
+ let r = run3(new DeclarationResolver(new FSProvider()));
+ if (!r) {
+ throw new Error(`monaco.d.ts generation error - Cannot continue`);
+ }
+ return r;
}
diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe
index d1b4e5d873a..356ef3ff046 100644
--- a/build/monaco/monaco.d.ts.recipe
+++ b/build/monaco/monaco.d.ts.recipe
@@ -25,21 +25,12 @@ declare namespace monaco {
dispose(): void;
}
- export enum MarkerTag {
- Unnecessary = 1,
- }
-
- export enum MarkerSeverity {
- Hint = 1,
- Info = 2,
- Warning = 4,
- Error = 8,
- }
-
+#include(vs/platform/markers/common/markers): MarkerTag, MarkerSeverity
#include(vs/base/common/winjs.base.d.ts): Promise
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI, UriComponents
-#include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod
+#include(vs/base/common/keyCodes): KeyCode
+#include(vs/editor/common/standalone/standaloneBase): KeyMod
#include(vs/base/common/htmlContent): IMarkdownString
#include(vs/base/browser/keyboardEvent): IKeyboardEvent
#include(vs/base/browser/mouseEvent): IMouseEvent
@@ -58,7 +49,7 @@ declare namespace monaco.editor {
#include(vs/editor/common/services/webWorker): MonacoWebWorker, IWebWorkerOptions
#include(vs/editor/standalone/browser/standaloneCodeEditor): IActionDescriptor, IEditorConstructionOptions, IDiffEditorConstructionOptions, IStandaloneCodeEditor, IStandaloneDiffEditor
export interface ICommandHandler {
- (...args:any[]): void;
+ (...args: any[]): void;
}
#include(vs/platform/contextkey/common/contextkey): IContextKey
#include(vs/editor/standalone/browser/standaloneServices): IEditorOverrideServices
@@ -94,3 +85,5 @@ declare namespace monaco.worker {
#includeAll(vs/editor/common/services/editorSimpleWorker;):
}
+
+//dtsv=2
\ No newline at end of file
diff --git a/build/npm/update-all-grammars.js b/build/npm/update-all-grammars.js
index 3ff7254c3e2..9ca9f85616c 100644
--- a/build/npm/update-all-grammars.js
+++ b/build/npm/update-all-grammars.js
@@ -39,7 +39,7 @@ extensions.forEach(extension => updateGrammar(`extensions/${extension}`));
// run integration tests
if (process.platform === 'win32') {
- cp.spawn('.\scripts\test-integration.bat', [], { env: process.env, stdio: 'inherit' });
+ cp.spawn('.\\scripts\\test-integration.bat', [], { env: process.env, stdio: 'inherit' });
} else {
cp.spawn('/bin/bash', ['./scripts/test-integration.sh'], { env: process.env, stdio: 'inherit' });
}
diff --git a/build/npm/update-grammar.js b/build/npm/update-grammar.js
index 2ccd808e152..c009e36285c 100644
--- a/build/npm/update-grammar.js
+++ b/build/npm/update-grammar.js
@@ -119,7 +119,7 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas
}
try {
- fs.writeFileSync(dest, JSON.stringify(result, null, '\t'));
+ fs.writeFileSync(dest, JSON.stringify(result, null, '\t').replace(/\n/g, '\r\n'));
if (info) {
console.log('Updated ' + path.basename(dest) + ' to ' + repoId + '@' + info.commitSha.substr(0, 7) + ' (' + info.commitDate.substr(0, 10) + ')');
} else {
diff --git a/build/package.json b/build/package.json
index 9ad3ffbe133..7e096ee9bab 100644
--- a/build/package.json
+++ b/build/package.json
@@ -16,6 +16,8 @@
"@types/gulp-util": "^3.0.34",
"@types/mime": "0.0.29",
"@types/minimatch": "^3.0.3",
+ "@types/minimist": "^1.2.0",
+ "@types/mocha": "2.2.39",
"@types/node": "8.0.33",
"@types/pump": "^1.0.1",
"@types/request": "^2.47.0",
@@ -25,15 +27,19 @@
"@types/uglify-es": "^3.0.0",
"@types/underscore": "^1.8.9",
"@types/xml2js": "0.0.33",
+ "applicationinsights": "1.0.6",
"azure-storage": "^2.1.0",
"documentdb": "1.13.0",
"github-releases": "^0.4.1",
"gulp-bom": "^1.0.0",
"gulp-sourcemaps": "^1.11.0",
+ "iconv-lite": "0.4.23",
"mime": "^1.3.4",
"minimist": "^1.2.0",
"request": "^2.85.0",
- "typescript": "3.1.1",
+ "tslint": "^5.9.1",
+ "typescript": "3.1.4",
+ "vsce": "1.48.0",
"xml2js": "^0.4.17"
},
"scripts": {
diff --git a/build/tfs/common/publish.ts b/build/tfs/common/publish.ts
index 7a74dc6106e..2095c2d2532 100644
--- a/build/tfs/common/publish.ts
+++ b/build/tfs/common/publish.ts
@@ -265,6 +265,11 @@ async function publish(commit: string, quality: string, platform: string, type:
}
function main(): void {
+ if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) {
+ console.warn('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH');
+ return;
+ }
+
const opts = minimist(process.argv.slice(2), {
boolean: ['upload-only']
});
diff --git a/build/tfs/darwin/continuous-build-darwin.yml b/build/tfs/darwin/continuous-build-darwin.yml
index 28e2a6079ab..99e17e940a6 100644
--- a/build/tfs/darwin/continuous-build-darwin.yml
+++ b/build/tfs/darwin/continuous-build-darwin.yml
@@ -32,17 +32,6 @@ steps:
- script: |
./scripts/test-integration.sh --tfs "Integration Tests"
displayName: Run Integration Tests
-- script: |
- yarn smoketest --screenshots "$(Build.ArtifactStagingDirectory)/artifacts" --log "$(Build.ArtifactStagingDirectory)/artifacts/smoketest.log"
- displayName: Run Smoke Tests
- continueOnError: true
-- task: PublishBuildArtifacts@1
- displayName: Publish Smoketest Artifacts
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
- ArtifactName: build-artifacts-darwin
- publishLocation: Container
- condition: eq(variables['System.PullRequest.IsFork'], 'False')
- task: PublishTestResults@2
displayName: Publish Tests Results
inputs:
diff --git a/build/tfs/darwin/enqueue.js b/build/tfs/darwin/enqueue.js
deleted file mode 100644
index d2243ad6ae1..00000000000
--- a/build/tfs/darwin/enqueue.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-Object.defineProperty(exports, "__esModule", { value: true });
-const child_process_1 = require("child_process");
-const azure = require("azure-storage");
-function queueSigningRequest(quality, commit) {
- const retryOperations = new azure.ExponentialRetryPolicyFilter();
- const queueSvc = azure
- .createQueueService(process.env['AZURE_STORAGE_ACCOUNT_2'], process.env['AZURE_STORAGE_ACCESS_KEY_2'])
- .withFilter(retryOperations);
- queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder();
- const message = `${quality}/${commit}`;
- return new Promise((c, e) => queueSvc.createMessage('sign-darwin', message, err => err ? e(err) : c()));
-}
-async function main(quality) {
- const commit = child_process_1.execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
- console.log(`Queueing signing request for '${quality}/${commit}'...`);
- await queueSigningRequest(quality, commit);
- // console.log('Waiting on signed build...');
- // await waitForSignedBuild(quality, commit);
- // console.log('Found signed build!');
-}
-main(process.argv[2]).catch(err => {
- console.error(err);
- process.exit(1);
-});
diff --git a/build/tfs/darwin/enqueue.ts b/build/tfs/darwin/enqueue.ts
deleted file mode 100644
index 2da255b0b97..00000000000
--- a/build/tfs/darwin/enqueue.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-'use strict';
-
-import { execSync } from 'child_process';
-import * as azure from 'azure-storage';
-
-
-function queueSigningRequest(quality: string, commit: string): Promise {
- const retryOperations = new azure.ExponentialRetryPolicyFilter();
- const queueSvc = azure
- .createQueueService(process.env['AZURE_STORAGE_ACCOUNT_2']!, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
- .withFilter(retryOperations);
-
- queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder();
-
- const message = `${quality}/${commit}`;
-
- return new Promise((c, e) => queueSvc.createMessage('sign-darwin', message, err => err ? e(err) : c()));
-}
-
-
-async function main(quality: string): Promise {
- const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
-
- console.log(`Queueing signing request for '${quality}/${commit}'...`);
- await queueSigningRequest(quality, commit);
-
- // console.log('Waiting on signed build...');
- // await waitForSignedBuild(quality, commit);
-
- // console.log('Found signed build!');
-}
-
-main(process.argv[2]).catch(err => {
- console.error(err);
- process.exit(1);
-});
\ No newline at end of file
diff --git a/build/tfs/darwin/product-build-darwin.yml b/build/tfs/darwin/product-build-darwin.yml
index f5520d06036..e5fa44ac50d 100644
--- a/build/tfs/darwin/product-build-darwin.yml
+++ b/build/tfs/darwin/product-build-darwin.yml
@@ -84,4 +84,7 @@ steps:
# upload configuration
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
yarn gulp -- upload-vscode-configuration
- displayName: Publish
\ No newline at end of file
+ displayName: Publish
+
+- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
+ displayName: 'Component Detection'
diff --git a/build/tfs/linux/.gitignore b/build/tfs/linux/.gitignore
index 5ca5f22fc5a..0f46fa7086a 100644
--- a/build/tfs/linux/.gitignore
+++ b/build/tfs/linux/.gitignore
@@ -1,2 +1 @@
-pat
-*.js
\ No newline at end of file
+pat
\ No newline at end of file
diff --git a/build/tfs/linux/frozen-check.js b/build/tfs/linux/frozen-check.js
new file mode 100644
index 00000000000..281632424b7
--- /dev/null
+++ b/build/tfs/linux/frozen-check.js
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+Object.defineProperty(exports, "__esModule", { value: true });
+const documentdb_1 = require("documentdb");
+function createDefaultConfig(quality) {
+ return {
+ id: quality,
+ frozen: false
+ };
+}
+function getConfig(quality) {
+ const client = new documentdb_1.DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT'], { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
+ const collection = 'dbs/builds/colls/config';
+ const query = {
+ query: `SELECT TOP 1 * FROM c WHERE c.id = @quality`,
+ parameters: [
+ { name: '@quality', value: quality }
+ ]
+ };
+ return new Promise((c, e) => {
+ client.queryDocuments(collection, query).toArray((err, results) => {
+ if (err && err.code !== 409) {
+ return e(err);
+ }
+ c(!results || results.length === 0 ? createDefaultConfig(quality) : results[0]);
+ });
+ });
+}
+getConfig(process.argv[2])
+ .then(config => {
+ console.log(config.frozen);
+ process.exit(0);
+})
+ .catch(err => {
+ console.error(err);
+ process.exit(1);
+});
diff --git a/build/tfs/linux/frozen-check.ts b/build/tfs/linux/frozen-check.ts
deleted file mode 100644
index 09bc36a2406..00000000000
--- a/build/tfs/linux/frozen-check.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-'use strict';
-
-import { DocumentClient } from 'documentdb';
-
-interface Config {
- id: string;
- frozen: boolean;
-}
-
-function createDefaultConfig(quality: string): Config {
- return {
- id: quality,
- frozen: false
- };
-}
-
-function getConfig(quality: string): Promise {
- const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
- const collection = 'dbs/builds/colls/config';
- const query = {
- query: `SELECT TOP 1 * FROM c WHERE c.id = @quality`,
- parameters: [
- { name: '@quality', value: quality }
- ]
- };
-
- return new Promise((c, e) => {
- client.queryDocuments(collection, query).toArray((err, results) => {
- if (err && err.code !== 409) { return e(err); }
-
- c(!results || results.length === 0 ? createDefaultConfig(quality) : results[0] as any as Config);
- });
- });
-}
-
-getConfig(process.argv[2])
- .then(config => {
- console.log(config.frozen);
- process.exit(0);
- })
- .catch(err => {
- console.error(err);
- process.exit(1);
- });
\ No newline at end of file
diff --git a/build/tfs/linux/ia32/Dockerfile b/build/tfs/linux/ia32/Dockerfile
deleted file mode 100644
index 25d621d99fb..00000000000
--- a/build/tfs/linux/ia32/Dockerfile
+++ /dev/null
@@ -1,53 +0,0 @@
-FROM microsoft/vsts-agent:ubuntu-14.04-standard
-MAINTAINER Joao Moreno
-
-ARG DEBIAN_FRONTEND=noninteractive
-RUN dpkg --add-architecture i386
-RUN apt-get update
-
-# Dependencies
-RUN apt-get install -y build-essential
-RUN apt-get install -y gcc-multilib g++-multilib
-RUN apt-get install -y git
-RUN apt-get install -y zip
-RUN apt-get install -y rpm
-RUN apt-get install -y createrepo
-RUN apt-get install -y python-gtk2
-RUN apt-get install -y jq
-RUN apt-get install -y xvfb
-RUN apt-get install -y fakeroot
-RUN apt-get install -y libgtk2.0-0:i386
-RUN apt-get install -y libgconf-2-4:i386
-RUN apt-get install -y libnss3:i386
-RUN apt-get install -y libasound2:i386
-RUN apt-get install -y libxtst6:i386
-RUN apt-get install -y libfuse2
-RUN apt-get install -y libnotify-bin
-RUN apt-get install -y libnotify4:i386
-RUN apt-get install -y libx11-dev:i386
-RUN apt-get install -y libxkbfile-dev:i386
-RUN apt-get install -y libxss1:i386
-RUN apt-get install -y libx11-xcb-dev:i386
-RUN apt-get install -y libgl1-mesa-glx:i386 libgl1-mesa-dri:i386
-RUN apt-get install -y libxkbfile-dev
-RUN apt-get install -y bc bsdmainutils
-RUN apt-get install -y libgirepository-1.0-1:i386 gir1.2-glib-2.0:i386 gir1.2-secret-1:i386 libsecret-1-dev:i386
-RUN apt-get install -y dpkg-dev:i386
-
-# Xvfb
-# Thanks https://medium.com/@griggheo/running-headless-selenium-webdriver-tests-in-docker-containers-342fdbabf756
-ADD xvfb.init /etc/init.d/xvfb
-RUN chmod +x /etc/init.d/xvfb
-RUN update-rc.d xvfb defaults
-
-# dbus
-RUN ln -sf /bin/dbus-daemon /usr/bin/dbus-daemon
-
-# nvm
-ENV NVM_DIR /usr/local/nvm
-RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
-
-# for libsecret
-ENV PKG_CONFIG_PATH /usr/lib/i386-linux-gnu/pkgconfig
-
-CMD (service xvfb start; service dbus start; export DISPLAY=:10; ./start.sh)
\ No newline at end of file
diff --git a/build/tfs/linux/ia32/run-agent.sh b/build/tfs/linux/ia32/run-agent.sh
deleted file mode 100755
index bcf9017f3cf..00000000000
--- a/build/tfs/linux/ia32/run-agent.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-if [ ! -f pat ]; then
- echo "Error: file pat not found"
- exit 1
-fi
-
-docker run \
- -e VSTS_ACCOUNT="monacotools" \
- -e VSTS_TOKEN="$(cat pat)" \
- -e VSTS_AGENT="tb-lnx-ia32-local" \
- -e VSTS_POOL="linux-ia32" \
- -e VSTS_WORK="/var/vsts/work" \
- --name "tb-lnx-ia32-local" \
- -it joaomoreno/vscode-vso-agent-ia32:latest
\ No newline at end of file
diff --git a/build/tfs/linux/ia32/xvfb.init b/build/tfs/linux/ia32/xvfb.init
deleted file mode 100644
index 4d77d253a26..00000000000
--- a/build/tfs/linux/ia32/xvfb.init
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-#
-# /etc/rc.d/init.d/xvfbd
-#
-# chkconfig: 345 95 28
-# description: Starts/Stops X Virtual Framebuffer server
-# processname: Xvfb
-#
-### BEGIN INIT INFO
-# Provides: xvfb
-# Required-Start: $remote_fs $syslog
-# Required-Stop: $remote_fs $syslog
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Start xvfb at boot time
-# Description: Enable xvfb provided by daemon.
-### END INIT INFO
-
-[ "${NETWORKING}" = "no" ] && exit 0
-
-PROG="/usr/bin/Xvfb"
-PROG_OPTIONS=":10 -ac"
-PROG_OUTPUT="/tmp/Xvfb.out"
-
-case "$1" in
- start)
- echo "Starting : X Virtual Frame Buffer "
- $PROG $PROG_OPTIONS>>$PROG_OUTPUT 2>&1 &
- disown -ar
- ;;
- stop)
- echo "Shutting down : X Virtual Frame Buffer"
- killproc $PROG
- RETVAL=$?
- [ $RETVAL -eq 0 ] && /bin/rm -f /var/lock/subsys/Xvfb
- /var/run/Xvfb.pid
- echo
- ;;
- restart|reload)
- $0 stop
- $0 start
- RETVAL=$?
- ;;
- status)
- status Xvfb
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $0 (start|stop|restart|reload|status)"
- exit 1
-esac
-
-exit $RETVAL
\ No newline at end of file
diff --git a/build/tfs/linux/new_package.json.template b/build/tfs/linux/new_package.json.template
deleted file mode 100644
index 77e2ada928e..00000000000
--- a/build/tfs/linux/new_package.json.template
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "PACKAGENAME",
- "version": "PACKAGEVERSION",
- "repositoryId": "REPOSITORYID",
- "sourceUrl": "PACKAGEURL"
-}
\ No newline at end of file
diff --git a/build/tfs/linux/product-build-linux.yml b/build/tfs/linux/product-build-linux.yml
index 7a8c637ef84..12269a80cfb 100644
--- a/build/tfs/linux/product-build-linux.yml
+++ b/build/tfs/linux/product-build-linux.yml
@@ -92,5 +92,20 @@ steps:
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/tfs/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH"
- # SNAP_FILENAME="$(ls $REPO/.build/linux/snap/$ARCH/ | grep .snap)"
- # SNAP_PATH="$REPO/.build/linux/snap/$ARCH/$SNAP_FILENAME"
+ # Publish Snap
+ npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-prepare-snap"
+
+ # Pack snap tarball artifact, in order to preserve file perms
+ mkdir -p $REPO/.build/linux/snap-tarball
+ SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz"
+ rm -rf $SNAP_TARBALL_PATH
+ (cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap)
+
+- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
+ displayName: 'Component Detection'
+
+- task: PublishPipelineArtifact@0
+ displayName: 'Publish Pipeline Artifact'
+ inputs:
+ artifactName: snap-$(VSCODE_ARCH)
+ targetPath: .build/linux/snap-tarball
diff --git a/build/tfs/linux/repoapi_client.sh b/build/tfs/linux/repoapi_client.sh
deleted file mode 100755
index b700aceff03..00000000000
--- a/build/tfs/linux/repoapi_client.sh
+++ /dev/null
@@ -1,365 +0,0 @@
-#!/bin/bash -e
-# This is a VERY basic script for Create/Delete operations on repos and packages
-#
-cmd=$1
-docDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # chrmarti: Changed to script's directory.
-packageJsonTemplate=$docDir/new_package.json.template
-repoJsonTemplate=$docDir/new_repo.json.template
-
-function Bail
-{
- echo "ERROR: $@"
- exit 1
-}
-
-function BailIfFileMissing {
- file="$1"
- if [ ! -f "$file" ]; then
- Bail "File $file does not exist"
- fi
-}
-
-function Usage {
- echo "USAGE: Manage repos and packages in an apt repository"
- echo "$0 -config FILENAME -listrepos | -listpkgs | -addrepo FILENAME | -addpkg FILENAME |"
- echo "-addpkgs FILENAME | -check ID | -delrepo REPOID | -delpkg PKGID"
- echo -e "\t-config FILENAME : JSON file containing API server name and creds"
- echo -e "Package Operations:"
- echo -e "\t-listpkgs [REGEX] : List packages, optionally filter by REGEX"
- echo -e "\t-addpkg FILENAME : Add package to repo using the specified JSON file"
- echo -e "\t-addpkgs FILENAME : Add packages to repo using urls contained in FILENAME"
- echo -e "\t-check ID : Check upload operation by ID"
- echo -e "\t-delpkg PKGID : Delete the specified package by ID"
- echo -e "File Operations:"
- echo -e "\t-uploadfile FILENAME: Upload FILENAME (does not publish) "
- echo -e "\t-addfile FILENAME : Upload FILENAME AND publish to the repo"
- echo -e "\t-listfiles : List uploaded files"
- echo -e "\t-delfile FILEID : Delete uploaded file by ID"
- echo -e "Repository Operations:"
- echo -e "\t-listrepos : List repositories"
- echo -e "\t-addrepo FILENAME : Create a new repo using the specified JSON file"
- echo -e "\t-delrepo REPOID : Delete the specified repo by ID"
- exit 1
-}
-
-function ParseFromJson {
- if [ -z "$secretContents" ]; then
- Bail "Unable to parse value because no JSON contents were specified"
- elif [ -z "$1" ]; then
- Bail "Unable to parse value from JSON because no key was specified"
- fi
- # Write value directly to stdout to be used by caller
- echo $secretContents | jq "$1" | tr -d '"'
-}
-
-function ParseConfigFile {
- configFile="$1"
- if [ -z "$configFile" ]; then
- echo "Must specify -config option"
- Usage
- fi
- BailIfFileMissing "$configFile"
- secretContents=$(cat "$configFile")
-
- server=$(ParseFromJson .server)
- protocol=$(ParseFromJson .protocol)
- port=$(ParseFromJson .port)
- repositoryId=$(ParseFromJson .repositoryId)
- user=$(ParseFromJson .username)
- pass=$(ParseFromJson .password)
- baseurl="$protocol://$user:$pass@$server:$port"
-}
-
-# List Repositories
-function ListRepositories
-{
- echo "Fetching repo list from $server..."
- curl -k "$baseurl/v1/repositories" | sed 's/,/,\n/g' | sed 's/^"/\t"/g'
- echo ""
-}
-
-# List packages, using $1 as a regex to filter results
-function ListPackages
-{
- echo "Fetching package list from $server"
- curl -k "$baseurl/v1/packages" | sed 's/{/\n{/g' | egrep "$1" | sed 's/,/,\n/g' | sed 's/^"/\t"/g'
- echo ""
-}
-
-# Create a new Repo using the specified JSON file
-function AddRepo
-{
- repoFile=$1
- if [ -z $repoFile ]; then
- Bail "Error: Must specify a JSON-formatted file. Reference $repoJsonTemplate"
- fi
- if [ ! -f $repoFile ]; then
- Bail "Error: Cannot create repo - $repoFile does not exist"
- fi
- packageUrl=$(grep "url" $repoFile | head -n 1 | awk '{print $2}' | tr -d ',')
- echo "Creating new repo on $server [$packageUrl]"
- curl -i -k "$baseurl/v1/repositories" --data @$repoFile -H "Content-Type: application/json"
- echo ""
-}
-
-# Upload AND publish the file
-function AddFile
-{
- packageFile=$1
- # Validity checks are performed by UploadFile
- echo "Uploading package to $server [$packageFile]"
- response=$(UploadFile $packageFile "true")
- id=$(echo $response | jq -r ".id")
-
- # Parse package metadata first to confirm it's a valid deb/rpm
- # Needs to be performed in this function so we can use it to publish the package
- jsonFile=$(WritePackageInfoToFile $packageFile)
-
- sed -i "s/REPOSITORYID/$repositoryId/g" $jsonFile
- # Replace the url field with fileId
- sed -i "s/PACKAGEURL/$id/g" $jsonFile
- sed -i "s/sourceUrl/fileId/g" $jsonFile
-
- AddPackage $jsonFile
- rm -f $jsonFile
- echo ""
-}
-
-# Upload a file
-function UploadFile
-{
- packageFile=$1
- quick=$2
- if [ -z $packageFile ]; then
- Bail "Error: Must specify the path to a file to upload "
- fi
- if [ ! -f $packageFile ]; then
- Bail "Error: Cannot upload - $packageFile does not exist"
- fi
-
- # Additional validation and output if quick mode isn't enabled
- # Basically, if this is part of a publish operation, these steps are handled elsewhere
- if [ "$quick" != "true" ]; then
- # Parse package metadata first to confirm it's a valid deb/rpm
- jsonFile=$(WritePackageInfoToFile $packageFile)
- rm -f $jsonFile
-
- echo "Uploading package to $server [$packageFile]"
- fi
- curl -s -k -X POST -F file=@$packageFile "$baseurl/v1/files"
- echo ""
-}
-
-function ListFiles
-{
- curl -s -k "$baseurl/v1/files" | jq
-}
-
-function DeleteFile
-{
- fileId=$1
- if [ -z "$fileId" ]; then
- Bail "Error: Must specify an ID to delete"
- fi
- curl -s -X DELETE "$baseurl/v1/files/$fileId"
-}
-
-# Upload a single package using the specified JSON file
-function AddPackage
-{
- packageFile=$1
- if [ -z $packageFile ]; then
- Bail "Error: Must specify a JSON-formatted file. Reference $packageJsonTemplate"
- fi
- if [ ! -f $packageFile ]; then
- Bail "Error: Cannot add package - $packageFile does not exist"
- fi
- packageUrl=$(grep "sourceUrl" $packageFile | head -n 1 | awk '{print $2}')
- echo "Adding package to $server [$packageUrl]"
- curl -i -k "$baseurl/v1/packages" --data @$packageFile -H "Content-Type: application/json"
- echo ""
-}
-
-# Gets the package name and version and writes it to a file
-function WritePackageInfoToFile
-{
- packageFile=$1
- tmpOut=$(mktemp)
- if [ -z "$packageFile" ]; then
- Bail "Error: Must specify path to a deb/rpm package"
- elif [ ! -f "$packageFile" ]; then
- Bail "Error: Specified file $packageFile does not exist"
- fi
- if dpkg -I $packageFile > $tmpOut 2> /dev/null; then
- >&2 echo "File is deb format"
- pkgName=$(grep "^\s*Package:" $tmpOut | awk '{print $2}')
- pkgVer=$(grep "^\s*Version:" $tmpOut | awk '{print $2}')
- elif rpm -qpi $packageFile > $tmpOut 2> /dev/null; then
- >&2 echo "File is rpm format"
- pkgName=$(egrep "^Name" $tmpOut | tr -d ':' | awk '{print $2}')
- pkgVer=$(egrep "^Version" $tmpOut | tr -d ':' | awk '{print $2}')
- else
- rm -f $tmpOut
- Bail "File is not a valid deb/rpm package $url"
- fi
-
- rm -f $tmpOut
- if [ -z "$pkgName" ]; then
- Bail "Unable to parse package name for $url"
- elif [ -z "$pkgVer" ]; then
- Bail "Unable to parse package version number for $url"
- fi
-
- # Create Package .json file
- outJson=$(mktemp)
- escapedUrl=$(echo "$url" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g')
- cp $packageJsonTemplate $outJson
- sed -i "s/PACKAGENAME/$pkgName/g" $outJson
- sed -i "s/PACKAGEVERSION/$pkgVer/g" $outJson
-
- # Return path to json file
- echo $outJson
-}
-
-# Upload a single package by dynamically creating a JSON file using a provided URL
-function AddPackageByUrl
-{
- url=$(echo "$1")
- if [ -z "$url" ]; then
- Bail "Unable to publish package because no URL was specified"
- fi
- tmpFile=$(mktemp)
- if ! wget -q "$url" -O $tmpFile; then
- rm -f $tmpFile
- Bail "Unable to download URL $url"
- fi
-
- jsonFile=$(WritePackageInfoToFile $tmpFile)
- # Create Package .json file
- escapedUrl=$(echo "$url" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g')
- sed -i "s/PACKAGEURL/$escapedUrl/g" $jsonFile
- sed -i "s/REPOSITORYID/$repositoryId/g" $jsonFile
- # Perform Upload
- AddPackage $jsonFile
- # Cleanup
- rm -f $jsonFile
-}
-
-# Upload multiple packages by reading urls line-by-line from the specified file
-function AddPackages
-{
- urlFile=$1
- if [ -z $urlFile ]; then
- Bail "Must specify a flat text file containing one or more URLs"
- fi
- if [ ! -f $urlFile ]; then
- Bail "Cannot add packages. File $urlFile does not exist"
- fi
- for url in $(cat $urlFile); do
- if [ -n "$url" ]; then
- AddPackageByUrl "$url"
- fi
- sleep 5
- done
-}
-
-# Check upload by ID
-function CheckUpload {
- id=$1
- if [ -z "$id" ]; then
- Bail "Must specify an ID"
- fi
- curl -s -k $baseurl/v1/packages/queue/$id | jq
- echo ""
-}
-
-# Delete the specified repo
-function DeleteRepo
-{
- repoId=$1
- if [ -z $repoId ]; then
- Bail "Please specify repository ID. Run -listrepos for a list of IDs"
- fi
- curl -I -k -X DELETE "$baseurl/v1/repositories/$repoId"
-}
-
-# Delete the specified package
-function DeletePackage
-{
- packageId=$1
- if [ -z $packageId ]; then
- Bail "Please specify package ID. Run -listpkgs for a list of IDs"
- fi
- echo Removing pkgId $packageId from repo $repositoryId
- curl -I -k -X DELETE "$baseurl/v1/packages/$packageId"
-}
-
-# Parse params
-# Not using getopts because this uses multi-char flags
-operation=
-while (( "$#" )); do
- if [[ "$1" == "-config" ]]; then
- shift
- configFile="$1"
- elif [[ "$1" == "-listrepos" ]]; then
- operation=ListRepositories
- elif [[ "$1" == "-listpkgs" ]]; then
- operation=ListPackages
- if [ -n "$2" ]; then
- shift
- operand="$1"
- fi
- elif [[ "$1" == "-addrepo" ]]; then
- operation=AddRepo
- shift
- operand="$1"
- elif [[ "$1" == "-addpkg" ]]; then
- operation=AddPackage
- shift
- operand="$1"
- elif [[ "$1" == "-addpkgs" ]]; then
- operation=AddPackages
- shift
- operand="$1"
- elif [[ "$1" == "-addfile" ]]; then
- operation=AddFile
- shift
- operand="$1"
- elif [[ "$1" == "-uploadfile" ]]; then
- operation=UploadFile
- shift
- operand="$1"
- elif [[ "$1" == "-listfiles" ]]; then
- operation=ListFiles
- elif [[ "$1" == "-delfile" ]]; then
- operation=DeleteFile
- shift
- operand="$1"
- elif [[ "$1" == "-check" ]]; then
- operation=CheckUpload
- shift
- operand="$1"
- elif [[ "$1" == "-delrepo" ]]; then
- operation=DeleteRepo
- shift
- operand="$1"
- elif [[ "$1" == "-delpkg" ]]; then
- operation=DeletePackage
- shift
- operand="$1"
- else
- Usage
- fi
- shift
-done
-
-echo "Performing $operation $operand"
-# Parse config file
-ParseConfigFile "$configFile"
-
-# Exit if no operation was specified
-if [ -z "operation" ]; then
- Usage
-fi
-
-$operation "$operand"
diff --git a/build/tfs/linux/snap-build-linux.yml b/build/tfs/linux/snap-build-linux.yml
new file mode 100644
index 00000000000..d38659aa189
--- /dev/null
+++ b/build/tfs/linux/snap-build-linux.yml
@@ -0,0 +1,42 @@
+steps:
+- task: NodeTool@0
+ inputs:
+ versionSpec: "8.12.0"
+
+- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
+ inputs:
+ versionSpec: "1.10.1"
+
+- task: DownloadPipelineArtifact@0
+ displayName: 'Download Pipeline Artifact'
+ inputs:
+ artifactName: snap-$(VSCODE_ARCH)
+ targetPath: .build/linux/snap-tarball
+
+- script: |
+ set -e
+
+ REPO="$(pwd)"
+ ARCH="$(VSCODE_ARCH)"
+ SNAP_ROOT="$REPO/.build/linux/snap/$ARCH"
+
+ # Install build dependencies
+ (cd build && yarn)
+
+ # Unpack snap tarball artifact, in order to preserve file perms
+ SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$ARCH.tar.gz"
+ (cd .build/linux && tar -xzf $SNAP_TARBALL_PATH)
+
+ # Create snap package
+ BUILD_VERSION="$(date +%s)"
+ SNAP_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.snap"
+ PACKAGEJSON="$(ls $SNAP_ROOT/code*/usr/share/code*/resources/app/package.json)"
+ VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
+ SNAP_PATH="$SNAP_ROOT/$SNAP_FILENAME"
+ (cd $SNAP_ROOT/code-* && snapcraft snap --output "$SNAP_PATH")
+
+ # Publish snap package
+ AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
+ AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
+ MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
+ node build/tfs/common/publish.js "$VSCODE_QUALITY" "linux-snap-$ARCH" package "$SNAP_FILENAME" "$VERSION" true "$SNAP_PATH"
\ No newline at end of file
diff --git a/build/tfs/linux/x64/Dockerfile b/build/tfs/linux/x64/Dockerfile
deleted file mode 100644
index ae9190c29db..00000000000
--- a/build/tfs/linux/x64/Dockerfile
+++ /dev/null
@@ -1,46 +0,0 @@
-FROM microsoft/vsts-agent:ubuntu-14.04-standard
-MAINTAINER Joao Moreno
-
-ARG DEBIAN_FRONTEND=noninteractive
-RUN apt-get update
-
-# Dependencies
-RUN apt-get install -y build-essential
-RUN apt-get install -y gcc-multilib g++-multilib
-RUN apt-get install -y git
-RUN apt-get install -y dpkg-dev
-RUN apt-get install -y zip
-RUN apt-get install -y rpm
-RUN apt-get install -y createrepo
-RUN apt-get install -y python-gtk2
-RUN apt-get install -y jq
-RUN apt-get install -y xvfb
-RUN apt-get install -y fakeroot
-RUN apt-get install -y libgtk2.0-0
-RUN apt-get install -y libgconf-2-4
-RUN apt-get install -y libnss3
-RUN apt-get install -y libasound2
-RUN apt-get install -y libxtst6
-RUN apt-get install -y libfuse2
-RUN apt-get install -y libnotify-bin
-RUN apt-get install -y libx11-dev
-RUN apt-get install -y libxss1
-RUN apt-get install -y libx11-xcb-dev
-RUN apt-get install -y libxkbfile-dev
-RUN apt-get install -y bc bsdmainutils
-RUN apt-get install -y libsecret-1-dev
-
-# Xvfb
-# Thanks https://medium.com/@griggheo/running-headless-selenium-webdriver-tests-in-docker-containers-342fdbabf756
-ADD xvfb.init /etc/init.d/xvfb
-RUN chmod +x /etc/init.d/xvfb
-RUN update-rc.d xvfb defaults
-
-# dbus
-RUN ln -sf /bin/dbus-daemon /usr/bin/dbus-daemon
-
-# nvm
-ENV NVM_DIR /usr/local/nvm
-RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
-
-CMD (service xvfb start; service dbus start; export DISPLAY=:10; ./start.sh)
\ No newline at end of file
diff --git a/build/tfs/linux/x64/run-agent.sh b/build/tfs/linux/x64/run-agent.sh
deleted file mode 100755
index 76978ce2b02..00000000000
--- a/build/tfs/linux/x64/run-agent.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-if [ ! -f pat ]; then
- echo "Error: file pat not found"
- exit 1
-fi
-
-docker run \
- -e VSTS_ACCOUNT="monacotools" \
- -e VSTS_TOKEN="$(cat pat)" \
- -e VSTS_AGENT="tb-lnx-x64-local" \
- -e VSTS_POOL="linux-x64" \
- -e VSTS_WORK="/var/vsts/work" \
- --name "tb-lnx-x64-local" \
- -it joaomoreno/vscode-vso-agent-x64:latest
\ No newline at end of file
diff --git a/build/tfs/linux/x64/xvfb.init b/build/tfs/linux/x64/xvfb.init
deleted file mode 100644
index 4d77d253a26..00000000000
--- a/build/tfs/linux/x64/xvfb.init
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-#
-# /etc/rc.d/init.d/xvfbd
-#
-# chkconfig: 345 95 28
-# description: Starts/Stops X Virtual Framebuffer server
-# processname: Xvfb
-#
-### BEGIN INIT INFO
-# Provides: xvfb
-# Required-Start: $remote_fs $syslog
-# Required-Stop: $remote_fs $syslog
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Start xvfb at boot time
-# Description: Enable xvfb provided by daemon.
-### END INIT INFO
-
-[ "${NETWORKING}" = "no" ] && exit 0
-
-PROG="/usr/bin/Xvfb"
-PROG_OPTIONS=":10 -ac"
-PROG_OUTPUT="/tmp/Xvfb.out"
-
-case "$1" in
- start)
- echo "Starting : X Virtual Frame Buffer "
- $PROG $PROG_OPTIONS>>$PROG_OUTPUT 2>&1 &
- disown -ar
- ;;
- stop)
- echo "Shutting down : X Virtual Frame Buffer"
- killproc $PROG
- RETVAL=$?
- [ $RETVAL -eq 0 ] && /bin/rm -f /var/lock/subsys/Xvfb
- /var/run/Xvfb.pid
- echo
- ;;
- restart|reload)
- $0 stop
- $0 start
- RETVAL=$?
- ;;
- status)
- status Xvfb
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $0 (start|stop|restart|reload|status)"
- exit 1
-esac
-
-exit $RETVAL
\ No newline at end of file
diff --git a/build/tfs/product-build.yml b/build/tfs/product-build.yml
index 417ae4f781c..afebc973ccc 100644
--- a/build/tfs/product-build.yml
+++ b/build/tfs/product-build.yml
@@ -4,6 +4,8 @@ resources:
image: joaomoreno/vscode-linux-build-agent:x64
- container: vscode-ia32
image: joaomoreno/vscode-linux-build-agent:ia32
+ - container: snapcraft
+ image: snapcore/snapcraft
jobs:
- job: Windows
@@ -34,6 +36,17 @@ jobs:
steps:
- template: linux/product-build-linux.yml
+- job: LinuxSnap
+ condition: eq(variables['VSCODE_BUILD_LINUX'], 'true')
+ pool:
+ vmImage: 'Ubuntu-16.04'
+ variables:
+ VSCODE_ARCH: x64
+ container: snapcraft
+ dependsOn: Linux
+ steps:
+ - template: linux/snap-build-linux.yml
+
- job: Linux32
condition: eq(variables['VSCODE_BUILD_LINUX_32BIT'], 'true')
pool:
diff --git a/build/tfs/win32/continuous-build-win32.yml b/build/tfs/win32/continuous-build-win32.yml
index 0df397a0a6a..7145e67e2ad 100644
--- a/build/tfs/win32/continuous-build-win32.yml
+++ b/build/tfs/win32/continuous-build-win32.yml
@@ -36,17 +36,6 @@ steps:
- powershell: |
.\scripts\test-integration.bat --tfs "Integration Tests"
displayName: Run Integration Tests
-- powershell: |
- yarn smoketest --screenshots "$(Build.ArtifactStagingDirectory)\artifacts" --log "$(Build.ArtifactStagingDirectory)\artifacts\smoketest.log"
- displayName: Run Smoke Tests
- continueOnError: true
-- task: PublishBuildArtifacts@1
- displayName: Publish Smoketest Artifacts
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
- ArtifactName: build-artifacts-win32
- publishLocation: Container
- condition: eq(variables['System.PullRequest.IsFork'], 'False')
- task: PublishTestResults@2
displayName: Publish Tests Results
inputs:
diff --git a/build/tfs/win32/product-build-win32.yml b/build/tfs/win32/product-build-win32.yml
index 9dd2d4c6516..d0b653d14f3 100644
--- a/build/tfs/win32/product-build-win32.yml
+++ b/build/tfs/win32/product-build-win32.yml
@@ -170,3 +170,6 @@ steps:
# publish hockeyapp symbols
$hockeyAppId = if ("$(VSCODE_ARCH)" -eq "ia32") { "$(VSCODE_HOCKEYAPP_ID_WIN32)" } else { "$(VSCODE_HOCKEYAPP_ID_WIN64)" }
exec { node build/tfs/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" $hockeyAppId }
+
+- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
+ displayName: 'Component Detection'
diff --git a/build/yarn.lock b/build/yarn.lock
index 9ec0f9fe922..45a09657223 100644
--- a/build/yarn.lock
+++ b/build/yarn.lock
@@ -151,6 +151,16 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
+"@types/minimist@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6"
+ integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=
+
+"@types/mocha@2.2.39":
+ version "2.2.39"
+ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.39.tgz#f68d63db8b69c38e9558b4073525cf96c4f7a829"
+ integrity sha1-9o1j24tpw46VWLQHNSXPlsT3qCk=
+
"@types/node@*":
version "8.0.51"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
@@ -318,6 +328,22 @@ ansi-wrap@0.1.0:
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768=
+applicationinsights@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb"
+ integrity sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==
+ dependencies:
+ diagnostic-channel "0.2.0"
+ diagnostic-channel-publishers "0.2.1"
+ zone.js "0.7.6"
+
+argparse@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+ integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
+ dependencies:
+ sprintf-js "~1.0.2"
+
array-differ@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
@@ -390,6 +416,15 @@ azure-storage@^2.1.0:
xml2js "0.2.7"
xmlbuilder "0.4.3"
+babel-code-frame@^6.22.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
+ integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
+ dependencies:
+ chalk "^1.1.3"
+ esutils "^2.0.2"
+ js-tokens "^3.0.2"
+
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -412,6 +447,11 @@ binary-search-bounds@2.0.3:
resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-2.0.3.tgz#5ff8616d6dd2ca5388bc85b2d6266e2b9da502dc"
integrity sha1-X/hhbW3SylOIvIWy1iZuK52lAtw=
+boolbase@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+ integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
+
boom@2.x.x:
version "2.10.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
@@ -446,12 +486,22 @@ browserify-mime@~1.2.9:
resolved "https://registry.yarnpkg.com/browserify-mime/-/browserify-mime-1.2.9.tgz#aeb1af28de6c0d7a6a2ce40adb68ff18422af31f"
integrity sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=
+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.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+ integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
+
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.0.0, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
@@ -462,7 +512,7 @@ chalk@^1.0.0:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.2.0:
+chalk@^2.2.0, chalk@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
@@ -471,6 +521,18 @@ chalk@^2.2.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+cheerio@^1.0.0-rc.1:
+ version "1.0.0-rc.2"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
+ integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=
+ dependencies:
+ css-select "~1.2.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "^3.9.1"
+ lodash "^4.15.0"
+ parse5 "^3.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"
@@ -522,6 +584,11 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
+commander@^2.12.1, commander@^2.8.1:
+ version "2.19.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
+ integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
+
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -553,6 +620,21 @@ cryptiles@3.x.x:
dependencies:
boom "5.x.x"
+css-select@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
+ integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "2.1"
+ domutils "1.5.1"
+ nth-check "~1.0.1"
+
+css-what@2.1:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d"
+ integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==
+
css@2.X:
version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
@@ -601,11 +683,33 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+denodeify@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631"
+ integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE=
+
detect-newline@2.X:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
+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"
+ integrity sha1-ji1geottef6IC1SLxYzGvrKIxPM=
+
+diagnostic-channel@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
+ integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
+ dependencies:
+ semver "^5.3.0"
+
+diff@^3.2.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
+ integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
+
documentdb@1.13.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/documentdb/-/documentdb-1.13.0.tgz#bba6f03150b2f42498cec4261bc439d834a33f8b"
@@ -616,6 +720,52 @@ documentdb@1.13.0:
semaphore "1.0.5"
underscore "1.8.3"
+dom-serializer@0, dom-serializer@~0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
+ integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=
+ dependencies:
+ domelementtype "~1.1.1"
+ entities "~1.1.1"
+
+domelementtype@1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.2.1.tgz#578558ef23befac043a1abb0db07635509393479"
+ integrity sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA==
+
+domelementtype@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
+ integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=
+
+domelementtype@~1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+ integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=
+
+domhandler@^2.3.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
+ integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
+ dependencies:
+ domelementtype "1"
+
+domutils@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
+ integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+domutils@^1.5.1:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
+ integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
duplexer2@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
@@ -630,11 +780,26 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
+entities@^1.1.1, entities@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
+ integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
+
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=
+esprima@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
+ integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+
+esutils@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+ integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
+
extend@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-1.2.1.tgz#a0f5fd6cfc83a5fe49ef698d60ec8a624dd4576c"
@@ -669,6 +834,13 @@ 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.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"
+
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -692,6 +864,11 @@ form-data@~2.3.1:
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"
@@ -709,6 +886,18 @@ github-releases@^0.4.1:
prettyjson "1.2.1"
request "2.81.0"
+glob@^7.0.6, glob@^7.1.1:
+ 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.1"
resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
@@ -860,6 +1049,18 @@ hoek@4.x.x:
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==
+htmlparser2@^3.9.1:
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464"
+ integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==
+ dependencies:
+ domelementtype "^1.3.0"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^3.0.6"
+
http-signature@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
@@ -878,7 +1079,22 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
-inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
+iconv-lite@0.4.23:
+ version "0.4.23"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
+ integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
+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.3, 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=
@@ -908,6 +1124,19 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+js-tokens@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+ integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
+
+js-yaml@^3.7.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
+ integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@@ -967,6 +1196,13 @@ lazy-debug-legacy@0.0.X:
resolved "https://registry.yarnpkg.com/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz#537716c0776e4cf79e3ed1b621f7658c2911b1b1"
integrity sha1-U3cWwHduTPeePtG2IfdljCkRsbE=
+linkify-it@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f"
+ integrity sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=
+ dependencies:
+ uc.micro "^1.0.1"
+
lodash._basecopy@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
@@ -1066,6 +1302,22 @@ lodash.templatesettings@^3.0.0:
lodash._reinterpolate "^3.0.0"
lodash.escape "^3.0.0"
+lodash@^4.15.0, lodash@^4.17.10:
+ version "4.17.11"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
+ integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
+
+markdown-it@^8.3.1:
+ version "8.4.2"
+ resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54"
+ integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==
+ dependencies:
+ argparse "^1.0.7"
+ entities "~1.1.1"
+ linkify-it "^2.0.0"
+ mdurl "^1.0.1"
+ uc.micro "^1.0.5"
+
md5.js@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
@@ -1074,6 +1326,11 @@ md5.js@1.3.4:
hash-base "^3.0.0"
inherits "^2.0.1"
+mdurl@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
+ integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
+
mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
@@ -1103,7 +1360,7 @@ mime@^1.3.4:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==
-minimatch@3.0.4:
+minimatch@3.0.4, minimatch@^3.0.3, 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==
@@ -1132,6 +1389,11 @@ multipipe@^0.1.2:
dependencies:
duplexer2 "0.0.2"
+mute-stream@~0.0.4:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
+ integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
+
normalize-path@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
@@ -1139,6 +1401,13 @@ normalize-path@^2.0.1:
dependencies:
remove-trailing-separator "^1.0.1"
+nth-check@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
+ integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
+ dependencies:
+ boolbase "~1.0.0"
+
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"
@@ -1154,6 +1423,13 @@ object-assign@^3.0.0:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+ dependencies:
+ wrappy "1"
+
optimist@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
@@ -1162,6 +1438,53 @@ optimist@0.6.1:
minimist "~0.0.1"
wordwrap "~0.0.2"
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+ integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
+
+os-tmpdir@^1.0.0, os-tmpdir@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+ integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
+
+osenv@^0.1.3:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
+ integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.0"
+
+parse-semver@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8"
+ integrity sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=
+ dependencies:
+ semver "^5.1.0"
+
+parse5@^3.0.1:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
+ integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==
+ dependencies:
+ "@types/node" "*"
+
+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-parse@^1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
+ integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
+
+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"
@@ -1200,6 +1523,11 @@ punycode@^1.4.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
+q@^1.0.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
+ integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
+
qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
@@ -1210,6 +1538,13 @@ qs@~6.5.1:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==
+read@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
+ integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=
+ dependencies:
+ mute-stream "~0.0.4"
+
readable-stream@^2.1.5:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@@ -1223,6 +1558,15 @@ readable-stream@^2.1.5:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
+readable-stream@^3.0.6:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a"
+ integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==
+ dependencies:
+ inherits "^2.0.3"
+ 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"
@@ -1316,6 +1660,13 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
+resolve@^1.3.2:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
+ integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==
+ dependencies:
+ path-parse "^1.0.5"
+
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -1326,6 +1677,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+"safer-buffer@>= 2.1.2 < 3":
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+
sax@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.2.tgz#735ffaa39a1cff8ffb9598f0223abdb03a9fb2ea"
@@ -1341,6 +1697,11 @@ semaphore@1.0.5:
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.0.5.tgz#b492576e66af193db95d65e25ec53f5f19798d60"
integrity sha1-tJJXbmavGT25XWXiXsU/Xxl5jWA=
+semver@^5.1.0, 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==
+
sntp@1.x.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
@@ -1381,6 +1742,11 @@ sparkles@^1.0.0:
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c"
integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==
+sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+ integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
@@ -1396,18 +1762,18 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
-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:
+string_decoder@^1.1.1, 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"
+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"
@@ -1452,6 +1818,13 @@ time-stamp@^1.0.0:
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=
+tmp@0.0.29:
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0"
+ integrity sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=
+ dependencies:
+ os-tmpdir "~1.0.1"
+
tough-cookie@~2.3.0:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
@@ -1466,6 +1839,36 @@ tough-cookie@~2.3.3:
dependencies:
punycode "^1.4.1"
+tslib@^1.8.0, tslib@^1.8.1:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
+ integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
+
+tslint@^5.9.1:
+ version "5.11.0"
+ resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed"
+ integrity sha1-mPMMAurjzecAYgHkwzywi0hYHu0=
+ dependencies:
+ babel-code-frame "^6.22.0"
+ builtin-modules "^1.1.1"
+ chalk "^2.3.0"
+ commander "^2.12.1"
+ diff "^3.2.0"
+ glob "^7.1.1"
+ js-yaml "^3.7.0"
+ minimatch "^3.0.4"
+ resolve "^1.3.2"
+ semver "^5.3.0"
+ tslib "^1.8.0"
+ tsutils "^2.27.2"
+
+tsutils@^2.27.2:
+ version "2.29.0"
+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
+ integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
+ dependencies:
+ tslib "^1.8.1"
+
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -1473,27 +1876,55 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
+tunnel@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.4.tgz#2d3785a158c174c9a16dc2c046ec5fc5f1742213"
+ integrity sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=
+
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@3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.1.tgz#3362ba9dd1e482ebb2355b02dfe8bcd19a2c7c96"
- integrity sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ==
+typed-rest-client@^0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-0.9.0.tgz#f768cc0dc3f4e950f06e04825c36b3e7834aa1f2"
+ integrity sha1-92jMDcP06VDwbgSCXDaz54NKofI=
+ dependencies:
+ tunnel "0.0.4"
+ underscore "1.8.3"
+
+typescript@3.1.4:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.4.tgz#c74ef7b3c2da65beff548b903022cb8c3cd997ed"
+ integrity sha512-JZHJtA6ZL15+Q3Dqkbh8iCUmvxD3iJ7ujXS+fVkKnwIVAdHc5BJTDNM0aTrnr2luKulFjU7W+SRhDZvi66Ru7Q==
+
+uc.micro@^1.0.1, uc.micro@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.5.tgz#0c65f15f815aa08b560a61ce8b4db7ffc3f45376"
+ integrity sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==
underscore@1.8.3, underscore@~1.8.3:
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=
+underscore@^1.8.3:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
+ integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
+
urix@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
-util-deprecate@~1.0.1:
+url-join@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
+ integrity sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=
+
+util-deprecate@^1.0.1, 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=
@@ -1540,11 +1971,49 @@ vinyl@^0.5.0:
clone-stats "^0.0.1"
replace-ext "0.0.1"
+vsce@1.48.0:
+ version "1.48.0"
+ resolved "https://registry.yarnpkg.com/vsce/-/vsce-1.48.0.tgz#31c1a4c6909c3b8bdc48b3d32cc8c8e94c7113a2"
+ integrity sha512-1qJn6QLRTu26FIvvMbK/gzHLLdxJVTg9CUTSnCjJHObCCF5CQ0F3FUv7t+5cT7i0J5v5YljrsRY09u7dPBcEnA==
+ dependencies:
+ cheerio "^1.0.0-rc.1"
+ commander "^2.8.1"
+ denodeify "^1.2.1"
+ glob "^7.0.6"
+ lodash "^4.17.10"
+ markdown-it "^8.3.1"
+ mime "^1.3.4"
+ minimatch "^3.0.3"
+ osenv "^0.1.3"
+ parse-semver "^1.1.1"
+ read "^1.0.7"
+ semver "^5.1.0"
+ tmp "0.0.29"
+ url-join "^1.1.0"
+ vso-node-api "6.1.2-preview"
+ yauzl "^2.3.1"
+ yazl "^2.2.2"
+
+vso-node-api@6.1.2-preview:
+ version "6.1.2-preview"
+ resolved "https://registry.yarnpkg.com/vso-node-api/-/vso-node-api-6.1.2-preview.tgz#aab3546df2451ecd894e071bb99b5df19c5fa78f"
+ integrity sha1-qrNUbfJFHs2JTgcbuZtd8Zxfp48=
+ dependencies:
+ q "^1.0.1"
+ tunnel "0.0.4"
+ typed-rest-client "^0.9.0"
+ underscore "^1.8.3"
+
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+ integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+
xml2js@0.2.7:
version "0.2.7"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.2.7.tgz#1838518bb01741cae0878bab4915e494c32306af"
@@ -1574,3 +2043,23 @@ 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.3.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.2:
+ 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"
+ integrity sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=
diff --git a/extensions/csharp/syntaxes/csharp.tmLanguage.json b/extensions/csharp/syntaxes/csharp.tmLanguage.json
index 358d1b76ce8..31fb9c6b818 100644
--- a/extensions/csharp/syntaxes/csharp.tmLanguage.json
+++ b/extensions/csharp/syntaxes/csharp.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/dotnet/csharp-tmLanguage/commit/822c147f65d9b009096d7163f7d624379812cd63",
+ "version": "https://github.com/dotnet/csharp-tmLanguage/commit/b95e4044ff1ac52e03f622de76f459dc5388954c",
"name": "C#",
"scopeName": "source.cs",
"patterns": [
@@ -2607,10 +2607,14 @@
},
"patterns": [
{
- "include": "#string-character-escape"
+ "include": "#char-character-escape"
}
]
},
+ "char-character-escape": {
+ "name": "constant.character.escape.cs",
+ "match": "\\\\(['\"\\\\0abfnrtv]|x[0-9a-fA-F]{1,4}|u[0-9a-fA-F]{4})"
+ },
"string-literal": {
"name": "string.quoted.double.cs",
"begin": "(?
-///
\ No newline at end of file
diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json
index c779f246284..3e5f4cf62e5 100644
--- a/extensions/css-language-features/package.json
+++ b/extensions/css-language-features/package.json
@@ -14,7 +14,6 @@
"onLanguage:scss",
"onCommand:_css.applyCodeAction"
],
- "enableProposedApi": true,
"main": "./client/out/cssMain",
"scripts": {
"compile": "gulp compile-extension:css-language-features-client compile-extension:css-language-features-server",
@@ -143,7 +142,7 @@
"error"
],
"default": "warning",
- "description": "%css.lint.fontFaceProperties.desc%"
+ "markdownDescription": "%css.lint.fontFaceProperties.desc%"
},
"css.lint.hexColorLength": {
"type": "string",
@@ -178,6 +177,16 @@
"default": "warning",
"description": "%css.lint.unknownProperties.desc%"
},
+ "css.lint.validProperties": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ },
+ "scope": "resource",
+ "default": [],
+ "description": "%css.lint.validProperties.desc%"
+ },
"css.lint.ieHack": {
"type": "string",
"scope": "resource",
@@ -220,7 +229,7 @@
"error"
],
"default": "ignore",
- "description": "%css.lint.important.desc%"
+ "markdownDescription": "%css.lint.important.desc%"
},
"css.lint.float": {
"type": "string",
@@ -418,6 +427,16 @@
"default": "warning",
"description": "%scss.lint.unknownProperties.desc%"
},
+ "scss.lint.validProperties": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ },
+ "scope": "resource",
+ "default": [],
+ "description": "%scss.lint.validProperties.desc%"
+ },
"scss.lint.ieHack": {
"type": "string",
"scope": "resource",
@@ -637,6 +656,16 @@
"default": "warning",
"description": "%less.lint.unknownProperties.desc%"
},
+ "less.lint.validProperties": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ },
+ "scope": "resource",
+ "default": [],
+ "description": "%less.lint.validProperties.desc%"
+ },
"less.lint.ieHack": {
"type": "string",
"scope": "resource",
@@ -679,7 +708,7 @@
"error"
],
"default": "ignore",
- "description": "%less.lint.important.desc%"
+ "markdownDescription": "%less.lint.important.desc%"
},
"less.lint.float": {
"type": "string",
diff --git a/extensions/css-language-features/package.nls.json b/extensions/css-language-features/package.nls.json
index f62c6fb669c..56eeb384643 100644
--- a/extensions/css-language-features/package.nls.json
+++ b/extensions/css-language-features/package.nls.json
@@ -18,6 +18,7 @@
"css.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.",
"css.lint.unknownAtRules.desc": "Unknown at-rule.",
"css.lint.unknownProperties.desc": "Unknown property.",
+ "css.lint.validProperties.desc": "A list of properties that are not validated against the `unknownProperties` rule.",
"css.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.",
"css.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.",
"css.lint.zeroUnits.desc": "No unit for zero needed.",
@@ -35,11 +36,12 @@
"less.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.",
"less.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.",
"less.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.",
- "less.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.",
+ "less.lint.important.desc": "Avoid using `!important`. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.",
"less.lint.importStatement.desc": "Import statements do not load in parallel.",
"less.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.",
"less.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.",
"less.lint.unknownProperties.desc": "Unknown property.",
+ "less.lint.validProperties.desc": "A list of properties that are not validated against the `unknownProperties` rule.",
"less.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.",
"less.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.",
"less.lint.zeroUnits.desc": "No unit for zero needed.",
@@ -56,11 +58,12 @@
"scss.lint.hexColorLength.desc": "Hex colors must consist of three or six hex numbers.",
"scss.lint.idSelector.desc": "Selectors should not contain IDs because these rules are too tightly coupled with the HTML.",
"scss.lint.ieHack.desc": "IE hacks are only necessary when supporting IE7 and older.",
- "scss.lint.important.desc": "Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.",
+ "scss.lint.important.desc": "Avoid using `!important`. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.",
"scss.lint.importStatement.desc": "Import statements do not load in parallel.",
"scss.lint.propertyIgnoredDueToDisplay.desc": "Property is ignored due to the display. E.g. with `display: inline`, the `width`, `height`, `margin-top`, `margin-bottom`, and `float` properties have no effect.",
"scss.lint.universalSelector.desc": "The universal selector (`*`) is known to be slow.",
"scss.lint.unknownProperties.desc": "Unknown property.",
+ "scss.lint.validProperties.desc": "A list of properties that are not validated against the `unknownProperties` rule.",
"scss.lint.unknownVendorSpecificProperties.desc": "Unknown vendor specific property.",
"scss.lint.vendorPrefix.desc": "When using a vendor-specific prefix, also include the standard property.",
"scss.lint.zeroUnits.desc": "No unit for zero needed.",
diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json
index c4a430eb067..28f60c966d7 100644
--- a/extensions/css-language-features/server/package.json
+++ b/extensions/css-language-features/server/package.json
@@ -9,7 +9,7 @@
},
"main": "./out/cssServerMain",
"dependencies": {
- "vscode-css-languageservice": "^3.0.12-next.1",
+ "vscode-css-languageservice": "^3.0.13-next.3",
"vscode-languageserver": "^5.1.0"
},
"devDependencies": {
diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock
index 133486a978e..30c2fb6c62f 100644
--- a/extensions/css-language-features/server/yarn.lock
+++ b/extensions/css-language-features/server/yarn.lock
@@ -229,10 +229,10 @@ supports-color@5.4.0:
dependencies:
has-flag "^3.0.0"
-vscode-css-languageservice@^3.0.12-next.1:
- version "3.0.12-next.1"
- resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.12-next.1.tgz#1bc76d04f68b6d3d9b25cf01592ba46cea91c26c"
- integrity sha512-Be1pfmRlcRsKMl1O/5rci8lu8RlE5vwT8LOjUEfHZkz5eHL2n9rTLo3dzmbVGtSL7+T1XEArjqUks9MzzDUhcw==
+vscode-css-languageservice@^3.0.13-next.3:
+ version "3.0.13-next.3"
+ resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.13-next.3.tgz#b9e6f253cace52fbb749d2fe194ae4b196f3543e"
+ integrity sha512-7+7JddZRt8zFRLbqygxJw+GHtbQ5o2YvgEFvi4ixvbUAX6KlY3Yw6CgUUbg9dmBla7h+GbtoDjwiLFV6Oy+SBQ==
dependencies:
vscode-languageserver-types "^3.13.0"
vscode-nls "^4.0.0"
diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts
index 23cb3185c25..f6634d35c9c 100644
--- a/extensions/emmet/src/abbreviationActions.ts
+++ b/extensions/emmet/src/abbreviationActions.ts
@@ -614,7 +614,7 @@ function expandAbbr(input: ExpandAbbreviationInput): string {
}
// If wrapping with a block element, insert newline in the text to wrap.
- if (wrappingNode && inlineElements.indexOf(wrappingNode.name) === -1) {
+ if (wrappingNode && inlineElements.indexOf(wrappingNode.name) === -1 && (expandOptions['profile'].hasOwnProperty('format') ? expandOptions['profile'].format : true)) {
wrappingNode.value = '\n\t' + wrappingNode.value + '\n';
}
}
diff --git a/extensions/emmet/src/test/wrapWithAbbreviation.test.ts b/extensions/emmet/src/test/wrapWithAbbreviation.test.ts
index 6e2bf273f92..9fc924508e2 100644
--- a/extensions/emmet/src/test/wrapWithAbbreviation.test.ts
+++ b/extensions/emmet/src/test/wrapWithAbbreviation.test.ts
@@ -5,7 +5,7 @@
import 'mocha';
import * as assert from 'assert';
-import { Selection } from 'vscode';
+import { Selection, workspace, ConfigurationTarget } from 'vscode';
import { withRandomFileEditor, closeAllEditors } from './testUtils';
import { wrapWithAbbreviation, wrapIndividualLinesWithAbbreviation } from '../abbreviationActions';
@@ -56,6 +56,13 @@ const wrapMultiLineAbbrExpected = `
`;
+const wrapInlineElementExpectedFormatFalse = `
+
+`;
+
suite('Tests for Wrap with Abbreviations', () => {
teardown(closeAllEditors);
@@ -63,6 +70,7 @@ suite('Tests for Wrap with Abbreviations', () => {
const multiCursorsWithSelection = [new Selection(2, 2, 2, 28), new Selection(3, 2, 3, 33)];
const multiCursorsWithFullLineSelection = [new Selection(2, 0, 2, 28), new Selection(3, 0, 4, 0)];
+ const oldValueForSyntaxProfiles = workspace.getConfiguration('emmet').inspect('syntaxProfile');
test('Wrap with block element using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'div', wrapBlockElementExpected);
@@ -340,11 +348,47 @@ suite('Tests for Wrap with Abbreviations', () => {
});
});
});
+
+ test('Wrap with abbreviation and format set to false', () => {
+ return workspace.getConfiguration('emmet').update('syntaxProfiles',{ 'html' : { 'format': false } } , ConfigurationTarget.Global).then(() => {
+ return testWrapWithAbbreviation(multiCursors,'h1',wrapInlineElementExpectedFormatFalse).then(() => {
+ return workspace.getConfiguration('emmet').update('syntaxProfiles',oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global);
+ });
+ });
+ });
+
+ test('Wrap multi line selections with abbreviation', () => {
+ const htmlContentsForWrapMultiLineTests = `
+
+ line1
+ line2
+
+ line3
+ line4
+
+ `;
+
+ const wrapMultiLineExpected = `
+
+
+ line1
+ line2
+
+
+
+ line3
+ line4
+
+
+ `;
+
+ return testWrapWithAbbreviation([new Selection(2, 4, 3, 9), new Selection(5, 4, 6, 9)], 'div', wrapMultiLineExpected, htmlContentsForWrapMultiLineTests);
+ });
});
-function testWrapWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string): Thenable {
- return withRandomFileEditor(htmlContentsForWrapTests, 'html', (editor, _) => {
+function testWrapWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string, input: string = htmlContentsForWrapTests): Thenable {
+ return withRandomFileEditor(input, 'html', (editor, _) => {
editor.selections = selections;
const promise = wrapWithAbbreviation({ abbreviation });
if (!promise) {
diff --git a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json
index 6b2b4265e54..067389b1650 100644
--- a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json
+++ b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/ionide/ionide-fsgrammar/commit/eb210da2bfea65a7dff46d22c97a0e9e410a9469",
+ "version": "https://github.com/ionide/ionide-fsgrammar/commit/24c1588529af144d205f66fbcec6889500f9aaa9",
"name": "fsharp",
"scopeName": "source.fsharp",
"patterns": [
@@ -48,10 +48,13 @@
"include": "#record_declaration"
},
{
- "include": "#keywords"
+ "include": "#records"
},
{
- "include": "#records"
+ "include": "#strp_inlined"
+ },
+ {
+ "include": "#keywords"
},
{
"include": "#cexprs"
@@ -61,10 +64,173 @@
}
],
"repository": {
+ "strp_inlined_body": {
+ "patterns": [
+ {
+ "include": "#comments"
+ },
+ {
+ "include": "#anonymous_functions"
+ },
+ {
+ "match": "(\\^[[:alpha:]0-9'._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "name": "keyword.fsharp",
+ "match": "\\b(and|when|or)\\b"
+ },
+ {
+ "begin": "(\\()",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "end": "(\\))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#strp_inlined_body"
+ }
+ ]
+ },
+ {
+ "match": "(static member|member)\\s*([[:alpha:]0-9'`<>^._]+|``[[:alpha:]0-9' <>^._]+``)\\s*(:)",
+ "captures": {
+ "1": {
+ "name": "keyword.fsharp"
+ },
+ "2": {
+ "name": "variable.fsharp"
+ },
+ "3": {
+ "name": "keyword.symbol.fsharp"
+ }
+ }
+ },
+ {
+ "include": "#constants"
+ },
+ {
+ "include": "#strings"
+ },
+ {
+ "include": "#chars"
+ },
+ {
+ "include": "#double_tick"
+ },
+ {
+ "include": "#keywords"
+ },
+ {
+ "include": "#text"
+ }
+ ]
+ },
+ "strp_inlined": {
+ "patterns": [
+ {
+ "begin": "(\\()",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "end": "(\\))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#strp_inlined_body"
+ }
+ ]
+ }
+ ]
+ },
"generic_declaration": {
"patterns": [
{
- "match": "([^<>,*()-])",
+ "comments": "SRTP syntax support",
+ "begin": "(:)\\s*(\\()\\s*(static member|member)",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "3": {
+ "name": "keyword.fsharp"
+ }
+ },
+ "end": "(\\))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "begin": "(\\()",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "end": "(\\))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#member_declaration"
+ }
+ ]
+ },
+ {
+ "match": "(('|\\^)[[:alpha:]0-9'._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "include": "#variables"
+ },
+ {
+ "include": "#keywords"
+ }
+ ]
+ },
+ {
+ "name": "keyword.fsharp",
+ "match": "\\b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\\!|return\\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|use|use\\!|struct|while|mutable)(?!')\\b"
+ },
+ {
+ "name": "keyword.fsharp",
+ "match": ":"
+ },
+ {
+ "include": "#constants"
+ },
+ {
+ "match": "(('|\\^)[[:alpha:]0-9'._]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
@@ -86,7 +252,7 @@
},
"patterns": [
{
- "match": "([^<>,*()-])",
+ "match": "(('|\\^)[[:alpha:]0-9'._]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
@@ -101,6 +267,24 @@
}
]
},
+ {
+ "match": "(?!when|and|or\\b)\\b([\\w0-9'`^._]+)",
+ "comments": "Here we need the \\w modifier in order to check that the words isn't blacklisted",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "match": "(\\|)",
+ "comments": "Prevent captures of `|>` as a keyword when defining custom operator like `<|>`",
+ "captures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ }
+ },
{
"include": "#keywords"
}
@@ -217,18 +401,23 @@
"include": "#comments"
},
{
- "include": "#member_declaration"
- },
- {
- "match": "(:)(\\s*([?[:alpha:]0-9'`<>^._ ]+))*",
- "captures": {
+ "begin": "(\\()",
+ "end": "\\s*(?=(->))",
+ "beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "entity.name.type.fsharp"
}
- }
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#member_declaration"
+ }
+ ]
},
{
"include": "#variables"
@@ -364,15 +553,18 @@
"include": "#common_declaration"
},
{
- "match": "\\?{0,1}([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([?[:alpha:]0-9'`^._ ]+)){0,1}",
+ "match": "(\\?{0,1})([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([[:alpha:]0-9'`^._ ]+)){0,1}",
"captures": {
"1": {
- "name": "variable.parameter.fsharp"
- },
- "2": {
"name": "keyword.symbol.fsharp"
},
+ "2": {
+ "name": "variable.parameter.fsharp"
+ },
"3": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "4": {
"name": "entity.name.type.fsharp"
}
}
@@ -391,11 +583,232 @@
}
]
},
+ "common_binding_definition": {
+ "patterns": [
+ {
+ "include": "#comments"
+ },
+ {
+ "include": "#attributes"
+ },
+ {
+ "comments": "SRTP syntax support",
+ "begin": "(:)\\s*(\\()\\s*(static member|member)",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "3": {
+ "name": "keyword.fsharp"
+ }
+ },
+ "end": "(\\))\\s*((?=,)|(?=\\=))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "match": "(\\^[[:alpha:]0-9'._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "include": "#variables"
+ },
+ {
+ "include": "#keywords"
+ }
+ ]
+ },
+ {
+ "begin": "(:)\\s*(\\()",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "end": "(\\)\\s*(([?[:alpha:]0-9'`^._ ]*)))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "entity.name.type.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#tuple_signature"
+ }
+ ]
+ },
+ {
+ "begin": "(:)\\s*(\\^[[:alpha:]0-9'._]+)\\s*(when)",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "entity.name.type.fsharp"
+ },
+ "3": {
+ "name": "keyword.fsharp"
+ }
+ },
+ "end": "(?=:)",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "name": "keyword.fsharp",
+ "match": "\\b(and|when|or)\\b"
+ },
+ {
+ "comment": "Because we first capture the keywords, we can capture what looks like a word and assume it's an entity definition",
+ "match": "([[:alpha:]0-9'^._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "name": "keyword.symbol.fsharp",
+ "match": "(\\(|\\))"
+ }
+ ]
+ },
+ {
+ "match": "(:)\\s*([?[:alpha:]0-9'`^._ ]+)",
+ "captures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "match": "(->)\\s*(\\()?\\s*([?[:alpha:]0-9'`^._ ]+)*",
+ "captures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "3": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "begin": "(\\*)\\s*(\\()",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "end": "(\\)\\s*(([?[:alpha:]0-9'`^._ ]+))+)",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "entity.name.type.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#tuple_signature"
+ }
+ ]
+ },
+ {
+ "match": "(\\*)(\\s*([?[:alpha:]0-9'`^._ ]+))*",
+ "captures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "begin": "(<(?![[:space:]]*\\)))",
+ "beginComment": "The group (?![[:space:]]*\\) is for protection against overload operator. static member (<)",
+ "end": "((?)",
+ "endComment": "The group (? when using SRTP synthax",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#generic_declaration"
+ }
+ ]
+ },
+ {
+ "begin": "({)",
+ "end": "(})",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#record_signature"
+ }
+ ]
+ },
+ {
+ "include": "#definition"
+ },
+ {
+ "include": "#variables"
+ },
+ {
+ "include": "#keywords"
+ }
+ ]
+ },
"definition": {
"patterns": [
{
"name": "binding.fsharp",
- "begin": "\\b(val mutable|val|let mutable|let inline|let|member val|member|static member|override|let!)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]+|(?<=,)\\s)*)?",
+ "begin": "\\b(let mutable|let inline|let|member val|static member inline|static member|member|override|let!)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]+|(?<=,)\\s)*)?",
"end": "\\s*(with\\b|=|\\n+=|(?<=\\=))",
"beginCaptures": {
"1": {
@@ -421,140 +834,34 @@
},
"patterns": [
{
- "include": "#comments"
+ "include": "#common_binding_definition"
+ }
+ ]
+ },
+ {
+ "name": "binding.fsharp",
+ "begin": "\\b(static val mutable|val mutable|val)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]+|(?<=,)\\s)*)?",
+ "end": "\\n$",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.fsharp"
},
- {
- "include": "#attributes"
+ "2": {
+ "name": "keyword.fsharp"
},
- {
- "begin": "(:)\\s*(\\()",
- "beginCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "keyword.symbol.fsharp"
- }
- },
- "end": "(\\)\\s*(([?[:alpha:]0-9'`^._ ]+))+)",
- "endCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "entity.name.type.fsharp"
- }
- },
- "patterns": [
- {
- "include": "#tuple_signature"
- }
- ]
+ "3": {
+ "name": "support.function.attribute.fsharp"
},
- {
- "match": "(:)\\s*([?[:alpha:]0-9'`^._ ]+)*",
- "captures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "entity.name.type.fsharp"
- }
- }
+ "4": {
+ "name": "keyword.fsharp"
},
+ "5": {
+ "name": "variable.fsharp"
+ }
+ },
+ "patterns": [
{
- "match": "(->)\\s*(\\()?\\s*([?[:alpha:]0-9'`^._ ]+)*",
- "captures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "keyword.symbol.fsharp"
- },
- "3": {
- "name": "entity.name.type.fsharp"
- }
- }
- },
- {
- "begin": "(\\*)\\s*(\\()",
- "beginCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "keyword.symbol.fsharp"
- }
- },
- "end": "(\\)\\s*(([?[:alpha:]0-9'`^._ ]+))+)",
- "endCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "entity.name.type.fsharp"
- }
- },
- "patterns": [
- {
- "include": "#tuple_signature"
- }
- ]
- },
- {
- "match": "(\\*)(\\s*([?[:alpha:]0-9'`^._ ]+))*",
- "captures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- },
- "2": {
- "name": "entity.name.type.fsharp"
- }
- }
- },
- {
- "begin": "(<(?![[:space:]]*\\)))",
- "end": "(>)",
- "beginCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- }
- },
- "endCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- }
- },
- "patterns": [
- {
- "include": "#generic_declaration"
- }
- ]
- },
- {
- "begin": "({)",
- "end": "(})",
- "beginCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- }
- },
- "endCaptures": {
- "1": {
- "name": "keyword.symbol.fsharp"
- }
- },
- "patterns": [
- {
- "include": "#record_signature"
- }
- ]
- },
- {
- "include": "#variables"
- },
- {
- "include": "#keywords"
+ "include": "#common_binding_definition"
}
]
}
@@ -613,7 +920,7 @@
"patterns": [
{
"name": "keyword.fsharp",
- "match": "\\b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\\!|return\\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|use|use\\!|struct|while|mutable)(?!')\\b"
+ "match": "\\b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\\!|return\\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|or|use|use\\!|struct|while|mutable)(?!')\\b"
},
{
"name": "keyword.symbol.fsharp",
@@ -817,8 +1124,15 @@
"match": "\\(\\)"
},
{
- "name": "variable.parameter.fsharp",
- "match": "``[[:alpha:]0-9'`^:,._ ]+``|[[:alpha:]0-9'`<>^._ ]\\w*"
+ "match": "(\\?{0,1})(``[[:alpha:]0-9'`^:,._ ]+``|[[:alpha:]0-9'`<>^._ ]\\w*)",
+ "captures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "variable.parameter.fsharp"
+ }
+ }
}
]
},
@@ -869,19 +1183,22 @@
}
},
{
- "begin": "\\?{0,1}([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([?[:alpha:]0-9'`^._ ]+)(<))",
+ "begin": "(\\?{0,1})([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([?[:alpha:]0-9'`^._ ]+)(<))",
"end": "(>)",
"beginCaptures": {
"1": {
- "name": "variable.parameter.fsharp"
+ "name": "keyword.symbol.fsharp"
},
"2": {
- "name": "keyword.symbol.fsharp"
+ "name": "variable.parameter.fsharp"
},
"3": {
"name": "keyword.symbol.fsharp"
},
"4": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "5": {
"name": "entity.name.type.fsharp"
}
},
@@ -909,13 +1226,26 @@
"member_declaration": {
"patterns": [
{
- "begin": "(\\()",
- "end": "(\\))",
+ "include": "#comments"
+ },
+ {
+ "include": "#common_declaration"
+ },
+ {
+ "comments": "SRTP syntax support",
+ "begin": "(:)\\s*(\\()\\s*(static member|member)",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "3": {
+ "name": "keyword.fsharp"
}
},
+ "end": "(\\))\\s*((?=,)|(?=\\=))",
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
@@ -923,29 +1253,75 @@
},
"patterns": [
{
- "include": "#comments"
+ "begin": "(\\()",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "end": "(\\))",
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#member_declaration"
+ }
+ ]
},
{
- "include": "#common_declaration"
- },
- {
- "match": "\\?{0,1}([[:alpha:]0-9'`^._ ]+)\\s*(:{0,1})(\\s*([?[:alpha:]0-9'`<>^._ ]+)){0,1}",
+ "match": "(\\^[[:alpha:]0-9'._]+)",
"captures": {
"1": {
- "name": "variable.parameter.fsharp"
- },
- "2": {
- "name": "keyword.symbol.fsharp"
- },
- "3": {
"name": "entity.name.type.fsharp"
}
}
},
+ {
+ "include": "#variables"
+ },
{
"include": "#keywords"
}
]
+ },
+ {
+ "match": "(\\^[[:alpha:]0-9'._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "name": "keyword.fsharp",
+ "match": "\\b(and|when|or)\\b"
+ },
+ {
+ "name": "keyword.symbol.fsharp",
+ "match": "(\\(|\\))"
+ },
+ {
+ "match": "(\\?{0,1})([[:alpha:]0-9'`^._]+|``[[:alpha:]0-9'`^:,._ ]+``)\\s*(:{0,1})(\\s*([?[:alpha:]0-9'`<>._ ]+)){0,1}",
+ "captures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "2": {
+ "name": "variable.parameter.fsharp"
+ },
+ "3": {
+ "name": "keyword.symbol.fsharp"
+ },
+ "4": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "include": "#keywords"
}
]
},
@@ -973,16 +1349,13 @@
{
"name": "record.fsharp",
"begin": "\\b(type)[\\s]+(private|internal|public)?\\s*",
- "end": "\\s*((with)|((as)\\s*([[:alpha:]0-9']+))|(=)|[\\n=]|(\\(\\)))",
+ "end": "\\s*((with)|((as)\\s+([[:alpha:]0-9']+))|(=)|[\\n=]|(\\(\\)))",
"beginCaptures": {
"1": {
"name": "keyword.fsharp"
},
"2": {
"name": "keyword.fsharp"
- },
- "3": {
- "name": "support.function.attribute.fsharp"
}
},
"endCaptures": {
@@ -1013,18 +1386,82 @@
"include": "#attributes"
},
{
- "match": "([[:alpha:]0-9'`^:,._]+|``[[:alpha:]0-9'`^:,._ ]+``)(<)",
+ "match": "([[:alpha:]0-9'^._]+|``[[:alpha:]0-9'`^:,._ ]+``)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
- },
- "2": {
- "name": "keyword.symbol.fsharp"
}
}
},
{
- "match": "\\s*(>)\\s*(private|internal|public)?",
+ "begin": "(<)",
+ "end": "((?)",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.fsharp"
+ }
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "match": "(('|\\^)``[[:alpha:]0-9`^:,._ ]+``|('|\\^)[[:alpha:]0-9`^:._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "name": "keyword.fsharp",
+ "match": "\\b(interface|with|abstract|and|when|or|not|struct|equality|comparison|unmanaged|delegate|enum)\\b"
+ },
+ {
+ "begin": "(\\()",
+ "end": "(\\))",
+ "beginCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "match": "(static member|member|new)",
+ "captures": {
+ "1": {
+ "name": "keyword.fsharp"
+ }
+ }
+ },
+ {
+ "include": "#common_binding_definition"
+ }
+ ]
+ },
+ {
+ "match": "([\\w0-9'`^._]+)",
+ "comments": "Here we need the \\w modifier in order to check that the words isn't blacklisted",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
+ {
+ "include": "#keywords"
+ }
+ ]
+ },
+ {
+ "match": "\\s*(private|internal|public)",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
@@ -1035,15 +1472,23 @@
}
},
{
- "match": "([[:alpha:]0-9'`^._ ]+)",
- "captures": {
+ "begin": "(\\()",
+ "end": "\\s*(?=(=)|[\\n=]|(\\(\\))|(as))",
+ "beginCaptures": {
"1": {
- "name": "entity.name.type.fsharp"
+ "name": "keyword.symbol.fsharp"
}
- }
- },
- {
- "include": "#member_declaration"
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.symbol.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#member_declaration"
+ }
+ ]
},
{
"include": "#keywords"
@@ -1099,9 +1544,6 @@
}
]
},
- {
- "include": "#chars"
- },
{
"include": "#compiler_directives"
},
diff --git a/extensions/fsharp/test/colorize-results/test_fs.json b/extensions/fsharp/test/colorize-results/test_fs.json
index 328557e57b3..37c0b61c14a 100644
--- a/extensions/fsharp/test/colorize-results/test_fs.json
+++ b/extensions/fsharp/test/colorize-results/test_fs.json
@@ -110,7 +110,18 @@
}
},
{
- "c": " age",
+ "c": " ",
+ "t": "source.fsharp record.fsharp",
+ "r": {
+ "dark_plus": "default: #D4D4D4",
+ "light_plus": "default: #000000",
+ "dark_vs": "default: #D4D4D4",
+ "light_vs": "default: #000000",
+ "hc_black": "default: #FFFFFF"
+ }
+ },
+ {
+ "c": "age",
"t": "source.fsharp record.fsharp variable.parameter.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
diff --git a/extensions/git/README.md b/extensions/git/README.md
index bd7a8ef26c2..a20f3207534 100644
--- a/extensions/git/README.md
+++ b/extensions/git/README.md
@@ -4,4 +4,17 @@
## Features
-See [Git support in VS Code](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support) to learn about the features of this extension.
\ No newline at end of file
+See [Git support in VS Code](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support) to learn about the features of this extension.
+
+## API
+
+The Git extension exposes an API, reachable by any other extension.
+
+1. Copy `src/api/git.d.ts` to your extension's sources;
+2. Include `git.d.ts` in your extension's compilation.
+3. Get a hold of the API with the following snippet:
+
+ ```ts
+ const gitExtension = vscode.extensions.getExtension('vscode.git').exports;
+ const git = gitExtension.getAPI(1);
+ ```
\ No newline at end of file
diff --git a/extensions/git/package.json b/extensions/git/package.json
index 81734a94d09..02ec66df32e 100644
--- a/extensions/git/package.json
+++ b/extensions/git/package.json
@@ -1339,7 +1339,7 @@
"dependencies": {
"byline": "^5.0.0",
"file-type": "^7.2.0",
- "iconv-lite": "0.4.19",
+ "iconv-lite": "^0.4.24",
"jschardet": "^1.6.0",
"vscode-extension-telemetry": "0.1.0",
"vscode-nls": "^4.0.0",
diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json
index 4d73891f818..071c07a2cf0 100644
--- a/extensions/git/package.nls.json
+++ b/extensions/git/package.nls.json
@@ -66,7 +66,7 @@
"config.autoRepositoryDetection.subFolders": "Scan for subfolders of the currently opened folder.",
"config.autoRepositoryDetection.openEditors": "Scan for parent folders of open files.",
"config.autorefresh": "Whether auto refreshing is enabled.",
- "config.autofetch": "Whether auto fetching is enabled.",
+ "config.autofetch": "When enabled, commits will automatically be fetched from the default remote of the current Git repository.",
"config.confirmSync": "Confirm before synchronizing git repositories.",
"config.countBadge": "Controls the git badge counter.",
"config.countBadge.all": "Count all changes.",
diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts
index 783fdf857ad..68622e7ac91 100644
--- a/extensions/git/src/api/api1.ts
+++ b/extensions/git/src/api/api1.ts
@@ -5,7 +5,7 @@
import { Model } from '../model';
import { Repository as BaseRepository, Resource } from '../repository';
-import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState } from './git';
+import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status } from './git';
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
import { mapEvent } from '../util';
@@ -17,7 +17,12 @@ class ApiInputBox implements InputBox {
export class ApiChange implements Change {
- constructor(_resource: Resource) { }
+ get uri(): Uri { return this.resource.resourceUri; }
+ get originalUri(): Uri { return this.resource.original; }
+ get renameUri(): Uri | undefined { return this.resource.renameResourceUri; }
+ get status(): Status { return this.resource.type; }
+
+ constructor(private readonly resource: Resource) { }
}
export class ApiRepositoryState implements RepositoryState {
@@ -67,6 +72,18 @@ export class ApiRepository implements Repository {
return this._repository.setConfig(key, value);
}
+ getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number; }> {
+ return this._repository.getObjectDetails(treeish, path);
+ }
+
+ detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
+ return this._repository.detectObjectType(object);
+ }
+
+ buffer(ref: string, filePath: string): Promise {
+ return this._repository.buffer(ref, filePath);
+ }
+
show(ref: string, path: string): Promise {
return this._repository.show(ref, path);
}
@@ -75,8 +92,8 @@ export class ApiRepository implements Repository {
return this._repository.getCommit(ref);
}
- getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number; }> {
- return this._repository.getObjectDetails(treeish, path);
+ clean(paths: string[]) {
+ return this._repository.clean(paths.map(p => Uri.file(p)));
}
diffWithHEAD(path: string): Promise {
@@ -111,8 +128,8 @@ export class ApiRepository implements Repository {
return this._repository.branch(name, checkout, ref);
}
- deleteBranch(name: string): Promise {
- return this._repository.deleteBranch(name);
+ deleteBranch(name: string, force?: boolean): Promise {
+ return this._repository.deleteBranch(name, force);
}
getBranch(name: string): Promise {
@@ -150,6 +167,10 @@ export class ApiRepository implements Repository {
pull(): Promise {
return this._repository.pull();
}
+
+ push(remoteName?: string, branchName?: string, setUpstream: boolean = false): Promise {
+ return this._repository.pushTo(remoteName, branchName, setUpstream);
+ }
}
export class ApiGit implements Git {
diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts
index 1ca1892a7bd..8d7dc611e62 100644
--- a/extensions/git/src/api/extension.ts
+++ b/extensions/git/src/api/extension.ts
@@ -6,6 +6,8 @@
import { Model } from '../model';
import { GitExtension, Repository, API } from './git';
import { ApiRepository, ApiImpl } from './api1';
+import { Event, EventEmitter } from 'vscode';
+import { latchEvent } from '../util';
export function deprecated(_target: any, key: string, descriptor: any): void {
if (typeof descriptor.value !== 'function') {
@@ -19,50 +21,56 @@ export function deprecated(_target: any, key: string, descriptor: any): void {
};
}
-class NoModelGitExtension implements GitExtension {
+export class GitExtensionImpl implements GitExtension {
+
+ enabled: boolean = false;
+
+ private _onDidChangeEnablement = new EventEmitter();
+ readonly onDidChangeEnablement: Event = latchEvent(this._onDidChangeEnablement.event);
+
+ private _model: Model | undefined = undefined;
+
+ set model(model: Model | undefined) {
+ this._model = model;
+
+ this.enabled = !!model;
+ this._onDidChangeEnablement.fire(this.enabled);
+ }
+
+ constructor(model?: Model) {
+ if (model) {
+ this.enabled = true;
+ this._model = model;
+ }
+ }
@deprecated
async getGitPath(): Promise {
- throw new Error('Git model not found');
- }
+ if (!this._model) {
+ throw new Error('Git model not found');
+ }
- @deprecated
- async getRepositories(): Promise {
- throw new Error('Git model not found');
- }
-
- getAPI(): API {
- throw new Error('Git model not found');
- }
-}
-
-class GitExtensionImpl implements GitExtension {
-
- constructor(private _model: Model) { }
-
- @deprecated
- async getGitPath(): Promise {
return this._model.git.path;
}
@deprecated
async getRepositories(): Promise {
+ if (!this._model) {
+ throw new Error('Git model not found');
+ }
+
return this._model.repositories.map(repository => new ApiRepository(repository));
}
getAPI(version: number): API {
+ if (!this._model) {
+ throw new Error('Git model not found');
+ }
+
if (version !== 1) {
throw new Error(`No API version ${version} found.`);
}
return new ApiImpl(this._model);
}
-}
-
-export function createGitExtension(model?: Model): GitExtension {
- if (!model) {
- return new NoModelGitExtension();
- }
-
- return new GitExtensionImpl(model);
-}
+}
\ No newline at end of file
diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts
index a20df351ea5..99ded276f33 100644
--- a/extensions/git/src/api/git.d.ts
+++ b/extensions/git/src/api/git.d.ts
@@ -61,8 +61,38 @@ export interface Remote {
readonly isReadOnly: boolean;
}
+export const enum Status {
+ INDEX_MODIFIED,
+ INDEX_ADDED,
+ INDEX_DELETED,
+ INDEX_RENAMED,
+ INDEX_COPIED,
+
+ MODIFIED,
+ DELETED,
+ UNTRACKED,
+ IGNORED,
+
+ ADDED_BY_US,
+ ADDED_BY_THEM,
+ DELETED_BY_US,
+ DELETED_BY_THEM,
+ BOTH_ADDED,
+ BOTH_DELETED,
+ BOTH_MODIFIED
+}
+
export interface Change {
- // TODO
+
+ /**
+ * Returns either `originalUri` or `renameUri`, depending
+ * on whether this change is a rename change. When
+ * in doubt always use `uri` over the other two alternatives.
+ */
+ readonly uri: Uri;
+ readonly originalUri: Uri;
+ readonly renameUri: Uri | undefined;
+ readonly status: Status;
}
export interface RepositoryState {
@@ -95,9 +125,13 @@ export interface Repository {
getConfig(key: string): Promise;
setConfig(key: string, value: string): Promise;
+ getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }>;
+ detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }>;
+ buffer(ref: string, path: string): Promise;
show(ref: string, path: string): Promise;
getCommit(ref: string): Promise;
- getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }>;
+
+ clean(paths: string[]): Promise;
diffWithHEAD(path: string): Promise;
diffWith(ref: string, path: string): Promise;
@@ -109,7 +143,7 @@ export interface Repository {
hashObject(data: string): Promise;
createBranch(name: string, checkout: boolean, ref?: string): Promise;
- deleteBranch(name: string): Promise;
+ deleteBranch(name: string, force?: boolean): Promise;
getBranch(name: string): Promise;
setBranchUpstream(name: string, upstream: string): Promise;
@@ -123,6 +157,7 @@ export interface Repository {
fetch(remote?: string, ref?: string): Promise;
pull(): Promise;
+ push(remoteName?: string, branchName?: string, setUpstream?: boolean): Promise;
}
export interface API {
@@ -134,9 +169,16 @@ export interface API {
export interface GitExtension {
+ readonly enabled: boolean;
+ readonly onDidChangeEnablement: Event;
+
/**
* Returns a specific API version.
*
+ * Throws error if git extension is disabled. You can listed to the
+ * [GitExtension.onDidChangeEnablement](#GitExtension.onDidChangeEnablement) event
+ * to know when the extension becomes enabled/disabled.
+ *
* @param version Version number.
* @returns API instance
*/
diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts
index f92f6951b8e..92a33b1ab71 100755
--- a/extensions/git/src/commands.ts
+++ b/extensions/git/src/commands.ts
@@ -5,7 +5,7 @@
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder } from 'vscode';
import { Git, CommitOptions, Stash, ForcePushMode } from './git';
-import { Repository, Resource, Status, ResourceGroupType } from './repository';
+import { Repository, Resource, ResourceGroupType } from './repository';
import { Model } from './model';
import { toGitUri, fromGitUri } from './uri';
import { grep, isDescendant, pathEquals } from './util';
@@ -15,7 +15,7 @@ import { lstat, Stats } from 'fs';
import * as os from 'os';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
-import { Ref, RefType, Branch, GitErrorCodes } from './api/git';
+import { Ref, RefType, Branch, GitErrorCodes, Status } from './api/git';
const localize = nls.loadMessageBundle();
@@ -655,6 +655,7 @@ export class CommandCenter {
@command('git.openHEADFile')
async openHEADFile(arg?: Resource | Uri): Promise {
let resource: Resource | undefined = undefined;
+ const preview = !(arg instanceof Resource);
if (arg instanceof Resource) {
resource = arg;
@@ -675,12 +676,18 @@ export class CommandCenter {
return;
}
- return await commands.executeCommand('vscode.open', HEAD);
+ const opts: TextDocumentShowOptions = {
+ preview
+ };
+
+ return await commands.executeCommand('vscode.open', HEAD, opts);
}
@command('git.openChange')
async openChange(arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise {
const preserveFocus = arg instanceof Resource;
+ const preview = !(arg instanceof Resource);
+
const preserveSelection = arg instanceof Uri || !arg;
let resources: Resource[] | undefined = undefined;
@@ -707,7 +714,6 @@ export class CommandCenter {
return;
}
- const preview = resources.length === 1 ? undefined : false;
for (const resource of resources) {
await this._openResource(resource, preview, preserveFocus, preserveSelection);
}
diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts
index dcfbf569ec9..0c27365bc51 100644
--- a/extensions/git/src/decorationProvider.ts
+++ b/extensions/git/src/decorationProvider.ts
@@ -5,11 +5,11 @@
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
import * as path from 'path';
-import { Repository, GitResourceGroup, Status } from './repository';
+import { Repository, GitResourceGroup } from './repository';
import { Model } from './model';
import { debounce } from './decorators';
import { filterEvent, dispose, anyEvent, fireEvent } from './util';
-import { GitErrorCodes } from './api/git';
+import { GitErrorCodes, Status } from './api/git';
type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void };
diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts
index 1ff683150a5..52b7c3c106a 100644
--- a/extensions/git/src/main.ts
+++ b/extensions/git/src/main.ts
@@ -17,7 +17,7 @@ import { toDisposable, filterEvent, eventToPromise } from './util';
import TelemetryReporter from 'vscode-extension-telemetry';
import { GitExtension } from './api/git';
import { GitProtocolHandler } from './protocolHandler';
-import { createGitExtension } from './api/extension';
+import { GitExtensionImpl } from './api/extension';
import * as path from 'path';
import * as fs from 'fs';
@@ -137,12 +137,15 @@ export async function activate(context: ExtensionContext): Promise
if (!enabled) {
const onConfigChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'));
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get('enabled') === true);
- await eventToPromise(onEnabled);
+ const result = new GitExtensionImpl();
+
+ eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannel, telemetryReporter, disposables));
+ return result;
}
try {
const model = await createModel(context, outputChannel, telemetryReporter, disposables);
- return createGitExtension(model);
+ return new GitExtensionImpl(model);
} catch (err) {
if (!/Git installation not found/.test(err.message || '')) {
throw err;
@@ -151,9 +154,9 @@ export async function activate(context: ExtensionContext): Promise
console.warn(err.message);
outputChannel.appendLine(err.message);
- await warnAboutMissingGit();
+ warnAboutMissingGit();
- return createGitExtension();
+ return new GitExtensionImpl();
}
}
diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts
index cff2a80a899..287552aef80 100644
--- a/extensions/git/src/repository.ts
+++ b/extensions/git/src/repository.ts
@@ -13,7 +13,7 @@ import * as path from 'path';
import * as nls from 'vscode-nls';
import * as fs from 'fs';
import { StatusBarCommands } from './statusbar';
-import { Branch, Ref, Remote, RefType, GitErrorCodes, TrackingShip } from './api/git';
+import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, TrackingShip } from './api/git';
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
@@ -29,27 +29,6 @@ export const enum RepositoryState {
Disposed
}
-export const enum Status {
- INDEX_MODIFIED,
- INDEX_ADDED,
- INDEX_DELETED,
- INDEX_RENAMED,
- INDEX_COPIED,
-
- MODIFIED,
- DELETED,
- UNTRACKED,
- IGNORED,
-
- ADDED_BY_US,
- ADDED_BY_THEM,
- DELETED_BY_US,
- DELETED_BY_THEM,
- BOTH_ADDED,
- BOTH_DELETED,
- BOTH_MODIFIED
-}
-
export const enum ResourceGroupType {
Merge,
Index,
@@ -122,6 +101,7 @@ export class Resource implements SourceControlResourceState {
case Status.DELETED_BY_US: return Resource.Icons[theme].Conflict;
case Status.BOTH_ADDED: return Resource.Icons[theme].Conflict;
case Status.BOTH_MODIFIED: return Resource.Icons[theme].Conflict;
+ default: throw new Error('Unknown git status: ' + this.type);
}
}
@@ -207,6 +187,8 @@ export class Resource implements SourceControlResourceState {
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return 'C';
+ default:
+ throw new Error('Unknown git status: ' + this.type);
}
}
@@ -234,6 +216,8 @@ export class Resource implements SourceControlResourceState {
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return new ThemeColor('gitDecoration.conflictingResourceForeground');
+ default:
+ throw new Error('Unknown git status: ' + this.type);
}
}
@@ -846,7 +830,7 @@ export class Repository implements Disposable {
}
async branch(name: string, _checkout: boolean, _ref?: string): Promise {
- await this.run(Operation.Branch, () => this.repository.branch(name, true));
+ await this.run(Operation.Branch, () => this.repository.branch(name, _checkout, _ref));
}
async deleteBranch(name: string, force?: boolean): Promise {
diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts
index ea1ddb97abb..820397f02da 100644
--- a/extensions/git/src/util.ts
+++ b/extensions/git/src/util.ts
@@ -44,6 +44,18 @@ export function filterEvent(event: Event, filter: (e: T) => boolean): Even
return (listener, thisArgs = null, disposables?) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables);
}
+export function latchEvent(event: Event): Event {
+ let firstCall = true;
+ let cache: T;
+
+ return filterEvent(event, value => {
+ let shouldEmit = firstCall || value !== cache;
+ firstCall = false;
+ cache = value;
+ return shouldEmit;
+ });
+}
+
export function anyEvent(...events: Event[]): Event {
return (listener, thisArgs = null, disposables?) => {
const result = combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i))));
diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock
index 4a18c906ecb..616d42caddf 100644
--- a/extensions/git/yarn.lock
+++ b/extensions/git/yarn.lock
@@ -151,10 +151,12 @@ he@1.1.1:
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
-iconv-lite@0.4.19:
- version "0.4.19"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
- integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==
+iconv-lite@^0.4.24:
+ version "0.4.24"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
+ integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
inflight@^1.0.4:
version "1.0.6"
@@ -294,6 +296,11 @@ 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":
+ 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.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
diff --git a/extensions/grunt/src/main.ts b/extensions/grunt/src/main.ts
index e90277cfe9e..38589e8a596 100644
--- a/extensions/grunt/src/main.ts
+++ b/extensions/grunt/src/main.ts
@@ -81,7 +81,7 @@ class FolderDetector {
}
public start(): void {
- let pattern = path.join(this._workspaceFolder.uri.fsPath, '[Gg]runtfile.js');
+ let pattern = path.join(this._workspaceFolder.uri.fsPath, '{node_modules,[Gg]runtfile.js}');
this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
this.fileWatcher.onDidChange(() => this.promise = undefined);
this.fileWatcher.onDidCreate(() => this.promise = undefined);
diff --git a/extensions/grunt/src/typings/refs.d.ts b/extensions/grunt/src/typings/refs.d.ts
index 954bab971e3..bc057c55878 100644
--- a/extensions/grunt/src/typings/refs.d.ts
+++ b/extensions/grunt/src/typings/refs.d.ts
@@ -4,5 +4,4 @@
*--------------------------------------------------------------------------------------------*/
///
-///
///
diff --git a/extensions/gulp/src/main.ts b/extensions/gulp/src/main.ts
index c5adf07d1b3..b8612d511c2 100644
--- a/extensions/gulp/src/main.ts
+++ b/extensions/gulp/src/main.ts
@@ -82,7 +82,7 @@ class FolderDetector {
}
public start(): void {
- let pattern = path.join(this._workspaceFolder.uri.fsPath, 'gulpfile{.babel.js,.js,.ts}');
+ let pattern = path.join(this._workspaceFolder.uri.fsPath, '{node_modules,gulpfile{.babel.js,.js,.ts}}');
this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
this.fileWatcher.onDidChange(() => this.promise = undefined);
this.fileWatcher.onDidCreate(() => this.promise = undefined);
diff --git a/extensions/gulp/src/typings/refs.d.ts b/extensions/gulp/src/typings/refs.d.ts
index 954bab971e3..bc057c55878 100644
--- a/extensions/gulp/src/typings/refs.d.ts
+++ b/extensions/gulp/src/typings/refs.d.ts
@@ -4,5 +4,4 @@
*--------------------------------------------------------------------------------------------*/
///
-///
///
diff --git a/extensions/html-language-features/client/src/typings/ref.d.ts b/extensions/html-language-features/client/src/typings/ref.d.ts
index 2b90c6587fe..9c1a5df18ed 100644
--- a/extensions/html-language-features/client/src/typings/ref.d.ts
+++ b/extensions/html-language-features/client/src/typings/ref.d.ts
@@ -4,4 +4,3 @@
*--------------------------------------------------------------------------------------------*/
///
-///
\ No newline at end of file
diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json
index 1bbfa36ead5..19ba1cb08dd 100644
--- a/extensions/html-language-features/package.json
+++ b/extensions/html-language-features/package.json
@@ -14,7 +14,6 @@
"onLanguage:handlebars",
"onLanguage:razor"
],
- "enableProposedApi": true,
"main": "./client/out/htmlMain",
"scripts": {
"compile": "gulp compile-extension:html-language-features-client compile-extension:html-language-features-server",
diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json
index c46f30cf5bc..93882a7ec94 100644
--- a/extensions/html-language-features/server/package.json
+++ b/extensions/html-language-features/server/package.json
@@ -9,8 +9,8 @@
},
"main": "./out/htmlServerMain",
"dependencies": {
- "vscode-css-languageservice": "^3.0.12-next.1",
- "vscode-html-languageservice": "^2.1.9",
+ "vscode-css-languageservice": "^3.0.12",
+ "vscode-html-languageservice": "^2.1.10",
"vscode-languageserver": "^5.1.0",
"vscode-languageserver-types": "^3.13.0",
"vscode-nls": "^4.0.0",
diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock
index 48ff5aef257..6530713c465 100644
--- a/extensions/html-language-features/server/yarn.lock
+++ b/extensions/html-language-features/server/yarn.lock
@@ -229,18 +229,18 @@ supports-color@5.4.0:
dependencies:
has-flag "^3.0.0"
-vscode-css-languageservice@^3.0.12-next.1:
- version "3.0.12-next.1"
- resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.12-next.1.tgz#1bc76d04f68b6d3d9b25cf01592ba46cea91c26c"
- integrity sha512-Be1pfmRlcRsKMl1O/5rci8lu8RlE5vwT8LOjUEfHZkz5eHL2n9rTLo3dzmbVGtSL7+T1XEArjqUks9MzzDUhcw==
+vscode-css-languageservice@^3.0.12:
+ version "3.0.12"
+ resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.12.tgz#fb4aac5ae3c5b761b1db1d7224b78ff824284dc3"
+ integrity sha512-+FLQ9LcukIhnxaGTjDOqb3Nb1hesz9BLXf5yeoZxUsuK7joADPLPdxLwlZugFcMAvgmtnaFIGnzkQhGOVqf5yw==
dependencies:
vscode-languageserver-types "^3.13.0"
vscode-nls "^4.0.0"
-vscode-html-languageservice@^2.1.9:
- version "2.1.9"
- resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.9.tgz#906f2f894b023d3a464739ebc5b4eb695ef1cf58"
- integrity sha512-zHb6zqt55THIkHjywsjBqGwBr9vCOmBDh6mGyyawGi/8XH2Y6yIAH7KXTxN4Ov9A2M0CT2mwSA3tl+IKtIJtjg==
+vscode-html-languageservice@^2.1.10:
+ version "2.1.10"
+ resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.10.tgz#3433fd53e188cb25d5ea190b61a148fe9965ff91"
+ integrity sha512-nuzLd7a3J+Ttvk/9Pg2H0vS7rV2oZRfsQYPRheHnUNJNqivkcieSI8ZCGvZjmr3NDBG2QQaRFambnCtceYAj3A==
dependencies:
vscode-languageserver-types "^3.13.0"
vscode-nls "^4.0.0"
diff --git a/extensions/jake/src/main.ts b/extensions/jake/src/main.ts
index c4e20edf10c..938ca51bec9 100644
--- a/extensions/jake/src/main.ts
+++ b/extensions/jake/src/main.ts
@@ -81,7 +81,7 @@ class FolderDetector {
}
public start(): void {
- let pattern = path.join(this._workspaceFolder.uri.fsPath, '{Jakefile,Jakefile.js}');
+ let pattern = path.join(this._workspaceFolder.uri.fsPath, '{node_modules,Jakefile,Jakefile.js}');
this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
this.fileWatcher.onDidChange(() => this.promise = undefined);
this.fileWatcher.onDidCreate(() => this.promise = undefined);
diff --git a/extensions/jake/src/typings/refs.d.ts b/extensions/jake/src/typings/refs.d.ts
index 954bab971e3..bc057c55878 100644
--- a/extensions/jake/src/typings/refs.d.ts
+++ b/extensions/jake/src/typings/refs.d.ts
@@ -4,5 +4,4 @@
*--------------------------------------------------------------------------------------------*/
///
-///
///
diff --git a/extensions/java/syntaxes/java.tmLanguage.json b/extensions/java/syntaxes/java.tmLanguage.json
index b0ecaec639f..2ccdc0733de 100644
--- a/extensions/java/syntaxes/java.tmLanguage.json
+++ b/extensions/java/syntaxes/java.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/atom/language-java/commit/295af4375e4a5da4a4352fa08a8bb3e17145ec47",
+ "version": "https://github.com/atom/language-java/commit/95ebcd0b15c369666ecc4d1593495466132dd5bf",
"name": "Java",
"scopeName": "source.java",
"patterns": [
@@ -373,7 +373,7 @@
"include": "#static-initializer"
},
{
- "include": "#methods"
+ "include": "#class-fields-and-methods"
},
{
"include": "#annotations"
@@ -389,6 +389,22 @@
}
]
},
+ "class-fields-and-methods": {
+ "patterns": [
+ {
+ "begin": "(?=\\=)",
+ "end": "(?=;)",
+ "patterns": [
+ {
+ "include": "#code"
+ }
+ ]
+ },
+ {
+ "include": "#methods"
+ }
+ ]
+ },
"code": {
"patterns": [
{
@@ -442,6 +458,9 @@
{
"include": "#variables"
},
+ {
+ "include": "#variables-local"
+ },
{
"include": "#objects"
},
@@ -479,9 +498,6 @@
"match": "/\\*\\*/",
"name": "comment.block.empty.java"
},
- {
- "include": "text.html.javadoc"
- },
{
"include": "#comments-inline"
}
@@ -911,7 +927,7 @@
"include": "#parens"
},
{
- "include": "#comments-inline"
+ "include": "#comments"
}
]
},
@@ -928,6 +944,9 @@
},
{
"include": "#parens"
+ },
+ {
+ "include": "#comments"
}
]
},
@@ -1496,12 +1515,12 @@
]
},
"variables": {
- "begin": "(?x)\n(?=\n (\n \\b(void|boolean|byte|char|short|int|float|long|double)\\b\n |\n (?>(\\w+\\.)*[A-Z]+\\w*) # e.g. `javax.ws.rs.Response`, or `String`\n )\n (\n <[\\w<>,\\.?\\s\\[\\]]*> # e.g. `HashMap`, or `List`\n )?\n (\n (\\[\\])* # int[][]\n )?\n \\s+\n [A-Za-z_$][\\w$]* # At least one identifier after space\n ([\\w\\[\\],$][\\w\\[\\],\\s]*)? # possibly primitive array or additional identifiers\n \\s*(=|;)\n)",
- "end": "(?=\\=|;)",
+ "begin": "(?x)\n(?=\n (\n \\b(void|boolean|byte|char|short|int|float|long|double)\\b\n |\n (?>(\\w+\\.)*[A-Z]+\\w*) # e.g. `javax.ws.rs.Response`, or `String`\n )\n (\n <[\\w<>,\\.?\\s\\[\\]]*> # e.g. `HashMap`, or `List`\n )?\n (\n (\\[\\])* # int[][]\n )?\n \\s+\n [A-Za-z_$][\\w$]* # At least one identifier after space\n ([\\w\\[\\],$][\\w\\[\\],\\s]*)? # possibly primitive array or additional identifiers\n \\s*(=|:|;)\n)",
+ "end": "(?=\\=|:|;)",
"name": "meta.definition.variable.java",
"patterns": [
{
- "match": "([A-Za-z$_][\\w$]*)(?=\\s*(\\[\\])*\\s*(;|=|,))",
+ "match": "([A-Za-z$_][\\w$]*)(?=\\s*(\\[\\])*\\s*(;|:|=|,))",
"captures": {
"1": {
"name": "variable.other.definition.java"
@@ -1515,6 +1534,28 @@
"include": "#code"
}
]
+ },
+ "variables-local": {
+ "begin": "(?=\\b(var)\\b\\s+[A-Za-z_$][\\w$]*\\s*(=|:|;))",
+ "end": "(?=\\=|:|;)",
+ "name": "meta.definition.variable.local.java",
+ "patterns": [
+ {
+ "match": "\\bvar\\b",
+ "name": "storage.type.local.java"
+ },
+ {
+ "match": "([A-Za-z$_][\\w$]*)(?=\\s*(\\[\\])*\\s*(=|:|;))",
+ "captures": {
+ "1": {
+ "name": "variable.other.definition.java"
+ }
+ }
+ },
+ {
+ "include": "#code"
+ }
+ ]
}
}
}
\ No newline at end of file
diff --git a/extensions/javascript/snippets/javascript.json b/extensions/javascript/snippets/javascript.json
index 5579e4e0c16..5da4ebe0c18 100644
--- a/extensions/javascript/snippets/javascript.json
+++ b/extensions/javascript/snippets/javascript.json
@@ -140,6 +140,15 @@
],
"description": "Set Timeout Function"
},
+ "Set Interval Function": {
+ "prefix": "setinterval",
+ "body": [
+ "setInterval(() => {",
+ "\t$0",
+ "}, ${1:interval});"
+ ],
+ "description": "Set Interval Function"
+ },
"Import external module.": {
"prefix": "import statement",
"body": [
diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json
index ab11abeb0a6..50fa8fca327 100644
--- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json
+++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/6e8a3830c29b6f29c06d2de091240e1a880f21aa",
+ "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/3133e3d914db9a2bb8812119f9273727a305f16b",
"name": "JavaScript (with React support)",
"scopeName": "source.js",
"patterns": [
@@ -1153,7 +1153,7 @@
"name": "meta.definition.function.js entity.name.function.js"
}
},
- "end": "(?=$|^|;)|(?<=\\})",
+ "end": "(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|(?<=\\})",
"patterns": [
{
"include": "#function-name"
@@ -1413,6 +1413,9 @@
},
{
"include": "#arrow-return-type"
+ },
+ {
+ "include": "#possibly-arrow-return-type"
}
]
},
@@ -1424,8 +1427,11 @@
"name": "storage.type.function.arrow.js"
}
},
- "end": "(?<=\\}|\\S)(?)|((?!\\{)(?=\\S))",
+ "end": "((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])",
"patterns": [
+ {
+ "include": "#single-line-comment-consuming-line-ending"
+ },
{
"include": "#decl-block"
},
@@ -2623,13 +2629,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.js",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2676,7 +2682,7 @@
"name": "keyword.operator.new.js"
}
},
- "end": "(?<=\\))|(?=[;),}\\]:]|\\|\\||\\&\\&|$|((?\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
+ "begin": "(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
"beginCaptures": {
"1": {
"name": "meta.arrow.js meta.return.type.arrow.js keyword.operator.type.annotation.js"
@@ -3587,6 +3593,14 @@
}
},
"patterns": [
+ {
+ "match": "(?)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
@@ -3937,7 +3948,7 @@
"include": "#typeof-operator"
},
{
- "begin": "([&|\\*])(?=\\s*\\{)",
+ "begin": "([&|])(?=\\s*\\{)",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.js"
@@ -3951,7 +3962,7 @@
]
},
{
- "begin": "[&|\\*]",
+ "begin": "[&|]",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.js"
@@ -4089,7 +4100,7 @@
"patterns": [
{
"name": "string.template.js",
- "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
+ "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
"beginCaptures": {
"1": {
"name": "entity.name.function.tagged-template.js"
diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json
index 85dd338686c..38aff66512d 100644
--- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json
+++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/6e8a3830c29b6f29c06d2de091240e1a880f21aa",
+ "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/3133e3d914db9a2bb8812119f9273727a305f16b",
"name": "JavaScript (with React support)",
"scopeName": "source.js.jsx",
"patterns": [
@@ -1153,7 +1153,7 @@
"name": "meta.definition.function.js.jsx entity.name.function.js.jsx"
}
},
- "end": "(?=$|^|;)|(?<=\\})",
+ "end": "(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|(?<=\\})",
"patterns": [
{
"include": "#function-name"
@@ -1413,6 +1413,9 @@
},
{
"include": "#arrow-return-type"
+ },
+ {
+ "include": "#possibly-arrow-return-type"
}
]
},
@@ -1424,8 +1427,11 @@
"name": "storage.type.function.arrow.js.jsx"
}
},
- "end": "(?<=\\}|\\S)(?)|((?!\\{)(?=\\S))",
+ "end": "((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])",
"patterns": [
+ {
+ "include": "#single-line-comment-consuming-line-ending"
+ },
{
"include": "#decl-block"
},
@@ -2623,13 +2629,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.js.jsx",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2676,7 +2682,7 @@
"name": "keyword.operator.new.js.jsx"
}
},
- "end": "(?<=\\))|(?=[;),}\\]:]|\\|\\||\\&\\&|$|((?\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
+ "begin": "(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
"beginCaptures": {
"1": {
"name": "meta.arrow.js.jsx meta.return.type.arrow.js.jsx keyword.operator.type.annotation.js.jsx"
@@ -3587,6 +3593,14 @@
}
},
"patterns": [
+ {
+ "match": "(?)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
@@ -3937,7 +3948,7 @@
"include": "#typeof-operator"
},
{
- "begin": "([&|\\*])(?=\\s*\\{)",
+ "begin": "([&|])(?=\\s*\\{)",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.js.jsx"
@@ -3951,7 +3962,7 @@
]
},
{
- "begin": "[&|\\*]",
+ "begin": "[&|]",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.js.jsx"
@@ -4089,7 +4100,7 @@
"patterns": [
{
"name": "string.template.js.jsx",
- "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
+ "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
"beginCaptures": {
"1": {
"name": "entity.name.function.tagged-template.js.jsx"
diff --git a/extensions/json-language-features/.vscode/tasks.json b/extensions/json-language-features/.vscode/tasks.json
index 9e5593ade83..390a93a3a7f 100644
--- a/extensions/json-language-features/.vscode/tasks.json
+++ b/extensions/json-language-features/.vscode/tasks.json
@@ -1,30 +1,11 @@
-// Available variables which can be used inside of strings.
-// ${workspaceFolder}: the root folder of the team
-// ${file}: the current opened file
-// ${fileBasename}: the current opened file's basename
-// ${fileDirname}: the current opened file's dirname
-// ${fileExtname}: the current opened file's extension
-// ${cwd}: the current working directory of the spawned process
-
-// A task runner that calls a custom npm script that compiles the extension.
{
- "version": "0.1.0",
-
- // we want to run npm
+ "version": "2.0.0",
"command": "npm",
-
- // the command is a shell script
- "isShellCommand": true,
-
- // show the output window only if unrecognized errors occur.
- "showOutput": "silent",
-
- // we run the custom script "compile" as defined in package.json
+ "type": "shell",
+ "presentation": {
+ "reveal": "silent"
+ },
"args": ["run", "compile"],
-
- // The tsc compiler is started in watching mode
- "isWatching": true,
-
- // use the standard tsc in watch mode problem matcher to find compile problems in the output.
+ "isBackground": true,
"problemMatcher": "$tsc-watch"
-}
\ No newline at end of file
+}
diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts
index 8da28460f36..759ef0381cd 100644
--- a/extensions/json-language-features/client/src/jsonMain.ts
+++ b/extensions/json-language-features/client/src/jsonMain.ts
@@ -8,8 +8,8 @@ import * as fs from 'fs';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
-import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration } from 'vscode';
-import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
+import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor } from 'vscode';
+import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature } from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry';
import { hash } from './utils/hash';
@@ -22,6 +22,10 @@ namespace SchemaContentChangeNotification {
export const type: NotificationType = new NotificationType('json/schemaContent');
}
+namespace ForceValidateRequest {
+ export const type: RequestType = new RequestType('json/validate');
+}
+
export interface ISchemaAssociations {
[pattern: string]: string[];
}
@@ -77,6 +81,14 @@ export function activate(context: ExtensionContext) {
let documentSelector = ['json', 'jsonc'];
+ let schemaResolutionErrorStatusBarItem = window.createStatusBarItem(StatusBarAlignment.Right, 0);
+ schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema';
+ schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema.') + ' ' + localize('json.clickToRetry', 'Click to retry.');
+ schemaResolutionErrorStatusBarItem.text = '$(alert)';
+ toDispose.push(schemaResolutionErrorStatusBarItem);
+
+ let fileSchemaErrors = new Map();
+
// Options to control the language client
let clientOptions: LanguageClientOptions = {
// Register the server for json documents
@@ -89,6 +101,23 @@ export function activate(context: ExtensionContext) {
middleware: {
workspace: {
didChangeConfiguration: () => client.sendNotification(DidChangeConfigurationNotification.type, { settings: getSettings() })
+ },
+ handleDiagnostics: (uri: Uri, diagnostics: Diagnostic[], next: HandleDiagnosticsSignature) => {
+ const schemaErrorIndex = diagnostics.findIndex(candidate => candidate.code === /* SchemaResolveError */ 0x300);
+
+ if (schemaErrorIndex === -1) {
+ fileSchemaErrors.delete(uri.toString());
+ return next(uri, diagnostics);
+ }
+
+ const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
+ fileSchemaErrors.set(uri.toString(), schemaResolveDiagnostic.message);
+
+ if (window.activeTextEditor && window.activeTextEditor.document.uri.toString() === uri.toString()) {
+ schemaResolutionErrorStatusBarItem.show();
+ }
+
+ next(uri, diagnostics);
}
}
};
@@ -121,8 +150,47 @@ export function activate(context: ExtensionContext) {
client.sendNotification(SchemaContentChangeNotification.type, uri.toString());
}
};
+
+ let handleActiveEditorChange = (activeEditor?: TextEditor) => {
+ if (!activeEditor) {
+ return;
+ }
+
+ const activeDocUri = activeEditor.document.uri.toString();
+
+ if (activeDocUri && fileSchemaErrors.has(activeDocUri)) {
+ schemaResolutionErrorStatusBarItem.show();
+ } else {
+ schemaResolutionErrorStatusBarItem.hide();
+ }
+ };
+
toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri)));
- toDispose.push(workspace.onDidCloseTextDocument(d => handleContentChange(d.uri)));
+ toDispose.push(workspace.onDidCloseTextDocument(d => {
+ handleContentChange(d.uri);
+ fileSchemaErrors.delete(d.uri.toString());
+ }));
+ toDispose.push(window.onDidChangeActiveTextEditor(handleActiveEditorChange));
+
+ let handleRetryResolveSchemaCommand = () => {
+ if (window.activeTextEditor) {
+ schemaResolutionErrorStatusBarItem.text = '$(watch)';
+ const activeDocUri = window.activeTextEditor.document.uri.toString();
+ client.sendRequest(ForceValidateRequest.type, activeDocUri).then((diagnostics) => {
+ const schemaErrorIndex = diagnostics.findIndex(candidate => candidate.code === /* SchemaResolveError */ 0x300);
+ if (schemaErrorIndex !== -1) {
+ // Show schema resolution errors in status bar only; ref: #51032
+ const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
+ fileSchemaErrors.set(activeDocUri, schemaResolveDiagnostic.message);
+ } else {
+ schemaResolutionErrorStatusBarItem.hide();
+ }
+ schemaResolutionErrorStatusBarItem.text = '$(alert)';
+ });
+ }
+ };
+
+ toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand));
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
});
diff --git a/extensions/json-language-features/client/src/typings/ref.d.ts b/extensions/json-language-features/client/src/typings/ref.d.ts
index 2b90c6587fe..9c1a5df18ed 100644
--- a/extensions/json-language-features/client/src/typings/ref.d.ts
+++ b/extensions/json-language-features/client/src/typings/ref.d.ts
@@ -4,4 +4,3 @@
*--------------------------------------------------------------------------------------------*/
///
-///
\ No newline at end of file
diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json
index 0e4b57cf994..a1a5204c8b5 100644
--- a/extensions/json-language-features/package.json
+++ b/extensions/json-language-features/package.json
@@ -13,10 +13,10 @@
"onLanguage:json",
"onLanguage:jsonc"
],
- "enableProposedApi": true,
"main": "./client/out/jsonMain",
"scripts": {
- "compile": "gulp compile-extension:json-language-features-client && gulp compile-extension:json-language-features-server",
+ "compile": "gulp compile-extension:json-language-features-client compile-extension:json-language-features-server",
+ "watch": "gulp watch-extension:json-language-features-client watch-extension:json-language-features-server",
"postinstall": "cd server && yarn install",
"install-client-next": "yarn add vscode-languageclient@next"
},
diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json
index 943de414e15..c61e7b70e8f 100644
--- a/extensions/json-language-features/package.nls.json
+++ b/extensions/json-language-features/package.nls.json
@@ -9,5 +9,7 @@
"json.format.enable.desc": "Enable/disable default JSON formatter",
"json.tracing.desc": "Traces the communication between VS Code and the JSON language server.",
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
- "json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`."
-}
\ No newline at end of file
+ "json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
+ "json.schemaResolutionErrorMessage": "Unable to resolve schema.",
+ "json.clickToRetry": "Click to retry."
+}
diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json
index 5e7de8ed719..db0182fa088 100644
--- a/extensions/json-language-features/server/package.json
+++ b/extensions/json-language-features/server/package.json
@@ -14,7 +14,7 @@
"dependencies": {
"jsonc-parser": "^2.0.2",
"request-light": "^0.2.4",
- "vscode-json-languageservice": "^3.2.0",
+ "vscode-json-languageservice": "^3.2.1",
"vscode-languageserver": "^5.1.0",
"vscode-nls": "^4.0.0",
"vscode-uri": "^1.0.6"
diff --git a/extensions/json-language-features/server/src/jsonServerMain.ts b/extensions/json-language-features/server/src/jsonServerMain.ts
index 6eadf2403b8..8a8ce642331 100644
--- a/extensions/json-language-features/server/src/jsonServerMain.ts
+++ b/extensions/json-language-features/server/src/jsonServerMain.ts
@@ -6,7 +6,7 @@
import {
createConnection, IConnection,
TextDocuments, TextDocument, InitializeParams, InitializeResult, NotificationType, RequestType,
- DocumentRangeFormattingRequest, Disposable, ServerCapabilities
+ DocumentRangeFormattingRequest, Disposable, ServerCapabilities, Diagnostic
} from 'vscode-languageserver';
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
@@ -34,6 +34,10 @@ namespace SchemaContentChangeNotification {
export const type: NotificationType = new NotificationType('json/schemaContent');
}
+namespace ForceValidateRequest {
+ export const type: RequestType = new RequestType('json/validate');
+}
+
// Create a connection for the server
const connection: IConnection = createConnection();
@@ -207,6 +211,21 @@ connection.onNotification(SchemaContentChangeNotification.type, uri => {
languageService.resetSchema(uri);
});
+// Retry schema validation on all open documents
+connection.onRequest(ForceValidateRequest.type, uri => {
+ return new Promise(resolve => {
+ const document = documents.get(uri);
+ if (document) {
+ updateConfiguration();
+ validateTextDocument(document, diagnostics => {
+ resolve(diagnostics);
+ });
+ } else {
+ resolve([]);
+ }
+ });
+});
+
function updateConfiguration() {
const languageSettings = {
validate: true,
@@ -271,10 +290,15 @@ function triggerValidation(textDocument: TextDocument): void {
}, validationDelayMs);
}
-function validateTextDocument(textDocument: TextDocument): void {
+function validateTextDocument(textDocument: TextDocument, callback?: (diagnostics: Diagnostic[]) => void): void {
+ const respond = (diagnostics: Diagnostic[]) => {
+ connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
+ if (callback) {
+ callback(diagnostics);
+ }
+ };
if (textDocument.getText().length === 0) {
- // ignore empty documents
- connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
+ respond([]); // ignore empty documents
return;
}
const jsonDocument = getJSONDocument(textDocument);
@@ -285,8 +309,7 @@ function validateTextDocument(textDocument: TextDocument): void {
setTimeout(() => {
const currDocument = documents.get(textDocument.uri);
if (currDocument && currDocument.version === version) {
- // Send the computed diagnostics to VSCode.
- connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
+ respond(diagnostics); // Send the computed diagnostics to VSCode.
}
}, 100);
}, error => {
@@ -405,4 +428,4 @@ connection.onFoldingRanges((params, token) => {
});
// Listen on the connection
-connection.listen();
\ No newline at end of file
+connection.listen();
diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock
index e4c2fee15a6..012e346360a 100644
--- a/extensions/json-language-features/server/yarn.lock
+++ b/extensions/json-language-features/server/yarn.lock
@@ -73,10 +73,10 @@ request-light@^0.2.4:
https-proxy-agent "^2.2.1"
vscode-nls "^4.0.0"
-vscode-json-languageservice@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.2.0.tgz#fe796c2ddbda966d87905442f9636f139e00f341"
- integrity sha512-tLAv9/D01fLAvnYnZ1OLy03HSHhVFjaSkUidEjfrwytHrxVDgqXLkHAJg+F6Q3mPYfpnPQvN2jTjiJ1yInuNVg==
+vscode-json-languageservice@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.2.1.tgz#991d51128ebd81c5525d0578cabfa5b03e3cba2a"
+ integrity sha512-ee9MJ70/xR55ywvm0bZsDLhA800HCRE27AYgMNTU14RSg20Y+ngHdQnUt6OmiTXrQDI/7sne6QUOtHIN0hPQYA==
dependencies:
jsonc-parser "^2.0.2"
vscode-languageserver-types "^3.13.0"
diff --git a/extensions/log/syntaxes/log.tmLanguage.json b/extensions/log/syntaxes/log.tmLanguage.json
index 15cb646dadb..e2e5af634b1 100644
--- a/extensions/log/syntaxes/log.tmLanguage.json
+++ b/extensions/log/syntaxes/log.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/emilast/vscode-logfile-highlighter/commit/03cb9582024f477f93f3d27c46f7c084b2b14afe",
+ "version": "https://github.com/emilast/vscode-logfile-highlighter/commit/30a19d24b9a0070b0fab5eef45f89c92e7cd71ea",
"name": "Log file",
"scopeName": "text.log",
"patterns": [
@@ -49,7 +49,7 @@
"name": "comment log.date"
},
{
- "match": "\\d{2}:\\d{2}(:\\d{2}([.,]\\d{3,})?)?(Z| ?[+-]\\d{2}:\\d{2})?\\b",
+ "match": "\\d{1,2}:\\d{2}(:\\d{2}([.,]\\d{1,})?)?(Z| ?[+-]\\d{1,2}:\\d{2})?\\b",
"name": "comment log.date"
},
{
@@ -69,7 +69,7 @@
"name": "string log.string"
},
{
- "match": "(^|[^\\w])'[^']*'",
+ "match": "(??) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in quotes…\n | ((\").+?(\")) # or in parens.\n )? # Title is optional\n \\s* # Optional whitespace\n $\n",
+ "match": "(?x)\n \\s* # Leading whitespace\n (\\[)([^]]+?)(\\])(:) # Reference name\n [ \\t]* # Optional whitespace\n ()(\\S+?)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in quotes…\n | ((\").+?(\")) # or in parens.\n )? # Title is optional\n \\s* # Optional whitespace\n $\n",
"name": "meta.link.reference.def.markdown"
},
"list_paragraph": {
diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json
index faa18bc663b..9bc9aa7595f 100644
--- a/extensions/markdown-basics/test/colorize-results/test_md.json
+++ b/extensions/markdown-basics/test/colorize-results/test_md.json
@@ -2520,7 +2520,7 @@
},
{
"c": "]",
- "t": "text.html.markdown meta.paragraph.markdown meta.link.reference.markdown",
+ "t": "text.html.markdown meta.paragraph.markdown meta.link.reference.markdown punctuation.definition.string.end.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
diff --git a/extensions/markdown-language-features/media/index.js b/extensions/markdown-language-features/media/index.js
index 99e63083556..25df5db9f4e 100644
--- a/extensions/markdown-language-features/media/index.js
+++ b/extensions/markdown-language-features/media/index.js
@@ -825,11 +825,11 @@ const getCodeLineElements = (() => {
let elements;
return () => {
if (!elements) {
- elements = Array.prototype.map.call(document.getElementsByClassName('code-line'), (element) => {
+ elements = ([{ element: document.body, line: 0 }]).concat(Array.prototype.map.call(document.getElementsByClassName('code-line'), (element) => {
const line = +element.getAttribute('data-line');
return { element, line };
})
- .filter((x) => !isNaN(x.line));
+ .filter((x) => !isNaN(x.line)));
}
return elements;
};
@@ -887,22 +887,30 @@ exports.getLineElementsAtPageOffset = getLineElementsAtPageOffset;
* Attempt to reveal the element for a source line in the editor.
*/
function scrollToRevealSourceLine(line) {
- const { previous, next } = getElementsForSourceLine(line);
- if (previous && settings_1.getSettings().scrollPreviewWithEditor) {
- let scrollTo = 0;
- const rect = previous.element.getBoundingClientRect();
- const previousTop = rect.top;
- if (next && next.line !== previous.line) {
- // Between two elements. Go to percentage offset between them.
- const betweenProgress = (line - previous.line) / (next.line - previous.line);
- const elementOffset = next.element.getBoundingClientRect().top - previousTop;
- scrollTo = previousTop + betweenProgress * elementOffset;
- }
- else {
- scrollTo = previousTop;
- }
- window.scroll(0, Math.max(1, window.scrollY + scrollTo));
+ if (!settings_1.getSettings().scrollPreviewWithEditor) {
+ return;
}
+ if (line <= 0) {
+ window.scroll(window.scrollX, 0);
+ return;
+ }
+ const { previous, next } = getElementsForSourceLine(line);
+ if (!previous) {
+ return;
+ }
+ let scrollTo = 0;
+ const rect = previous.element.getBoundingClientRect();
+ const previousTop = rect.top;
+ if (next && next.line !== previous.line) {
+ // Between two elements. Go to percentage offset between them.
+ const betweenProgress = (line - previous.line) / (next.line - previous.line);
+ const elementOffset = next.element.getBoundingClientRect().top - previousTop;
+ scrollTo = previousTop + betweenProgress * elementOffset;
+ }
+ else {
+ scrollTo = previousTop;
+ }
+ window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo));
}
exports.scrollToRevealSourceLine = scrollToRevealSourceLine;
function getEditorLineNumberForPageOffset(offset) {
@@ -970,4 +978,4 @@ exports.getSettings = getSettings;
/***/ })
/******/ });
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2xvZGFzaC50aHJvdHRsZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2FjdGl2ZUxpbmVNYXJrZXIudHMiLCJ3ZWJwYWNrOi8vLy4vcHJldmlldy1zcmMvZXZlbnRzLnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2luZGV4LnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL21lc3NhZ2luZy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zY3JvbGwtc3luYy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNB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LENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsQ0FBQztJQUNGLENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFWRCwwQkFVQztBQUVEO0lBQ0MsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUNwQixNQUFNLENBQUMsY0FBYyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxjQUFjLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsTUFBTSxDQUFDLGNBQWMsQ0FBQztJQUN2QixDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFYRCxrQ0FXQyIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwge1xuIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbiBcdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG4gXHRcdFx0XHRnZXQ6IGdldHRlclxuIFx0XHRcdH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3ByZXZpZXctc3JjL2luZGV4LnRzXCIpO1xuIiwiLyoqXG4gKiBsb2Rhc2ggKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCBqUXVlcnkgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIDxodHRwczovL2pxdWVyeS5vcmcvPlxuICogUmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICovXG5cbi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBOQU4gPSAwIC8gMDtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgc2VsZmAuICovXG52YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjtcblxuLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG52YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlXG4gKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBHZXRzIHRoZSB0aW1lc3RhbXAgb2YgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdGhhdCBoYXZlIGVsYXBzZWQgc2luY2VcbiAqIHRoZSBVbml4IGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMi40LjBcbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lc3RhbXAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gTG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgaW52b2NhdGlvbi5cbiAqL1xudmFyIG5vdyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcm9vdC5EYXRlLm5vdygpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gKiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYCBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGVcbiAqIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YCB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWRcbiAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAqIGNhbGxzIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgXG4gKiBpbnZvY2F0aW9uLlxuICpcbiAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uXG4gKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gKlxuICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gKlxuICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4V2FpdF1cbiAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3Jlc2l6ZScsIF8uZGVib3VuY2UoY2FsY3VsYXRlTGF5b3V0LCAxNTApKTtcbiAqXG4gKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmRlYm91bmNlKHNlbmRNYWlsLCAzMDAsIHtcbiAqICAgJ2xlYWRpbmcnOiB0cnVlLFxuICogICAndHJhaWxpbmcnOiBmYWxzZVxuICogfSkpO1xuICpcbiAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gKiB2YXIgZGVib3VuY2VkID0gXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7ICdtYXhXYWl0JzogMTAwMCB9KTtcbiAqIHZhciBzb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UoJy9zdHJlYW0nKTtcbiAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAqXG4gKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIGRlYm91bmNlZCBpbnZvY2F0aW9uLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgdmFyIGxhc3RBcmdzLFxuICAgICAgbGFzdFRoaXMsXG4gICAgICBtYXhXYWl0LFxuICAgICAgcmVzdWx0LFxuICAgICAgdGltZXJJZCxcbiAgICAgIGxhc3RDYWxsVGltZSxcbiAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgIGxlYWRpbmcgPSBmYWxzZSxcbiAgICAgIG1heGluZyA9IGZhbHNlLFxuICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHdhaXQgPSB0b051bWJlcih3YWl0KSB8fCAwO1xuICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgbWF4aW5nID0gJ21heFdhaXQnIGluIG9wdGlvbnM7XG4gICAgbWF4V2FpdCA9IG1heGluZyA/IG5hdGl2ZU1heCh0b051bWJlcihvcHRpb25zLm1heFdhaXQpIHx8IDAsIHdhaXQpIDogbWF4V2FpdDtcbiAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlRnVuYyh0aW1lKSB7XG4gICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgdGhpc0FyZyA9IGxhc3RUaGlzO1xuXG4gICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gbGVhZGluZ0VkZ2UodGltZSkge1xuICAgIC8vIFJlc2V0IGFueSBgbWF4V2FpdGAgdGltZXIuXG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIC8vIFN0YXJ0IHRoZSB0aW1lciBmb3IgdGhlIHRyYWlsaW5nIGVkZ2UuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICByZXR1cm4gbGVhZGluZyA/IGludm9rZUZ1bmModGltZSkgOiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lLFxuICAgICAgICByZXN1bHQgPSB3YWl0IC0gdGltZVNpbmNlTGFzdENhbGw7XG5cbiAgICByZXR1cm4gbWF4aW5nID8gbmF0aXZlTWluKHJlc3VsdCwgbWF4V2FpdCAtIHRpbWVTaW5jZUxhc3RJbnZva2UpIDogcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvdWxkSW52b2tlKHRpbWUpIHtcbiAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lO1xuXG4gICAgLy8gRWl0aGVyIHRoaXMgaXMgdGhlIGZpcnN0IGNhbGwsIGFjdGl2aXR5IGhhcyBzdG9wcGVkIGFuZCB3ZSdyZSBhdCB0aGVcbiAgICAvLyB0cmFpbGluZyBlZGdlLCB0aGUgc3lzdGVtIHRpbWUgaGFzIGdvbmUgYmFja3dhcmRzIGFuZCB3ZSdyZSB0cmVhdGluZ1xuICAgIC8vIGl0IGFzIHRoZSB0cmFpbGluZyBlZGdlLCBvciB3ZSd2ZSBoaXQgdGhlIGBtYXhXYWl0YCBsaW1pdC5cbiAgICByZXR1cm4gKGxhc3RDYWxsVGltZSA9PT0gdW5kZWZpbmVkIHx8ICh0aW1lU2luY2VMYXN0Q2FsbCA+PSB3YWl0KSB8fFxuICAgICAgKHRpbWVTaW5jZUxhc3RDYWxsIDwgMCkgfHwgKG1heGluZyAmJiB0aW1lU2luY2VMYXN0SW52b2tlID49IG1heFdhaXQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRpbWVyRXhwaXJlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpO1xuICAgIGlmIChzaG91bGRJbnZva2UodGltZSkpIHtcbiAgICAgIHJldHVybiB0cmFpbGluZ0VkZ2UodGltZSk7XG4gICAgfVxuICAgIC8vIFJlc3RhcnQgdGhlIHRpbWVyLlxuICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgcmVtYWluaW5nV2FpdCh0aW1lKSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkge1xuICAgIHRpbWVySWQgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBPbmx5IGludm9rZSBpZiB3ZSBoYXZlIGBsYXN0QXJnc2Agd2hpY2ggbWVhbnMgYGZ1bmNgIGhhcyBiZWVuXG4gICAgLy8gZGVib3VuY2VkIGF0IGxlYXN0IG9uY2UuXG4gICAgaWYgKHRyYWlsaW5nICYmIGxhc3RBcmdzKSB7XG4gICAgICByZXR1cm4gaW52b2tlRnVuYyh0aW1lKTtcbiAgICB9XG4gICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgIGlmICh0aW1lcklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICB9XG4gICAgbGFzdEludm9rZVRpbWUgPSAwO1xuICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgcmV0dXJuIHRpbWVySWQgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IHRyYWlsaW5nRWRnZShub3coKSk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWJvdW5jZWQoKSB7XG4gICAgdmFyIHRpbWUgPSBub3coKSxcbiAgICAgICAgaXNJbnZva2luZyA9IHNob3VsZEludm9rZSh0aW1lKTtcblxuICAgIGxhc3RBcmdzID0gYXJndW1lbnRzO1xuICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICBsYXN0Q2FsbFRpbWUgPSB0aW1lO1xuXG4gICAgaWYgKGlzSW52b2tpbmcpIHtcbiAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGxlYWRpbmdFZGdlKGxhc3RDYWxsVGltZSk7XG4gICAgICB9XG4gICAgICBpZiAobWF4aW5nKSB7XG4gICAgICAgIC8vIEhhbmRsZSBpbnZvY2F0aW9ucyBpbiBhIHRpZ2h0IGxvb3AuXG4gICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgICAgIHJldHVybiBpbnZva2VGdW5jKGxhc3RDYWxsVGltZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgZGVib3VuY2VkLmNhbmNlbCA9IGNhbmNlbDtcbiAgZGVib3VuY2VkLmZsdXNoID0gZmx1c2g7XG4gIHJldHVybiBkZWJvdW5jZWQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHRocm90dGxlZCBmdW5jdGlvbiB0aGF0IG9ubHkgaW52b2tlcyBgZnVuY2AgYXQgbW9zdCBvbmNlIHBlclxuICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGBcbiAqIG1ldGhvZCB0byBjYW5jZWwgZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG9cbiAqIGltbWVkaWF0ZWx5IGludm9rZSB0aGVtLiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYFxuICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YFxuICogdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZVxuICogdGhyb3R0bGVkIGZ1bmN0aW9uLiBTdWJzZXF1ZW50IGNhbGxzIHRvIHRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gcmV0dXJuIHRoZVxuICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICpcbiAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uXG4gKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gKlxuICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gKlxuICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLnRocm90dGxlYCBhbmQgYF8uZGVib3VuY2VgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gdGhyb3R0bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gdGhyb3R0bGUgaW52b2NhdGlvbnMgdG8uXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz10cnVlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgdGhyb3R0bGVkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBBdm9pZCBleGNlc3NpdmVseSB1cGRhdGluZyB0aGUgcG9zaXRpb24gd2hpbGUgc2Nyb2xsaW5nLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpO1xuICpcbiAqIC8vIEludm9rZSBgcmVuZXdUb2tlbmAgd2hlbiB0aGUgY2xpY2sgZXZlbnQgaXMgZmlyZWQsIGJ1dCBub3QgbW9yZSB0aGFuIG9uY2UgZXZlcnkgNSBtaW51dGVzLlxuICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pO1xuICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHRocm90dGxlZCk7XG4gKlxuICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIHRocm90dGxlZC5jYW5jZWwpO1xuICovXG5mdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIHZhciBsZWFkaW5nID0gdHJ1ZSxcbiAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gJ2xlYWRpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMubGVhZGluZyA6IGxlYWRpbmc7XG4gICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgfVxuICByZXR1cm4gZGVib3VuY2UoZnVuYywgd2FpdCwge1xuICAgICdsZWFkaW5nJzogbGVhZGluZyxcbiAgICAnbWF4V2FpdCc6IHdhaXQsXG4gICAgJ3RyYWlsaW5nJzogdHJhaWxpbmdcbiAgfSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYFxuICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N5bWJvbCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdzeW1ib2wnIHx8XG4gICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvTnVtYmVyKDMuMik7XG4gKiAvLyA9PiAzLjJcbiAqXG4gKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gNWUtMzI0XG4gKlxuICogXy50b051bWJlcihJbmZpbml0eSk7XG4gKiAvLyA9PiBJbmZpbml0eVxuICpcbiAqIF8udG9OdW1iZXIoJzMuMicpO1xuICogLy8gPT4gMy4yXG4gKi9cbmZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiBOQU47XG4gIH1cbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICB2YWx1ZSA9IGlzT2JqZWN0KG90aGVyKSA/IChvdGhlciArICcnKSA6IG90aGVyO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTtcbiAgfVxuICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UocmVUcmltLCAnJyk7XG4gIHZhciBpc0JpbmFyeSA9IHJlSXNCaW5hcnkudGVzdCh2YWx1ZSk7XG4gIHJldHVybiAoaXNCaW5hcnkgfHwgcmVJc09jdGFsLnRlc3QodmFsdWUpKVxuICAgID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KVxuICAgIDogKHJlSXNCYWRIZXgudGVzdCh2YWx1ZSkgPyBOQU4gOiArdmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRocm90dGxlO1xuIiwidmFyIGc7XHJcblxyXG4vLyBUaGlzIHdvcmtzIGluIG5vbi1zdHJpY3QgbW9kZVxyXG5nID0gKGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiB0aGlzO1xyXG59KSgpO1xyXG5cclxudHJ5IHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcclxuXHRnID0gZyB8fCBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCkgfHwgKDEsIGV2YWwpKFwidGhpc1wiKTtcclxufSBjYXRjaCAoZSkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXHJcblx0aWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIpIGcgPSB3aW5kb3c7XHJcbn1cclxuXHJcbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cclxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3NcclxuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnO1xyXG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbmltcG9ydCB7IGdldEVsZW1lbnRzRm9yU291cmNlTGluZSB9IGZyb20gJy4vc2Nyb2xsLXN5bmMnO1xuXG5leHBvcnQgY2xhc3MgQWN0aXZlTGluZU1hcmtlciB7XG5cdHByaXZhdGUgX2N1cnJlbnQ6IGFueTtcblxuXHRvbkRpZENoYW5nZVRleHRFZGl0b3JTZWxlY3Rpb24obGluZTogbnVtYmVyKSB7XG5cdFx0Y29uc3QgeyBwcmV2aW91cyB9ID0gZ2V0RWxlbWVudHNGb3JTb3VyY2VMaW5lKGxpbmUpO1xuXHRcdHRoaXMuX3VwZGF0ZShwcmV2aW91cyAmJiBwcmV2aW91cy5lbGVtZW50KTtcblx0fVxuXG5cdF91cGRhdGUoYmVmb3JlOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCkge1xuXHRcdHRoaXMuX3VubWFya0FjdGl2ZUVsZW1lbnQodGhpcy5fY3VycmVudCk7XG5cdFx0dGhpcy5fbWFya0FjdGl2ZUVsZW1lbnQoYmVmb3JlKTtcblx0XHR0aGlzLl9jdXJyZW50ID0gYmVmb3JlO1xuXHR9XG5cblx0X3VubWFya0FjdGl2ZUVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpIHtcblx0XHRpZiAoIWVsZW1lbnQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKC9cXGJjb2RlLWFjdGl2ZS1saW5lXFxiL2csICcnKTtcblx0fVxuXG5cdF9tYXJrQWN0aXZlRWxlbWVudChlbGVtZW50OiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCkge1xuXHRcdGlmICghZWxlbWVudCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRlbGVtZW50LmNsYXNzTmFtZSArPSAnIGNvZGUtYWN0aXZlLWxpbmUnO1xuXHR9XG59IiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbmV4cG9ydCBmdW5jdGlvbiBvbmNlRG9jdW1lbnRMb2FkZWQoZjogKCkgPT4gdm9pZCkge1xuXHRpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnIHx8IGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICd1bmluaXRpYWxpemVkJykge1xuXHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmKTtcblx0fSBlbHNlIHtcblx0XHRmKCk7XG5cdH1cbn0iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuaW1wb3J0IHsgQWN0aXZlTGluZU1hcmtlciB9IGZyb20gJy4vYWN0aXZlTGluZU1hcmtlcic7XG5pbXBvcnQgeyBvbmNlRG9jdW1lbnRMb2FkZWQgfSBmcm9tICcuL2V2ZW50cyc7XG5pbXBvcnQgeyBjcmVhdGVQb3N0ZXJGb3JWc0NvZGUgfSBmcm9tICcuL21lc3NhZ2luZyc7XG5pbXBvcnQgeyBnZXRFZGl0b3JMaW5lTnVtYmVyRm9yUGFnZU9mZnNldCwgc2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lIH0gZnJvbSAnLi9zY3JvbGwtc3luYyc7XG5pbXBvcnQgeyBnZXRTZXR0aW5ncywgZ2V0RGF0YSB9IGZyb20gJy4vc2V0dGluZ3MnO1xuaW1wb3J0IHRocm90dGxlID0gcmVxdWlyZSgnbG9kYXNoLnRocm90dGxlJyk7XG5cbmRlY2xhcmUgdmFyIGFjcXVpcmVWc0NvZGVBcGk6IGFueTtcblxudmFyIHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcbmNvbnN0IG1hcmtlciA9IG5ldyBBY3RpdmVMaW5lTWFya2VyKCk7XG5jb25zdCBzZXR0aW5ncyA9IGdldFNldHRpbmdzKCk7XG5cbmNvbnN0IHZzY29kZSA9IGFjcXVpcmVWc0NvZGVBcGkoKTtcblxuLy8gU2V0IFZTIENvZGUgc3RhdGVcbmNvbnN0IHN0YXRlID0gZ2V0RGF0YSgnZGF0YS1zdGF0ZScpO1xudnNjb2RlLnNldFN0YXRlKHN0YXRlKTtcblxuY29uc3QgbWVzc2FnaW5nID0gY3JlYXRlUG9zdGVyRm9yVnNDb2RlKHZzY29kZSk7XG5cbndpbmRvdy5jc3BBbGVydGVyLnNldFBvc3RlcihtZXNzYWdpbmcpO1xud2luZG93LnN0eWxlTG9hZGluZ01vbml0b3Iuc2V0UG9zdGVyKG1lc3NhZ2luZyk7XG5cbndpbmRvdy5vbmxvYWQgPSAoKSA9PiB7XG5cdHVwZGF0ZUltYWdlU2l6ZXMoKTtcbn07XG5cbm9uY2VEb2N1bWVudExvYWRlZCgoKSA9PiB7XG5cdGlmIChzZXR0aW5ncy5zY3JvbGxQcmV2aWV3V2l0aEVkaXRvcikge1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0Y29uc3QgaW5pdGlhbExpbmUgPSArc2V0dGluZ3MubGluZTtcblx0XHRcdGlmICghaXNOYU4oaW5pdGlhbExpbmUpKSB7XG5cdFx0XHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRcdFx0c2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lKGluaXRpYWxMaW5lKTtcblx0XHRcdH1cblx0XHR9LCAwKTtcblx0fVxufSk7XG5cbmNvbnN0IG9uVXBkYXRlVmlldyA9ICgoKSA9PiB7XG5cdGNvbnN0IGRvU2Nyb2xsID0gdGhyb3R0bGUoKGxpbmU6IG51bWJlcikgPT4ge1xuXHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRzY3JvbGxUb1JldmVhbFNvdXJjZUxpbmUobGluZSk7XG5cdH0sIDUwKTtcblxuXHRyZXR1cm4gKGxpbmU6IG51bWJlciwgc2V0dGluZ3M6IGFueSkgPT4ge1xuXHRcdGlmICghaXNOYU4obGluZSkpIHtcblx0XHRcdHNldHRpbmdzLmxpbmUgPSBsaW5lO1xuXHRcdFx0ZG9TY3JvbGwobGluZSk7XG5cdFx0fVxuXHR9O1xufSkoKTtcblxubGV0IHVwZGF0ZUltYWdlU2l6ZXMgPSB0aHJvdHRsZSgoKSA9PiB7XG5cdGNvbnN0IGltYWdlSW5mbzogeyBpZDogc3RyaW5nLCBoZWlnaHQ6IG51bWJlciwgd2lkdGg6IG51bWJlciB9W10gPSBbXTtcblx0bGV0IGltYWdlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbWcnKTtcblx0aWYgKGltYWdlcykge1xuXHRcdGxldCBpO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBpbWFnZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGltZyA9IGltYWdlc1tpXTtcblxuXHRcdFx0aWYgKGltZy5jbGFzc0xpc3QuY29udGFpbnMoJ2xvYWRpbmcnKSkge1xuXHRcdFx0XHRpbWcuY2xhc3NMaXN0LnJlbW92ZSgnbG9hZGluZycpO1xuXHRcdFx0fVxuXG5cdFx0XHRpbWFnZUluZm8ucHVzaCh7XG5cdFx0XHRcdGlkOiBpbWcuaWQsXG5cdFx0XHRcdGhlaWdodDogaW1nLmhlaWdodCxcblx0XHRcdFx0d2lkdGg6IGltZy53aWR0aFxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdjYWNoZUltYWdlU2l6ZXMnLCBpbWFnZUluZm8pO1xuXHR9XG59LCA1MCk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCAoKSA9PiB7XG5cdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0dXBkYXRlSW1hZ2VTaXplcygpO1xufSwgdHJ1ZSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZXZlbnQgPT4ge1xuXHRpZiAoZXZlbnQuZGF0YS5zb3VyY2UgIT09IHNldHRpbmdzLnNvdXJjZSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHN3aXRjaCAoZXZlbnQuZGF0YS50eXBlKSB7XG5cdFx0Y2FzZSAnb25EaWRDaGFuZ2VUZXh0RWRpdG9yU2VsZWN0aW9uJzpcblx0XHRcdG1hcmtlci5vbkRpZENoYW5nZVRleHRFZGl0b3JTZWxlY3Rpb24oZXZlbnQuZGF0YS5saW5lKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAndXBkYXRlVmlldyc6XG5cdFx0XHRvblVwZGF0ZVZpZXcoZXZlbnQuZGF0YS5saW5lLCBzZXR0aW5ncyk7XG5cdFx0XHRicmVhaztcblx0fVxufSwgZmFsc2UpO1xuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIGV2ZW50ID0+IHtcblx0aWYgKCFzZXR0aW5ncy5kb3VibGVDbGlja1RvU3dpdGNoVG9FZGl0b3IpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBJZ25vcmUgY2xpY2tzIG9uIGxpbmtzXG5cdGZvciAobGV0IG5vZGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7IG5vZGU7IG5vZGUgPSBub2RlLnBhcmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpIHtcblx0XHRpZiAobm9kZS50YWdOYW1lID09PSAnQScpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdH1cblxuXHRjb25zdCBvZmZzZXQgPSBldmVudC5wYWdlWTtcblx0Y29uc3QgbGluZSA9IGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0KG9mZnNldCk7XG5cdGlmICh0eXBlb2YgbGluZSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKGxpbmUpKSB7XG5cdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdkaWRDbGljaycsIHsgbGluZTogTWF0aC5mbG9vcihsaW5lKSB9KTtcblx0fVxufSk7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQgPT4ge1xuXHRpZiAoIWV2ZW50KSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0bGV0IG5vZGU6IGFueSA9IGV2ZW50LnRhcmdldDtcblx0d2hpbGUgKG5vZGUpIHtcblx0XHRpZiAobm9kZS50YWdOYW1lICYmIG5vZGUudGFnTmFtZSA9PT0gJ0EnICYmIG5vZGUuaHJlZikge1xuXHRcdFx0aWYgKG5vZGUuZ2V0QXR0cmlidXRlKCdocmVmJykuc3RhcnRzV2l0aCgnIycpKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKG5vZGUuaHJlZi5zdGFydHNXaXRoKCdmaWxlOi8vJykgfHwgbm9kZS5ocmVmLnN0YXJ0c1dpdGgoJ3ZzY29kZS1yZXNvdXJjZTonKSkge1xuXHRcdFx0XHRjb25zdCBbcGF0aCwgZnJhZ21lbnRdID0gbm9kZS5ocmVmLnJlcGxhY2UoL14oZmlsZTpcXC9cXC98dnNjb2RlLXJlc291cmNlOikvaSwgJycpLnNwbGl0KCcjJyk7XG5cdFx0XHRcdG1lc3NhZ2luZy5wb3N0TWVzc2FnZSgnY2xpY2tMaW5rJywgeyBwYXRoLCBmcmFnbWVudCB9KTtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG5cdH1cbn0sIHRydWUpO1xuXG5pZiAoc2V0dGluZ3Muc2Nyb2xsRWRpdG9yV2l0aFByZXZpZXcpIHtcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRocm90dGxlKCgpID0+IHtcblx0XHRpZiAoc2Nyb2xsRGlzYWJsZWQpIHtcblx0XHRcdHNjcm9sbERpc2FibGVkID0gZmFsc2U7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGxpbmUgPSBnZXRFZGl0b3JMaW5lTnVtYmVyRm9yUGFnZU9mZnNldCh3aW5kb3cuc2Nyb2xsWSk7XG5cdFx0XHRpZiAodHlwZW9mIGxpbmUgPT09ICdudW1iZXInICYmICFpc05hTihsaW5lKSkge1xuXHRcdFx0XHRtZXNzYWdpbmcucG9zdE1lc3NhZ2UoJ3JldmVhbExpbmUnLCB7IGxpbmUgfSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LCA1MCkpO1xufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5pbXBvcnQgeyBnZXRTZXR0aW5ncyB9IGZyb20gJy4vc2V0dGluZ3MnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1lc3NhZ2VQb3N0ZXIge1xuXHQvKipcblx0ICogUG9zdCBhIG1lc3NhZ2UgdG8gdGhlIG1hcmtkb3duIGV4dGVuc2lvblxuXHQgKi9cblx0cG9zdE1lc3NhZ2UodHlwZTogc3RyaW5nLCBib2R5OiBvYmplY3QpOiB2b2lkO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlUG9zdGVyRm9yVnNDb2RlID0gKHZzY29kZTogYW55KSA9PiB7XG5cdHJldHVybiBuZXcgY2xhc3MgaW1wbGVtZW50cyBNZXNzYWdlUG9zdGVyIHtcblx0XHRwb3N0TWVzc2FnZSh0eXBlOiBzdHJpbmcsIGJvZHk6IG9iamVjdCk6IHZvaWQge1xuXHRcdFx0dnNjb2RlLnBvc3RNZXNzYWdlKHtcblx0XHRcdFx0dHlwZSxcblx0XHRcdFx0c291cmNlOiBnZXRTZXR0aW5ncygpLnNvdXJjZSxcblx0XHRcdFx0Ym9keVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9O1xufTtcblxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbmltcG9ydCB7IGdldFNldHRpbmdzIH0gZnJvbSAnLi9zZXR0aW5ncyc7XG5cblxuZnVuY3Rpb24gY2xhbXAobWluOiBudW1iZXIsIG1heDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKSB7XG5cdHJldHVybiBNYXRoLm1pbihtYXgsIE1hdGgubWF4KG1pbiwgdmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gY2xhbXBMaW5lKGxpbmU6IG51bWJlcikge1xuXHRyZXR1cm4gY2xhbXAoMCwgZ2V0U2V0dGluZ3MoKS5saW5lQ291bnQgLSAxLCBsaW5lKTtcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIENvZGVMaW5lRWxlbWVudCB7XG5cdGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXHRsaW5lOiBudW1iZXI7XG59XG5cbmNvbnN0IGdldENvZGVMaW5lRWxlbWVudHMgPSAoKCkgPT4ge1xuXHRsZXQgZWxlbWVudHM6IENvZGVMaW5lRWxlbWVudFtdO1xuXHRyZXR1cm4gKCkgPT4ge1xuXHRcdGlmICghZWxlbWVudHMpIHtcblx0XHRcdGVsZW1lbnRzID0gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKFxuXHRcdFx0XHRkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjb2RlLWxpbmUnKSxcblx0XHRcdFx0KGVsZW1lbnQ6IGFueSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IGxpbmUgPSArZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtbGluZScpO1xuXHRcdFx0XHRcdHJldHVybiB7IGVsZW1lbnQsIGxpbmUgfTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmZpbHRlcigoeDogYW55KSA9PiAhaXNOYU4oeC5saW5lKSk7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtZW50cztcblx0fTtcbn0pKCk7XG5cbi8qKlxuICogRmluZCB0aGUgaHRtbCBlbGVtZW50cyB0aGF0IG1hcCB0byBhIHNwZWNpZmljIHRhcmdldCBsaW5lIGluIHRoZSBlZGl0b3IuXG4gKlxuICogSWYgYW4gZXhhY3QgbWF0Y2gsIHJldHVybnMgYSBzaW5nbGUgZWxlbWVudC4gSWYgdGhlIGxpbmUgaXMgYmV0d2VlbiBlbGVtZW50cyxcbiAqIHJldHVybnMgdGhlIGVsZW1lbnQgcHJpb3IgdG8gYW5kIHRoZSBlbGVtZW50IGFmdGVyIHRoZSBnaXZlbiBsaW5lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudHNGb3JTb3VyY2VMaW5lKHRhcmdldExpbmU6IG51bWJlcik6IHsgcHJldmlvdXM6IENvZGVMaW5lRWxlbWVudDsgbmV4dD86IENvZGVMaW5lRWxlbWVudDsgfSB7XG5cdGNvbnN0IGxpbmVOdW1iZXIgPSBNYXRoLmZsb29yKHRhcmdldExpbmUpO1xuXHRjb25zdCBsaW5lcyA9IGdldENvZGVMaW5lRWxlbWVudHMoKTtcblx0bGV0IHByZXZpb3VzID0gbGluZXNbMF0gfHwgbnVsbDtcblx0Zm9yIChjb25zdCBlbnRyeSBvZiBsaW5lcykge1xuXHRcdGlmIChlbnRyeS5saW5lID09PSBsaW5lTnVtYmVyKSB7XG5cdFx0XHRyZXR1cm4geyBwcmV2aW91czogZW50cnksIG5leHQ6IHVuZGVmaW5lZCB9O1xuXHRcdH1cblx0XHRlbHNlIGlmIChlbnRyeS5saW5lID4gbGluZU51bWJlcikge1xuXHRcdFx0cmV0dXJuIHsgcHJldmlvdXMsIG5leHQ6IGVudHJ5IH07XG5cdFx0fVxuXHRcdHByZXZpb3VzID0gZW50cnk7XG5cdH1cblx0cmV0dXJuIHsgcHJldmlvdXMgfTtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBodG1sIGVsZW1lbnRzIHRoYXQgYXJlIGF0IGEgc3BlY2lmaWMgcGl4ZWwgb2Zmc2V0IG9uIHRoZSBwYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGluZUVsZW1lbnRzQXRQYWdlT2Zmc2V0KG9mZnNldDogbnVtYmVyKTogeyBwcmV2aW91czogQ29kZUxpbmVFbGVtZW50OyBuZXh0PzogQ29kZUxpbmVFbGVtZW50OyB9IHtcblx0Y29uc3QgbGluZXMgPSBnZXRDb2RlTGluZUVsZW1lbnRzKCk7XG5cdGNvbnN0IHBvc2l0aW9uID0gb2Zmc2V0IC0gd2luZG93LnNjcm9sbFk7XG5cdGxldCBsbyA9IC0xO1xuXHRsZXQgaGkgPSBsaW5lcy5sZW5ndGggLSAxO1xuXHR3aGlsZSAobG8gKyAxIDwgaGkpIHtcblx0XHRjb25zdCBtaWQgPSBNYXRoLmZsb29yKChsbyArIGhpKSAvIDIpO1xuXHRcdGNvbnN0IGJvdW5kcyA9IGxpbmVzW21pZF0uZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRpZiAoYm91bmRzLnRvcCArIGJvdW5kcy5oZWlnaHQgPj0gcG9zaXRpb24pIHtcblx0XHRcdGhpID0gbWlkO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGxvID0gbWlkO1xuXHRcdH1cblx0fVxuXHRjb25zdCBoaUVsZW1lbnQgPSBsaW5lc1toaV07XG5cdGNvbnN0IGhpQm91bmRzID0gaGlFbGVtZW50LmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdGlmIChoaSA+PSAxICYmIGhpQm91bmRzLnRvcCA+IHBvc2l0aW9uKSB7XG5cdFx0Y29uc3QgbG9FbGVtZW50ID0gbGluZXNbbG9dO1xuXHRcdHJldHVybiB7IHByZXZpb3VzOiBsb0VsZW1lbnQsIG5leHQ6IGhpRWxlbWVudCB9O1xuXHR9XG5cdHJldHVybiB7IHByZXZpb3VzOiBoaUVsZW1lbnQgfTtcbn1cblxuLyoqXG4gKiBBdHRlbXB0IHRvIHJldmVhbCB0aGUgZWxlbWVudCBmb3IgYSBzb3VyY2UgbGluZSBpbiB0aGUgZWRpdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lKGxpbmU6IG51bWJlcikge1xuXHRjb25zdCB7IHByZXZpb3VzLCBuZXh0IH0gPSBnZXRFbGVtZW50c0ZvclNvdXJjZUxpbmUobGluZSk7XG5cdGlmIChwcmV2aW91cyAmJiBnZXRTZXR0aW5ncygpLnNjcm9sbFByZXZpZXdXaXRoRWRpdG9yKSB7XG5cdFx0bGV0IHNjcm9sbFRvID0gMDtcblx0XHRjb25zdCByZWN0ID0gcHJldmlvdXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRjb25zdCBwcmV2aW91c1RvcCA9IHJlY3QudG9wO1xuXHRcdGlmIChuZXh0ICYmIG5leHQubGluZSAhPT0gcHJldmlvdXMubGluZSkge1xuXHRcdFx0Ly8gQmV0d2VlbiB0d28gZWxlbWVudHMuIEdvIHRvIHBlcmNlbnRhZ2Ugb2Zmc2V0IGJldHdlZW4gdGhlbS5cblx0XHRcdGNvbnN0IGJldHdlZW5Qcm9ncmVzcyA9IChsaW5lIC0gcHJldmlvdXMubGluZSkgLyAobmV4dC5saW5lIC0gcHJldmlvdXMubGluZSk7XG5cdFx0XHRjb25zdCBlbGVtZW50T2Zmc2V0ID0gbmV4dC5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIHByZXZpb3VzVG9wO1xuXHRcdFx0c2Nyb2xsVG8gPSBwcmV2aW91c1RvcCArIGJldHdlZW5Qcm9ncmVzcyAqIGVsZW1lbnRPZmZzZXQ7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0c2Nyb2xsVG8gPSBwcmV2aW91c1RvcDtcblx0XHR9XG5cdFx0d2luZG93LnNjcm9sbCgwLCBNYXRoLm1heCgxLCB3aW5kb3cuc2Nyb2xsWSArIHNjcm9sbFRvKSk7XG5cdH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0KG9mZnNldDogbnVtYmVyKSB7XG5cdGNvbnN0IHsgcHJldmlvdXMsIG5leHQgfSA9IGdldExpbmVFbGVtZW50c0F0UGFnZU9mZnNldChvZmZzZXQpO1xuXHRpZiAocHJldmlvdXMpIHtcblx0XHRjb25zdCBwcmV2aW91c0JvdW5kcyA9IHByZXZpb3VzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0Y29uc3Qgb2Zmc2V0RnJvbVByZXZpb3VzID0gKG9mZnNldCAtIHdpbmRvdy5zY3JvbGxZIC0gcHJldmlvdXNCb3VuZHMudG9wKTtcblx0XHRpZiAobmV4dCkge1xuXHRcdFx0Y29uc3QgcHJvZ3Jlc3NCZXR3ZWVuRWxlbWVudHMgPSBvZmZzZXRGcm9tUHJldmlvdXMgLyAobmV4dC5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIHByZXZpb3VzQm91bmRzLnRvcCk7XG5cdFx0XHRjb25zdCBsaW5lID0gcHJldmlvdXMubGluZSArIHByb2dyZXNzQmV0d2VlbkVsZW1lbnRzICogKG5leHQubGluZSAtIHByZXZpb3VzLmxpbmUpO1xuXHRcdFx0cmV0dXJuIGNsYW1wTGluZShsaW5lKTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRjb25zdCBwcm9ncmVzc1dpdGhpbkVsZW1lbnQgPSBvZmZzZXRGcm9tUHJldmlvdXMgLyAocHJldmlvdXNCb3VuZHMuaGVpZ2h0KTtcblx0XHRcdGNvbnN0IGxpbmUgPSBwcmV2aW91cy5saW5lICsgcHJvZ3Jlc3NXaXRoaW5FbGVtZW50O1xuXHRcdFx0cmV0dXJuIGNsYW1wTGluZShsaW5lKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIG51bGw7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuZXhwb3J0IGludGVyZmFjZSBQcmV2aWV3U2V0dGluZ3Mge1xuXHRzb3VyY2U6IHN0cmluZztcblx0bGluZTogbnVtYmVyO1xuXHRsaW5lQ291bnQ6IG51bWJlcjtcblx0c2Nyb2xsUHJldmlld1dpdGhFZGl0b3I/OiBib29sZWFuO1xuXHRzY3JvbGxFZGl0b3JXaXRoUHJldmlldzogYm9vbGVhbjtcblx0ZGlzYWJsZVNlY3VyaXR5V2FybmluZ3M6IGJvb2xlYW47XG5cdGRvdWJsZUNsaWNrVG9Td2l0Y2hUb0VkaXRvcjogYm9vbGVhbjtcbn1cblxubGV0IGNhY2hlZFNldHRpbmdzOiBQcmV2aWV3U2V0dGluZ3MgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhKGtleTogc3RyaW5nKTogUHJldmlld1NldHRpbmdzIHtcblx0Y29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2c2NvZGUtbWFya2Rvd24tcHJldmlldy1kYXRhJyk7XG5cdGlmIChlbGVtZW50KSB7XG5cdFx0Y29uc3QgZGF0YSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSk7XG5cdFx0aWYgKGRhdGEpIHtcblx0XHRcdHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xuXHRcdH1cblx0fVxuXG5cdHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGxvYWQgZGF0YSBmb3IgJHtrZXl9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZXR0aW5ncygpOiBQcmV2aWV3U2V0dGluZ3Mge1xuXHRpZiAoY2FjaGVkU2V0dGluZ3MpIHtcblx0XHRyZXR1cm4gY2FjaGVkU2V0dGluZ3M7XG5cdH1cblxuXHRjYWNoZWRTZXR0aW5ncyA9IGdldERhdGEoJ2RhdGEtc2V0dGluZ3MnKTtcblx0aWYgKGNhY2hlZFNldHRpbmdzKSB7XG5cdFx0cmV0dXJuIGNhY2hlZFNldHRpbmdzO1xuXHR9XG5cblx0dGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgbG9hZCBzZXR0aW5ncycpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2xvZGFzaC50aHJvdHRsZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2FjdGl2ZUxpbmVNYXJrZXIudHMiLCJ3ZWJwYWNrOi8vLy4vcHJldmlldy1zcmMvZXZlbnRzLnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2luZGV4LnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL21lc3NhZ2luZy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zY3JvbGwtc3luYy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNB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Q0FBQztBQWpCRCw0RUFpQkM7Ozs7Ozs7Ozs7Ozs7O0FDdElEOzs7Z0dBR2dHOztBQVloRyxJQUFJLGNBQWMsR0FBZ0MsU0FBUyxDQUFDO0FBRTVELGlCQUF3QixHQUFXO0lBQ2xDLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsOEJBQThCLENBQUMsQ0FBQztJQUN4RSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2IsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ1YsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsQ0FBQztJQUNGLENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFWRCwwQkFVQztBQUVEO0lBQ0MsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUNwQixNQUFNLENBQUMsY0FBYyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxjQUFjLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsTUFBTSxDQUFDLGNBQWMsQ0FBQztJQUN2QixDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFYRCxrQ0FXQyIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwge1xuIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbiBcdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG4gXHRcdFx0XHRnZXQ6IGdldHRlclxuIFx0XHRcdH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3ByZXZpZXctc3JjL2luZGV4LnRzXCIpO1xuIiwiLyoqXG4gKiBsb2Rhc2ggKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCBqUXVlcnkgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIDxodHRwczovL2pxdWVyeS5vcmcvPlxuICogUmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICovXG5cbi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBOQU4gPSAwIC8gMDtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgc2VsZmAuICovXG52YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjtcblxuLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG52YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlXG4gKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBHZXRzIHRoZSB0aW1lc3RhbXAgb2YgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdGhhdCBoYXZlIGVsYXBzZWQgc2luY2VcbiAqIHRoZSBVbml4IGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMi40LjBcbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lc3RhbXAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gTG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgaW52b2NhdGlvbi5cbiAqL1xudmFyIG5vdyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcm9vdC5EYXRlLm5vdygpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gKiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYCBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGVcbiAqIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YCB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWRcbiAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAqIGNhbGxzIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgXG4gKiBpbnZvY2F0aW9uLlxuICpcbiAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uXG4gKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gKlxuICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gKlxuICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4V2FpdF1cbiAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3Jlc2l6ZScsIF8uZGVib3VuY2UoY2FsY3VsYXRlTGF5b3V0LCAxNTApKTtcbiAqXG4gKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmRlYm91bmNlKHNlbmRNYWlsLCAzMDAsIHtcbiAqICAgJ2xlYWRpbmcnOiB0cnVlLFxuICogICAndHJhaWxpbmcnOiBmYWxzZVxuICogfSkpO1xuICpcbiAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gKiB2YXIgZGVib3VuY2VkID0gXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7ICdtYXhXYWl0JzogMTAwMCB9KTtcbiAqIHZhciBzb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UoJy9zdHJlYW0nKTtcbiAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAqXG4gKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIGRlYm91bmNlZCBpbnZvY2F0aW9uLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgdmFyIGxhc3RBcmdzLFxuICAgICAgbGFzdFRoaXMsXG4gICAgICBtYXhXYWl0LFxuICAgICAgcmVzdWx0LFxuICAgICAgdGltZXJJZCxcbiAgICAgIGxhc3RDYWxsVGltZSxcbiAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgIGxlYWRpbmcgPSBmYWxzZSxcbiAgICAgIG1heGluZyA9IGZhbHNlLFxuICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHdhaXQgPSB0b051bWJlcih3YWl0KSB8fCAwO1xuICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgbWF4aW5nID0gJ21heFdhaXQnIGluIG9wdGlvbnM7XG4gICAgbWF4V2FpdCA9IG1heGluZyA/IG5hdGl2ZU1heCh0b051bWJlcihvcHRpb25zLm1heFdhaXQpIHx8IDAsIHdhaXQpIDogbWF4V2FpdDtcbiAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlRnVuYyh0aW1lKSB7XG4gICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgdGhpc0FyZyA9IGxhc3RUaGlzO1xuXG4gICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gbGVhZGluZ0VkZ2UodGltZSkge1xuICAgIC8vIFJlc2V0IGFueSBgbWF4V2FpdGAgdGltZXIuXG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIC8vIFN0YXJ0IHRoZSB0aW1lciBmb3IgdGhlIHRyYWlsaW5nIGVkZ2UuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICByZXR1cm4gbGVhZGluZyA/IGludm9rZUZ1bmModGltZSkgOiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lLFxuICAgICAgICByZXN1bHQgPSB3YWl0IC0gdGltZVNpbmNlTGFzdENhbGw7XG5cbiAgICByZXR1cm4gbWF4aW5nID8gbmF0aXZlTWluKHJlc3VsdCwgbWF4V2FpdCAtIHRpbWVTaW5jZUxhc3RJbnZva2UpIDogcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvdWxkSW52b2tlKHRpbWUpIHtcbiAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lO1xuXG4gICAgLy8gRWl0aGVyIHRoaXMgaXMgdGhlIGZpcnN0IGNhbGwsIGFjdGl2aXR5IGhhcyBzdG9wcGVkIGFuZCB3ZSdyZSBhdCB0aGVcbiAgICAvLyB0cmFpbGluZyBlZGdlLCB0aGUgc3lzdGVtIHRpbWUgaGFzIGdvbmUgYmFja3dhcmRzIGFuZCB3ZSdyZSB0cmVhdGluZ1xuICAgIC8vIGl0IGFzIHRoZSB0cmFpbGluZyBlZGdlLCBvciB3ZSd2ZSBoaXQgdGhlIGBtYXhXYWl0YCBsaW1pdC5cbiAgICByZXR1cm4gKGxhc3RDYWxsVGltZSA9PT0gdW5kZWZpbmVkIHx8ICh0aW1lU2luY2VMYXN0Q2FsbCA+PSB3YWl0KSB8fFxuICAgICAgKHRpbWVTaW5jZUxhc3RDYWxsIDwgMCkgfHwgKG1heGluZyAmJiB0aW1lU2luY2VMYXN0SW52b2tlID49IG1heFdhaXQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRpbWVyRXhwaXJlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpO1xuICAgIGlmIChzaG91bGRJbnZva2UodGltZSkpIHtcbiAgICAgIHJldHVybiB0cmFpbGluZ0VkZ2UodGltZSk7XG4gICAgfVxuICAgIC8vIFJlc3RhcnQgdGhlIHRpbWVyLlxuICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgcmVtYWluaW5nV2FpdCh0aW1lKSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkge1xuICAgIHRpbWVySWQgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBPbmx5IGludm9rZSBpZiB3ZSBoYXZlIGBsYXN0QXJnc2Agd2hpY2ggbWVhbnMgYGZ1bmNgIGhhcyBiZWVuXG4gICAgLy8gZGVib3VuY2VkIGF0IGxlYXN0IG9uY2UuXG4gICAgaWYgKHRyYWlsaW5nICYmIGxhc3RBcmdzKSB7XG4gICAgICByZXR1cm4gaW52b2tlRnVuYyh0aW1lKTtcbiAgICB9XG4gICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgIGlmICh0aW1lcklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICB9XG4gICAgbGFzdEludm9rZVRpbWUgPSAwO1xuICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgcmV0dXJuIHRpbWVySWQgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IHRyYWlsaW5nRWRnZShub3coKSk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWJvdW5jZWQoKSB7XG4gICAgdmFyIHRpbWUgPSBub3coKSxcbiAgICAgICAgaXNJbnZva2luZyA9IHNob3VsZEludm9rZSh0aW1lKTtcblxuICAgIGxhc3RBcmdzID0gYXJndW1lbnRzO1xuICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICBsYXN0Q2FsbFRpbWUgPSB0aW1lO1xuXG4gICAgaWYgKGlzSW52b2tpbmcpIHtcbiAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGxlYWRpbmdFZGdlKGxhc3RDYWxsVGltZSk7XG4gICAgICB9XG4gICAgICBpZiAobWF4aW5nKSB7XG4gICAgICAgIC8vIEhhbmRsZSBpbnZvY2F0aW9ucyBpbiBhIHRpZ2h0IGxvb3AuXG4gICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgICAgIHJldHVybiBpbnZva2VGdW5jKGxhc3RDYWxsVGltZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgZGVib3VuY2VkLmNhbmNlbCA9IGNhbmNlbDtcbiAgZGVib3VuY2VkLmZsdXNoID0gZmx1c2g7XG4gIHJldHVybiBkZWJvdW5jZWQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHRocm90dGxlZCBmdW5jdGlvbiB0aGF0IG9ubHkgaW52b2tlcyBgZnVuY2AgYXQgbW9zdCBvbmNlIHBlclxuICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGBcbiAqIG1ldGhvZCB0byBjYW5jZWwgZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG9cbiAqIGltbWVkaWF0ZWx5IGludm9rZSB0aGVtLiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYFxuICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YFxuICogdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZVxuICogdGhyb3R0bGVkIGZ1bmN0aW9uLiBTdWJzZXF1ZW50IGNhbGxzIHRvIHRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gcmV0dXJuIHRoZVxuICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICpcbiAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uXG4gKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gKlxuICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gKlxuICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLnRocm90dGxlYCBhbmQgYF8uZGVib3VuY2VgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gdGhyb3R0bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gdGhyb3R0bGUgaW52b2NhdGlvbnMgdG8uXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz10cnVlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgdGhyb3R0bGVkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBBdm9pZCBleGNlc3NpdmVseSB1cGRhdGluZyB0aGUgcG9zaXRpb24gd2hpbGUgc2Nyb2xsaW5nLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpO1xuICpcbiAqIC8vIEludm9rZSBgcmVuZXdUb2tlbmAgd2hlbiB0aGUgY2xpY2sgZXZlbnQgaXMgZmlyZWQsIGJ1dCBub3QgbW9yZSB0aGFuIG9uY2UgZXZlcnkgNSBtaW51dGVzLlxuICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pO1xuICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHRocm90dGxlZCk7XG4gKlxuICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIHRocm90dGxlZC5jYW5jZWwpO1xuICovXG5mdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIHZhciBsZWFkaW5nID0gdHJ1ZSxcbiAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gJ2xlYWRpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMubGVhZGluZyA6IGxlYWRpbmc7XG4gICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgfVxuICByZXR1cm4gZGVib3VuY2UoZnVuYywgd2FpdCwge1xuICAgICdsZWFkaW5nJzogbGVhZGluZyxcbiAgICAnbWF4V2FpdCc6IHdhaXQsXG4gICAgJ3RyYWlsaW5nJzogdHJhaWxpbmdcbiAgfSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYFxuICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N5bWJvbCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdzeW1ib2wnIHx8XG4gICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvTnVtYmVyKDMuMik7XG4gKiAvLyA9PiAzLjJcbiAqXG4gKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gNWUtMzI0XG4gKlxuICogXy50b051bWJlcihJbmZpbml0eSk7XG4gKiAvLyA9PiBJbmZpbml0eVxuICpcbiAqIF8udG9OdW1iZXIoJzMuMicpO1xuICogLy8gPT4gMy4yXG4gKi9cbmZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiBOQU47XG4gIH1cbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICB2YWx1ZSA9IGlzT2JqZWN0KG90aGVyKSA/IChvdGhlciArICcnKSA6IG90aGVyO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTtcbiAgfVxuICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UocmVUcmltLCAnJyk7XG4gIHZhciBpc0JpbmFyeSA9IHJlSXNCaW5hcnkudGVzdCh2YWx1ZSk7XG4gIHJldHVybiAoaXNCaW5hcnkgfHwgcmVJc09jdGFsLnRlc3QodmFsdWUpKVxuICAgID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KVxuICAgIDogKHJlSXNCYWRIZXgudGVzdCh2YWx1ZSkgPyBOQU4gOiArdmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRocm90dGxlO1xuIiwidmFyIGc7XHJcblxyXG4vLyBUaGlzIHdvcmtzIGluIG5vbi1zdHJpY3QgbW9kZVxyXG5nID0gKGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiB0aGlzO1xyXG59KSgpO1xyXG5cclxudHJ5IHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcclxuXHRnID0gZyB8fCBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCkgfHwgKDEsIGV2YWwpKFwidGhpc1wiKTtcclxufSBjYXRjaCAoZSkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXHJcblx0aWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIpIGcgPSB3aW5kb3c7XHJcbn1cclxuXHJcbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cclxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3NcclxuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnO1xyXG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbmltcG9ydCB7IGdldEVsZW1lbnRzRm9yU291cmNlTGluZSB9IGZyb20gJy4vc2Nyb2xsLXN5bmMnO1xuXG5leHBvcnQgY2xhc3MgQWN0aXZlTGluZU1hcmtlciB7XG5cdHByaXZhdGUgX2N1cnJlbnQ6IGFueTtcblxuXHRvbkRpZENoYW5nZVRleHRFZGl0b3JTZWxlY3Rpb24obGluZTogbnVtYmVyKSB7XG5cdFx0Y29uc3QgeyBwcmV2aW91cyB9ID0gZ2V0RWxlbWVudHNGb3JTb3VyY2VMaW5lKGxpbmUpO1xuXHRcdHRoaXMuX3VwZGF0ZShwcmV2aW91cyAmJiBwcmV2aW91cy5lbGVtZW50KTtcblx0fVxuXG5cdF91cGRhdGUoYmVmb3JlOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCkge1xuXHRcdHRoaXMuX3VubWFya0FjdGl2ZUVsZW1lbnQodGhpcy5fY3VycmVudCk7XG5cdFx0dGhpcy5fbWFya0FjdGl2ZUVsZW1lbnQoYmVmb3JlKTtcblx0XHR0aGlzLl9jdXJyZW50ID0gYmVmb3JlO1xuXHR9XG5cblx0X3VubWFya0FjdGl2ZUVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpIHtcblx0XHRpZiAoIWVsZW1lbnQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKC9cXGJjb2RlLWFjdGl2ZS1saW5lXFxiL2csICcnKTtcblx0fVxuXG5cdF9tYXJrQWN0aXZlRWxlbWVudChlbGVtZW50OiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCkge1xuXHRcdGlmICghZWxlbWVudCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRlbGVtZW50LmNsYXNzTmFtZSArPSAnIGNvZGUtYWN0aXZlLWxpbmUnO1xuXHR9XG59IiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbmV4cG9ydCBmdW5jdGlvbiBvbmNlRG9jdW1lbnRMb2FkZWQoZjogKCkgPT4gdm9pZCkge1xuXHRpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnIHx8IGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICd1bmluaXRpYWxpemVkJykge1xuXHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmKTtcblx0fSBlbHNlIHtcblx0XHRmKCk7XG5cdH1cbn0iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuaW1wb3J0IHsgQWN0aXZlTGluZU1hcmtlciB9IGZyb20gJy4vYWN0aXZlTGluZU1hcmtlcic7XG5pbXBvcnQgeyBvbmNlRG9jdW1lbnRMb2FkZWQgfSBmcm9tICcuL2V2ZW50cyc7XG5pbXBvcnQgeyBjcmVhdGVQb3N0ZXJGb3JWc0NvZGUgfSBmcm9tICcuL21lc3NhZ2luZyc7XG5pbXBvcnQgeyBnZXRFZGl0b3JMaW5lTnVtYmVyRm9yUGFnZU9mZnNldCwgc2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lIH0gZnJvbSAnLi9zY3JvbGwtc3luYyc7XG5pbXBvcnQgeyBnZXRTZXR0aW5ncywgZ2V0RGF0YSB9IGZyb20gJy4vc2V0dGluZ3MnO1xuaW1wb3J0IHRocm90dGxlID0gcmVxdWlyZSgnbG9kYXNoLnRocm90dGxlJyk7XG5cbmRlY2xhcmUgdmFyIGFjcXVpcmVWc0NvZGVBcGk6IGFueTtcblxudmFyIHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcbmNvbnN0IG1hcmtlciA9IG5ldyBBY3RpdmVMaW5lTWFya2VyKCk7XG5jb25zdCBzZXR0aW5ncyA9IGdldFNldHRpbmdzKCk7XG5cbmNvbnN0IHZzY29kZSA9IGFjcXVpcmVWc0NvZGVBcGkoKTtcblxuLy8gU2V0IFZTIENvZGUgc3RhdGVcbmNvbnN0IHN0YXRlID0gZ2V0RGF0YSgnZGF0YS1zdGF0ZScpO1xudnNjb2RlLnNldFN0YXRlKHN0YXRlKTtcblxuY29uc3QgbWVzc2FnaW5nID0gY3JlYXRlUG9zdGVyRm9yVnNDb2RlKHZzY29kZSk7XG5cbndpbmRvdy5jc3BBbGVydGVyLnNldFBvc3RlcihtZXNzYWdpbmcpO1xud2luZG93LnN0eWxlTG9hZGluZ01vbml0b3Iuc2V0UG9zdGVyKG1lc3NhZ2luZyk7XG5cbndpbmRvdy5vbmxvYWQgPSAoKSA9PiB7XG5cdHVwZGF0ZUltYWdlU2l6ZXMoKTtcbn07XG5cbm9uY2VEb2N1bWVudExvYWRlZCgoKSA9PiB7XG5cdGlmIChzZXR0aW5ncy5zY3JvbGxQcmV2aWV3V2l0aEVkaXRvcikge1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0Y29uc3QgaW5pdGlhbExpbmUgPSArc2V0dGluZ3MubGluZTtcblx0XHRcdGlmICghaXNOYU4oaW5pdGlhbExpbmUpKSB7XG5cdFx0XHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRcdFx0c2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lKGluaXRpYWxMaW5lKTtcblx0XHRcdH1cblx0XHR9LCAwKTtcblx0fVxufSk7XG5cbmNvbnN0IG9uVXBkYXRlVmlldyA9ICgoKSA9PiB7XG5cdGNvbnN0IGRvU2Nyb2xsID0gdGhyb3R0bGUoKGxpbmU6IG51bWJlcikgPT4ge1xuXHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRzY3JvbGxUb1JldmVhbFNvdXJjZUxpbmUobGluZSk7XG5cdH0sIDUwKTtcblxuXHRyZXR1cm4gKGxpbmU6IG51bWJlciwgc2V0dGluZ3M6IGFueSkgPT4ge1xuXHRcdGlmICghaXNOYU4obGluZSkpIHtcblx0XHRcdHNldHRpbmdzLmxpbmUgPSBsaW5lO1xuXHRcdFx0ZG9TY3JvbGwobGluZSk7XG5cdFx0fVxuXHR9O1xufSkoKTtcblxubGV0IHVwZGF0ZUltYWdlU2l6ZXMgPSB0aHJvdHRsZSgoKSA9PiB7XG5cdGNvbnN0IGltYWdlSW5mbzogeyBpZDogc3RyaW5nLCBoZWlnaHQ6IG51bWJlciwgd2lkdGg6IG51bWJlciB9W10gPSBbXTtcblx0bGV0IGltYWdlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbWcnKTtcblx0aWYgKGltYWdlcykge1xuXHRcdGxldCBpO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBpbWFnZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGltZyA9IGltYWdlc1tpXTtcblxuXHRcdFx0aWYgKGltZy5jbGFzc0xpc3QuY29udGFpbnMoJ2xvYWRpbmcnKSkge1xuXHRcdFx0XHRpbWcuY2xhc3NMaXN0LnJlbW92ZSgnbG9hZGluZycpO1xuXHRcdFx0fVxuXG5cdFx0XHRpbWFnZUluZm8ucHVzaCh7XG5cdFx0XHRcdGlkOiBpbWcuaWQsXG5cdFx0XHRcdGhlaWdodDogaW1nLmhlaWdodCxcblx0XHRcdFx0d2lkdGg6IGltZy53aWR0aFxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdjYWNoZUltYWdlU2l6ZXMnLCBpbWFnZUluZm8pO1xuXHR9XG59LCA1MCk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCAoKSA9PiB7XG5cdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0dXBkYXRlSW1hZ2VTaXplcygpO1xufSwgdHJ1ZSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZXZlbnQgPT4ge1xuXHRpZiAoZXZlbnQuZGF0YS5zb3VyY2UgIT09IHNldHRpbmdzLnNvdXJjZSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHN3aXRjaCAoZXZlbnQuZGF0YS50eXBlKSB7XG5cdFx0Y2FzZSAnb25EaWRDaGFuZ2VUZXh0RWRpdG9yU2VsZWN0aW9uJzpcblx0XHRcdG1hcmtlci5vbkRpZENoYW5nZVRleHRFZGl0b3JTZWxlY3Rpb24oZXZlbnQuZGF0YS5saW5lKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAndXBkYXRlVmlldyc6XG5cdFx0XHRvblVwZGF0ZVZpZXcoZXZlbnQuZGF0YS5saW5lLCBzZXR0aW5ncyk7XG5cdFx0XHRicmVhaztcblx0fVxufSwgZmFsc2UpO1xuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIGV2ZW50ID0+IHtcblx0aWYgKCFzZXR0aW5ncy5kb3VibGVDbGlja1RvU3dpdGNoVG9FZGl0b3IpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBJZ25vcmUgY2xpY2tzIG9uIGxpbmtzXG5cdGZvciAobGV0IG5vZGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7IG5vZGU7IG5vZGUgPSBub2RlLnBhcmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpIHtcblx0XHRpZiAobm9kZS50YWdOYW1lID09PSAnQScpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdH1cblxuXHRjb25zdCBvZmZzZXQgPSBldmVudC5wYWdlWTtcblx0Y29uc3QgbGluZSA9IGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0KG9mZnNldCk7XG5cdGlmICh0eXBlb2YgbGluZSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKGxpbmUpKSB7XG5cdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdkaWRDbGljaycsIHsgbGluZTogTWF0aC5mbG9vcihsaW5lKSB9KTtcblx0fVxufSk7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQgPT4ge1xuXHRpZiAoIWV2ZW50KSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0bGV0IG5vZGU6IGFueSA9IGV2ZW50LnRhcmdldDtcblx0d2hpbGUgKG5vZGUpIHtcblx0XHRpZiAobm9kZS50YWdOYW1lICYmIG5vZGUudGFnTmFtZSA9PT0gJ0EnICYmIG5vZGUuaHJlZikge1xuXHRcdFx0aWYgKG5vZGUuZ2V0QXR0cmlidXRlKCdocmVmJykuc3RhcnRzV2l0aCgnIycpKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKG5vZGUuaHJlZi5zdGFydHNXaXRoKCdmaWxlOi8vJykgfHwgbm9kZS5ocmVmLnN0YXJ0c1dpdGgoJ3ZzY29kZS1yZXNvdXJjZTonKSkge1xuXHRcdFx0XHRjb25zdCBbcGF0aCwgZnJhZ21lbnRdID0gbm9kZS5ocmVmLnJlcGxhY2UoL14oZmlsZTpcXC9cXC98dnNjb2RlLXJlc291cmNlOikvaSwgJycpLnNwbGl0KCcjJyk7XG5cdFx0XHRcdG1lc3NhZ2luZy5wb3N0TWVzc2FnZSgnY2xpY2tMaW5rJywgeyBwYXRoLCBmcmFnbWVudCB9KTtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG5cdH1cbn0sIHRydWUpO1xuXG5pZiAoc2V0dGluZ3Muc2Nyb2xsRWRpdG9yV2l0aFByZXZpZXcpIHtcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRocm90dGxlKCgpID0+IHtcblx0XHRpZiAoc2Nyb2xsRGlzYWJsZWQpIHtcblx0XHRcdHNjcm9sbERpc2FibGVkID0gZmFsc2U7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGxpbmUgPSBnZXRFZGl0b3JMaW5lTnVtYmVyRm9yUGFnZU9mZnNldCh3aW5kb3cuc2Nyb2xsWSk7XG5cdFx0XHRpZiAodHlwZW9mIGxpbmUgPT09ICdudW1iZXInICYmICFpc05hTihsaW5lKSkge1xuXHRcdFx0XHRtZXNzYWdpbmcucG9zdE1lc3NhZ2UoJ3JldmVhbExpbmUnLCB7IGxpbmUgfSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LCA1MCkpO1xufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5pbXBvcnQgeyBnZXRTZXR0aW5ncyB9IGZyb20gJy4vc2V0dGluZ3MnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1lc3NhZ2VQb3N0ZXIge1xuXHQvKipcblx0ICogUG9zdCBhIG1lc3NhZ2UgdG8gdGhlIG1hcmtkb3duIGV4dGVuc2lvblxuXHQgKi9cblx0cG9zdE1lc3NhZ2UodHlwZTogc3RyaW5nLCBib2R5OiBvYmplY3QpOiB2b2lkO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlUG9zdGVyRm9yVnNDb2RlID0gKHZzY29kZTogYW55KSA9PiB7XG5cdHJldHVybiBuZXcgY2xhc3MgaW1wbGVtZW50cyBNZXNzYWdlUG9zdGVyIHtcblx0XHRwb3N0TWVzc2FnZSh0eXBlOiBzdHJpbmcsIGJvZHk6IG9iamVjdCk6IHZvaWQge1xuXHRcdFx0dnNjb2RlLnBvc3RNZXNzYWdlKHtcblx0XHRcdFx0dHlwZSxcblx0XHRcdFx0c291cmNlOiBnZXRTZXR0aW5ncygpLnNvdXJjZSxcblx0XHRcdFx0Ym9keVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9O1xufTtcblxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbmltcG9ydCB7IGdldFNldHRpbmdzIH0gZnJvbSAnLi9zZXR0aW5ncyc7XG5cblxuZnVuY3Rpb24gY2xhbXAobWluOiBudW1iZXIsIG1heDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKSB7XG5cdHJldHVybiBNYXRoLm1pbihtYXgsIE1hdGgubWF4KG1pbiwgdmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gY2xhbXBMaW5lKGxpbmU6IG51bWJlcikge1xuXHRyZXR1cm4gY2xhbXAoMCwgZ2V0U2V0dGluZ3MoKS5saW5lQ291bnQgLSAxLCBsaW5lKTtcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIENvZGVMaW5lRWxlbWVudCB7XG5cdGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXHRsaW5lOiBudW1iZXI7XG59XG5cbmNvbnN0IGdldENvZGVMaW5lRWxlbWVudHMgPSAoKCkgPT4ge1xuXHRsZXQgZWxlbWVudHM6IENvZGVMaW5lRWxlbWVudFtdO1xuXHRyZXR1cm4gKCkgPT4ge1xuXHRcdGlmICghZWxlbWVudHMpIHtcblx0XHRcdGVsZW1lbnRzID0gKFt7IGVsZW1lbnQ6IGRvY3VtZW50LmJvZHksIGxpbmU6IDAgfV0pLmNvbmNhdChBcnJheS5wcm90b3R5cGUubWFwLmNhbGwoXG5cdFx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2NvZGUtbGluZScpLFxuXHRcdFx0XHQoZWxlbWVudDogYW55KSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgbGluZSA9ICtlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1saW5lJyk7XG5cdFx0XHRcdFx0cmV0dXJuIHsgZWxlbWVudCwgbGluZSB9O1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQuZmlsdGVyKCh4OiBhbnkpID0+ICFpc05hTih4LmxpbmUpKSk7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtZW50cztcblx0fTtcbn0pKCk7XG5cbi8qKlxuICogRmluZCB0aGUgaHRtbCBlbGVtZW50cyB0aGF0IG1hcCB0byBhIHNwZWNpZmljIHRhcmdldCBsaW5lIGluIHRoZSBlZGl0b3IuXG4gKlxuICogSWYgYW4gZXhhY3QgbWF0Y2gsIHJldHVybnMgYSBzaW5nbGUgZWxlbWVudC4gSWYgdGhlIGxpbmUgaXMgYmV0d2VlbiBlbGVtZW50cyxcbiAqIHJldHVybnMgdGhlIGVsZW1lbnQgcHJpb3IgdG8gYW5kIHRoZSBlbGVtZW50IGFmdGVyIHRoZSBnaXZlbiBsaW5lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudHNGb3JTb3VyY2VMaW5lKHRhcmdldExpbmU6IG51bWJlcik6IHsgcHJldmlvdXM6IENvZGVMaW5lRWxlbWVudDsgbmV4dD86IENvZGVMaW5lRWxlbWVudDsgfSB7XG5cdGNvbnN0IGxpbmVOdW1iZXIgPSBNYXRoLmZsb29yKHRhcmdldExpbmUpO1xuXHRjb25zdCBsaW5lcyA9IGdldENvZGVMaW5lRWxlbWVudHMoKTtcblx0bGV0IHByZXZpb3VzID0gbGluZXNbMF0gfHwgbnVsbDtcblx0Zm9yIChjb25zdCBlbnRyeSBvZiBsaW5lcykge1xuXHRcdGlmIChlbnRyeS5saW5lID09PSBsaW5lTnVtYmVyKSB7XG5cdFx0XHRyZXR1cm4geyBwcmV2aW91czogZW50cnksIG5leHQ6IHVuZGVmaW5lZCB9O1xuXHRcdH0gZWxzZSBpZiAoZW50cnkubGluZSA+IGxpbmVOdW1iZXIpIHtcblx0XHRcdHJldHVybiB7IHByZXZpb3VzLCBuZXh0OiBlbnRyeSB9O1xuXHRcdH1cblx0XHRwcmV2aW91cyA9IGVudHJ5O1xuXHR9XG5cdHJldHVybiB7IHByZXZpb3VzIH07XG59XG5cbi8qKlxuICogRmluZCB0aGUgaHRtbCBlbGVtZW50cyB0aGF0IGFyZSBhdCBhIHNwZWNpZmljIHBpeGVsIG9mZnNldCBvbiB0aGUgcGFnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExpbmVFbGVtZW50c0F0UGFnZU9mZnNldChvZmZzZXQ6IG51bWJlcik6IHsgcHJldmlvdXM6IENvZGVMaW5lRWxlbWVudDsgbmV4dD86IENvZGVMaW5lRWxlbWVudDsgfSB7XG5cdGNvbnN0IGxpbmVzID0gZ2V0Q29kZUxpbmVFbGVtZW50cygpO1xuXHRjb25zdCBwb3NpdGlvbiA9IG9mZnNldCAtIHdpbmRvdy5zY3JvbGxZO1xuXHRsZXQgbG8gPSAtMTtcblx0bGV0IGhpID0gbGluZXMubGVuZ3RoIC0gMTtcblx0d2hpbGUgKGxvICsgMSA8IGhpKSB7XG5cdFx0Y29uc3QgbWlkID0gTWF0aC5mbG9vcigobG8gKyBoaSkgLyAyKTtcblx0XHRjb25zdCBib3VuZHMgPSBsaW5lc1ttaWRdLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0aWYgKGJvdW5kcy50b3AgKyBib3VuZHMuaGVpZ2h0ID49IHBvc2l0aW9uKSB7XG5cdFx0XHRoaSA9IG1pZDtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRsbyA9IG1pZDtcblx0XHR9XG5cdH1cblx0Y29uc3QgaGlFbGVtZW50ID0gbGluZXNbaGldO1xuXHRjb25zdCBoaUJvdW5kcyA9IGhpRWxlbWVudC5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRpZiAoaGkgPj0gMSAmJiBoaUJvdW5kcy50b3AgPiBwb3NpdGlvbikge1xuXHRcdGNvbnN0IGxvRWxlbWVudCA9IGxpbmVzW2xvXTtcblx0XHRyZXR1cm4geyBwcmV2aW91czogbG9FbGVtZW50LCBuZXh0OiBoaUVsZW1lbnQgfTtcblx0fVxuXHRyZXR1cm4geyBwcmV2aW91czogaGlFbGVtZW50IH07XG59XG5cbi8qKlxuICogQXR0ZW1wdCB0byByZXZlYWwgdGhlIGVsZW1lbnQgZm9yIGEgc291cmNlIGxpbmUgaW4gdGhlIGVkaXRvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvUmV2ZWFsU291cmNlTGluZShsaW5lOiBudW1iZXIpIHtcblx0aWYgKCFnZXRTZXR0aW5ncygpLnNjcm9sbFByZXZpZXdXaXRoRWRpdG9yKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKGxpbmUgPD0gMCkge1xuXHRcdHdpbmRvdy5zY3JvbGwod2luZG93LnNjcm9sbFgsIDApO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGNvbnN0IHsgcHJldmlvdXMsIG5leHQgfSA9IGdldEVsZW1lbnRzRm9yU291cmNlTGluZShsaW5lKTtcblx0aWYgKCFwcmV2aW91cykge1xuXHRcdHJldHVybjtcblx0fVxuXHRsZXQgc2Nyb2xsVG8gPSAwO1xuXHRjb25zdCByZWN0ID0gcHJldmlvdXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0Y29uc3QgcHJldmlvdXNUb3AgPSByZWN0LnRvcDtcblx0aWYgKG5leHQgJiYgbmV4dC5saW5lICE9PSBwcmV2aW91cy5saW5lKSB7XG5cdFx0Ly8gQmV0d2VlbiB0d28gZWxlbWVudHMuIEdvIHRvIHBlcmNlbnRhZ2Ugb2Zmc2V0IGJldHdlZW4gdGhlbS5cblx0XHRjb25zdCBiZXR3ZWVuUHJvZ3Jlc3MgPSAobGluZSAtIHByZXZpb3VzLmxpbmUpIC8gKG5leHQubGluZSAtIHByZXZpb3VzLmxpbmUpO1xuXHRcdGNvbnN0IGVsZW1lbnRPZmZzZXQgPSBuZXh0LmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wIC0gcHJldmlvdXNUb3A7XG5cdFx0c2Nyb2xsVG8gPSBwcmV2aW91c1RvcCArIGJldHdlZW5Qcm9ncmVzcyAqIGVsZW1lbnRPZmZzZXQ7XG5cdH0gZWxzZSB7XG5cdFx0c2Nyb2xsVG8gPSBwcmV2aW91c1RvcDtcblx0fVxuXHR3aW5kb3cuc2Nyb2xsKHdpbmRvdy5zY3JvbGxYLCBNYXRoLm1heCgxLCB3aW5kb3cuc2Nyb2xsWSArIHNjcm9sbFRvKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFZGl0b3JMaW5lTnVtYmVyRm9yUGFnZU9mZnNldChvZmZzZXQ6IG51bWJlcikge1xuXHRjb25zdCB7IHByZXZpb3VzLCBuZXh0IH0gPSBnZXRMaW5lRWxlbWVudHNBdFBhZ2VPZmZzZXQob2Zmc2V0KTtcblx0aWYgKHByZXZpb3VzKSB7XG5cdFx0Y29uc3QgcHJldmlvdXNCb3VuZHMgPSBwcmV2aW91cy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdGNvbnN0IG9mZnNldEZyb21QcmV2aW91cyA9IChvZmZzZXQgLSB3aW5kb3cuc2Nyb2xsWSAtIHByZXZpb3VzQm91bmRzLnRvcCk7XG5cdFx0aWYgKG5leHQpIHtcblx0XHRcdGNvbnN0IHByb2dyZXNzQmV0d2VlbkVsZW1lbnRzID0gb2Zmc2V0RnJvbVByZXZpb3VzIC8gKG5leHQuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgLSBwcmV2aW91c0JvdW5kcy50b3ApO1xuXHRcdFx0Y29uc3QgbGluZSA9IHByZXZpb3VzLmxpbmUgKyBwcm9ncmVzc0JldHdlZW5FbGVtZW50cyAqIChuZXh0LmxpbmUgLSBwcmV2aW91cy5saW5lKTtcblx0XHRcdHJldHVybiBjbGFtcExpbmUobGluZSk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0Y29uc3QgcHJvZ3Jlc3NXaXRoaW5FbGVtZW50ID0gb2Zmc2V0RnJvbVByZXZpb3VzIC8gKHByZXZpb3VzQm91bmRzLmhlaWdodCk7XG5cdFx0XHRjb25zdCBsaW5lID0gcHJldmlvdXMubGluZSArIHByb2dyZXNzV2l0aGluRWxlbWVudDtcblx0XHRcdHJldHVybiBjbGFtcExpbmUobGluZSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBudWxsO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJldmlld1NldHRpbmdzIHtcblx0c291cmNlOiBzdHJpbmc7XG5cdGxpbmU6IG51bWJlcjtcblx0bGluZUNvdW50OiBudW1iZXI7XG5cdHNjcm9sbFByZXZpZXdXaXRoRWRpdG9yPzogYm9vbGVhbjtcblx0c2Nyb2xsRWRpdG9yV2l0aFByZXZpZXc6IGJvb2xlYW47XG5cdGRpc2FibGVTZWN1cml0eVdhcm5pbmdzOiBib29sZWFuO1xuXHRkb3VibGVDbGlja1RvU3dpdGNoVG9FZGl0b3I6IGJvb2xlYW47XG59XG5cbmxldCBjYWNoZWRTZXR0aW5nczogUHJldmlld1NldHRpbmdzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGF0YShrZXk6IHN0cmluZyk6IFByZXZpZXdTZXR0aW5ncyB7XG5cdGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndnNjb2RlLW1hcmtkb3duLXByZXZpZXctZGF0YScpO1xuXHRpZiAoZWxlbWVudCkge1xuXHRcdGNvbnN0IGRhdGEgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShrZXkpO1xuXHRcdGlmIChkYXRhKSB7XG5cdFx0XHRyZXR1cm4gSlNPTi5wYXJzZShkYXRhKTtcblx0XHR9XG5cdH1cblxuXHR0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBsb2FkIGRhdGEgZm9yICR7a2V5fWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2V0dGluZ3MoKTogUHJldmlld1NldHRpbmdzIHtcblx0aWYgKGNhY2hlZFNldHRpbmdzKSB7XG5cdFx0cmV0dXJuIGNhY2hlZFNldHRpbmdzO1xuXHR9XG5cblx0Y2FjaGVkU2V0dGluZ3MgPSBnZXREYXRhKCdkYXRhLXNldHRpbmdzJyk7XG5cdGlmIChjYWNoZWRTZXR0aW5ncykge1xuXHRcdHJldHVybiBjYWNoZWRTZXR0aW5ncztcblx0fVxuXG5cdHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGxvYWQgc2V0dGluZ3MnKTtcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=
\ No newline at end of file
diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json
index d8860815e0e..54b289a7d23 100644
--- a/extensions/markdown-language-features/package.json
+++ b/extensions/markdown-language-features/package.json
@@ -6,7 +6,6 @@
"icon": "icon.png",
"publisher": "vscode",
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
- "enableProposedApi": true,
"engines": {
"vscode": "^1.20.0"
},
@@ -325,4 +324,4 @@
"webpack": "^4.1.0",
"webpack-cli": "^2.0.10"
}
-}
\ No newline at end of file
+}
diff --git a/extensions/markdown-language-features/preview-src/scroll-sync.ts b/extensions/markdown-language-features/preview-src/scroll-sync.ts
index dacc14a8676..3bd2939e029 100644
--- a/extensions/markdown-language-features/preview-src/scroll-sync.ts
+++ b/extensions/markdown-language-features/preview-src/scroll-sync.ts
@@ -24,13 +24,13 @@ const getCodeLineElements = (() => {
let elements: CodeLineElement[];
return () => {
if (!elements) {
- elements = Array.prototype.map.call(
+ elements = ([{ element: document.body, line: 0 }]).concat(Array.prototype.map.call(
document.getElementsByClassName('code-line'),
(element: any) => {
const line = +element.getAttribute('data-line');
return { element, line };
})
- .filter((x: any) => !isNaN(x.line));
+ .filter((x: any) => !isNaN(x.line)));
}
return elements;
};
@@ -49,8 +49,7 @@ export function getElementsForSourceLine(targetLine: number): { previous: CodeLi
for (const entry of lines) {
if (entry.line === lineNumber) {
return { previous: entry, next: undefined };
- }
- else if (entry.line > lineNumber) {
+ } else if (entry.line > lineNumber) {
return { previous, next: entry };
}
previous = entry;
@@ -89,22 +88,31 @@ export function getLineElementsAtPageOffset(offset: number): { previous: CodeLin
* Attempt to reveal the element for a source line in the editor.
*/
export function scrollToRevealSourceLine(line: number) {
- const { previous, next } = getElementsForSourceLine(line);
- if (previous && getSettings().scrollPreviewWithEditor) {
- let scrollTo = 0;
- const rect = previous.element.getBoundingClientRect();
- const previousTop = rect.top;
- if (next && next.line !== previous.line) {
- // Between two elements. Go to percentage offset between them.
- const betweenProgress = (line - previous.line) / (next.line - previous.line);
- const elementOffset = next.element.getBoundingClientRect().top - previousTop;
- scrollTo = previousTop + betweenProgress * elementOffset;
- }
- else {
- scrollTo = previousTop;
- }
- window.scroll(0, Math.max(1, window.scrollY + scrollTo));
+ if (!getSettings().scrollPreviewWithEditor) {
+ return;
}
+
+ if (line <= 0) {
+ window.scroll(window.scrollX, 0);
+ return;
+ }
+
+ const { previous, next } = getElementsForSourceLine(line);
+ if (!previous) {
+ return;
+ }
+ let scrollTo = 0;
+ const rect = previous.element.getBoundingClientRect();
+ const previousTop = rect.top;
+ if (next && next.line !== previous.line) {
+ // Between two elements. Go to percentage offset between them.
+ const betweenProgress = (line - previous.line) / (next.line - previous.line);
+ const elementOffset = next.element.getBoundingClientRect().top - previousTop;
+ scrollTo = previousTop + betweenProgress * elementOffset;
+ } else {
+ scrollTo = previousTop;
+ }
+ window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo));
}
export function getEditorLineNumberForPageOffset(offset: number) {
diff --git a/extensions/markdown-language-features/src/features/previewContentProvider.ts b/extensions/markdown-language-features/src/features/previewContentProvider.ts
index a11bf3b1162..30767b88c5d 100644
--- a/extensions/markdown-language-features/src/features/previewContentProvider.ts
+++ b/extensions/markdown-language-features/src/features/previewContentProvider.ts
@@ -104,7 +104,7 @@ export class MarkdownContentProvider {
// Use href if it is already an URL
const hrefUri = vscode.Uri.parse(href);
if (['http', 'https'].indexOf(hrefUri.scheme) >= 0) {
- return hrefUri.toString();
+ return hrefUri.toString(true);
}
// Use href as file URI if it is absolute
@@ -131,7 +131,7 @@ export class MarkdownContentProvider {
private computeCustomStyleSheetIncludes(resource: vscode.Uri, config: MarkdownPreviewConfiguration): string {
if (Array.isArray(config.styles)) {
return config.styles.map(style => {
- return ``;
+ return ``;
}).join('\n');
}
return '';
diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts
index 085b1a5e2eb..9bd90ead16a 100644
--- a/extensions/markdown-language-features/src/markdownEngine.ts
+++ b/extensions/markdown-language-features/src/markdownEngine.ts
@@ -46,6 +46,9 @@ export class MarkdownEngine {
if (lang && lang.toLocaleLowerCase() === 'json5') {
lang = 'json';
}
+ if (lang && lang.toLocaleLowerCase() === 'c#') {
+ lang = 'cs';
+ }
if (lang && hljs.getLanguage(lang)) {
try {
return `${hljs.highlight(lang, str, true).value}
`;
@@ -178,7 +181,8 @@ export class MarkdownEngine {
try {
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
if (externalSchemeUri) {
- return normalizeLink(externalSchemeUri.toString());
+ // set true to skip encoding
+ return normalizeLink(externalSchemeUri.toString(true));
}
diff --git a/extensions/markdown-language-features/src/typings/ref.d.ts b/extensions/markdown-language-features/src/typings/ref.d.ts
index 954bab971e3..bc057c55878 100644
--- a/extensions/markdown-language-features/src/typings/ref.d.ts
+++ b/extensions/markdown-language-features/src/typings/ref.d.ts
@@ -4,5 +4,4 @@
*--------------------------------------------------------------------------------------------*/
///
-///
///
diff --git a/extensions/markdown-language-features/src/util/links.ts b/extensions/markdown-language-features/src/util/links.ts
index e1fc274d092..1afcbff83bd 100644
--- a/extensions/markdown-language-features/src/util/links.ts
+++ b/extensions/markdown-language-features/src/util/links.ts
@@ -5,7 +5,7 @@
import * as vscode from 'vscode';
-const knownSchemes = ['http:', 'https:', 'file:', 'mailto:'];
+const knownSchemes = ['http:', 'https:', 'file:', 'mailto:', 'data:', 'vscode-resource:'];
export function getUriForLinkWithKnownExternalScheme(
link: string,
diff --git a/extensions/npm/package.json b/extensions/npm/package.json
index 6c8578ad784..b50486c6bb3 100644
--- a/extensions/npm/package.json
+++ b/extensions/npm/package.json
@@ -7,7 +7,6 @@
"engines": {
"vscode": "0.10.x"
},
- "enableProposedApi": true,
"icon": "images/npm_icon.png",
"categories": [
"Other"
diff --git a/extensions/npm/src/main.ts b/extensions/npm/src/main.ts
index bc40b996a0d..5903d6ebb58 100644
--- a/extensions/npm/src/main.ts
+++ b/extensions/npm/src/main.ts
@@ -11,9 +11,11 @@ import { invalidateTasksCache, NpmTaskProvider } from './tasks';
import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover';
import { runSelectedScript } from './commands';
+let treeDataProvider: NpmScriptsTreeDataProvider | undefined;
+
export async function activate(context: vscode.ExtensionContext): Promise {
registerTaskProvider(context);
- const treeDataProvider = registerExplorer(context);
+ treeDataProvider = registerExplorer(context);
registerHoverProvider(context);
configureHttpRequest();
@@ -46,6 +48,9 @@ function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposab
function invalidateScriptCaches() {
invalidateHoverScriptsCache();
invalidateTasksCache();
+ if (treeDataProvider) {
+ treeDataProvider.refresh();
+ }
}
if (vscode.workspace.workspaceFolders) {
diff --git a/extensions/npm/src/npmView.ts b/extensions/npm/src/npmView.ts
index 2a7fd295656..9bcd272a958 100644
--- a/extensions/npm/src/npmView.ts
+++ b/extensions/npm/src/npmView.ts
@@ -108,6 +108,13 @@ class NpmScript extends TreeItem {
dark: context.asAbsolutePath(path.join('resources', 'dark', 'script.svg'))
};
}
+
+ let uri = getPackageJsonUriFromTask(task);
+ getScripts(uri!).then(scripts => {
+ if (scripts && scripts[task.definition['script']]) {
+ this.tooltip = scripts[task.definition['script']];
+ }
+ });
}
getFolder(): WorkspaceFolder {
diff --git a/extensions/npm/src/typings/refs.d.ts b/extensions/npm/src/typings/refs.d.ts
index 954bab971e3..bc057c55878 100644
--- a/extensions/npm/src/typings/refs.d.ts
+++ b/extensions/npm/src/typings/refs.d.ts
@@ -4,5 +4,4 @@
*--------------------------------------------------------------------------------------------*/
///
-///
///
diff --git a/extensions/package.json b/extensions/package.json
index 10a06e899b4..9c80cfc7731 100644
--- a/extensions/package.json
+++ b/extensions/package.json
@@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "Dependencies shared by all extensions",
"dependencies": {
- "typescript": "3.1.3"
+ "typescript": "3.1.4"
},
"scripts": {
"postinstall": "node ./postinstall"
diff --git a/extensions/php/.vscode/tasks.json b/extensions/php/.vscode/tasks.json
index 9e5593ade83..390a93a3a7f 100644
--- a/extensions/php/.vscode/tasks.json
+++ b/extensions/php/.vscode/tasks.json
@@ -1,30 +1,11 @@
-// Available variables which can be used inside of strings.
-// ${workspaceFolder}: the root folder of the team
-// ${file}: the current opened file
-// ${fileBasename}: the current opened file's basename
-// ${fileDirname}: the current opened file's dirname
-// ${fileExtname}: the current opened file's extension
-// ${cwd}: the current working directory of the spawned process
-
-// A task runner that calls a custom npm script that compiles the extension.
{
- "version": "0.1.0",
-
- // we want to run npm
+ "version": "2.0.0",
"command": "npm",
-
- // the command is a shell script
- "isShellCommand": true,
-
- // show the output window only if unrecognized errors occur.
- "showOutput": "silent",
-
- // we run the custom script "compile" as defined in package.json
+ "type": "shell",
+ "presentation": {
+ "reveal": "silent"
+ },
"args": ["run", "compile"],
-
- // The tsc compiler is started in watching mode
- "isWatching": true,
-
- // use the standard tsc in watch mode problem matcher to find compile problems in the output.
+ "isBackground": true,
"problemMatcher": "$tsc-watch"
-}
\ No newline at end of file
+}
diff --git a/extensions/php/syntaxes/html.tmLanguage.json b/extensions/php/syntaxes/html.tmLanguage.json
index 59db289a2d5..809b1120530 100644
--- a/extensions/php/syntaxes/html.tmLanguage.json
+++ b/extensions/php/syntaxes/html.tmLanguage.json
@@ -4,10 +4,17 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/atom/language-php/commit/72bfa9592e689fdcb70562ff7d882ad5308e79f7",
+ "version": "https://github.com/atom/language-php/commit/b6c5e83016b52311cdc622c2579462861ee91587",
"name": "PHP",
"scopeName": "text.html.php",
"injections": {
+ "text.html.php - (meta.embedded | meta.tag), L:((text.html.php meta.tag) - (meta.embedded.block.php | meta.embedded.line.php)), L:(source.js.embedded.html - (meta.embedded.block.php | meta.embedded.line.php))": {
+ "patterns": [
+ {
+ "include": "#php-tag"
+ }
+ ]
+ },
"L:source.php string.quoted.single.sql.php source.sql.embedded.php": {
"patterns": [
{
@@ -108,13 +115,6 @@
"include": "source.php#interpolation_double_quoted"
}
]
- },
- "text.html.php - (meta.embedded | meta.tag), L:text.html.php meta.tag, L:text.html.php source.js": {
- "patterns": [
- {
- "include": "#php-tag"
- }
- ]
}
},
"patterns": [
diff --git a/extensions/php/test/colorize-results/issue-28354_php.json b/extensions/php/test/colorize-results/issue-28354_php.json
index 12e439430fb..329c9d6f998 100644
--- a/extensions/php/test/colorize-results/issue-28354_php.json
+++ b/extensions/php/test/colorize-results/issue-28354_php.json
@@ -66,85 +66,8 @@
}
},
{
- "c": "",
- "t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php punctuation.section.embedded.end.php",
+ "c": "php",
+ "t": "text.html.php meta.embedded.block.html source.js variable.other.readwrite.js",
"r": {
- "dark_plus": "punctuation.section.embedded.end.php: #569CD6",
- "light_plus": "punctuation.section.embedded.end.php: #800000",
- "dark_vs": "punctuation.section.embedded.end.php: #569CD6",
- "light_vs": "punctuation.section.embedded.end.php: #800000",
- "hc_black": "punctuation.section.embedded: #569CD6"
+ "dark_plus": "variable: #9CDCFE",
+ "light_plus": "variable: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "variable: #9CDCFE"
}
},
{
- "c": " ",
+ "c": " ",
"t": "text.html.php meta.embedded.block.html source.js",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
@@ -484,58 +110,300 @@
}
},
{
- "c": "...",
- "t": "text.html.php meta.embedded.block.html source.js keyword.operator.spread.js",
+ "c": "foreach",
+ "t": "text.html.php meta.embedded.block.html source.js meta.function-call.js entity.name.function.js",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
- "dark_vs": "keyword.operator: #D4D4D4",
- "light_vs": "keyword.operator: #000000",
- "hc_black": "keyword.operator: #D4D4D4"
+ "dark_plus": "entity.name.function: #DCDCAA",
+ "light_plus": "entity.name.function: #795E26",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "entity.name.function: #DCDCAA"
}
},
{
- "c": "<",
- "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html source.js",
+ "c": "(",
+ "t": "text.html.php meta.embedded.block.html source.js meta.brace.round.js",
"r": {
- "dark_plus": "punctuation.definition.tag: #808080",
- "light_plus": "punctuation.definition.tag: #800000",
- "dark_vs": "punctuation.definition.tag: #808080",
- "light_vs": "punctuation.definition.tag: #800000",
- "hc_black": "punctuation.definition.tag: #808080"
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
- "c": "/",
- "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.begin.html",
+ "c": "$actID",
+ "t": "text.html.php meta.embedded.block.html source.js variable.other.readwrite.js",
"r": {
- "dark_plus": "punctuation.definition.tag: #808080",
- "light_plus": "punctuation.definition.tag: #800000",
- "dark_vs": "punctuation.definition.tag: #808080",
- "light_vs": "punctuation.definition.tag: #800000",
- "hc_black": "punctuation.definition.tag: #808080"
+ "dark_plus": "variable: #9CDCFE",
+ "light_plus": "variable: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "variable: #9CDCFE"
}
},
{
- "c": "script",
- "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html entity.name.tag.html",
+ "c": " ",
+ "t": "text.html.php meta.embedded.block.html source.js",
"r": {
- "dark_plus": "entity.name.tag: #569CD6",
- "light_plus": "entity.name.tag: #800000",
- "dark_vs": "entity.name.tag: #569CD6",
- "light_vs": "entity.name.tag: #800000",
- "hc_black": "entity.name.tag: #569CD6"
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
- "c": ">",
- "t": "text.html.php meta.embedded.block.html meta.tag.metadata.script.end.html punctuation.definition.tag.end.html",
+ "c": "AS",
+ "t": "text.html.php meta.embedded.block.html source.js variable.other.constant.js",
"r": {
- "dark_plus": "punctuation.definition.tag: #808080",
- "light_plus": "punctuation.definition.tag: #800000",
- "dark_vs": "punctuation.definition.tag: #808080",
- "light_vs": "punctuation.definition.tag: #800000",
- "hc_black": "punctuation.definition.tag: #808080"
+ "dark_plus": "variable: #9CDCFE",
+ "light_plus": "variable: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "variable: #9CDCFE"
+ }
+ },
+ {
+ "c": " ",
+ "t": "text.html.php meta.embedded.block.html source.js",
+ "r": {
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
+ }
+ },
+ {
+ "c": "$act",
+ "t": "text.html.php meta.embedded.block.html source.js variable.other.readwrite.js",
+ "r": {
+ "dark_plus": "variable: #9CDCFE",
+ "light_plus": "variable: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "variable: #9CDCFE"
+ }
+ },
+ {
+ "c": ")",
+ "t": "text.html.php meta.embedded.block.html source.js meta.brace.round.js",
+ "r": {
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
+ }
+ },
+ {
+ "c": " ",
+ "t": "text.html.php meta.embedded.block.html source.js",
+ "r": {
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
+ }
+ },
+ {
+ "c": "{",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js punctuation.definition.block.js",
+ "r": {
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
+ }
+ },
+ {
+ "c": " echo ",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js",
+ "r": {
+ "dark_plus": "meta.embedded: #D4D4D4",
+ "light_plus": "meta.embedded: #000000",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.embedded: #FFFFFF"
+ }
+ },
+ {
+ "c": "'",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js punctuation.definition.string.begin.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": "divNames.push(",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": "\\'",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js constant.character.escape.js",
+ "r": {
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #FF0000",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "constant.character: #569CD6"
+ }
+ },
+ {
+ "c": "[nid=",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": "'",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js punctuation.definition.string.end.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": ".$act.",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js",
+ "r": {
+ "dark_plus": "meta.object-literal.key: #9CDCFE",
+ "light_plus": "meta.object-literal.key: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.object-literal.key: #9CDCFE"
+ }
+ },
+ {
+ "c": "'",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js punctuation.definition.string.begin.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": "]",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": "\\'",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js constant.character.escape.js",
+ "r": {
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #FF0000",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "constant.character: #569CD6"
+ }
+ },
+ {
+ "c": ");",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": "'",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js string.quoted.single.js punctuation.definition.string.end.js",
+ "r": {
+ "dark_plus": "string: #CE9178",
+ "light_plus": "string: #A31515",
+ "dark_vs": "string: #CE9178",
+ "light_vs": "string: #A31515",
+ "hc_black": "string: #CE9178"
+ }
+ },
+ {
+ "c": ";",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js",
+ "r": {
+ "dark_plus": "meta.object-literal.key: #9CDCFE",
+ "light_plus": "meta.object-literal.key: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.object-literal.key: #9CDCFE"
+ }
+ },
+ {
+ "c": " }",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js",
+ "r": {
+ "dark_plus": "meta.object-literal.key: #9CDCFE",
+ "light_plus": "meta.object-literal.key: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.object-literal.key: #9CDCFE"
+ }
+ },
+ {
+ "c": " ?>",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js",
+ "r": {
+ "dark_plus": "meta.object-literal.key: #9CDCFE",
+ "light_plus": "meta.object-literal.key: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.object-literal.key: #9CDCFE"
+ }
+ },
+ {
+ "c": " ...",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js",
+ "r": {
+ "dark_plus": "meta.object-literal.key: #9CDCFE",
+ "light_plus": "meta.object-literal.key: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.object-literal.key: #9CDCFE"
+ }
+ },
+ {
+ "c": "",
+ "t": "text.html.php meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js meta.object-literal.key.js",
+ "r": {
+ "dark_plus": "meta.object-literal.key: #9CDCFE",
+ "light_plus": "meta.object-literal.key: #001080",
+ "dark_vs": "meta.embedded: #D4D4D4",
+ "light_vs": "meta.embedded: #000000",
+ "hc_black": "meta.object-literal.key: #9CDCFE"
}
}
]
\ No newline at end of file
diff --git a/extensions/python/syntaxes/MagicPython.tmLanguage.json b/extensions/python/syntaxes/MagicPython.tmLanguage.json
index 44a995bc046..e51fcce1a85 100644
--- a/extensions/python/syntaxes/MagicPython.tmLanguage.json
+++ b/extensions/python/syntaxes/MagicPython.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/MagicStack/MagicPython/commit/b453f26ed856c9b16a053517c41207e3a72cc7d5",
+ "version": "https://github.com/MagicStack/MagicPython/commit/8ff35b3e5fcde471fae62a57ea1ae1c7cd34c9fc",
"name": "MagicPython",
"scopeName": "source.python",
"patterns": [
@@ -97,7 +97,8 @@
},
"docstring-statement": {
"begin": "^(?=\\s*[rR]?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))",
- "end": "(?<=\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\")",
+ "comment": "the string either terminates correctly or by the beginning of a new line (this is for single line docstrings that aren't terminated) AND it's not followed by another docstring",
+ "end": "((?<=\\1)|^)(?!\\s*[rR]?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))",
"patterns": [
{
"include": "#docstring"
@@ -164,7 +165,7 @@
{
"name": "string.quoted.docstring.single.python",
"begin": "(\\'|\\\")",
- "end": "(\\1)|((?=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n",
+ "name": "meta.format.brace.python",
+ "match": "(?x)\n (\n {{ | }}\n | (?:\n {\n \\w* (\\.[[:alpha:]_]\\w* | \\[[^\\]'\"]+\\])*\n (![rsa])?\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n",
"captures": {
- "2": {
- "name": "storage.type.format.python"
+ "1": {
+ "name": "constant.character.format.placeholder.other.python"
},
"3": {
"name": "storage.type.format.python"
+ },
+ "4": {
+ "name": "storage.type.format.python"
}
}
},
{
- "name": "constant.character.format.placeholder.other.python",
- "begin": "(?x)\n \\{\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n (:)\n (?=[^'\"}\\n]*\\})\n",
- "end": "\\}",
- "beginCaptures": {
- "2": {
- "name": "storage.type.format.python"
+ "name": "meta.format.brace.python",
+ "match": "(?x)\n (\n {\n \\w* (\\.[[:alpha:]_]\\w* | \\[[^\\]'\"]+\\])*\n (![rsa])?\n (:)\n [^'\"{}\\n]* (?:\n \\{ [^'\"}\\n]*? \\} [^'\"{}\\n]*\n )*\n }\n )\n",
+ "captures": {
+ "1": {
+ "name": "constant.character.format.placeholder.other.python"
},
"3": {
"name": "storage.type.format.python"
+ },
+ "4": {
+ "name": "storage.type.format.python"
}
- },
- "patterns": [
- {
- "match": "(?x) \\{ [^'\"}\\n]*? \\} (?=.*?\\})\n"
- }
- ]
+ }
}
]
},
@@ -899,25 +915,43 @@
"match": "(}(?!}))"
},
"import": {
- "comment": "Import statements\n",
+ "comment": "Import statements used to correctly mark `from`, `import`, and `as`\n",
"patterns": [
{
- "match": "(?x)\n \\s* \\b(from)\\b \\s*(\\.+)\\s* (import)?\n",
- "captures": {
+ "begin": "\\b(?)|((?!\\{)(?=\\S))",
+ "end": "((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])",
"patterns": [
+ {
+ "include": "#single-line-comment-consuming-line-ending"
+ },
{
"include": "#decl-block"
},
@@ -2620,13 +2626,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.ts",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2673,7 +2679,7 @@
"name": "keyword.operator.new.ts"
}
},
- "end": "(?<=\\))|(?=[;),}\\]:]|\\|\\||\\&\\&|$|((?\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
+ "begin": "(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
"beginCaptures": {
"1": {
"name": "meta.arrow.ts meta.return.type.arrow.ts keyword.operator.type.annotation.ts"
@@ -3621,6 +3627,14 @@
}
},
"patterns": [
+ {
+ "match": "(?)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
@@ -3971,7 +3982,7 @@
"include": "#typeof-operator"
},
{
- "begin": "([&|\\*])(?=\\s*\\{)",
+ "begin": "([&|])(?=\\s*\\{)",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.ts"
@@ -3985,7 +3996,7 @@
]
},
{
- "begin": "[&|\\*]",
+ "begin": "[&|]",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.ts"
@@ -4123,7 +4134,7 @@
"patterns": [
{
"name": "string.template.ts",
- "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
+ "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
"beginCaptures": {
"1": {
"name": "entity.name.function.tagged-template.ts"
diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json
index d96e10f5ead..6d39e0862c5 100644
--- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json
+++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/6e8a3830c29b6f29c06d2de091240e1a880f21aa",
+ "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/3133e3d914db9a2bb8812119f9273727a305f16b",
"name": "TypeScriptReact",
"scopeName": "source.tsx",
"patterns": [
@@ -1153,7 +1153,7 @@
"name": "meta.definition.function.tsx entity.name.function.tsx"
}
},
- "end": "(?=$|^|;)|(?<=\\})",
+ "end": "(?=;|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))|(?<=\\})",
"patterns": [
{
"include": "#function-name"
@@ -1413,6 +1413,9 @@
},
{
"include": "#arrow-return-type"
+ },
+ {
+ "include": "#possibly-arrow-return-type"
}
]
},
@@ -1424,8 +1427,11 @@
"name": "storage.type.function.arrow.tsx"
}
},
- "end": "(?<=\\}|\\S)(?)|((?!\\{)(?=\\S))",
+ "end": "((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])",
"patterns": [
+ {
+ "include": "#single-line-comment-consuming-line-ending"
+ },
{
"include": "#decl-block"
},
@@ -2623,13 +2629,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.tsx",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
+ "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2676,7 +2682,7 @@
"name": "keyword.operator.new.tsx"
}
},
- "end": "(?<=\\))|(?=[;),}\\]:]|\\|\\||\\&\\&|$|((?\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
+ "begin": "(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<[^<>]+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)",
"beginCaptures": {
"1": {
"name": "meta.arrow.tsx meta.return.type.arrow.tsx keyword.operator.type.annotation.tsx"
@@ -3587,6 +3593,14 @@
}
},
"patterns": [
+ {
+ "match": "(?)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
@@ -3937,7 +3948,7 @@
"include": "#typeof-operator"
},
{
- "begin": "([&|\\*])(?=\\s*\\{)",
+ "begin": "([&|])(?=\\s*\\{)",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.tsx"
@@ -3951,7 +3962,7 @@
]
},
{
- "begin": "[&|\\*]",
+ "begin": "[&|]",
"beginCaptures": {
"0": {
"name": "keyword.operator.type.tsx"
@@ -4089,7 +4100,7 @@
"patterns": [
{
"name": "string.template.tsx",
- "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(\\*(?=\\s*[,>]))|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
+ "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)",
"beginCaptures": {
"1": {
"name": "entity.name.function.tagged-template.tsx"
diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json
index 048c8d669c4..92160253eba 100644
--- a/extensions/typescript-language-features/package.json
+++ b/extensions/typescript-language-features/package.json
@@ -42,6 +42,7 @@
"onCommand:typescript.goToProjectConfig",
"onCommand:typescript.openTsServerLog",
"onCommand:workbench.action.tasks.runTask",
+ "onCommand:_typescript.configurePlugin",
"onLanguage:jsonc"
],
"main": "./out/extension",
diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json
index 9308f771233..2cd347a012a 100644
--- a/extensions/typescript-language-features/package.nls.json
+++ b/extensions/typescript-language-features/package.nls.json
@@ -5,7 +5,7 @@
"configuration.typescript": "TypeScript",
"configuration.suggest.completeFunctionCalls": "Complete functions with their parameter signature.",
"typescript.tsdk.desc": "Specifies the folder path containing the tsserver and lib*.d.ts files to use.",
- "typescript.disableAutomaticTypeAcquisition": "Disables automatic type acquisition.",
+ "typescript.disableAutomaticTypeAcquisition": "Disables automatic type acquisition. Automatic type acquisition fetches `@types` packages from npm to improve IntelliSense for external libraries.",
"typescript.tsserver.log": "Enables logging of the TS server to a file. This log can be used to diagnose TS Server issues. The log may contain file paths, source code, and other potentially sensitive information from your project.",
"typescript.tsserver.pluginPaths": "Additional paths to discover Typescript Language Service plugins. Requires using TypeScript 2.3.0 or newer in the workspace.",
"typescript.tsserver.pluginPaths.item": "Either an absolute or relative path. Relative path will be resolved against workspace folder(s).",
diff --git a/extensions/typescript-language-features/src/commands.ts b/extensions/typescript-language-features/src/commands.ts
index 2c40c512e18..8a353e30807 100644
--- a/extensions/typescript-language-features/src/commands.ts
+++ b/extensions/typescript-language-features/src/commands.ts
@@ -10,6 +10,7 @@ import { Command } from './utils/commandManager';
import { Lazy } from './utils/lazy';
import { isImplicitProjectConfigFile, openOrCreateConfigFile } from './utils/tsconfig';
import { nulToken } from './utils/cancellation';
+import { PluginConfigProvider } from './typescriptServiceClient';
const localize = nls.loadMessageBundle();
@@ -105,6 +106,18 @@ export class JavaScriptGoToProjectConfigCommand implements Command {
}
}
+export class ConfigurePluginCommand implements Command {
+ public readonly id = '_typescript.configurePlugin';
+
+ public constructor(
+ private readonly pluginConfigProvider: PluginConfigProvider,
+ ) { }
+
+ public execute(pluginId: string, configuration: any) {
+ this.pluginConfigProvider.set(pluginId, configuration);
+ }
+}
+
async function goToProjectConfig(
clientHost: TypeScriptServiceClientHost,
isTypeScriptProject: boolean,
diff --git a/extensions/typescript-language-features/src/extension.ts b/extensions/typescript-language-features/src/extension.ts
index 48415ef1f1f..cce5a94dda7 100644
--- a/extensions/typescript-language-features/src/extension.ts
+++ b/extensions/typescript-language-features/src/extension.ts
@@ -18,19 +18,36 @@ import ManagedFileContextManager from './utils/managedFileContext';
import { getContributedTypeScriptServerPlugins, TypeScriptServerPlugin } from './utils/plugins';
import * as ProjectStatus from './utils/projectStatus';
import { Surveyor } from './utils/surveyor';
+import { PluginConfigProvider } from './typescriptServiceClient';
+interface ApiV0 {
+ readonly onCompletionAccepted: vscode.Event;
+}
+
+
+
+interface Api {
+ getAPI(version: 0): ApiV0 | undefined;
+}
+
export function activate(
context: vscode.ExtensionContext
-): void {
+): Api {
const plugins = getContributedTypeScriptServerPlugins();
+ const pluginConfigProvider = new PluginConfigProvider();
const commandManager = new CommandManager();
context.subscriptions.push(commandManager);
- const lazyClientHost = createLazyClientHost(context, plugins, commandManager);
+ const onCompletionAccepted = new vscode.EventEmitter();
+ context.subscriptions.push(onCompletionAccepted);
- registerCommands(commandManager, lazyClientHost);
+ const lazyClientHost = createLazyClientHost(context, plugins, pluginConfigProvider, commandManager, item => {
+ onCompletionAccepted.fire(item);
+ });
+
+ registerCommands(commandManager, lazyClientHost, pluginConfigProvider);
context.subscriptions.push(new TypeScriptTaskProviderManager(lazyClientHost.map(x => x.serviceClient)));
context.subscriptions.push(new LanguageConfigurationManager());
@@ -62,12 +79,25 @@ export function activate(
break;
}
}
+
+ return {
+ getAPI(version) {
+ if (version === 0) {
+ return {
+ onCompletionAccepted: onCompletionAccepted.event
+ } as ApiV0;
+ }
+ return undefined;
+ }
+ } as Api;
}
function createLazyClientHost(
context: vscode.ExtensionContext,
plugins: TypeScriptServerPlugin[],
- commandManager: CommandManager
+ pluginConfigProvider: PluginConfigProvider,
+ commandManager: CommandManager,
+ onCompletionAccepted: (item: vscode.CompletionItem) => void,
): Lazy {
return lazy(() => {
const logDirectoryProvider = new LogDirectoryProvider(context);
@@ -76,8 +106,10 @@ function createLazyClientHost(
standardLanguageDescriptions,
context.workspaceState,
plugins,
+ pluginConfigProvider,
commandManager,
- logDirectoryProvider);
+ logDirectoryProvider,
+ onCompletionAccepted);
context.subscriptions.push(clientHost);
@@ -99,7 +131,8 @@ function createLazyClientHost(
function registerCommands(
commandManager: CommandManager,
- lazyClientHost: Lazy
+ lazyClientHost: Lazy,
+ pluginConfigProvider: PluginConfigProvider,
) {
commandManager.register(new commands.ReloadTypeScriptProjectsCommand(lazyClientHost));
commandManager.register(new commands.ReloadJavaScriptProjectsCommand(lazyClientHost));
@@ -108,6 +141,7 @@ function registerCommands(
commandManager.register(new commands.RestartTsServerCommand(lazyClientHost));
commandManager.register(new commands.TypeScriptGoToProjectConfigCommand(lazyClientHost));
commandManager.register(new commands.JavaScriptGoToProjectConfigCommand(lazyClientHost));
+ commandManager.register(new commands.ConfigurePluginCommand(pluginConfigProvider));
}
function isSupportedDocument(
diff --git a/extensions/typescript-language-features/src/features/completions.ts b/extensions/typescript-language-features/src/features/completions.ts
index 01f598b5b6b..1dfb2530981 100644
--- a/extensions/typescript-language-features/src/features/completions.ts
+++ b/extensions/typescript-language-features/src/features/completions.ts
@@ -76,15 +76,32 @@ class MyCompletionItem extends vscode.CompletionItem {
}
}
- if (tsEntry.kindModifiers && tsEntry.kindModifiers.match(/\boptional\b/)) {
- if (!this.insertText) {
- this.insertText = this.label;
+ if (tsEntry.kindModifiers) {
+ const kindModifiers = new Set(tsEntry.kindModifiers.split(/\s+/g));
+
+ if (kindModifiers.has(PConst.KindModifiers.optional)) {
+ if (!this.insertText) {
+ this.insertText = this.label;
+ }
+
+ if (!this.filterText) {
+ this.filterText = this.label;
+ }
+ this.label += '?';
}
- if (!this.filterText) {
- this.filterText = this.label;
+ if (tsEntry.kind === PConst.Kind.script) {
+ for (const extModifier of PConst.KindModifiers.fileExtensionKindModifiers) {
+ if (kindModifiers.has(extModifier)) {
+ if (tsEntry.name.toLowerCase().endsWith(extModifier)) {
+ this.detail = tsEntry.name;
+ } else {
+ this.detail = tsEntry.name + extModifier;
+ }
+ break;
+ }
+ }
}
- this.label += '?';
}
this.resolveRange(line);
}
@@ -191,6 +208,31 @@ class MyCompletionItem extends vscode.CompletionItem {
}
}
+class CompositeCommand implements Command {
+ public static readonly ID = '_typescript.composite';
+ public readonly id = CompositeCommand.ID;
+
+ public execute(...commands: vscode.Command[]) {
+ for (const command of commands) {
+ vscode.commands.executeCommand(command.command, ...(command.arguments || []));
+ }
+ }
+}
+
+
+class CompletionAcceptedCommand implements Command {
+ public static readonly ID = '_typescript.onCompletionAccepted';
+ public readonly id = CompletionAcceptedCommand.ID;
+
+ public constructor(
+ private readonly onCompletionAccepted: (item: vscode.CompletionItem) => void,
+ ) { }
+
+ public execute(item: vscode.CompletionItem) {
+ this.onCompletionAccepted(item);
+ }
+}
+
class ApplyCompletionCodeActionCommand implements Command {
public static readonly ID = '_typescript.applyCompletionCodeAction';
public readonly id = ApplyCompletionCodeActionCommand.ID;
@@ -270,9 +312,12 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
private readonly modeId: string,
private readonly typingsStatus: TypingsStatus,
private readonly fileConfigurationManager: FileConfigurationManager,
- commandManager: CommandManager
+ commandManager: CommandManager,
+ onCompletionAccepted: (item: vscode.CompletionItem) => void
) {
commandManager.register(new ApplyCompletionCodeActionCommand(this.client));
+ commandManager.register(new CompositeCommand());
+ commandManager.register(new CompletionAcceptedCommand(onCompletionAccepted));
}
public async provideCompletionItems(
@@ -372,30 +417,46 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
]
};
- let details: Proto.CompletionEntryDetails[] | undefined;
const response = await this.client.execute('completionEntryDetails', args, token);
- if (response.type !== 'response') {
+ if (response.type !== 'response' || !response.body) {
return item;
}
- const { body } = response;
- details = body;
- if (!details || !details.length || !details[0]) {
- return item;
+ const detail = response.body[0];
+
+ if (!item.detail && detail.displayParts.length) {
+ item.detail = Previewer.plain(detail.displayParts);
}
- const detail = details[0];
- item.detail = detail.displayParts.length ? Previewer.plain(detail.displayParts) : undefined;
item.documentation = this.getDocumentation(detail, item);
- const { command, additionalTextEdits } = this.getCodeActions(detail, filepath);
- item.command = command;
- item.additionalTextEdits = additionalTextEdits;
+ const codeAction = this.getCodeActions(detail, filepath);
+ const commands: vscode.Command[] = [{
+ command: CompletionAcceptedCommand.ID,
+ title: '',
+ arguments: [item]
+ }];
+ if (codeAction.command) {
+ commands.push(codeAction.command);
+ }
+ item.additionalTextEdits = codeAction.additionalTextEdits;
if (detail && item.useCodeSnippet) {
const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position, token);
if (shouldCompleteFunction) {
item.insertText = this.snippetForFunctionCall(item, detail);
- item.command = { title: 'triggerParameterHints', command: 'editor.action.triggerParameterHints' };
+ commands.push({ title: 'triggerParameterHints', command: 'editor.action.triggerParameterHints' });
+ }
+ }
+
+ if (commands.length) {
+ if (commands.length === 1) {
+ item.command = commands[0];
+ } else {
+ item.command = {
+ command: CompositeCommand.ID,
+ title: '',
+ arguments: commands
+ };
}
}
@@ -456,14 +517,16 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
document: vscode.TextDocument,
position: vscode.Position
): boolean {
- // TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/13456
- // Only enable dot completions when previous character is an identifier.
- // Prevents incorrectly completing while typing spread operators.
- if (position.character > 1) {
- const preText = document.getText(new vscode.Range(
- position.line, 0,
- position.line, position.character));
- return preText.match(/(^|[a-z_$\(\)\[\]\{\}]|[^.]\.)\s*$/ig) !== null;
+ if (this.client.apiVersion.lt(API.v320)) {
+ // Workaround for https://github.com/Microsoft/TypeScript/issues/27742
+ // Only enable dot completions when previous character not a dot preceeded by whitespace.
+ // Prevents incorrectly completing while typing spread operators.
+ if (position.character > 1) {
+ const preText = document.getText(new vscode.Range(
+ position.line, 0,
+ position.line, position.character));
+ return preText.match(/(\s|^)\.$/ig) === null;
+ }
}
return true;
@@ -628,9 +691,10 @@ export function register(
typingsStatus: TypingsStatus,
fileConfigurationManager: FileConfigurationManager,
commandManager: CommandManager,
+ onCompletionAccepted: (item: vscode.CompletionItem) => void
) {
return new ConfigurationDependentRegistration(modeId, 'suggest.enabled', () =>
vscode.languages.registerCompletionItemProvider(selector,
- new TypeScriptCompletionItemProvider(client, modeId, typingsStatus, fileConfigurationManager, commandManager),
+ new TypeScriptCompletionItemProvider(client, modeId, typingsStatus, fileConfigurationManager, commandManager, onCompletionAccepted),
...TypeScriptCompletionItemProvider.triggerCharacters));
}
diff --git a/extensions/typescript-language-features/src/features/refactor.ts b/extensions/typescript-language-features/src/features/refactor.ts
index 93aab9d7ca8..3e49abaaef4 100644
--- a/extensions/typescript-language-features/src/features/refactor.ts
+++ b/extensions/typescript-language-features/src/features/refactor.ts
@@ -194,7 +194,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider {
return false;
}
- return rangeOrSelection instanceof vscode.Selection && !rangeOrSelection.isEmpty;
+ return rangeOrSelection instanceof vscode.Selection;
}
private static getKind(refactor: Proto.RefactorActionInfo) {
diff --git a/extensions/typescript-language-features/src/features/signatureHelp.ts b/extensions/typescript-language-features/src/features/signatureHelp.ts
index 001155c7e02..8eac3a9ca91 100644
--- a/extensions/typescript-language-features/src/features/signatureHelp.ts
+++ b/extensions/typescript-language-features/src/features/signatureHelp.ts
@@ -73,16 +73,20 @@ class TypeScriptSignatureHelpProvider implements vscode.SignatureHelpProvider {
function toTsTriggerReason(context: vscode.SignatureHelpContext): Proto.SignatureHelpTriggerReason {
switch (context.triggerReason) {
- case vscode.SignatureHelpTriggerReason.Retrigger:
- return { kind: 'retrigger' };
-
case vscode.SignatureHelpTriggerReason.TriggerCharacter:
if (context.triggerCharacter) {
- return { kind: 'characterTyped', triggerCharacter: context.triggerCharacter as any };
+ if (context.isRetrigger) {
+ return { kind: 'retrigger', triggerCharacter: context.triggerCharacter as any };
+ } else {
+ return { kind: 'characterTyped', triggerCharacter: context.triggerCharacter as any };
+ }
} else {
return { kind: 'invoked' };
}
+ case vscode.SignatureHelpTriggerReason.ContentChange:
+ return context.isRetrigger ? { kind: 'retrigger' } : { kind: 'invoked' };
+
case vscode.SignatureHelpTriggerReason.Invoke:
default:
return { kind: 'invoked' };
diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts
index 25cb080ec61..c95fc1e70f4 100644
--- a/extensions/typescript-language-features/src/languageProvider.ts
+++ b/extensions/typescript-language-features/src/languageProvider.ts
@@ -29,7 +29,8 @@ export default class LanguageProvider extends Disposable {
private readonly commandManager: CommandManager,
private readonly telemetryReporter: TelemetryReporter,
private readonly typingsStatus: TypingsStatus,
- private readonly fileConfigurationManager: FileConfigurationManager
+ private readonly fileConfigurationManager: FileConfigurationManager,
+ private readonly onCompletionAccepted: (item: vscode.CompletionItem) => void,
) {
super();
vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables);
@@ -57,7 +58,7 @@ export default class LanguageProvider extends Disposable {
const cachedResponse = new CachedNavTreeResponse();
- this._register((await import('./features/completions')).register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager));
+ this._register((await import('./features/completions')).register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.onCompletionAccepted));
this._register((await import('./features/definitions')).register(selector, this.client));
this._register((await import('./features/directiveCommentCompletions')).register(selector, this.client));
this._register((await import('./features/documentHighlight')).register(selector, this.client));
diff --git a/extensions/typescript-language-features/src/protocol.const.ts b/extensions/typescript-language-features/src/protocol.const.ts
index 241bffd24d5..d06820b106f 100644
--- a/extensions/typescript-language-features/src/protocol.const.ts
+++ b/extensions/typescript-language-features/src/protocol.const.ts
@@ -39,4 +39,24 @@ export class DiagnosticCategory {
public static readonly error = 'error';
public static readonly warning = 'warning';
public static readonly suggestion = 'suggestion';
+}
+
+export class KindModifiers {
+ public static readonly optional = 'optional';
+
+ public static readonly dtsFile = '.d.ts';
+ public static readonly tsFile = '.ts';
+ public static readonly tsxFile = '.tsx';
+ public static readonly jsFile = '.js';
+ public static readonly jsxFile = '.jsx';
+ public static readonly jsonFile = '.json';
+
+ public static readonly fileExtensionKindModifiers = [
+ KindModifiers.dtsFile,
+ KindModifiers.tsFile,
+ KindModifiers.tsxFile,
+ KindModifiers.jsFile,
+ KindModifiers.jsxFile,
+ KindModifiers.jsonFile,
+ ];
}
\ No newline at end of file
diff --git a/extensions/typescript-language-features/src/test/requestQueue.test.ts b/extensions/typescript-language-features/src/test/requestQueue.test.ts
new file mode 100644
index 00000000000..c157ae244cf
--- /dev/null
+++ b/extensions/typescript-language-features/src/test/requestQueue.test.ts
@@ -0,0 +1,122 @@
+/*---------------------------------------------------------------------------------------------
+ * 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 'mocha';
+import { RequestQueue, RequestQueueingType } from '../tsServer/requestQueue';
+
+suite('RequestQueue', () => {
+ test('should be empty on creation', async () => {
+ const queue = new RequestQueue();
+ assert.strictEqual(queue.length, 0);
+ assert.strictEqual(queue.shift(), undefined);
+ });
+
+ suite('RequestQueue.createRequest', () => {
+ test('should create items with increasing sequence numbers', async () => {
+ const queue = new RequestQueue();
+
+ for (let i = 0; i < 100; ++i) {
+ const command = `command-${i}`;
+ const request = queue.createRequest(command, i);
+ assert.strictEqual(request.seq, i);
+ assert.strictEqual(request.command, command);
+ assert.strictEqual(request.arguments, i);
+ }
+ });
+ });
+
+ test('should queue normal requests in first in first out order', async () => {
+ const queue = new RequestQueue();
+ assert.strictEqual(queue.length, 0);
+
+ const request1 = queue.createRequest('a', 1);
+ queue.push({ request: request1, expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
+ assert.strictEqual(queue.length, 1);
+
+ const request2 = queue.createRequest('b', 2);
+ queue.push({ request: request2, expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
+ assert.strictEqual(queue.length, 2);
+
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 1);
+ assert.strictEqual(item!.request.command, 'a');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 0);
+ assert.strictEqual(item!.request.command, 'b');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(item, undefined);
+ assert.strictEqual(queue.length, 0);
+ }
+ });
+
+ test('should put normal requests in front of low priority requests', async () => {
+ const queue = new RequestQueue();
+ assert.strictEqual(queue.length, 0);
+
+ queue.push({ request: queue.createRequest('low-1', 1), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
+ queue.push({ request: queue.createRequest('low-2', 1), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
+ queue.push({ request: queue.createRequest('normal-1', 2), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
+ queue.push({ request: queue.createRequest('normal-2', 2), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
+
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 3);
+ assert.strictEqual(item!.request.command, 'normal-1');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 2);
+ assert.strictEqual(item!.request.command, 'normal-2');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 1);
+ assert.strictEqual(item!.request.command, 'low-1');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 0);
+ assert.strictEqual(item!.request.command, 'low-2');
+ }
+ });
+
+ test('should not push fence requests front of low priority requests', async () => {
+ const queue = new RequestQueue();
+ assert.strictEqual(queue.length, 0);
+
+ queue.push({ request: queue.createRequest('low-1', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
+ queue.push({ request: queue.createRequest('fence', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Fence });
+ queue.push({ request: queue.createRequest('low-2', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.LowPriority });
+ queue.push({ request: queue.createRequest('normal', 0), expectsResponse: true, isAsync: false, queueingType: RequestQueueingType.Normal });
+
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 3);
+ assert.strictEqual(item!.request.command, 'low-1');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 2);
+ assert.strictEqual(item!.request.command, 'fence');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 1);
+ assert.strictEqual(item!.request.command, 'normal');
+ }
+ {
+ const item = queue.shift();
+ assert.strictEqual(queue.length, 0);
+ assert.strictEqual(item!.request.command, 'low-2');
+ }
+ });
+});
+
diff --git a/extensions/typescript-language-features/src/tsServer/callbackMap.ts b/extensions/typescript-language-features/src/tsServer/callbackMap.ts
new file mode 100644
index 00000000000..ec80c07ab02
--- /dev/null
+++ b/extensions/typescript-language-features/src/tsServer/callbackMap.ts
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as Proto from '../protocol';
+import { CancelledResponse, ServerResponse } from '../typescriptService';
+
+export interface CallbackItem {
+ readonly onSuccess: (value: R) => void;
+ readonly onError: (err: any) => void;
+ readonly startTime: number;
+ readonly isAsync: boolean;
+}
+
+export class CallbackMap {
+ private readonly _callbacks = new Map | undefined>>();
+ private readonly _asyncCallbacks = new Map | undefined>>();
+
+ public destroy(cause: string): void {
+ const cancellation = new CancelledResponse(cause);
+ for (const callback of this._callbacks.values()) {
+ callback.onSuccess(cancellation);
+ }
+ this._callbacks.clear();
+ for (const callback of this._asyncCallbacks.values()) {
+ callback.onSuccess(cancellation);
+ }
+ this._asyncCallbacks.clear();
+ }
+
+ public add(seq: number, callback: CallbackItem | undefined>, isAsync: boolean) {
+ if (isAsync) {
+ this._asyncCallbacks.set(seq, callback);
+ }
+ else {
+ this._callbacks.set(seq, callback);
+ }
+ }
+
+ public fetch(seq: number): CallbackItem | undefined> | undefined {
+ const callback = this._callbacks.get(seq) || this._asyncCallbacks.get(seq);
+ this.delete(seq);
+ return callback;
+ }
+
+ private delete(seq: number) {
+ if (!this._callbacks.delete(seq)) {
+ this._asyncCallbacks.delete(seq);
+ }
+ }
+}
\ No newline at end of file
diff --git a/extensions/typescript-language-features/src/tsServer/requestQueue.ts b/extensions/typescript-language-features/src/tsServer/requestQueue.ts
new file mode 100644
index 00000000000..4ca1c44b072
--- /dev/null
+++ b/extensions/typescript-language-features/src/tsServer/requestQueue.ts
@@ -0,0 +1,81 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as Proto from '../protocol';
+
+export enum RequestQueueingType {
+ /**
+ * Normal request that is executed in order.
+ */
+ Normal = 1,
+
+ /**
+ * Request that normal requests jump in front of in the queue.
+ */
+ LowPriority = 2,
+
+ /**
+ * A fence that blocks request reordering.
+ *
+ * Fences are not reordered but unlike a normal request, a fence will never jump in front of a low priority request
+ * in the request queue.
+ */
+ Fence = 3,
+}
+
+export interface RequestItem {
+ readonly request: Proto.Request;
+ readonly expectsResponse: boolean;
+ readonly isAsync: boolean;
+ readonly queueingType: RequestQueueingType;
+}
+
+export class RequestQueue {
+ private readonly queue: RequestItem[] = [];
+ private sequenceNumber: number = 0;
+
+ public get length(): number {
+ return this.queue.length;
+ }
+
+ public push(item: RequestItem): void {
+ if (item.queueingType === RequestQueueingType.Normal) {
+ let index = this.queue.length - 1;
+ while (index >= 0) {
+ if (this.queue[index].queueingType !== RequestQueueingType.LowPriority) {
+ break;
+ }
+ --index;
+ }
+ this.queue.splice(index + 1, 0, item);
+ } else {
+ //if none is low priority just push to end
+ this.queue.push(item);
+ }
+ }
+
+ public shift(): RequestItem | undefined {
+ return this.queue.shift();
+ }
+
+ public tryCancelPendingRequest(seq: number): boolean {
+ for (let i = 0; i < this.queue.length; i++) {
+ if (this.queue[i].request.seq === seq) {
+ this.queue.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public createRequest(command: string, args: any): Proto.Request {
+ return {
+ seq: this.sequenceNumber++,
+ type: 'request',
+ command: command,
+ arguments: args
+ };
+ }
+}
\ No newline at end of file
diff --git a/extensions/typescript-language-features/src/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts
similarity index 81%
rename from extensions/typescript-language-features/src/server.ts
rename to extensions/typescript-language-features/src/tsServer/server.ts
index cd216ce6d63..a57c679e039 100644
--- a/extensions/typescript-language-features/src/server.ts
+++ b/extensions/typescript-language-features/src/tsServer/server.ts
@@ -7,108 +7,22 @@ import * as cp from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
-import * as Proto from './protocol';
-import { CancelledResponse, NoContentResponse, ServerResponse } from './typescriptService';
-import API from './utils/api';
-import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
-import { Disposable } from './utils/dispose';
-import * as electron from './utils/electron';
-import LogDirectoryProvider from './utils/logDirectoryProvider';
-import Logger from './utils/logger';
-import { TypeScriptPluginPathsProvider } from './utils/pluginPathsProvider';
-import { TypeScriptServerPlugin } from './utils/plugins';
-import TelemetryReporter from './utils/telemetry';
-import Tracer from './utils/tracer';
-import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider';
-import { Reader } from './utils/wireProtocol';
-
-interface CallbackItem {
- readonly onSuccess: (value: R) => void;
- readonly onError: (err: any) => void;
- readonly startTime: number;
- readonly isAsync: boolean;
-}
-
-class CallbackMap {
- private readonly _callbacks = new Map | undefined>>();
- private readonly _asyncCallbacks = new Map | undefined>>();
-
- public destroy(cause: string): void {
- const cancellation = new CancelledResponse(cause);
- for (const callback of this._callbacks.values()) {
- callback.onSuccess(cancellation);
- }
- this._callbacks.clear();
-
- for (const callback of this._asyncCallbacks.values()) {
- callback.onSuccess(cancellation);
- }
- this._asyncCallbacks.clear();
- }
-
- public add(seq: number, callback: CallbackItem | undefined>, isAsync: boolean) {
- if (isAsync) {
- this._asyncCallbacks.set(seq, callback);
- } else {
- this._callbacks.set(seq, callback);
- }
- }
-
-
- public fetch(seq: number): CallbackItem | undefined> | undefined {
- const callback = this._callbacks.get(seq) || this._asyncCallbacks.get(seq);
- this.delete(seq);
- return callback;
- }
-
- private delete(seq: number) {
- if (!this._callbacks.delete(seq)) {
- this._asyncCallbacks.delete(seq);
- }
- }
-}
-
-interface RequestItem {
- readonly request: Proto.Request;
- readonly expectsResponse: boolean;
- readonly isAsync: boolean;
-}
-
-class RequestQueue {
- private readonly queue: RequestItem[] = [];
- private sequenceNumber: number = 0;
-
- public get length(): number {
- return this.queue.length;
- }
-
- public push(item: RequestItem): void {
- this.queue.push(item);
- }
-
- public shift(): RequestItem | undefined {
- return this.queue.shift();
- }
-
- public tryCancelPendingRequest(seq: number): boolean {
- for (let i = 0; i < this.queue.length; i++) {
- if (this.queue[i].request.seq === seq) {
- this.queue.splice(i, 1);
- return true;
- }
- }
- return false;
- }
-
- public createRequest(command: string, args: any): Proto.Request {
- return {
- seq: this.sequenceNumber++,
- type: 'request',
- command: command,
- arguments: args
- };
- }
-}
+import * as Proto from '../protocol';
+import { CancelledResponse, NoContentResponse } from '../typescriptService';
+import API from '../utils/api';
+import { TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration';
+import { Disposable } from '../utils/dispose';
+import * as electron from '../utils/electron';
+import LogDirectoryProvider from '../utils/logDirectoryProvider';
+import Logger from '../utils/logger';
+import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider';
+import { TypeScriptServerPlugin } from '../utils/plugins';
+import TelemetryReporter from '../utils/telemetry';
+import Tracer from '../utils/tracer';
+import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider';
+import { Reader } from '../utils/wireProtocol';
+import { CallbackMap } from './callbackMap';
+import { RequestQueue, RequestItem, RequestQueueingType } from './requestQueue';
export class TypeScriptServerSpawner {
public constructor(
@@ -381,12 +295,13 @@ export class TypeScriptServer extends Disposable {
}
}
- public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean }): Promise {
+ public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise {
const request = this._requestQueue.createRequest(command, args);
const requestInfo: RequestItem = {
request: request,
expectsResponse: executeInfo.expectsResult,
- isAsync: executeInfo.isAsync
+ isAsync: executeInfo.isAsync,
+ queueingType: getQueueingType(command, executeInfo.lowPriority)
};
let result: Promise;
if (executeInfo.expectsResult) {
@@ -490,3 +405,15 @@ export class TypeScriptServer extends Disposable {
}
}
+const fenceCommands = new Set(['change', 'close', 'open']);
+
+function getQueueingType(
+ command: string,
+ lowPriority?: boolean
+): RequestQueueingType {
+ if (fenceCommands.has(command)) {
+ return RequestQueueingType.Fence;
+ }
+ return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal;
+}
+
diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts
index df5613d849a..2fa36ce3959 100644
--- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts
+++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts
@@ -14,7 +14,7 @@ import FileConfigurationManager from './features/fileConfigurationManager';
import LanguageProvider from './languageProvider';
import * as Proto from './protocol';
import * as PConst from './protocol.const';
-import TypeScriptServiceClient from './typescriptServiceClient';
+import TypeScriptServiceClient, { PluginConfigProvider } from './typescriptServiceClient';
import API from './utils/api';
import { CommandManager } from './utils/commandManager';
import { Disposable } from './utils/dispose';
@@ -49,8 +49,10 @@ export default class TypeScriptServiceClientHost extends Disposable {
descriptions: LanguageDescription[],
workspaceState: vscode.Memento,
plugins: TypeScriptServerPlugin[],
+ pluginConfigProvider: PluginConfigProvider,
private readonly commandManager: CommandManager,
- logDirectoryProvider: LogDirectoryProvider
+ logDirectoryProvider: LogDirectoryProvider,
+ onCompletionAccepted: (item: vscode.CompletionItem) => void,
) {
super();
const handleProjectCreateOrDelete = () => {
@@ -72,6 +74,7 @@ export default class TypeScriptServiceClientHost extends Disposable {
workspaceState,
version => this.versionStatus.onDidChangeTypeScriptVersion(version),
plugins,
+ pluginConfigProvider,
logDirectoryProvider,
allModeIds));
@@ -89,7 +92,7 @@ export default class TypeScriptServiceClientHost extends Disposable {
this.fileConfigurationManager = this._register(new FileConfigurationManager(this.client));
for (const description of descriptions) {
- const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager);
+ const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager, onCompletionAccepted);
this.languages.push(manager);
this._register(manager);
this.languagePerId.set(description.id, manager);
@@ -122,7 +125,7 @@ export default class TypeScriptServiceClientHost extends Disposable {
diagnosticOwner: 'typescript',
isExternal: true
};
- const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager);
+ const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager, onCompletionAccepted);
this.languages.push(manager);
this._register(manager);
this.languagePerId.set(description.id, manager);
diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts
index 8852e8b4929..d14201af795 100644
--- a/extensions/typescript-language-features/src/typescriptService.ts
+++ b/extensions/typescript-language-features/src/typescriptService.ts
@@ -95,7 +95,8 @@ export interface ITypeScriptServiceClient {
execute(
command: K,
args: TypeScriptRequestTypes[K][0],
- token: vscode.CancellationToken
+ token: vscode.CancellationToken,
+ lowPriority?: boolean
): Promise>;
executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void;
diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts
index a70d25330e2..41d53385257 100644
--- a/extensions/typescript-language-features/src/typescriptServiceClient.ts
+++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts
@@ -10,7 +10,7 @@ import * as nls from 'vscode-nls';
import BufferSyncSupport from './features/bufferSyncSupport';
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
import * as Proto from './protocol';
-import { TypeScriptServer, TypeScriptServerSpawner } from './server';
+import { TypeScriptServer, TypeScriptServerSpawner } from './tsServer/server';
import { ITypeScriptServiceClient } from './typescriptService';
import API from './utils/api';
import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
@@ -29,6 +29,22 @@ import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionPro
const localize = nls.loadMessageBundle();
+export class PluginConfigProvider extends Disposable {
+ private readonly _config = new Map();
+
+ private readonly _onDidUpdateConfig = this._register(new vscode.EventEmitter<{ pluginId: string, config: {} }>());
+ public readonly onDidUpdateConfig = this._onDidUpdateConfig.event;
+
+ public set(pluginId: string, config: {}) {
+ this._config.set(pluginId, config);
+ this._onDidUpdateConfig.fire({ pluginId, config });
+ }
+
+ public entries(): IterableIterator<[string, {}]> {
+ return this._config.entries();
+ }
+}
+
export interface TsDiagnostics {
readonly kind: DiagnosticKind;
readonly resource: vscode.Uri;
@@ -75,6 +91,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
private readonly workspaceState: vscode.Memento,
private readonly onDidChangeTypeScriptVersion: (version: TypeScriptVersion) => void,
public readonly plugins: TypeScriptServerPlugin[],
+ private readonly pluginConfigProvider: PluginConfigProvider,
private readonly logDirectoryProvider: LogDirectoryProvider,
allModeIds: string[]
) {
@@ -132,6 +149,10 @@ export default class TypeScriptServiceClient extends Disposable implements IType
this.telemetryReporter = this._register(new TelemetryReporter(() => this._tsserverVersion || this._apiVersion.versionString));
this.typescriptServerSpawner = new TypeScriptServerSpawner(this.versionProvider, this.logDirectoryProvider, this.pluginPathsProvider, this.logger, this.telemetryReporter, this.tracer);
+
+ this._register(this.pluginConfigProvider.onDidUpdateConfig(update => {
+ this.configurePlugin(update.pluginId, update.config);
+ }));
}
public get configuration() {
@@ -406,6 +427,11 @@ export default class TypeScriptServiceClient extends Disposable implements IType
if (resendModels) {
this._onResendModelsRequested.fire();
}
+
+ // Reconfigure any plugins
+ for (const [config, pluginName] of this.pluginConfigProvider.entries()) {
+ this.configurePlugin(config, pluginName);
+ }
}
private setCompilerOptionsForInferredProjects(configuration: TypeScriptServiceConfiguration): void {
@@ -560,11 +586,12 @@ export default class TypeScriptServiceClient extends Disposable implements IType
return undefined;
}
- public execute(command: string, args: any, token: vscode.CancellationToken): Promise {
+ public execute(command: string, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise {
return this.executeImpl(command, args, {
isAsync: false,
token,
- expectsResult: true
+ expectsResult: true,
+ lowPriority
});
}
@@ -584,7 +611,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
});
}
- private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean }): Promise {
+ private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise {
const server = this.service();
if (!server) {
return Promise.reject(new Error('Could not load TS Server'));
@@ -718,8 +745,13 @@ export default class TypeScriptServiceClient extends Disposable implements IType
this._apiVersion = API.defaultVersion;
this._tsserverVersion = undefined;
}
-}
+ private configurePlugin(pluginName: string, configuration: {}): any {
+ if (this._apiVersion.gte(API.v314)) {
+ this.executeWithoutWaitingForResponse('configurePlugin', { pluginName, configuration });
+ }
+ }
+}
function getDignosticsKind(event: Proto.Event) {
switch (event.event) {
diff --git a/extensions/typescript-language-features/src/utils/api.ts b/extensions/typescript-language-features/src/utils/api.ts
index 9bcab14cf59..0c7f5b9ff69 100644
--- a/extensions/typescript-language-features/src/utils/api.ts
+++ b/extensions/typescript-language-features/src/utils/api.ts
@@ -31,6 +31,7 @@ export default class API {
public static readonly v292 = API.fromSimpleString('2.9.2');
public static readonly v300 = API.fromSimpleString('3.0.0');
public static readonly v310 = API.fromSimpleString('3.1.0');
+ public static readonly v314 = API.fromSimpleString('3.1.4');
public static readonly v320 = API.fromSimpleString('3.2.0');
diff --git a/extensions/vscode-api-tests/.vscode/tasks.json b/extensions/vscode-api-tests/.vscode/tasks.json
index e2a020d0645..390a93a3a7f 100644
--- a/extensions/vscode-api-tests/.vscode/tasks.json
+++ b/extensions/vscode-api-tests/.vscode/tasks.json
@@ -1,30 +1,11 @@
-// Available variables which can be used inside of strings.
-// ${workspaceFolder}: the root folder of the team
-// ${file}: the current opened file
-// ${fileBasename}: the current opened file's basename
-// ${fileDirname}: the current opened file's dirname
-// ${fileExtname}: the current opened file's extension
-// ${cwd}: the current working directory of the spawned process
-
-// A task runner that calls a custom npm script that compiles the extension.
{
- "version": "0.1.0",
-
- // we want to run npm
+ "version": "2.0.0",
"command": "npm",
-
- // the command is a shell script
- "isShellCommand": true,
-
- // show the output window only if unrecognized errors occur.
- "showOutput": "silent",
-
- // we run the custom script "compile" as defined in package.json
- "args": ["run", "compile", "--loglevel", "silent"],
-
- // The tsc compiler is started in watching mode
- "isWatching": true,
-
- // use the standard tsc in watch mode problem matcher to find compile problems in the output.
+ "type": "shell",
+ "presentation": {
+ "reveal": "silent"
+ },
+ "args": ["run", "compile"],
+ "isBackground": true,
"problemMatcher": "$tsc-watch"
-}
\ No newline at end of file
+}
diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts
index dce3b608da5..1c56454d0d5 100644
--- a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts
+++ b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts
@@ -384,6 +384,7 @@ suite('window namespace tests', () => {
test('showQuickPick, accept first', async function () {
const pick = window.showQuickPick(['eins', 'zwei', 'drei']);
+ await new Promise(resolve => setTimeout(resolve, 10)); // Allow UI to update.
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
assert.equal(await pick, 'eins');
});
@@ -421,6 +422,7 @@ suite('window namespace tests', () => {
canPickMany: true
});
const first = new Promise(resolve => resolves.push(resolve));
+ await new Promise(resolve => setTimeout(resolve, 10)); // Allow UI to update.
await commands.executeCommand('workbench.action.quickOpenSelectNext');
assert.equal(await first, 'eins');
await commands.executeCommand('workbench.action.quickPickManyToggle');
@@ -442,6 +444,7 @@ suite('window namespace tests', () => {
], {
canPickMany: true
});
+ await new Promise(resolve => setTimeout(resolve, 10)); // Allow UI to update.
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
assert.deepStrictEqual((await picks)!.map(pick => pick.label), ['zwei', 'drei']);
});
diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts
index 7af7b00b60c..8921b4aee46 100644
--- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts
+++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts
@@ -520,8 +520,9 @@ suite('workspace-namespace', () => {
});
assert.equal(results.length, 1);
- assert(results[0].preview.text.indexOf('foo') >= 0);
- assert.equal(vscode.workspace.asRelativePath(results[0].uri), '10linefile.ts');
+ const match = results[0];
+ assert(match.preview.text.indexOf('foo') >= 0);
+ assert.equal(vscode.workspace.asRelativePath(match.uri), '10linefile.ts');
});
test('findTextInFiles, cancellation', async () => {
diff --git a/extensions/vscode-colorize-tests/.vscode/tasks.json b/extensions/vscode-colorize-tests/.vscode/tasks.json
index 3b6c357da2d..390a93a3a7f 100644
--- a/extensions/vscode-colorize-tests/.vscode/tasks.json
+++ b/extensions/vscode-colorize-tests/.vscode/tasks.json
@@ -1,31 +1,11 @@
-// Available variables which can be used inside of strings.
-// ${workspaceFolder}: the root folder of the team
-// ${file}: the current opened file
-// ${relativeFile}: the current opened file relative to cwd
-// ${fileBasename}: the current opened file's basename
-// ${fileDirname}: the current opened file's dirname
-// ${fileExtname}: the current opened file's extension
-// ${cwd}: the current working directory of the spawned process
-
-// A task runner that calls a custom npm script that compiles the extension.
{
- "version": "0.1.0",
-
- // we want to run npm
+ "version": "2.0.0",
"command": "npm",
-
- // the command is a shell script
- "isShellCommand": true,
-
- // show the output window only if unrecognized errors occur.
- "showOutput": "silent",
-
- // we run the custom script "compile" as defined in package.json
- "args": ["run", "compile", "--loglevel", "silent"],
-
- // The tsc compiler is started in watching mode
- "isWatching": true,
-
- // use the standard tsc in watch mode problem matcher to find compile problems in the output.
+ "type": "shell",
+ "presentation": {
+ "reveal": "silent"
+ },
+ "args": ["run", "compile"],
+ "isBackground": true,
"problemMatcher": "$tsc-watch"
-}
\ No newline at end of file
+}
diff --git a/extensions/yarn.lock b/extensions/yarn.lock
index 0630b4a19f8..e2dfd06e5bb 100644
--- a/extensions/yarn.lock
+++ b/extensions/yarn.lock
@@ -2,7 +2,7 @@
# yarn lockfile v1
-typescript@3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
- integrity sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA==
+typescript@3.1.4:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.4.tgz#c74ef7b3c2da65beff548b903022cb8c3cd997ed"
+ integrity sha512-JZHJtA6ZL15+Q3Dqkbh8iCUmvxD3iJ7ujXS+fVkKnwIVAdHc5BJTDNM0aTrnr2luKulFjU7W+SRhDZvi66Ru7Q==
diff --git a/package.json b/package.json
index d362ad36c35..d15b3dfc915 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
- "version": "1.29.0",
- "distro": "eceef408e99ace55c0a17a2a90b88e46a8c9090a",
+ "version": "1.30.0",
+ "distro": "3e54b1cdfa3b0bb32253d0e81e2fe2b875b2a92a",
"author": {
"name": "Microsoft Corporation"
},
@@ -46,13 +46,14 @@
"spdlog": "0.7.2",
"sudo-prompt": "8.2.0",
"v8-inspect-profiler": "^0.0.8",
- "vscode-chokidar": "1.6.4",
+ "vscode-chokidar": "1.6.5",
"vscode-debugprotocol": "1.32.0",
"vscode-nsfw": "1.1.1",
- "vscode-ripgrep": "^1.2.2",
+ "vscode-proxy-agent": "0.1.1",
+ "vscode-ripgrep": "^1.2.4",
"vscode-sqlite3": "4.0.2",
"vscode-textmate": "^4.0.1",
- "vscode-xterm": "3.9.0-beta9",
+ "vscode-xterm": "3.9.0-beta13",
"winreg": "^1.2.4",
"yauzl": "^2.9.1",
"yazl": "^2.4.3"
@@ -124,7 +125,7 @@
"source-map": "^0.4.4",
"ts-loader": "^4.4.2",
"tslint": "^5.9.1",
- "typescript": "3.1.1",
+ "typescript": "3.1.4",
"typescript-formatter": "7.1.0",
"uglify-es": "^3.0.18",
"underscore": "^1.8.2",
diff --git a/product.json b/product.json
index e95e36c0ec8..eb6526c2d8f 100644
--- a/product.json
+++ b/product.json
@@ -17,5 +17,8 @@
"win32ShellNameShort": "C&ode - OSS",
"darwinBundleIdentifier": "com.visualstudio.code.oss",
"reportIssueUrl": "https://github.com/Microsoft/vscode/issues/new",
- "urlProtocol": "code-oss"
+ "urlProtocol": "code-oss",
+ "extensionAllowedProposedApi": [
+ "ms-vscode.references-view"
+ ]
}
diff --git a/resources/linux/snap/electron-launch b/resources/linux/snap/electron-launch
old mode 100644
new mode 100755
index 65c91d6fc1b..6fdd68a34cf
--- a/resources/linux/snap/electron-launch
+++ b/resources/linux/snap/electron-launch
@@ -1,3 +1,6 @@
#!/bin/sh
-exec "$@" --executed-from="$(pwd)" --pid=$$
+# Create $XDG_RUNTIME_DIR if it doesn't exist
+[ -n "$XDG_RUNTIME_DIR" ] && mkdir -p $XDG_RUNTIME_DIR -m 700
+
+exec "$@"
diff --git a/resources/linux/snap/snapUpdate.sh b/resources/linux/snap/snapUpdate.sh
new file mode 100755
index 00000000000..d9299ca4d58
--- /dev/null
+++ b/resources/linux/snap/snapUpdate.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+sleep 2
+@@NAME@@
\ No newline at end of file
diff --git a/resources/linux/snap/snapcraft.yaml b/resources/linux/snap/snapcraft.yaml
index e8a5d48fdf1..e0772308684 100644
--- a/resources/linux/snap/snapcraft.yaml
+++ b/resources/linux/snap/snapcraft.yaml
@@ -15,6 +15,7 @@ parts:
source: .
stage-packages:
- libasound2
+ - libc++1
- libgconf2-4
- libnotify4
- libnspr4
@@ -23,20 +24,21 @@ parts:
- libpulse0
- libxss1
- libxtst6
- # desktop-gtk2 deps below
- libxkbcommon0
- - libgtk2.0-0
- # - unity-gtk2-module
+ - libgtk-3-0
+ - libgdk-pixbuf2.0-0
+ - libglib2.0-bin
+ - unity-gtk2-module
- libappindicator1
+ - xdg-user-dirs
+ - libsecret-1-0
+ # TODO@joao @Tyriar check these deps
+ # - libatomic1
+ # - libgtk2.0-bin
prime:
- -usr/share/dh-python
- electron-launch:
- plugin: dump
- source: .
- organize:
- electron-launch: bin/electron-launch
apps:
@@NAME@@:
- command: bin/electron-launch ${SNAP}/usr/share/@@NAME@@/bin/@@NAME@@
+ command: electron-launch ${SNAP}/usr/share/@@NAME@@/bin/@@NAME@@
desktop: usr/share/applications/@@NAME@@.desktop
\ No newline at end of file
diff --git a/scripts/code.bat b/scripts/code.bat
index 58d5ca2d6e0..6789e54fdda 100644
--- a/scripts/code.bat
+++ b/scripts/code.bat
@@ -17,7 +17,7 @@ set CODE=".build\electron\%NAMESHORT%"
node build\lib\electron.js
if %errorlevel% neq 0 node .\node_modules\gulp\bin\gulp.js electron
-:: Manage build-in extensions
+:: Manage built-in extensions
if "%1"=="--builtin" goto builtin
:: Sync built-in extensions
@@ -49,4 +49,4 @@ goto end
popd
-endlocal
\ No newline at end of file
+endlocal
diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat
index 4b8310ee04a..fc13a2d99b4 100644
--- a/scripts/test-integration.bat
+++ b/scripts/test-integration.bat
@@ -5,12 +5,16 @@ pushd %~dp0\..
set VSCODEUSERDATADIR=%TMP%\vscodeuserfolder-%RANDOM%-%TIME:~6,5%
-:: Tests in the extension host
-call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
+:: Integration & performance tests in AMD
+call .\scripts\test.bat --runGlob **\*.integrationTest.js %*
if %errorlevel% neq 0 exit /b %errorlevel%
-call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
-if %errorlevel% neq 0 exit /b %errorlevel%
+:: Tests in the extension host
+REM call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
+REM if %errorlevel% neq 0 exit /b %errorlevel%
+
+REM call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
+REM if %errorlevel% neq 0 exit /b %errorlevel%
call .\scripts\code.bat %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
if %errorlevel% neq 0 exit /b %errorlevel%
@@ -18,10 +22,6 @@ if %errorlevel% neq 0 exit /b %errorlevel%
call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disableExtensions --user-data-dir=%VSCODEUSERDATADIR% .
if %errorlevel% neq 0 exit /b %errorlevel%
-:: Integration & performance tests in AMD
-call .\scripts\test.bat --runGlob **\*.integrationTest.js %*
-if %errorlevel% neq 0 exit /b %errorlevel%
-
# Tests in commonJS (HTML, CSS, JSON language server tests...)
call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\*\server\out\test\**\*.test.js
if %errorlevel% neq 0 exit /b %errorlevel%
diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh
index d2225c4475d..a51f3ee172c 100755
--- a/scripts/test-integration.sh
+++ b/scripts/test-integration.sh
@@ -12,6 +12,9 @@ fi
cd $ROOT
+# Integration tests in AMD
+./scripts/test.sh --runGlob **/*.integrationTest.js "$@"
+
# Tests in the extension host
./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disableExtensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started
./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disableExtensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started
@@ -22,9 +25,6 @@ mkdir $ROOT/extensions/emmet/test-fixtures
./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disableExtensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started .
rm -r $ROOT/extensions/emmet/test-fixtures
-# Integration tests in AMD
-./scripts/test.sh --runGlob **/*.integrationTest.js "$@"
-
# Tests in commonJS
cd $ROOT/extensions/css-language-features/server && $ROOT/scripts/node-electron.sh test/index.js
cd $ROOT/extensions/html-language-features/server && $ROOT/scripts/node-electron.sh test/index.js
diff --git a/src/main.js b/src/main.js
index 92375bc68c0..a551417c8e8 100644
--- a/src/main.js
+++ b/src/main.js
@@ -81,17 +81,14 @@ function onReady() {
nlsConfiguration = Promise.resolve(undefined);
}
- // We first need to test a user defined locale. If it fails we try the app locale.
+ // First, we need to test a user defined locale. If it fails we try the app locale.
// If that fails we fall back to English.
nlsConfiguration.then((nlsConfig) => {
const startup = nlsConfig => {
nlsConfig._languagePackSupport = true;
process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfig);
-
- if (cachedDataDir) {
- process.env['VSCODE_NODE_CACHED_DATA_DIR'] = cachedDataDir;
- }
+ process.env['VSCODE_NODE_CACHED_DATA_DIR'] = cachedDataDir || '';
// Load main in AMD
require('./bootstrap-amd').load('vs/code/electron-main/main');
@@ -407,7 +404,7 @@ function rimraf(location) {
});
}
-// Language tags are case insensitve however an amd loader is case sensitive
+// Language tags are case insensitive however an amd loader is case sensitive
// To make this work on case preserving & insensitive FS we do the following:
// the language bundles have lower case language tags and we always lower case
// the locale we receive from the user or OS.
@@ -608,4 +605,4 @@ function getNLSConfiguration(locale) {
return defaultResult(locale);
}
}
-//#endregion
\ No newline at end of file
+//#endregion
diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json
index 9e295f40659..1bf4732a4a0 100644
--- a/src/tsconfig.monaco.json
+++ b/src/tsconfig.monaco.json
@@ -1,5 +1,4 @@
{
- "$schema": "https://schemastore.azurewebsites.net/schemas/json/tsconfig.json",
"compilerOptions": {
"noEmit": true,
"module": "amd",
diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json
index 2d17fd87162..1bd3c7c6fd6 100644
--- a/src/tsconfig.strictNullChecks.json
+++ b/src/tsconfig.strictNullChecks.json
@@ -22,11 +22,22 @@
"./vs/base/browser/mouseEvent.ts",
"./vs/base/browser/touch.ts",
"./vs/base/browser/ui/aria/aria.ts",
+ "./vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts",
"./vs/base/browser/ui/button/button.ts",
+ "./vs/base/browser/ui/centered/centeredViewLayout.ts",
"./vs/base/browser/ui/contextview/contextview.ts",
"./vs/base/browser/ui/countBadge/countBadge.ts",
+ "./vs/base/browser/ui/grid/grid.ts",
+ "./vs/base/browser/ui/grid/gridview.ts",
+ "./vs/base/browser/ui/highlightedlabel/highlightedLabel.ts",
+ "./vs/base/browser/ui/iconLabel/iconLabel.ts",
"./vs/base/browser/ui/keybindingLabel/keybindingLabel.ts",
"./vs/base/browser/ui/list/list.ts",
+ "./vs/base/browser/ui/list/listPaging.ts",
+ "./vs/base/browser/ui/list/listView.ts",
+ "./vs/base/browser/ui/list/listWidget.ts",
+ "./vs/base/browser/ui/list/rangeMap.ts",
+ "./vs/base/browser/ui/list/rowCache.ts",
"./vs/base/browser/ui/list/splice.ts",
"./vs/base/browser/ui/octiconLabel/octiconLabel.mock.ts",
"./vs/base/browser/ui/octiconLabel/octiconLabel.ts",
@@ -40,31 +51,76 @@
"./vs/base/browser/ui/scrollbar/scrollbarState.ts",
"./vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts",
"./vs/base/browser/ui/scrollbar/verticalScrollbar.ts",
+ "./vs/base/browser/ui/splitview/panelview.ts",
"./vs/base/browser/ui/splitview/splitview.ts",
+ "./vs/base/browser/ui/tree/abstractTree.ts",
+ "./vs/base/browser/ui/tree/dataTree.ts",
+ "./vs/base/browser/ui/tree/indexTree.ts",
+ "./vs/base/browser/ui/tree/indexTreeModel.ts",
+ "./vs/base/browser/ui/tree/objectTree.ts",
+ "./vs/base/browser/ui/tree/objectTreeModel.ts",
"./vs/base/browser/ui/tree/tree.ts",
"./vs/base/browser/ui/widget.ts",
+ "./vs/base/common/json.ts",
+ "./vs/base/common/jsonEdit.ts",
+ "./vs/base/common/jsonFormatter.ts",
+ "./vs/base/common/paths.ts",
+ "./vs/base/common/uriIpc.ts",
+ "./vs/base/node/console.ts",
+ "./vs/base/node/crypto.ts",
"./vs/base/node/decoder.ts",
+ "./vs/base/node/encoding.ts",
+ "./vs/base/node/extfs.ts",
+ "./vs/base/node/flow.ts",
"./vs/base/node/id.ts",
"./vs/base/node/paths.ts",
+ "./vs/base/node/pfs.ts",
"./vs/base/node/ports.ts",
+ "./vs/base/node/processes.ts",
+ "./vs/base/node/proxy.ts",
"./vs/base/node/request.ts",
+ "./vs/base/node/stats.ts",
+ "./vs/base/node/storage.ts",
+ "./vs/base/node/stream.ts",
"./vs/base/parts/contextmenu/common/contextmenu.ts",
"./vs/base/parts/contextmenu/electron-browser/contextmenu.ts",
"./vs/base/parts/contextmenu/electron-main/contextmenu.ts",
+ "./vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts",
+ "./vs/base/parts/ipc/electron-main/ipc.electron-main.ts",
+ "./vs/base/parts/ipc/node/ipc.cp.ts",
+ "./vs/base/parts/ipc/node/ipc.electron.ts",
+ "./vs/base/parts/ipc/node/ipc.net.ts",
"./vs/base/parts/ipc/node/ipc.ts",
+ "./vs/base/parts/ipc/test/node/testApp.ts",
"./vs/base/parts/ipc/test/node/testService.ts",
"./vs/base/parts/quickopen/common/quickOpen.ts",
+ "./vs/base/test/browser/ui/grid/util.ts",
+ "./vs/base/test/common/json.test.ts",
+ "./vs/base/test/common/jsonEdit.test.ts",
+ "./vs/base/test/common/jsonFormatter.test.ts",
+ "./vs/base/test/common/paths.test.ts",
"./vs/base/test/common/utils.ts",
+ "./vs/base/test/node/processes/fixtures/fork.ts",
+ "./vs/base/test/node/processes/fixtures/fork_large.ts",
"./vs/base/test/node/uri.test.perf.ts",
+ "./vs/base/test/node/utils.ts",
"./vs/base/worker/defaultWorkerFactory.ts",
"./vs/base/worker/workerMain.ts",
"./vs/code/code.main.ts",
"./vs/code/electron-browser/issue/issueReporterModel.ts",
"./vs/code/electron-browser/issue/issueReporterPage.ts",
"./vs/code/electron-browser/issue/issueReporterUtil.ts",
+ "./vs/code/electron-browser/sharedProcess/contrib/contributions.ts",
+ "./vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts",
+ "./vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner.ts",
+ "./vs/code/electron-main/auth.ts",
"./vs/code/electron-main/keyboard.ts",
+ "./vs/code/electron-main/sharedProcess.ts",
"./vs/code/electron-main/theme.ts",
+ "./vs/code/node/paths.ts",
"./vs/code/node/shellEnv.ts",
+ "./vs/code/node/wait.ts",
+ "./vs/code/node/windowsFinder.ts",
"./vs/editor/browser/config/charWidthReader.ts",
"./vs/editor/browser/config/configuration.ts",
"./vs/editor/browser/config/elementSizeObserver.ts",
@@ -199,6 +255,7 @@
"./vs/editor/common/services/resourceConfigurationImpl.ts",
"./vs/editor/common/services/webWorker.ts",
"./vs/editor/common/standalone/standaloneBase.ts",
+ "./vs/editor/common/standalone/standaloneEnums.ts",
"./vs/editor/common/view/editorColorRegistry.ts",
"./vs/editor/common/view/minimapCharRenderer.ts",
"./vs/editor/common/view/overviewZoneManager.ts",
@@ -226,13 +283,18 @@
"./vs/editor/contrib/caretOperations/transpose.ts",
"./vs/editor/contrib/clipboard/clipboard.ts",
"./vs/editor/contrib/codeAction/codeAction.ts",
+ "./vs/editor/contrib/codeAction/codeActionModel.ts",
"./vs/editor/contrib/codeAction/codeActionTrigger.ts",
+ "./vs/editor/contrib/codeAction/lightBulbWidget.ts",
+ "./vs/editor/contrib/codelens/codelens.ts",
"./vs/editor/contrib/colorPicker/color.ts",
+ "./vs/editor/contrib/colorPicker/colorDetector.ts",
"./vs/editor/contrib/colorPicker/colorPickerModel.ts",
"./vs/editor/contrib/comment/blockCommentCommand.ts",
"./vs/editor/contrib/comment/comment.ts",
"./vs/editor/contrib/comment/lineCommentCommand.ts",
"./vs/editor/contrib/cursorUndo/cursorUndo.ts",
+ "./vs/editor/contrib/dnd/dnd.ts",
"./vs/editor/contrib/dnd/dragAndDropCommand.ts",
"./vs/editor/contrib/find/findDecorations.ts",
"./vs/editor/contrib/find/findModel.ts",
@@ -256,20 +318,27 @@
"./vs/editor/contrib/fontZoom/fontZoom.ts",
"./vs/editor/contrib/goToDefinition/clickLinkGesture.ts",
"./vs/editor/contrib/goToDefinition/goToDefinition.ts",
+ "./vs/editor/contrib/gotoError/gotoErrorWidget.ts",
"./vs/editor/contrib/hover/getHover.ts",
"./vs/editor/contrib/hover/hoverOperation.ts",
"./vs/editor/contrib/hover/hoverWidgets.ts",
+ "./vs/editor/contrib/hover/modesGlyphHover.ts",
"./vs/editor/contrib/inPlaceReplace/inPlaceReplaceCommand.ts",
"./vs/editor/contrib/indentation/indentUtils.ts",
"./vs/editor/contrib/linesOperations/copyLinesCommand.ts",
"./vs/editor/contrib/linesOperations/deleteLinesCommand.ts",
+ "./vs/editor/contrib/linesOperations/moveLinesCommand.ts",
"./vs/editor/contrib/linesOperations/sortLinesCommand.ts",
"./vs/editor/contrib/links/getLinks.ts",
"./vs/editor/contrib/links/links.ts",
+ "./vs/editor/contrib/markdown/markdownRenderer.ts",
"./vs/editor/contrib/message/messageController.ts",
"./vs/editor/contrib/parameterHints/provideSignatureHelp.ts",
"./vs/editor/contrib/quickOpen/quickOpen.ts",
"./vs/editor/contrib/referenceSearch/referencesModel.ts",
+ "./vs/editor/contrib/rename/rename.ts",
+ "./vs/editor/contrib/rename/renameInputField.ts",
+ "./vs/editor/contrib/smartSelect/tokenSelectionSupport.ts",
"./vs/editor/contrib/smartSelect/tokenTree.ts",
"./vs/editor/contrib/snippet/snippetParser.ts",
"./vs/editor/contrib/suggest/suggest.ts",
@@ -277,8 +346,10 @@
"./vs/editor/contrib/suggest/wordDistance.ts",
"./vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.ts",
"./vs/editor/contrib/wordHighlighter/wordHighlighter.ts",
+ "./vs/editor/contrib/wordOperations/test/wordTestUtils.ts",
"./vs/editor/contrib/wordOperations/wordOperations.ts",
"./vs/editor/contrib/wordPartOperations/wordPartOperations.ts",
+ "./vs/editor/contrib/zoneWidget/zoneWidget.ts",
"./vs/editor/editor.worker.ts",
"./vs/editor/standalone/browser/colorizer.ts",
"./vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts",
@@ -293,6 +364,8 @@
"./vs/editor/standalone/common/themes.ts",
"./vs/editor/test/browser/controller/imeTester.ts",
"./vs/editor/test/browser/editorTestServices.ts",
+ "./vs/editor/test/browser/testCodeEditor.ts",
+ "./vs/editor/test/browser/testCommand.ts",
"./vs/editor/test/browser/view/minimapFontCreator.ts",
"./vs/editor/test/common/commentMode.ts",
"./vs/editor/test/common/core/viewLineToken.ts",
@@ -300,7 +373,12 @@
"./vs/editor/test/common/mocks/mockMode.ts",
"./vs/editor/test/common/mocks/testConfiguration.ts",
"./vs/editor/test/common/model/benchmark/benchmarkUtils.ts",
+ "./vs/editor/test/common/model/benchmark/entry.ts",
+ "./vs/editor/test/common/model/benchmark/modelbuilder.benchmark.ts",
+ "./vs/editor/test/common/model/benchmark/operations.benchmark.ts",
+ "./vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts",
"./vs/editor/test/common/model/editableTextModelTestUtils.ts",
+ "./vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils.ts",
"./vs/editor/test/common/modes/supports/javascriptOnEnterRules.ts",
"./vs/editor/test/common/modesTestUtils.ts",
"./vs/editor/test/common/view/minimapCharRendererFactory.ts",
@@ -309,16 +387,24 @@
"./vs/nls.d.ts",
"./vs/nls.mock.ts",
"./vs/platform/actions/common/actions.ts",
+ "./vs/platform/actions/common/menu.ts",
+ "./vs/platform/actions/common/menuService.ts",
"./vs/platform/backup/common/backup.ts",
"./vs/platform/broadcast/electron-browser/broadcastService.ts",
"./vs/platform/clipboard/common/clipboardService.ts",
"./vs/platform/clipboard/electron-browser/clipboardService.ts",
"./vs/platform/commands/common/commands.ts",
"./vs/platform/configuration/common/configuration.ts",
+ "./vs/platform/configuration/common/configurationModels.ts",
"./vs/platform/configuration/common/configurationRegistry.ts",
"./vs/platform/contextkey/browser/contextKeyService.ts",
"./vs/platform/contextkey/common/contextkey.ts",
+ "./vs/platform/dialogs/common/dialogs.ts",
+ "./vs/platform/dialogs/node/dialogIpc.ts",
+ "./vs/platform/dialogs/node/dialogService.ts",
"./vs/platform/download/common/download.ts",
+ "./vs/platform/download/node/downloadService.ts",
+ "./vs/platform/driver/node/driver.ts",
"./vs/platform/editor/common/editor.ts",
"./vs/platform/environment/common/environment.ts",
"./vs/platform/environment/node/argv.ts",
@@ -329,11 +415,14 @@
"./vs/platform/extensionManagement/node/extensionLifecycle.ts",
"./vs/platform/extensionManagement/node/extensionManagementIpc.ts",
"./vs/platform/extensionManagement/node/extensionManagementUtil.ts",
+ "./vs/platform/extensionManagement/node/extensionsManifestCache.ts",
"./vs/platform/extensions/common/extensionHost.ts",
"./vs/platform/extensions/common/extensions.ts",
"./vs/platform/extensions/node/extensionValidator.ts",
"./vs/platform/files/common/files.ts",
"./vs/platform/files/node/files.ts",
+ "./vs/platform/history/common/history.ts",
+ "./vs/platform/history/electron-main/historyMainService.ts",
"./vs/platform/instantiation/common/descriptors.ts",
"./vs/platform/instantiation/common/extensions.ts",
"./vs/platform/instantiation/common/graph.ts",
@@ -344,6 +433,7 @@
"./vs/platform/integrity/common/integrity.ts",
"./vs/platform/integrity/node/integrityServiceImpl.ts",
"./vs/platform/issue/common/issue.ts",
+ "./vs/platform/issue/node/issueIpc.ts",
"./vs/platform/jsonschemas/common/jsonContributionRegistry.ts",
"./vs/platform/keybinding/common/abstractKeybindingService.ts",
"./vs/platform/keybinding/common/keybinding.ts",
@@ -355,12 +445,18 @@
"./vs/platform/label/common/label.ts",
"./vs/platform/label/electron-browser/label.contribution.ts",
"./vs/platform/lifecycle/common/lifecycle.ts",
+ "./vs/platform/lifecycle/electron-browser/lifecycleService.ts",
+ "./vs/platform/lifecycle/electron-main/lifecycleMain.ts",
"./vs/platform/localizations/common/localizations.ts",
+ "./vs/platform/localizations/node/localizationsIpc.ts",
"./vs/platform/log/common/bufferLog.ts",
"./vs/platform/log/common/log.ts",
+ "./vs/platform/log/node/logIpc.ts",
"./vs/platform/log/node/spdlogService.ts",
+ "./vs/platform/markers/common/markerService.ts",
"./vs/platform/markers/common/markers.ts",
"./vs/platform/menubar/common/menubar.ts",
+ "./vs/platform/menubar/node/menubarIpc.ts",
"./vs/platform/node/minimalTranslations.ts",
"./vs/platform/node/package.ts",
"./vs/platform/node/product.ts",
@@ -372,33 +468,64 @@
"./vs/platform/quickOpen/common/quickOpen.ts",
"./vs/platform/quickinput/common/quickInput.ts",
"./vs/platform/registry/common/platform.ts",
+ "./vs/platform/request/electron-browser/requestService.ts",
+ "./vs/platform/request/electron-main/requestService.ts",
"./vs/platform/request/node/request.ts",
+ "./vs/platform/request/node/requestService.ts",
+ "./vs/platform/search/common/replace.ts",
"./vs/platform/search/common/search.ts",
+ "./vs/platform/search/test/common/replace.test.ts",
"./vs/platform/state/common/state.ts",
"./vs/platform/statusbar/common/statusbar.ts",
"./vs/platform/storage/common/storage.ts",
+ "./vs/platform/storage/common/storageLegacyService.ts",
"./vs/platform/telemetry/browser/errorTelemetry.ts",
"./vs/platform/telemetry/common/telemetry.ts",
"./vs/platform/telemetry/common/telemetryService.ts",
"./vs/platform/telemetry/common/telemetryUtils.ts",
+ "./vs/platform/telemetry/node/commonProperties.ts",
+ "./vs/platform/telemetry/node/telemetryIpc.ts",
"./vs/platform/telemetry/node/telemetryNodeUtils.ts",
"./vs/platform/theme/common/colorRegistry.ts",
"./vs/platform/theme/common/styler.ts",
"./vs/platform/theme/common/themeService.ts",
"./vs/platform/theme/test/common/testThemeService.ts",
"./vs/platform/update/common/update.ts",
+ "./vs/platform/update/electron-main/abstractUpdateService.ts",
+ "./vs/platform/update/electron-main/updateService.darwin.ts",
+ "./vs/platform/update/electron-main/updateService.linux.ts",
"./vs/platform/update/node/update.config.contribution.ts",
+ "./vs/platform/update/node/updateIpc.ts",
"./vs/platform/url/common/url.ts",
"./vs/platform/url/common/urlService.ts",
+ "./vs/platform/url/electron-main/electronUrlListener.ts",
+ "./vs/platform/url/node/urlIpc.ts",
+ "./vs/platform/widget/common/contextScopedWidget.ts",
+ "./vs/platform/windows/common/windows.ts",
+ "./vs/platform/windows/electron-browser/windowService.ts",
+ "./vs/platform/windows/electron-main/windows.ts",
+ "./vs/platform/windows/node/windowsIpc.ts",
"./vs/platform/workbench/common/contextkeys.ts",
"./vs/platform/workspace/common/workspace.ts",
"./vs/platform/workspace/test/common/testWorkspace.ts",
"./vs/platform/workspaces/common/workspaces.ts",
+ "./vs/platform/workspaces/electron-main/workspacesMainService.ts",
"./vs/platform/workspaces/node/workspaces.ts",
+ "./vs/platform/workspaces/node/workspacesIpc.ts",
"./vs/vscode.d.ts",
"./vs/vscode.proposed.d.ts",
+ "./vs/workbench/api/node/extHostExtensionActivator.ts",
"./vs/workbench/api/shared/tasks.ts",
+ "./vs/workbench/browser/actions/toggleActivityBarVisibility.ts",
+ "./vs/workbench/browser/actions/toggleCenteredLayout.ts",
+ "./vs/workbench/browser/actions/toggleSidebarPosition.ts",
+ "./vs/workbench/browser/actions/toggleSidebarVisibility.ts",
+ "./vs/workbench/browser/actions/toggleStatusbarVisibility.ts",
+ "./vs/workbench/browser/actions/toggleTabsVisibility.ts",
+ "./vs/workbench/browser/actions/toggleZenMode.ts",
"./vs/workbench/browser/part.ts",
+ "./vs/workbench/browser/parts/editor/editorWidgets.ts",
+ "./vs/workbench/browser/parts/notifications/notificationsAlerts.ts",
"./vs/workbench/browser/parts/quickinput/quickInputUtils.ts",
"./vs/workbench/browser/parts/quickopen/quickopen.ts",
"./vs/workbench/browser/parts/statusbar/statusbar.ts",
@@ -409,47 +536,81 @@
"./vs/workbench/common/contributions.ts",
"./vs/workbench/common/extensionHostProtocol.ts",
"./vs/workbench/common/memento.ts",
+ "./vs/workbench/common/notifications.ts",
"./vs/workbench/common/panel.ts",
"./vs/workbench/common/resources.ts",
"./vs/workbench/common/theme.ts",
"./vs/workbench/common/viewlet.ts",
"./vs/workbench/common/views.ts",
+ "./vs/workbench/parts/cli/electron-browser/cli.contribution.ts",
"./vs/workbench/parts/codeEditor/browser/menuPreventer.ts",
"./vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts",
"./vs/workbench/parts/codeEditor/electron-browser/accessibility.ts",
"./vs/workbench/parts/codeEditor/electron-browser/largeFileOptimizations.ts",
"./vs/workbench/parts/codeEditor/electron-browser/selectionClipboard.ts",
+ "./vs/workbench/parts/codeEditor/electron-browser/toggleMinimap.ts",
+ "./vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.ts",
+ "./vs/workbench/parts/codeEditor/electron-browser/toggleRenderControlCharacter.ts",
+ "./vs/workbench/parts/codeEditor/electron-browser/toggleRenderWhitespace.ts",
"./vs/workbench/parts/codeEditor/electron-browser/toggleWordWrap.ts",
"./vs/workbench/parts/comments/common/commentModel.ts",
"./vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts",
+ "./vs/workbench/parts/comments/electron-browser/commentService.ts",
"./vs/workbench/parts/emmet/browser/actions/showEmmetCommands.ts",
"./vs/workbench/parts/emmet/browser/emmet.browser.contribution.ts",
+ "./vs/workbench/parts/emmet/electron-browser/actions/expandAbbreviation.ts",
+ "./vs/workbench/parts/emmet/electron-browser/emmet.contribution.ts",
+ "./vs/workbench/parts/emmet/electron-browser/emmetActions.ts",
+ "./vs/workbench/parts/emmet/test/electron-browser/emmetAction.test.ts",
"./vs/workbench/parts/execution/common/execution.ts",
+ "./vs/workbench/parts/execution/electron-browser/terminal.ts",
"./vs/workbench/parts/extensions/common/extensionQuery.ts",
"./vs/workbench/parts/extensions/common/extensions.ts",
"./vs/workbench/parts/extensions/common/extensionsFileTemplate.ts",
+ "./vs/workbench/parts/extensions/electron-browser/extensionsActivationProgress.ts",
+ "./vs/workbench/parts/extensions/electron-browser/extensionsUtils.ts",
"./vs/workbench/parts/logs/common/logConstants.ts",
+ "./vs/workbench/parts/logs/electron-browser/logs.contribution.ts",
+ "./vs/workbench/parts/logs/electron-browser/logsActions.ts",
"./vs/workbench/parts/markers/electron-browser/constants.ts",
"./vs/workbench/parts/markers/electron-browser/markers.ts",
+ "./vs/workbench/parts/markers/electron-browser/markersFileDecorations.ts",
"./vs/workbench/parts/markers/electron-browser/markersFilterOptions.ts",
"./vs/workbench/parts/markers/electron-browser/markersModel.ts",
"./vs/workbench/parts/markers/electron-browser/messages.ts",
"./vs/workbench/parts/outline/electron-browser/outline.ts",
"./vs/workbench/parts/output/common/output.ts",
+ "./vs/workbench/parts/output/common/outputLinkComputer.ts",
+ "./vs/workbench/parts/output/common/outputLinkProvider.ts",
"./vs/workbench/parts/performance/electron-browser/stats.ts",
"./vs/workbench/parts/preferences/common/smartSnippetInserter.ts",
"./vs/workbench/parts/scm/common/scm.ts",
"./vs/workbench/parts/scm/electron-browser/scmUtil.ts",
"./vs/workbench/parts/search/common/constants.ts",
+ "./vs/workbench/parts/search/common/queryBuilder.ts",
"./vs/workbench/parts/surveys/electron-browser/nps.contribution.ts",
+ "./vs/workbench/parts/tasks/common/problemCollectors.ts",
+ "./vs/workbench/parts/tasks/common/problemMatcher.ts",
+ "./vs/workbench/parts/tasks/common/taskDefinitionRegistry.ts",
+ "./vs/workbench/parts/tasks/common/taskService.ts",
+ "./vs/workbench/parts/tasks/common/taskSystem.ts",
"./vs/workbench/parts/tasks/common/taskTemplates.ts",
+ "./vs/workbench/parts/tasks/common/tasks.ts",
+ "./vs/workbench/parts/tasks/electron-browser/jsonSchemaCommon.ts",
+ "./vs/workbench/parts/tasks/node/tasks.ts",
+ "./vs/workbench/parts/terminal/browser/terminalTab.ts",
"./vs/workbench/parts/terminal/browser/terminalWidgetManager.ts",
"./vs/workbench/parts/terminal/common/terminal.ts",
"./vs/workbench/parts/terminal/common/terminalColorRegistry.ts",
"./vs/workbench/parts/terminal/common/terminalCommands.ts",
"./vs/workbench/parts/terminal/common/terminalMenu.ts",
+ "./vs/workbench/parts/terminal/common/terminalService.ts",
+ "./vs/workbench/parts/terminal/node/terminal.ts",
"./vs/workbench/parts/terminal/node/terminalCommandTracker.ts",
"./vs/workbench/parts/terminal/node/terminalEnvironment.ts",
+ "./vs/workbench/parts/terminal/node/terminalProcess.ts",
+ "./vs/workbench/parts/terminal/node/terminalProcessExtHostProxy.ts",
+ "./vs/workbench/parts/url/electron-browser/url.contribution.ts",
"./vs/workbench/parts/webview/electron-browser/webviewProtocols.ts",
"./vs/workbench/parts/welcome/gettingStarted/electron-browser/gettingStarted.ts",
"./vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts",
@@ -458,19 +619,30 @@
"./vs/workbench/services/backup/common/backup.ts",
"./vs/workbench/services/commands/common/commandService.ts",
"./vs/workbench/services/configuration/common/configuration.ts",
+ "./vs/workbench/services/configuration/common/configurationExtensionPoint.ts",
+ "./vs/workbench/services/configuration/common/configurationModels.ts",
"./vs/workbench/services/configuration/common/jsonEditing.ts",
"./vs/workbench/services/configurationResolver/common/configurationResolver.ts",
+ "./vs/workbench/services/crashReporter/electron-browser/crashReporterService.ts",
"./vs/workbench/services/decorations/browser/decorations.ts",
"./vs/workbench/services/extensions/common/extensions.ts",
"./vs/workbench/services/extensions/common/extensionsRegistry.ts",
+ "./vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts",
"./vs/workbench/services/extensions/node/extensionDescriptionRegistry.ts",
"./vs/workbench/services/extensions/node/extensionManagementServerService.ts",
"./vs/workbench/services/extensions/node/lazyPromise.ts",
"./vs/workbench/services/extensions/node/proxyIdentifier.ts",
"./vs/workbench/services/extensions/node/rpcProtocol.ts",
+ "./vs/workbench/services/files/electron-browser/encoding.ts",
"./vs/workbench/services/files/node/watcher/common.ts",
"./vs/workbench/services/files/node/watcher/nsfw/watcher.ts",
+ "./vs/workbench/services/files/node/watcher/nsfw/watcherIpc.ts",
+ "./vs/workbench/services/files/node/watcher/nsfw/watcherService.ts",
"./vs/workbench/services/files/node/watcher/unix/watcher.ts",
+ "./vs/workbench/services/files/node/watcher/unix/watcherIpc.ts",
+ "./vs/workbench/services/files/node/watcher/unix/watcherService.ts",
+ "./vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts",
+ "./vs/workbench/services/files/node/watcher/win32/watcherService.ts",
"./vs/workbench/services/files/test/electron-browser/utils.ts",
"./vs/workbench/services/hash/common/hashService.ts",
"./vs/workbench/services/hash/node/hashService.ts",
@@ -482,13 +654,23 @@
"./vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts",
"./vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts",
"./vs/workbench/services/mode/common/workbenchModeService.ts",
+ "./vs/workbench/services/notification/common/notificationService.ts",
"./vs/workbench/services/panel/common/panelService.ts",
- "./vs/workbench/services/progress/common/progress.ts",
+ "./vs/workbench/services/part/common/partService.ts",
"./vs/workbench/services/scm/common/scm.ts",
"./vs/workbench/services/scm/common/scmService.ts",
+ "./vs/workbench/services/search/common/searchHelpers.ts",
+ "./vs/workbench/services/search/node/fileSearchManager.ts",
+ "./vs/workbench/services/search/node/legacy/search.ts",
+ "./vs/workbench/services/search/node/ripgrepSearchProvider.ts",
+ "./vs/workbench/services/search/node/ripgrepSearchUtils.ts",
+ "./vs/workbench/services/search/node/ripgrepTextSearchEngine.ts",
"./vs/workbench/services/search/node/search.ts",
"./vs/workbench/services/search/node/searchHistoryService.ts",
"./vs/workbench/services/search/node/searchIpc.ts",
+ "./vs/workbench/services/search/node/textSearchManager.ts",
+ "./vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts",
+ "./vs/workbench/services/search/test/node/textSearchManager.test.ts",
"./vs/workbench/services/textMate/electron-browser/TMGrammars.ts",
"./vs/workbench/services/textMate/electron-browser/TMHelper.ts",
"./vs/workbench/services/textMate/electron-browser/textMateService.ts",
@@ -502,6 +684,7 @@
"./vs/workbench/test/electron-browser/api/mock.ts"
],
"exclude": [
- "./typings/require-monaco.d.ts"
+ "./typings/require-monaco.d.ts",
+ "../node_modules/windows-process-tree/typings/windows-process-tree.d.ts"
]
}
\ No newline at end of file
diff --git a/src/typings/node-pty.d.ts b/src/typings/node-pty.d.ts
index e3ee561a60c..2fdb9dff99a 100644
--- a/src/typings/node-pty.d.ts
+++ b/src/typings/node-pty.d.ts
@@ -11,7 +11,7 @@ declare module 'node-pty' {
* escaped properly.
* @param options The options of the terminal.
* @see CommandLineToArgvW https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx
- * @see Parsing C++ Comamnd-Line Arguments https://msdn.microsoft.com/en-us/library/17w5ykft.aspx
+ * @see Parsing C++ Command-Line Arguments https://msdn.microsoft.com/en-us/library/17w5ykft.aspx
* @see GetCommandLine https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx
*/
export function spawn(file: string, args: string[] | string, options: IPtyForkOptions): IPty;
@@ -58,7 +58,7 @@ declare module 'node-pty' {
/**
* Resizes the dimensions of the pty.
- * @param columns THe number of columns to use.
+ * @param columns The number of columns to use.
* @param rows The number of rows to use.
*/
resize(columns: number, rows: number): void;
diff --git a/src/typings/vscode-proxy-agent.d.ts b/src/typings/vscode-proxy-agent.d.ts
new file mode 100644
index 00000000000..a997fa97801
--- /dev/null
+++ b/src/typings/vscode-proxy-agent.d.ts
@@ -0,0 +1,6 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+declare module 'vscode-proxy-agent';
diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts
index 33c9f3d7b4d..08d9b2b8ec8 100644
--- a/src/vs/base/browser/browser.ts
+++ b/src/vs/base/browser/browser.ts
@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as Platform from 'vs/base/common/platform';
-import { Event, Emitter } from 'vs/base/common/event';
+import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
+import * as platform from 'vs/base/common/platform';
class WindowManager {
@@ -74,11 +74,11 @@ class WindowManager {
}
// --- Accessibility
- private _accessibilitySupport = Platform.AccessibilitySupport.Unknown;
+ private _accessibilitySupport = platform.AccessibilitySupport.Unknown;
private readonly _onDidChangeAccessibilitySupport: Emitter = new Emitter();
public readonly onDidChangeAccessibilitySupport: Event = this._onDidChangeAccessibilitySupport.event;
- public setAccessibilitySupport(accessibilitySupport: Platform.AccessibilitySupport): void {
+ public setAccessibilitySupport(accessibilitySupport: platform.AccessibilitySupport): void {
if (this._accessibilitySupport === accessibilitySupport) {
return;
}
@@ -86,7 +86,7 @@ class WindowManager {
this._accessibilitySupport = accessibilitySupport;
this._onDidChangeAccessibilitySupport.fire();
}
- public getAccessibilitySupport(): Platform.AccessibilitySupport {
+ public getAccessibilitySupport(): platform.AccessibilitySupport {
return this._accessibilitySupport;
}
}
@@ -126,10 +126,10 @@ export function isFullscreen(): boolean {
}
export const onDidChangeFullscreen = WindowManager.INSTANCE.onDidChangeFullscreen;
-export function setAccessibilitySupport(accessibilitySupport: Platform.AccessibilitySupport): void {
+export function setAccessibilitySupport(accessibilitySupport: platform.AccessibilitySupport): void {
WindowManager.INSTANCE.setAccessibilitySupport(accessibilitySupport);
}
-export function getAccessibilitySupport(): Platform.AccessibilitySupport {
+export function getAccessibilitySupport(): platform.AccessibilitySupport {
return WindowManager.INSTANCE.getAccessibilitySupport();
}
export function onDidChangeAccessibilitySupport(callback: () => void): IDisposable {
diff --git a/src/vs/base/browser/contextmenu.ts b/src/vs/base/browser/contextmenu.ts
index 92e1e6d8533..5b7891e108a 100644
--- a/src/vs/base/browser/contextmenu.ts
+++ b/src/vs/base/browser/contextmenu.ts
@@ -23,7 +23,7 @@ export class ContextSubMenu extends SubmenuAction {
export interface IContextMenuDelegate {
getAnchor(): HTMLElement | { x: number; y: number; width?: number; height?: number; };
- getActions(): Thenable<(IAction | ContextSubMenu)[]>;
+ getActions(): (IAction | ContextSubMenu)[];
getActionItem?(action: IAction): IActionItem;
getActionsContext?(event?: IContextMenuEvent): any;
getKeyBinding?(action: IAction): ResolvedKeybinding;
diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts
index 3ad8440553d..d1628b42d91 100644
--- a/src/vs/base/browser/dom.ts
+++ b/src/vs/base/browser/dom.ts
@@ -3,16 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as platform from 'vs/base/common/platform';
-import { TimeoutTimer } from 'vs/base/common/async';
-import { onUnexpectedError } from 'vs/base/common/errors';
-import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import * as browser from 'vs/base/browser/browser';
+import { domEvent } from 'vs/base/browser/event';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
+import { TimeoutTimer } from 'vs/base/common/async';
import { CharCode } from 'vs/base/common/charCode';
-import { Event, Emitter } from 'vs/base/common/event';
-import { domEvent } from 'vs/base/browser/event';
+import { onUnexpectedError } from 'vs/base/common/errors';
+import { Emitter, Event } from 'vs/base/common/event';
+import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
+import * as platform from 'vs/base/common/platform';
export function clearNode(node: HTMLElement): void {
while (node.firstChild) {
@@ -560,7 +560,7 @@ export class Dimension {
this.height = height;
}
- static equals(a: Dimension, b: Dimension): boolean {
+ static equals(a: Dimension | undefined, b: Dimension | undefined): boolean {
if (a === b) {
return true;
}
diff --git a/src/vs/base/browser/globalMouseMoveMonitor.ts b/src/vs/base/browser/globalMouseMoveMonitor.ts
index ed365f47786..50b25d776e6 100644
--- a/src/vs/base/browser/globalMouseMoveMonitor.ts
+++ b/src/vs/base/browser/globalMouseMoveMonitor.ts
@@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import * as dom from 'vs/base/browser/dom';
import { IframeUtils } from 'vs/base/browser/iframe';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
+import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
export interface IStandardMouseMoveEventData {
leftButton: boolean;
diff --git a/src/vs/base/browser/keyboardEvent.ts b/src/vs/base/browser/keyboardEvent.ts
index 87f6635f6ec..0d7fcc3f1ff 100644
--- a/src/vs/base/browser/keyboardEvent.ts
+++ b/src/vs/base/browser/keyboardEvent.ts
@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
+import * as browser from 'vs/base/browser/browser';
import { KeyCode, KeyCodeUtils, KeyMod, SimpleKeybinding } from 'vs/base/common/keyCodes';
import * as platform from 'vs/base/common/platform';
-import * as browser from 'vs/base/browser/browser';
let KEY_CODE_MAP: { [keyCode: number]: KeyCode } = new Array(230);
let INVERSE_KEY_CODE_MAP: KeyCode[] = new Array(KeyCode.MAX_VALUE);
diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts
index 3b943702023..ab32deee7f2 100644
--- a/src/vs/base/browser/mouseEvent.ts
+++ b/src/vs/base/browser/mouseEvent.ts
@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as platform from 'vs/base/common/platform';
import * as browser from 'vs/base/browser/browser';
import { IframeUtils } from 'vs/base/browser/iframe';
+import * as platform from 'vs/base/common/platform';
export interface IMouseEvent {
readonly browserEvent: MouseEvent;
diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
index 4a2b7396a9e..42f43d27322 100644
--- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
+++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
@@ -118,8 +118,8 @@ export class BreadcrumbsWidget {
this._freeNodes.length = 0;
}
- layout(dim: dom.Dimension): void {
- if (dom.Dimension.equals(dim, this._dimension)) {
+ layout(dim: dom.Dimension | undefined): void {
+ if (dim && dom.Dimension.equals(dim, this._dimension)) {
return;
}
if (this._pendingLayout) {
@@ -146,9 +146,11 @@ export class BreadcrumbsWidget {
private _updateScrollbar(): IDisposable {
return dom.measure(() => {
- this._scrollable.setRevealOnScroll(false);
- this._scrollable.scanDomNode();
- this._scrollable.setRevealOnScroll(true);
+ dom.measure(() => { // double RAF
+ this._scrollable.setRevealOnScroll(false);
+ this._scrollable.scanDomNode();
+ this._scrollable.setRevealOnScroll(true);
+ });
});
}
@@ -277,8 +279,8 @@ export class BreadcrumbsWidget {
}
setItems(items: BreadcrumbsItem[]): void {
- let prefix: number;
- let removed: BreadcrumbsItem[];
+ let prefix: number | undefined;
+ let removed: BreadcrumbsItem[] = [];
try {
prefix = commonPrefixLength(this._items, items, (a, b) => a.equals(b));
removed = this._items.splice(prefix, this._items.length - prefix, ...items.slice(prefix));
@@ -302,17 +304,21 @@ export class BreadcrumbsWidget {
// case a: more nodes -> remove them
while (start < this._nodes.length) {
const free = this._nodes.pop();
- this._freeNodes.push(free);
- free.remove();
+ if (free) {
+ this._freeNodes.push(free);
+ free.remove();
+ }
}
// case b: more items -> render them
for (; start < this._items.length; start++) {
let item = this._items[start];
let node = this._freeNodes.length > 0 ? this._freeNodes.pop() : document.createElement('div');
- this._renderItem(item, node);
- this._domNode.appendChild(node);
- this._nodes.push(node);
+ if (node) {
+ this._renderItem(item, node);
+ this._domNode.appendChild(node);
+ this._nodes.push(node);
+ }
}
this.layout(undefined);
}
@@ -327,7 +333,7 @@ export class BreadcrumbsWidget {
}
private _onClick(event: IMouseEvent): void {
- for (let el = event.target; el; el = el.parentElement) {
+ for (let el: HTMLElement | null = event.target; el; el = el.parentElement) {
let idx = this._nodes.indexOf(el as any);
if (idx >= 0) {
this._focus(idx, event);
diff --git a/src/vs/base/browser/ui/centered/centeredViewLayout.ts b/src/vs/base/browser/ui/centered/centeredViewLayout.ts
index 03b876df89b..7964af23c07 100644
--- a/src/vs/base/browser/ui/centered/centeredViewLayout.ts
+++ b/src/vs/base/browser/ui/centered/centeredViewLayout.ts
@@ -50,15 +50,15 @@ export interface ICenteredViewStyles extends ISplitViewStyles {
export class CenteredViewLayout {
- private splitView: SplitView;
+ private splitView?: SplitView;
private width: number = 0;
private height: number = 0;
private style: ICenteredViewStyles;
private didLayout = false;
- private emptyViews: ISplitViewView[];
+ private emptyViews: ISplitViewView[] | undefined;
private splitViewDisposables: IDisposable[] = [];
- constructor(private container: HTMLElement, private view: IView, public readonly state: CenteredViewState = GOLDEN_RATIO) {
+ constructor(private container: HTMLElement, private view: IView, public readonly state: CenteredViewState = { leftMarginRatio: GOLDEN_RATIO.leftMarginRatio, rightMarginRatio: GOLDEN_RATIO.rightMarginRatio }) {
this.container.appendChild(this.view.element);
// Make sure to hide the split view overflow like sashes #52892
this.container.style.overflow = 'hidden';
@@ -84,6 +84,9 @@ export class CenteredViewLayout {
}
private resizeMargins(): void {
+ if (!this.splitView) {
+ return;
+ }
this.splitView.resizeView(0, this.state.leftMarginRatio * this.width);
this.splitView.resizeView(2, this.state.rightMarginRatio * this.width);
}
@@ -94,7 +97,7 @@ export class CenteredViewLayout {
styles(style: ICenteredViewStyles): void {
this.style = style;
- if (this.splitView) {
+ if (this.splitView && this.emptyViews) {
this.splitView.style(this.style);
this.emptyViews[0].element.style.backgroundColor = this.style.background.toString();
this.emptyViews[1].element.style.backgroundColor = this.style.background.toString();
@@ -115,8 +118,10 @@ export class CenteredViewLayout {
});
this.splitViewDisposables.push(this.splitView.onDidSashChange(() => {
- this.state.leftMarginRatio = this.splitView.getViewSize(0) / this.width;
- this.state.rightMarginRatio = this.splitView.getViewSize(2) / this.width;
+ if (this.splitView) {
+ this.state.leftMarginRatio = this.splitView.getViewSize(0) / this.width;
+ this.state.rightMarginRatio = this.splitView.getViewSize(2) / this.width;
+ }
}));
this.splitViewDisposables.push(this.splitView.onDidSashReset(() => {
this.state.leftMarginRatio = GOLDEN_RATIO.leftMarginRatio;
@@ -130,9 +135,13 @@ export class CenteredViewLayout {
this.splitView.addView(this.emptyViews[0], this.state.leftMarginRatio * this.width, 0);
this.splitView.addView(this.emptyViews[1], this.state.rightMarginRatio * this.width, 2);
} else {
- this.container.removeChild(this.splitView.el);
+ if (this.splitView) {
+ this.container.removeChild(this.splitView.el);
+ }
this.splitViewDisposables = dispose(this.splitViewDisposables);
- this.splitView.dispose();
+ if (this.splitView) {
+ this.splitView.dispose();
+ }
this.splitView = undefined;
this.emptyViews = undefined;
this.container.appendChild(this.view.element);
diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts
index 1c44f12d262..409f3c9497f 100644
--- a/src/vs/base/browser/ui/contextview/contextview.ts
+++ b/src/vs/base/browser/ui/contextview/contextview.ts
@@ -212,8 +212,8 @@ export class ContextView extends Disposable {
around = {
top: realAnchor.y,
left: realAnchor.x,
- width: realAnchor.width || 0,
- height: realAnchor.height || 0
+ width: realAnchor.width || 1,
+ height: realAnchor.height || 2
};
}
diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts
index dc82ccd5b90..53f814bbf75 100644
--- a/src/vs/base/browser/ui/dropdown/dropdown.ts
+++ b/src/vs/base/browser/ui/dropdown/dropdown.ts
@@ -243,7 +243,7 @@ export class DropdownMenu extends BaseDropdown {
this._contextMenuProvider.showContextMenu({
getAnchor: () => this.element,
- getActions: () => Promise.resolve(this.actions),
+ getActions: () => this.actions,
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
getActionItem: action => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null,
getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : null,
@@ -332,4 +332,4 @@ export class DropdownMenuActionItem extends BaseActionItem {
this.dropdownMenu.show();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts
index f09231bc05f..336329a05e2 100644
--- a/src/vs/base/browser/ui/grid/grid.ts
+++ b/src/vs/base/browser/ui/grid/grid.ts
@@ -139,10 +139,15 @@ export function getRelativeLocation(rootOrientation: Orientation, location: numb
function indexInParent(element: HTMLElement): number {
const parentElement = element.parentElement;
+
+ if (!parentElement) {
+ throw new Error('Invalid grid element');
+ }
+
let el = parentElement.firstElementChild;
let index = 0;
- while (el !== element && el !== parentElement.lastElementChild) {
+ while (el !== element && el !== parentElement.lastElementChild && el) {
el = el.nextElementSibling;
index++;
}
@@ -157,12 +162,18 @@ function indexInParent(element: HTMLElement): number {
* This will break as soon as DOM structures of the Splitview or Gridview change.
*/
function getGridLocation(element: HTMLElement): number[] {
- if (/\bmonaco-grid-view\b/.test(element.parentElement.className)) {
+ const parentElement = element.parentElement;
+
+ if (!parentElement) {
+ throw new Error('Invalid grid element');
+ }
+
+ if (/\bmonaco-grid-view\b/.test(parentElement.className)) {
return [];
}
- const index = indexInParent(element.parentElement);
- const ancestor = element.parentElement.parentElement.parentElement.parentElement;
+ const index = indexInParent(parentElement);
+ const ancestor = parentElement.parentElement!.parentElement!.parentElement!;
return [...getGridLocation(ancestor), index];
}
@@ -193,7 +204,7 @@ export class Grid implements IDisposable {
get minimumHeight(): number { return this.gridview.minimumHeight; }
get maximumWidth(): number { return this.gridview.maximumWidth; }
get maximumHeight(): number { return this.gridview.maximumHeight; }
- get onDidChange(): Event<{ width: number; height: number; }> { return this.gridview.onDidChange; }
+ get onDidChange(): Event<{ width: number; height: number; } | undefined> { return this.gridview.onDidChange; }
get element(): HTMLElement { return this.gridview.element; }
@@ -368,7 +379,7 @@ export interface ISerializableView extends IView {
}
export interface IViewDeserializer {
- fromJSON(json: object): T;
+ fromJSON(json: object | null): T;
}
interface InitialLayoutContext {
@@ -379,7 +390,7 @@ interface InitialLayoutContext {
export interface ISerializedLeafNode {
type: 'leaf';
- data: object;
+ data: object | null;
size: number;
}
@@ -415,18 +426,15 @@ export class SerializableGrid extends Grid {
throw new Error('Invalid JSON');
}
- const type = json.type;
- const data = json.data;
-
- if (type === 'branch') {
- if (!Array.isArray(data)) {
+ if (json.type === 'branch') {
+ if (!Array.isArray(json.data)) {
throw new Error('Invalid JSON: \'data\' property of branch must be an array.');
}
const children: GridNode[] = [];
let offset = 0;
- for (const child of data) {
+ for (const child of json.data) {
if (typeof child.size !== 'number') {
throw new Error('Invalid JSON: \'size\' property of node must be a number.');
}
@@ -441,8 +449,8 @@ export class SerializableGrid extends Grid {
return { children, box };
- } else if (type === 'leaf') {
- const view = deserializer.fromJSON(data) as T;
+ } else if (json.type === 'leaf') {
+ const view = deserializer.fromJSON(json.data) as T;
return { view, box };
}
@@ -527,13 +535,13 @@ export class SerializableGrid extends Grid {
const firstLeaves = node.children.map(c => SerializableGrid.getFirstLeaf(c));
for (let i = 1; i < firstLeaves.length; i++) {
- const size = orientation === Orientation.VERTICAL ? firstLeaves[i].box.height : firstLeaves[i].box.width;
- this.addView(firstLeaves[i].view, size, referenceView, direction);
- referenceView = firstLeaves[i].view;
+ const size = orientation === Orientation.VERTICAL ? firstLeaves[i]!.box.height : firstLeaves[i]!.box.width;
+ this.addView(firstLeaves[i]!.view, size, referenceView, direction);
+ referenceView = firstLeaves[i]!.view;
}
for (let i = 0; i < node.children.length; i++) {
- this.restoreViews(firstLeaves[i].view, orthogonal(orientation), node.children[i]);
+ this.restoreViews(firstLeaves[i]!.view, orthogonal(orientation), node.children[i]);
}
}
@@ -611,10 +619,10 @@ function getDimensions(node: ISerializedNode, orientation: Orientation): { width
if (orientation === Orientation.VERTICAL) {
const width = node.size || (childrenDimensions.length === 0 ? undefined : Math.max(...childrenDimensions.map(d => d.width || 0)));
- const height = childrenDimensions.length === 0 ? undefined : childrenDimensions.reduce((r, d) => r + d.height, 0);
+ const height = childrenDimensions.length === 0 ? undefined : childrenDimensions.reduce((r, d) => r + (d.height || 0), 0);
return { width, height };
} else {
- const width = childrenDimensions.length === 0 ? undefined : childrenDimensions.reduce((r, d) => r + d.width, 0);
+ const width = childrenDimensions.length === 0 ? undefined : childrenDimensions.reduce((r, d) => r + (d.width || 0), 0);
const height = node.size || (childrenDimensions.length === 0 ? undefined : Math.max(...childrenDimensions.map(d => d.height || 0)));
return { width, height };
}
diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts
index 531575bb123..f0ac2e0984d 100644
--- a/src/vs/base/browser/ui/grid/gridview.ts
+++ b/src/vs/base/browser/ui/grid/gridview.ts
@@ -6,13 +6,13 @@
import 'vs/css!./gridview';
import { Event, anyEvent, Emitter, mapEvent, Relay } from 'vs/base/common/event';
import { Orientation, Sash } from 'vs/base/browser/ui/sash/sash';
-import { SplitView, IView as ISplitView, Sizing, ISplitViewStyles } from 'vs/base/browser/ui/splitview/splitview';
+import { SplitView, IView as ISplitView, Sizing, LayoutPriority, ISplitViewStyles } from 'vs/base/browser/ui/splitview/splitview';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { $ } from 'vs/base/browser/dom';
import { tail2 as tail } from 'vs/base/common/arrays';
import { Color } from 'vs/base/common/color';
-export { Sizing } from 'vs/base/browser/ui/splitview/splitview';
+export { Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview';
export { Orientation } from 'vs/base/browser/ui/sash/sash';
export interface IView {
@@ -22,6 +22,8 @@ export interface IView {
readonly minimumHeight: number;
readonly maximumHeight: number;
readonly onDidChange: Event<{ width: number; height: number; }>;
+ readonly priority?: LayoutPriority;
+ readonly snapSize?: number;
layout(width: number, height: number): void;
}
@@ -60,6 +62,7 @@ const defaultStyles: IGridViewStyles = {
export interface IGridViewOptions {
styles?: IGridViewStyles;
+ proportionalLayout?: boolean; // default true
}
class BranchNode implements ISplitView, IDisposable {
@@ -135,6 +138,7 @@ class BranchNode implements ISplitView, IDisposable {
constructor(
readonly orientation: Orientation,
styles: IGridViewStyles,
+ readonly proportionalLayout: boolean,
size: number = 0,
orthogonalSize: number = 0
) {
@@ -450,6 +454,14 @@ class LeafNode implements ISplitView, IDisposable {
return this.orientation === Orientation.HORIZONTAL ? this.maximumHeight : this.maximumWidth;
}
+ get priority(): LayoutPriority | undefined {
+ return this.view.priority;
+ }
+
+ get snapSize(): number | undefined {
+ return this.view.snapSize;
+ }
+
get minimumOrthogonalSize(): number {
return this.orientation === Orientation.HORIZONTAL ? this.minimumWidth : this.minimumHeight;
}
@@ -483,7 +495,7 @@ type Node = BranchNode | LeafNode;
function flipNode(node: T, size: number, orthogonalSize: number): T {
if (node instanceof BranchNode) {
- const result = new BranchNode(orthogonal(node.orientation), node.styles, size, orthogonalSize);
+ const result = new BranchNode(orthogonal(node.orientation), node.styles, node.proportionalLayout, size, orthogonalSize);
let totalSize = 0;
@@ -512,6 +524,7 @@ export class GridView implements IDisposable {
readonly element: HTMLElement;
private styles: IGridViewStyles;
+ private proportionalLayout: boolean;
private _root: BranchNode;
private onDidSashResetRelay = new Relay();
@@ -560,13 +573,14 @@ export class GridView implements IDisposable {
get maximumWidth(): number { return this.root.maximumHeight; }
get maximumHeight(): number { return this.root.maximumHeight; }
- private _onDidChange = new Relay<{ width: number; height: number; }>();
+ private _onDidChange = new Relay<{ width: number; height: number; } | undefined>();
readonly onDidChange = this._onDidChange.event;
constructor(options: IGridViewOptions = {}) {
this.element = $('.monaco-grid-view');
this.styles = options.styles || defaultStyles;
- this.root = new BranchNode(Orientation.VERTICAL, this.styles);
+ this.proportionalLayout = typeof options.proportionalLayout !== 'undefined' ? !!options.proportionalLayout : true;
+ this.root = new BranchNode(Orientation.VERTICAL, this.styles, this.proportionalLayout);
}
style(styles: IGridViewStyles): void {
@@ -596,7 +610,7 @@ export class GridView implements IDisposable {
const [, parentIndex] = tail(rest);
grandParent.removeChild(parentIndex);
- const newParent = new BranchNode(parent.orientation, this.styles, parent.size, parent.orthogonalSize);
+ const newParent = new BranchNode(parent.orientation, this.styles, this.proportionalLayout, parent.size, parent.orthogonalSize);
grandParent.addChild(newParent, parent.size, parentIndex);
newParent.orthogonalLayout(parent.orthogonalSize);
diff --git a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts
index 58e154c751e..a8e3d6c3200 100644
--- a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts
+++ b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts
@@ -21,7 +21,7 @@ export class HighlightedLabel implements IDisposable {
private highlights: IHighlight[];
private didEverRender: boolean;
- constructor(container: HTMLElement) {
+ constructor(container: HTMLElement, private supportOcticons: boolean) {
this.domNode = document.createElement('span');
this.domNode.className = 'monaco-highlighted-label';
this.didEverRender = false;
@@ -68,19 +68,22 @@ export class HighlightedLabel implements IDisposable {
}
if (pos < highlight.start) {
htmlContent.push('');
- htmlContent.push(renderOcticons(this.text.substring(pos, highlight.start)));
+ const substring = this.text.substring(pos, highlight.start);
+ htmlContent.push(this.supportOcticons ? renderOcticons(substring) : substring);
htmlContent.push('');
pos = highlight.end;
}
htmlContent.push('');
- htmlContent.push(renderOcticons(this.text.substring(highlight.start, highlight.end)));
+ const substring = this.text.substring(highlight.start, highlight.end);
+ htmlContent.push(this.supportOcticons ? renderOcticons(substring) : substring);
htmlContent.push('');
pos = highlight.end;
}
if (pos < this.text.length) {
htmlContent.push('');
- htmlContent.push(renderOcticons(this.text.substring(pos)));
+ const substring = this.text.substring(pos);
+ htmlContent.push(this.supportOcticons ? renderOcticons(substring) : substring);
htmlContent.push('');
}
@@ -90,8 +93,8 @@ export class HighlightedLabel implements IDisposable {
}
dispose() {
- this.text = null;
- this.highlights = null;
+ this.text = null!; // StrictNullOverride: nulling out ok in dispose
+ this.highlights = null!; // StrictNullOverride: nulling out ok in dispose
}
static escapeNewLines(text: string, highlights: IHighlight[]): string {
diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts
index a2af0b7e72b..752437df1ba 100644
--- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts
+++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts
@@ -12,6 +12,7 @@ import { IDisposable, combinedDisposable, Disposable } from 'vs/base/common/life
export interface IIconLabelCreationOptions {
supportHighlights?: boolean;
supportDescriptionHighlights?: boolean;
+ donotSupportOcticons?: boolean;
}
export interface IIconLabelValueOptions {
@@ -99,13 +100,13 @@ export class IconLabel extends Disposable {
this.labelDescriptionContainer = this._register(new FastLabelNode(dom.append(this.domNode.element, dom.$('.monaco-icon-label-description-container'))));
if (options && options.supportHighlights) {
- this.labelNode = this._register(new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('a.label-name'))));
+ this.labelNode = this._register(new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('a.label-name')), !options.donotSupportOcticons));
} else {
this.labelNode = this._register(new FastLabelNode(dom.append(this.labelDescriptionContainer.element, dom.$('a.label-name'))));
}
if (options && options.supportDescriptionHighlights) {
- this.descriptionNodeFactory = () => this._register(new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('span.label-description'))));
+ this.descriptionNodeFactory = () => this._register(new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('span.label-description')), !options.donotSupportOcticons));
} else {
this.descriptionNodeFactory = () => this._register(new FastLabelNode(dom.append(this.labelDescriptionContainer.element, dom.$('span.label-description'))));
}
@@ -137,7 +138,7 @@ export class IconLabel extends Disposable {
this.domNode.title = options && options.title ? options.title : '';
if (this.labelNode instanceof HighlightedLabel) {
- this.labelNode.set(label || '', options ? options.matches : void 0, void 0, options && options.labelEscapeNewLines);
+ this.labelNode.set(label || '', options ? options.matches : void 0, options && options.title ? options.title : void 0, options && options.labelEscapeNewLines);
} else {
this.labelNode.textContent = label || '';
}
diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts
index b9815b6ef0b..cb0be292bff 100644
--- a/src/vs/base/browser/ui/list/list.ts
+++ b/src/vs/base/browser/ui/list/list.ts
@@ -44,7 +44,7 @@ export interface IListGestureEvent {
export interface IListContextMenuEvent {
browserEvent: UIEvent;
- element: T;
+ element: T | undefined;
index: number;
- anchor: HTMLElement | { x: number; y: number; };
+ anchor: HTMLElement | { x: number; y: number; } | undefined;
}
diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts
index 1317c4f5b43..d4491cecefd 100644
--- a/src/vs/base/browser/ui/list/listPaging.ts
+++ b/src/vs/base/browser/ui/list/listPaging.ts
@@ -17,8 +17,8 @@ export interface IPagedRenderer extends IListRenderer {
- data: T;
- disposable: IDisposable;
+ data?: T;
+ disposable?: IDisposable;
}
class PagedRenderer implements IListRenderer> {
@@ -36,7 +36,13 @@ class PagedRenderer implements IListRenderer): void {
- data.disposable.dispose();
+ if (data.disposable) {
+ data.disposable.dispose();
+ }
+
+ if (!data.data) {
+ return;
+ }
const model = this.modelProvider();
@@ -49,7 +55,7 @@ class PagedRenderer implements IListRenderer cts.cancel() };
this.renderer.renderPlaceholder(index, data.data);
- promise.then(entry => this.renderer.renderElement(entry, index, data.data));
+ promise.then(entry => this.renderer.renderElement(entry, index, data.data!));
}
disposeElement(): void {
@@ -57,10 +63,14 @@ class PagedRenderer implements IListRenderer): void {
- data.disposable.dispose();
- data.disposable = null;
- this.renderer.disposeTemplate(data.data);
- data.data = null;
+ if (data.disposable) {
+ data.disposable.dispose();
+ data.disposable = undefined;
+ }
+ if (data.data) {
+ this.renderer.disposeTemplate(data.data);
+ data.data = undefined;
+ }
}
}
@@ -124,7 +134,7 @@ export class PagedList implements IDisposable {
}
get onContextMenu(): Event> {
- return mapEvent(this.list.onContextMenu, ({ element, index, anchor, browserEvent }) => ({ element: this._model.get(element), index, anchor, browserEvent }));
+ return mapEvent(this.list.onContextMenu, ({ element, index, anchor, browserEvent }) => ({ element: this._model.get(element!), index, anchor, browserEvent }));
}
get model(): IPagedModel {
diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts
index 61b6d478b26..a045bf269a8 100644
--- a/src/vs/base/browser/ui/list/listView.ts
+++ b/src/vs/base/browser/ui/list/listView.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { getOrDefault } from 'vs/base/common/objects';
+import { getOrDefault2 } from 'vs/base/common/objects';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
import * as DOM from 'vs/base/browser/dom';
@@ -39,7 +39,7 @@ interface IItem {
element: T;
size: number;
templateId: string;
- row: IRow;
+ row: IRow | null;
}
export interface IListViewOptions {
@@ -48,7 +48,7 @@ export interface IListViewOptions {
setRowLineHeight?: boolean;
}
-const DefaultOptions: IListViewOptions = {
+const DefaultOptions = {
useShadows: true,
verticalScrollMode: ScrollbarVisibility.Auto,
setRowLineHeight: true
@@ -105,8 +105,8 @@ export class ListView implements ISpliceable, IDisposable {
this.scrollableElement = new ScrollableElement(this.rowsContainer, {
alwaysConsumeMouseWheel: true,
horizontal: ScrollbarVisibility.Hidden,
- vertical: getOrDefault(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode),
- useShadows: getOrDefault(options, o => o.useShadows, DefaultOptions.useShadows)
+ vertical: getOrDefault2(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode),
+ useShadows: getOrDefault2(options, o => o.useShadows, DefaultOptions.useShadows)
});
this._domNode.appendChild(this.scrollableElement.getDomNode());
@@ -125,7 +125,7 @@ export class ListView implements ISpliceable, IDisposable {
const onDragOver = mapEvent(domEvent(this.rowsContainer, 'dragover'), e => new DragMouseEvent(e));
onDragOver(this.onDragOver, this, this.disposables);
- this.setRowLineHeight = getOrDefault(options, o => o.setRowLineHeight, DefaultOptions.setRowLineHeight);
+ this.setRowLineHeight = getOrDefault2(options, o => o.setRowLineHeight, DefaultOptions.setRowLineHeight);
this.layout();
}
@@ -169,8 +169,18 @@ export class ListView implements ISpliceable, IDisposable {
row: null
}));
- this.rangeMap.splice(start, deleteCount, ...inserted);
- const deleted = this.items.splice(start, deleteCount, ...inserted);
+ let deleted: IItem[];
+
+ // TODO@joao: improve this optimization to catch even more cases
+ if (start === 0 && deleteCount >= this.items.length) {
+ this.rangeMap = new RangeMap();
+ this.rangeMap.splice(0, 0, inserted);
+ this.items = inserted;
+ deleted = [];
+ } else {
+ this.rangeMap.splice(start, deleteCount, inserted);
+ deleted = this.items.splice(start, deleteCount, ...inserted);
+ }
const delta = elements.length - deleteCount;
const renderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
@@ -232,7 +242,7 @@ export class ListView implements ISpliceable, IDisposable {
return this.items[index].element;
}
- domElement(index: number): HTMLElement {
+ domElement(index: number): HTMLElement | null {
const row = this.items[index].row;
return row && row.domNode;
}
@@ -302,18 +312,18 @@ export class ListView implements ISpliceable, IDisposable {
item.row = this.cache.alloc(item.templateId);
}
- if (!item.row.domNode.parentElement) {
+ if (!item.row.domNode!.parentElement) {
if (beforeElement) {
- this.rowsContainer.insertBefore(item.row.domNode, beforeElement);
+ this.rowsContainer.insertBefore(item.row.domNode!, beforeElement);
} else {
- this.rowsContainer.appendChild(item.row.domNode);
+ this.rowsContainer.appendChild(item.row.domNode!);
}
}
- item.row.domNode.style.height = `${item.size}px`;
+ item.row.domNode!.style.height = `${item.size}px`;
if (this.setRowLineHeight) {
- item.row.domNode.style.lineHeight = `${item.size}px`;
+ item.row.domNode!.style.lineHeight = `${item.size}px`;
}
this.updateItemInDOM(item, index);
@@ -323,11 +333,11 @@ export class ListView implements ISpliceable, IDisposable {
}
private updateItemInDOM(item: IItem, index: number): void {
- item.row.domNode.style.top = `${this.elementTop(index)}px`;
- item.row.domNode.setAttribute('data-index', `${index}`);
- item.row.domNode.setAttribute('data-last-element', index === this.length - 1 ? 'true' : 'false');
- item.row.domNode.setAttribute('aria-setsize', `${this.length}`);
- item.row.domNode.setAttribute('aria-posinset', `${index + 1}`);
+ item.row!.domNode!.style.top = `${this.elementTop(index)}px`;
+ item.row!.domNode!.setAttribute('data-index', `${index}`);
+ item.row!.domNode!.setAttribute('data-last-element', index === this.length - 1 ? 'true' : 'false');
+ item.row!.domNode!.setAttribute('aria-setsize', `${this.length}`);
+ item.row!.domNode!.setAttribute('aria-posinset', `${index + 1}`);
}
private removeItemFromDOM(index: number): void {
@@ -335,10 +345,10 @@ export class ListView implements ISpliceable, IDisposable {
const renderer = this.renderers.get(item.templateId);
if (renderer.disposeElement) {
- renderer.disposeElement(item.element, index, item.row.templateData);
+ renderer.disposeElement(item.element, index, item.row!.templateData);
}
- this.cache.release(item.row);
+ this.cache.release(item.row!);
item.row = null;
}
@@ -378,21 +388,21 @@ export class ListView implements ISpliceable, IDisposable {
@memoize get onTap(): Event> { return filterEvent(mapEvent(domEvent(this.rowsContainer, TouchEventType.Tap), e => this.toGestureEvent(e)), e => e.index >= 0); }
private toMouseEvent(browserEvent: MouseEvent): IListMouseEvent {
- const index = this.getItemIndexFromEventTarget(browserEvent.target);
+ const index = this.getItemIndexFromEventTarget(browserEvent.target || null);
const item = index < 0 ? undefined : this.items[index];
const element = item && item.element;
return { browserEvent, index, element };
}
private toTouchEvent(browserEvent: TouchEvent): IListTouchEvent {
- const index = this.getItemIndexFromEventTarget(browserEvent.target);
+ const index = this.getItemIndexFromEventTarget(browserEvent.target || null);
const item = index < 0 ? undefined : this.items[index];
const element = item && item.element;
return { browserEvent, index, element };
}
private toGestureEvent(browserEvent: GestureEvent): IListGestureEvent {
- const index = this.getItemIndexFromEventTarget(browserEvent.initialTarget);
+ const index = this.getItemIndexFromEventTarget(browserEvent.initialTarget || null);
const item = index < 0 ? undefined : this.items[index];
const element = item && item.element;
return { browserEvent, index, element };
@@ -445,7 +455,7 @@ export class ListView implements ISpliceable, IDisposable {
this.dragAndDropScrollTimeout = window.setTimeout(() => {
this.cancelDragAndDropScrollInterval();
- this.dragAndDropScrollTimeout = null;
+ this.dragAndDropScrollTimeout = -1;
}, 1000);
}
}
@@ -453,7 +463,7 @@ export class ListView implements ISpliceable, IDisposable {
private cancelDragAndDropScrollInterval(): void {
if (this.dragAndDropScrollInterval) {
window.clearInterval(this.dragAndDropScrollInterval);
- this.dragAndDropScrollInterval = null;
+ this.dragAndDropScrollInterval = -1;
}
this.cancelDragAndDropScrollTimeout();
@@ -462,15 +472,16 @@ export class ListView implements ISpliceable, IDisposable {
private cancelDragAndDropScrollTimeout(): void {
if (this.dragAndDropScrollTimeout) {
window.clearTimeout(this.dragAndDropScrollTimeout);
- this.dragAndDropScrollTimeout = null;
+ this.dragAndDropScrollTimeout = -1;
}
}
// Util
- private getItemIndexFromEventTarget(target: EventTarget): number {
- while (target instanceof HTMLElement && target !== this.rowsContainer) {
- const element = target as HTMLElement;
+ private getItemIndexFromEventTarget(target: EventTarget | null): number {
+ let element: HTMLElement | null = target as (HTMLElement | null);
+
+ while (element instanceof HTMLElement && element !== this.rowsContainer) {
const rawIndex = element.getAttribute('data-index');
if (rawIndex) {
@@ -481,7 +492,7 @@ export class ListView implements ISpliceable, IDisposable {
}
}
- target = element.parentElement;
+ element = element.parentElement;
}
return -1;
@@ -522,16 +533,14 @@ export class ListView implements ISpliceable, IDisposable {
if (item.row) {
const renderer = this.renderers.get(item.row.templateId);
renderer.disposeTemplate(item.row.templateData);
- item.row = null;
}
}
- this.items = null;
+ this.items = [];
}
- if (this._domNode && this._domNode.parentElement) {
+ if (this._domNode && this._domNode.parentNode) {
this._domNode.parentNode.removeChild(this._domNode);
- this._domNode = null;
}
this.disposables = dispose(this.disposables);
diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts
index 5754251a97d..84700441bdb 100644
--- a/src/vs/base/browser/ui/list/listWidget.ts
+++ b/src/vs/base/browser/ui/list/listWidget.ts
@@ -25,8 +25,8 @@ import { ISpliceable } from 'vs/base/common/sequence';
import { CombinedSpliceable } from 'vs/base/browser/ui/list/splice';
import { clamp } from 'vs/base/common/numbers';
-export interface IIdentityProvider {
- (element: T): string;
+export interface IIdentityProvider {
+ (element: T): R;
}
interface ITraitChangeEvent {
@@ -180,7 +180,6 @@ class Trait implements ISpliceable, IDisposable {
}
dispose() {
- this.indexes = null;
this._onChange = dispose(this._onChange);
}
}
@@ -188,7 +187,7 @@ class Trait implements ISpliceable, IDisposable {
class FocusTrait extends Trait {
constructor(
- private getDomId: IIdentityProvider
+ private getDomId: IIdentityProvider
) {
super('focused');
}
@@ -224,8 +223,9 @@ class TraitSpliceable implements ISpliceable {
return this.trait.splice(start, deleteCount, elements.map(e => false));
}
- const pastElementsWithTrait = this.trait.get().map(i => this.getId(this.view.element(i)));
- const elementsWithTrait = elements.map(e => pastElementsWithTrait.indexOf(this.getId(e)) > -1);
+ const getId = this.getId;
+ const pastElementsWithTrait = this.trait.get().map(i => getId(this.view.element(i)));
+ const elementsWithTrait = elements.map(e => pastElementsWithTrait.indexOf(getId(e)) > -1);
this.trait.splice(start, deleteCount, elementsWithTrait);
}
@@ -357,6 +357,11 @@ class DOMFocusController implements IDisposable {
}
const focusedDomElement = this.view.domElement(focus[0]);
+
+ if (!focusedDomElement) {
+ return;
+ }
+
const tabIndexElement = focusedDomElement.querySelector('[tabIndex]');
if (!tabIndexElement || !(tabIndexElement instanceof HTMLElement) || tabIndexElement.tabIndex === -1) {
@@ -421,7 +426,7 @@ class MouseController implements IDisposable {
.map(event => {
const index = this.list.getFocus()[0];
const element = this.view.element(index);
- const anchor = this.view.domElement(index);
+ const anchor = this.view.domElement(index) || undefined;
return { index, element, anchor, browserEvent: event.browserEvent };
})
.event;
@@ -436,7 +441,7 @@ class MouseController implements IDisposable {
.map(browserEvent => {
const index = this.list.getFocus()[0];
const element = this.view.element(index);
- const anchor = this.view.domElement(index);
+ const anchor = this.view.domElement(index) || undefined;
return { index, element, anchor, browserEvent };
})
.filter(({ anchor }) => !!anchor)
@@ -751,7 +756,7 @@ function getContiguousRangeContaining(range: number[], value: number): number[]
return [];
}
- const result = [];
+ const result: number[] = [];
let i = index - 1;
while (i >= 0 && range[i] === value - (index - i)) {
result.push(range[i--]);
@@ -771,7 +776,7 @@ function getContiguousRangeContaining(range: number[], value: number): number[]
* betweem them (OR).
*/
function disjunction(one: number[], other: number[]): number[] {
- const result = [];
+ const result: number[] = [];
let i = 0, j = 0;
while (i < one.length || j < other.length) {
@@ -799,7 +804,7 @@ function disjunction(one: number[], other: number[]): number[] {
* complement between them (XOR).
*/
function relativeComplement(one: number[], other: number[]): number[] {
- const result = [];
+ const result: number[] = [];
let i = 0, j = 0;
while (i < one.length || j < other.length) {
@@ -974,10 +979,7 @@ export class List implements ISpliceable, IDisposable {
this.styleElement = DOM.createStyleSheet(this.view.domNode);
- this.styleController = options.styleController;
- if (!this.styleController) {
- this.styleController = new DefaultStyleController(this.styleElement, this.idPrefix);
- }
+ this.styleController = options.styleController || new DefaultStyleController(this.styleElement, this.idPrefix);
this.spliceable = new CombinedSpliceable([
new TraitSpliceable(this.focus, this.view, options.identityProvider),
@@ -987,8 +989,8 @@ export class List implements ISpliceable, IDisposable {
this.disposables = [this.focus, this.selection, this.view, this._onDidDispose];
- this.onDidFocus = mapEvent(domEvent(this.view.domNode, 'focus', true), () => null);
- this.onDidBlur = mapEvent(domEvent(this.view.domNode, 'blur', true), () => null);
+ this.onDidFocus = mapEvent(domEvent(this.view.domNode, 'focus', true), () => null!);
+ this.onDidBlur = mapEvent(domEvent(this.view.domNode, 'blur', true), () => null!);
this.disposables.push(new DOMFocusController(this, this.view));
@@ -1087,7 +1089,7 @@ export class List implements ISpliceable, IDisposable {
if (this.length === 0) { return; }
const focus = this.focus.get();
let index = focus.length > 0 ? focus[0] + n : 0;
- this.setFocus(loop ? [index % this.length] : [Math.min(index, this.length - 1)]);
+ this.setFocus(loop ? [index % this.length] : [Math.min(index, this.length - 1)], browserEvent);
}
focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void {
@@ -1095,7 +1097,7 @@ export class List implements ISpliceable, IDisposable {
const focus = this.focus.get();
let index = focus.length > 0 ? focus[0] - n : 0;
if (loop && index < 0) { index = (this.length + (index % this.length)) % this.length; }
- this.setFocus([Math.max(index, 0)]);
+ this.setFocus([Math.max(index, 0)], browserEvent);
}
focusNextPage(browserEvent?: UIEvent): void {
@@ -1105,14 +1107,14 @@ export class List implements ISpliceable, IDisposable {
const currentlyFocusedElement = this.getFocusedElements()[0];
if (currentlyFocusedElement !== lastPageElement) {
- this.setFocus([lastPageIndex]);
+ this.setFocus([lastPageIndex], browserEvent);
} else {
const previousScrollTop = this.view.getScrollTop();
this.view.setScrollTop(previousScrollTop + this.view.renderHeight - this.view.elementHeight(lastPageIndex));
if (this.view.getScrollTop() !== previousScrollTop) {
// Let the scroll event listener run
- setTimeout(() => this.focusNextPage(), 0);
+ setTimeout(() => this.focusNextPage(browserEvent), 0);
}
}
}
@@ -1131,26 +1133,26 @@ export class List implements ISpliceable, IDisposable {
const currentlyFocusedElement = this.getFocusedElements()[0];
if (currentlyFocusedElement !== firstPageElement) {
- this.setFocus([firstPageIndex]);
+ this.setFocus([firstPageIndex], browserEvent);
} else {
const previousScrollTop = scrollTop;
this.view.setScrollTop(scrollTop - this.view.renderHeight);
if (this.view.getScrollTop() !== previousScrollTop) {
// Let the scroll event listener run
- setTimeout(() => this.focusPreviousPage(), 0);
+ setTimeout(() => this.focusPreviousPage(browserEvent), 0);
}
}
}
focusLast(browserEvent?: UIEvent): void {
if (this.length === 0) { return; }
- this.setFocus([this.length - 1]);
+ this.setFocus([this.length - 1], browserEvent);
}
focusFirst(browserEvent?: UIEvent): void {
if (this.length === 0) { return; }
- this.setFocus([0]);
+ this.setFocus([0], browserEvent);
}
getFocus(): number[] {
diff --git a/src/vs/base/browser/ui/list/rangeMap.ts b/src/vs/base/browser/ui/list/rangeMap.ts
index 3c4d78563b9..45b164c5392 100644
--- a/src/vs/base/browser/ui/list/rangeMap.ts
+++ b/src/vs/base/browser/ui/list/rangeMap.ts
@@ -92,7 +92,7 @@ export class RangeMap {
private groups: IRangedGroup[] = [];
private _size = 0;
- splice(index: number, deleteCount: number, ...items: IItem[]): void {
+ splice(index: number, deleteCount: number, items: IItem[] = []): void {
const diff = items.length - deleteCount;
const before = groupIntersect({ start: 0, end: index }, this.groups);
const after = groupIntersect({ start: index + deleteCount, end: Number.POSITIVE_INFINITY }, this.groups)
@@ -188,6 +188,6 @@ export class RangeMap {
}
dispose() {
- this.groups = null;
+ this.groups = null!; // StrictNullOverride: nulling out ok in dispose
}
}
\ No newline at end of file
diff --git a/src/vs/base/browser/ui/list/rowCache.ts b/src/vs/base/browser/ui/list/rowCache.ts
index 756b1f9a678..b7007c2fc0f 100644
--- a/src/vs/base/browser/ui/list/rowCache.ts
+++ b/src/vs/base/browser/ui/list/rowCache.ts
@@ -8,14 +8,16 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { $, removeClass } from 'vs/base/browser/dom';
export interface IRow {
- domNode: HTMLElement;
+ domNode: HTMLElement | null;
templateId: string;
templateData: any;
}
function removeFromParent(element: HTMLElement): void {
try {
- element.parentElement.removeChild(element);
+ if (element.parentElement) {
+ element.parentElement.removeChild(element);
+ }
} catch (e) {
// this will throw if this happens due to a blur event, nasty business
}
@@ -57,8 +59,10 @@ export class RowCache implements IDisposable {
private releaseRow(row: IRow): void {
const { domNode, templateId } = row;
- removeClass(domNode, 'scrolling');
- removeFromParent(domNode);
+ if (domNode) {
+ removeClass(domNode, 'scrolling');
+ removeFromParent(domNode);
+ }
const cache = this.getTemplateCache(templateId);
cache.push(row);
@@ -95,6 +99,6 @@ export class RowCache implements IDisposable {
dispose(): void {
this.garbageCollect();
this.cache.clear();
- this.renderers = null;
+ this.renderers = null!; // StrictNullOverride: nulling out ok in dispose
}
}
\ No newline at end of file
diff --git a/src/vs/base/browser/ui/menu/menu.css b/src/vs/base/browser/ui/menu/menu.css
index 63c1860664d..ecbb197f55c 100644
--- a/src/vs/base/browser/ui/menu/menu.css
+++ b/src/vs/base/browser/ui/menu/menu.css
@@ -55,8 +55,8 @@
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
height: 100%;
- -webkit-mask: url('submenu.svg') no-repeat 90% 50%/14px 14px;
- mask: url('submenu.svg') no-repeat 90% 50%/14px 14px;
+ -webkit-mask: url('submenu.svg') no-repeat 90% 50%/13px 13px;
+ mask: url('submenu.svg') no-repeat 90% 50%/13px 13px;
}
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .keybinding,
@@ -106,7 +106,7 @@
/* Context Menu */
.context-view.monaco-menu-container {
- font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif;
outline: 0;
border: none;
-webkit-animation: fadeIn 0.083s linear;
diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts
index 1cc3f375b27..75554c14fd5 100644
--- a/src/vs/base/browser/ui/menu/menu.ts
+++ b/src/vs/base/browser/ui/menu/menu.ts
@@ -191,7 +191,7 @@ export class Menu extends ActionBar {
if (options.enableMnemonics) {
const mnemonic = menuActionItem.getMnemonic();
if (mnemonic && menuActionItem.isEnabled()) {
- let actionItems = [];
+ let actionItems: MenuActionItem[] = [];
if (this.mnemonics.has(mnemonic)) {
actionItems = this.mnemonics.get(mnemonic);
}
@@ -217,7 +217,7 @@ export class Menu extends ActionBar {
if (options.enableMnemonics) {
const mnemonic = menuActionItem.getMnemonic();
if (mnemonic && menuActionItem.isEnabled()) {
- let actionItems = [];
+ let actionItems: MenuActionItem[] = [];
if (this.mnemonics.has(mnemonic)) {
actionItems = this.mnemonics.get(mnemonic);
}
diff --git a/src/vs/base/browser/ui/menu/submenu.svg b/src/vs/base/browser/ui/menu/submenu.svg
index 8eeac7b7b66..98a0aa5924a 100644
--- a/src/vs/base/browser/ui/menu/submenu.svg
+++ b/src/vs/base/browser/ui/menu/submenu.svg
@@ -1,3 +1,3 @@
diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts
index bcee192ab85..c9d3aa68d0e 100644
--- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts
+++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts
@@ -3,16 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as Platform from 'vs/base/common/platform';
-import * as DomUtils from 'vs/base/browser/dom';
-import { IMouseEvent, StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
-import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
-import { Widget } from 'vs/base/browser/ui/widget';
+import * as dom from 'vs/base/browser/dom';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
-import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
+import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
+import { IMouseEvent, StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { ScrollbarArrow, ScrollbarArrowOptions } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
+import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
import { ScrollbarVisibilityController } from 'vs/base/browser/ui/scrollbar/scrollbarVisibilityController';
-import { Scrollable, ScrollbarVisibility, INewScrollPosition } from 'vs/base/common/scrollable';
+import { Widget } from 'vs/base/browser/ui/widget';
+import * as platform from 'vs/base/common/platform';
+import { INewScrollPosition, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
/**
* The orthogonal distance to the slider at which dragging "resets". This implements "snapping"
@@ -197,7 +197,7 @@ export abstract class AbstractScrollbar extends Widget {
offsetX = e.browserEvent.offsetX;
offsetY = e.browserEvent.offsetY;
} else {
- const domNodePosition = DomUtils.getDomNodePagePosition(this.domNode.domNode);
+ const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);
offsetX = e.posx - domNodePosition.left;
offsetY = e.posy - domNodePosition.top;
}
@@ -220,7 +220,7 @@ export abstract class AbstractScrollbar extends Widget {
const mouseOrthogonalPosition = this._sliderOrthogonalMousePosition(mouseMoveData);
const mouseOrthogonalDelta = Math.abs(mouseOrthogonalPosition - initialMouseOrthogonalPosition);
- if (Platform.isWindows && mouseOrthogonalDelta > MOUSE_DRAG_RESET_DISTANCE) {
+ if (platform.isWindows && mouseOrthogonalDelta > MOUSE_DRAG_RESET_DISTANCE) {
// The mouse has wondered away from the scrollbar => reset dragging
this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());
return;
diff --git a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts
index ce87928154d..f49deda9ec7 100644
--- a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts
+++ b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts
@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { AbstractScrollbar, ScrollbarHost, ISimplifiedMouseEvent } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import { StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
+import { AbstractScrollbar, ISimplifiedMouseEvent, ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import { ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
-import { Scrollable, ScrollEvent, ScrollbarVisibility, INewScrollPosition } from 'vs/base/common/scrollable';
-import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
import { ARROW_IMG_SIZE } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
+import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
+import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
export class HorizontalScrollbar extends AbstractScrollbar {
diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts
index 69bdfbca025..ea42ceac6e8 100644
--- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts
+++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts
@@ -4,20 +4,19 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/scrollbars';
-
-import * as DomUtils from 'vs/base/browser/dom';
-import * as Platform from 'vs/base/common/platform';
-import { StandardMouseWheelEvent, IMouseEvent } from 'vs/base/browser/mouseEvent';
+import * as dom from 'vs/base/browser/dom';
+import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
+import { IMouseEvent, StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
+import { ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import { HorizontalScrollbar } from 'vs/base/browser/ui/scrollbar/horizontalScrollbar';
+import { ScrollableElementChangeOptions, ScrollableElementCreationOptions, ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import { VerticalScrollbar } from 'vs/base/browser/ui/scrollbar/verticalScrollbar';
-import { ScrollableElementCreationOptions, ScrollableElementChangeOptions, ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
-import { IDisposable, dispose } from 'vs/base/common/lifecycle';
-import { Scrollable, ScrollEvent, ScrollbarVisibility, INewScrollDimensions, IScrollDimensions, INewScrollPosition, IScrollPosition } from 'vs/base/common/scrollable';
import { Widget } from 'vs/base/browser/ui/widget';
import { TimeoutTimer } from 'vs/base/common/async';
-import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
-import { ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
-import { Event, Emitter } from 'vs/base/common/event';
+import { Emitter, Event } from 'vs/base/common/event';
+import { IDisposable, dispose } from 'vs/base/common/lifecycle';
+import * as platform from 'vs/base/common/platform';
+import { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
const HIDE_TIMEOUT = 500;
const SCROLL_WHEEL_SENSITIVITY = 50;
@@ -267,7 +266,7 @@ export abstract class AbstractScrollableElement extends Widget {
public updateClassName(newClassName: string): void {
this._options.className = newClassName;
// Defaults are different on Macs
- if (Platform.isMacintosh) {
+ if (platform.isMacintosh) {
this._options.className += ' mac';
}
this._domNode.className = 'monaco-scrollable-element ' + this._options.className;
@@ -313,8 +312,8 @@ export abstract class AbstractScrollableElement extends Widget {
this._onMouseWheel(e);
};
- this._mouseWheelToDispose.push(DomUtils.addDisposableListener(this._listenOnDomNode, 'mousewheel', onMouseWheel));
- this._mouseWheelToDispose.push(DomUtils.addDisposableListener(this._listenOnDomNode, 'DOMMouseScroll', onMouseWheel));
+ this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, 'mousewheel', onMouseWheel));
+ this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, 'DOMMouseScroll', onMouseWheel));
}
}
@@ -337,7 +336,7 @@ export abstract class AbstractScrollableElement extends Widget {
// Convert vertical scrolling to horizontal if shift is held, this
// is handled at a higher level on Mac
- const shiftConvert = !Platform.isMacintosh && e.browserEvent && e.browserEvent.shiftKey;
+ const shiftConvert = !platform.isMacintosh && e.browserEvent && e.browserEvent.shiftKey;
if ((this._options.scrollYToX || shiftConvert) && !deltaX) {
deltaX = deltaY;
deltaY = 0;
@@ -478,7 +477,7 @@ export class ScrollableElement extends AbstractScrollableElement {
constructor(element: HTMLElement, options: ScrollableElementCreationOptions) {
options = options || {};
options.mouseWheelSmoothScroll = false;
- const scrollable = new Scrollable(0, (callback) => DomUtils.scheduleAtNextAnimationFrame(callback));
+ const scrollable = new Scrollable(0, (callback) => dom.scheduleAtNextAnimationFrame(callback));
super(element, options, scrollable);
this._register(scrollable);
}
@@ -563,7 +562,7 @@ function resolveOptions(opts: ScrollableElementCreationOptions): ScrollableEleme
result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);
// Defaults are different on Macs
- if (Platform.isMacintosh) {
+ if (platform.isMacintosh) {
result.className += ' mac';
}
diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts b/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts
index b66a7196ab1..b174952d7ae 100644
--- a/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts
+++ b/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts
@@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
+import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { Widget } from 'vs/base/browser/ui/widget';
-import { TimeoutTimer, IntervalTimer } from 'vs/base/common/async';
+import { IntervalTimer, TimeoutTimer } from 'vs/base/common/async';
/**
* The arrow image size.
diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts
index 52a4b60b592..a77792ee223 100644
--- a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts
+++ b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts
@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { Disposable } from 'vs/base/common/lifecycle';
-import { TimeoutTimer } from 'vs/base/common/async';
import { FastDomNode } from 'vs/base/browser/fastDomNode';
+import { TimeoutTimer } from 'vs/base/common/async';
+import { Disposable } from 'vs/base/common/lifecycle';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
export class ScrollbarVisibilityController extends Disposable {
diff --git a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts
index ab07329614a..77d19898d28 100644
--- a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts
+++ b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts
@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { AbstractScrollbar, ScrollbarHost, ISimplifiedMouseEvent } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import { StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
+import { AbstractScrollbar, ISimplifiedMouseEvent, ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import { ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
-import { Scrollable, ScrollEvent, ScrollbarVisibility, INewScrollPosition } from 'vs/base/common/scrollable';
-import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
import { ARROW_IMG_SIZE } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
+import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
+import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
export class VerticalScrollbar extends AbstractScrollbar {
diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts
index 65a883bcb17..36b40a6995c 100644
--- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts
+++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts
@@ -129,6 +129,13 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate {
- this.selectElement.title = e.target.value;
this.selected = e.target.selectedIndex;
this._onDidSelect.fire({
index: e.target.selectedIndex,
@@ -301,7 +307,6 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate();
readonly onDidChange: Event = this._onDidChange.event;
@@ -131,7 +129,7 @@ export abstract class Panel implements IView {
this._expanded = !!expanded;
this.updateHeader();
- this._onDidChange.fire(expanded ? this.cachedExpandedSize : undefined);
+ this._onDidChange.fire(expanded ? this.expandedSize : undefined);
}
get headerVisible(): boolean {
@@ -192,14 +190,8 @@ export abstract class Panel implements IView {
const headerSize = this.headerVisible ? Panel.HEADER_SIZE : 0;
if (this.isExpanded()) {
- const bodySize = size - headerSize;
-
- if (bodySize !== this.cachedBodySize) {
- this.layoutBody(bodySize);
- this.cachedBodySize = bodySize;
- }
-
- this.cachedExpandedSize = size;
+ this.layoutBody(size - headerSize);
+ this.expandedSize = size;
}
}
@@ -264,7 +256,7 @@ class PanelDraggable extends Disposable {
}
private onDragStart(e: DragEvent): void {
- if (!this.dnd.canDrag(this.panel)) {
+ if (!this.dnd.canDrag(this.panel) || !e.dataTransfer) {
e.preventDefault();
e.stopPropagation();
return;
@@ -272,7 +264,7 @@ class PanelDraggable extends Disposable {
e.dataTransfer.effectAllowed = 'move';
- const dragImage = append(document.body, $('.monaco-panel-drag-image', {}, this.panel.draggableElement.textContent));
+ const dragImage = append(document.body, $('.monaco-panel-drag-image', {}, this.panel.draggableElement.textContent || ''));
e.dataTransfer.setDragImage(dragImage, -10, -10);
setTimeout(() => document.body.removeChild(dragImage), 0);
@@ -371,7 +363,7 @@ interface IPanelItem {
export class PanelView extends Disposable {
- private dnd: IPanelDndController | null;
+ private dnd: IPanelDndController | undefined;
private dndContext: IDndContext = { draggable: null };
private el: HTMLElement;
private panelItems: IPanelItem[] = [];
diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts
index bdef6277a62..0de80a6c763 100644
--- a/src/vs/base/browser/ui/splitview/splitview.ts
+++ b/src/vs/base/browser/ui/splitview/splitview.ts
@@ -29,6 +29,16 @@ export interface ISplitViewOptions {
orthogonalStartSash?: Sash;
orthogonalEndSash?: Sash;
inverseAltBehavior?: boolean;
+ proportionalLayout?: boolean; // default true
+}
+
+/**
+ * Only used when `proportionalLayout` is false.
+ */
+export const enum LayoutPriority {
+ Normal,
+ Low,
+ High
}
export interface IView {
@@ -36,6 +46,8 @@ export interface IView {
readonly minimumSize: number;
readonly maximumSize: number;
readonly onDidChange: Event;
+ readonly priority?: LayoutPriority;
+ readonly snapSize?: number;
layout(size: number, orientation: Orientation): void;
}
@@ -87,7 +99,6 @@ export namespace Sizing {
export class SplitView extends Disposable {
readonly orientation: Orientation;
- // TODO@Joao have the same pattern as grid here
readonly el: HTMLElement;
private sashContainer: HTMLElement;
private viewContainer: HTMLElement;
@@ -99,6 +110,7 @@ export class SplitView extends Disposable {
private sashDragState: ISashDragState;
private state: State = State.Idle;
private inverseAltBehavior: boolean;
+ private proportionalLayout: boolean;
private _onDidSashChange = this._register(new Emitter());
readonly onDidSashChange = this._onDidSashChange.event;
@@ -147,6 +159,7 @@ export class SplitView extends Disposable {
this.orientation = types.isUndefined(options.orientation) ? Orientation.VERTICAL : options.orientation;
this.inverseAltBehavior = !!options.inverseAltBehavior;
+ this.proportionalLayout = types.isUndefined(options.proportionalLayout) ? true : !!options.proportionalLayout;
this.el = document.createElement('div');
dom.addClass(this.el, 'monaco-split-view2');
@@ -317,8 +330,10 @@ export class SplitView extends Disposable {
private relayout(lowPriorityIndex?: number, highPriorityIndex?: number): void {
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
+ const lowPriorityIndexes = typeof lowPriorityIndex === 'number' ? [lowPriorityIndex] : undefined;
+ const highPriorityIndexes = typeof highPriorityIndex === 'number' ? [highPriorityIndex] : undefined;
- this.resize(this.viewItems.length - 1, this.size - contentSize, undefined, lowPriorityIndex, highPriorityIndex);
+ this.resize(this.viewItems.length - 1, this.size - contentSize, undefined, lowPriorityIndexes, highPriorityIndexes);
this.distributeEmptySpace();
this.layoutViews();
this.saveProportions();
@@ -329,11 +344,15 @@ export class SplitView extends Disposable {
this.size = size;
if (!this.proportions) {
- this.resize(this.viewItems.length - 1, size - previousSize);
+ const indexes = range(this.viewItems.length);
+ const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.Low);
+ const highPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.High);
+
+ this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
} else {
for (let i = 0; i < this.viewItems.length; i++) {
const item = this.viewItems[i];
- item.size = clamp(Math.round(this.proportions[i] * size), item.view.minimumSize, item.view.maximumSize);
+ item.size = SplitView.clamp(item, Math.round(this.proportions[i] * size));
}
}
@@ -342,7 +361,7 @@ export class SplitView extends Disposable {
}
private saveProportions(): void {
- if (this.contentSize > 0) {
+ if (this.proportionalLayout && this.contentSize > 0) {
this.proportions = this.viewItems.map(i => i.size / this.contentSize);
}
}
@@ -425,7 +444,7 @@ export class SplitView extends Disposable {
}
size = typeof size === 'number' ? size : item.size;
- size = clamp(size, item.view.minimumSize, item.view.maximumSize);
+ size = SplitView.clamp(item, size);
if (this.inverseAltBehavior && index > 0) {
// In this case, we want the view to grow or shrink both sides equally
@@ -500,8 +519,8 @@ export class SplitView extends Disposable {
index: number,
delta: number,
sizes = this.viewItems.map(i => i.size),
- lowPriorityIndex?: number,
- highPriorityIndex?: number,
+ lowPriorityIndexes?: number[],
+ highPriorityIndexes?: number[],
overloadMinDelta: number = Number.NEGATIVE_INFINITY,
overloadMaxDelta: number = Number.POSITIVE_INFINITY
): number {
@@ -512,14 +531,18 @@ export class SplitView extends Disposable {
const upIndexes = range(index, -1);
const downIndexes = range(index + 1, this.viewItems.length);
- if (typeof highPriorityIndex === 'number') {
- pushToStart(upIndexes, highPriorityIndex);
- pushToStart(downIndexes, highPriorityIndex);
+ if (highPriorityIndexes) {
+ for (const index of highPriorityIndexes) {
+ pushToStart(upIndexes, index);
+ pushToStart(downIndexes, index);
+ }
}
- if (typeof lowPriorityIndex === 'number') {
- pushToEnd(upIndexes, lowPriorityIndex);
- pushToEnd(downIndexes, lowPriorityIndex);
+ if (lowPriorityIndexes) {
+ for (const index of lowPriorityIndexes) {
+ pushToEnd(upIndexes, index);
+ pushToEnd(downIndexes, index);
+ }
}
const upItems = upIndexes.map(i => this.viewItems[i]);
@@ -528,27 +551,29 @@ export class SplitView extends Disposable {
const downItems = downIndexes.map(i => this.viewItems[i]);
const downSizes = downIndexes.map(i => sizes[i]);
- const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.minimumSize - sizes[i]), 0);
+ const minDeltaUp = upIndexes.reduce((r, i) => r + ((typeof this.viewItems[i].view.snapSize === 'number' ? 0 : this.viewItems[i].view.minimumSize) - sizes[i]), 0);
const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - sizes[i]), 0);
- const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.minimumSize), 0);
+ const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - (typeof this.viewItems[i].view.snapSize === 'number' ? 0 : this.viewItems[i].view.minimumSize)), 0);
const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.maximumSize), 0);
const minDelta = Math.max(minDeltaUp, minDeltaDown, overloadMinDelta);
const maxDelta = Math.min(maxDeltaDown, maxDeltaUp, overloadMaxDelta);
- delta = clamp(delta, minDelta, maxDelta);
+ const tentativeDelta = clamp(delta, minDelta, maxDelta);
+ let actualDelta = 0;
- for (let i = 0, deltaUp = delta; i < upItems.length; i++) {
+ for (let i = 0, deltaUp = tentativeDelta; i < upItems.length; i++) {
const item = upItems[i];
- const size = clamp(upSizes[i] + deltaUp, item.view.minimumSize, item.view.maximumSize);
+ const size = SplitView.clamp(item, upSizes[i] + deltaUp/* , upIndexes[i] === index */);
const viewDelta = size - upSizes[i];
+ actualDelta += viewDelta;
deltaUp -= viewDelta;
item.size = size;
}
- for (let i = 0, deltaDown = delta; i < downItems.length; i++) {
+ for (let i = 0, deltaDown = actualDelta; i < downItems.length; i++) {
const item = downItems[i];
- const size = clamp(downSizes[i] - deltaDown, item.view.minimumSize, item.view.maximumSize);
+ const size = SplitView.clamp(item, downSizes[i] - deltaDown);
const viewDelta = size - downSizes[i];
deltaDown += viewDelta;
@@ -558,13 +583,24 @@ export class SplitView extends Disposable {
return delta;
}
+ private static clamp(item: IViewItem, size: number): number {
+ const result = clamp(size, item.view.minimumSize, item.view.maximumSize);
+
+ if (typeof item.view.snapSize !== 'number' || size >= item.view.minimumSize) {
+ return result;
+ }
+
+ const snapSize = Math.min(item.view.snapSize, item.view.minimumSize);
+ return size < snapSize ? 0 : item.view.minimumSize;
+ }
+
private distributeEmptySpace(): void {
let contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
let emptyDelta = this.size - contentSize;
for (let i = this.viewItems.length - 1; emptyDelta !== 0 && i >= 0; i--) {
const item = this.viewItems[i];
- const size = clamp(item.size + emptyDelta, item.view.minimumSize, item.view.maximumSize);
+ const size = SplitView.clamp(item, item.size + emptyDelta);
const viewDelta = size - item.size;
emptyDelta -= viewDelta;
diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts
index 807cead7989..2b339b430b2 100644
--- a/src/vs/base/browser/ui/tree/abstractTree.ts
+++ b/src/vs/base/browser/ui/tree/abstractTree.ts
@@ -11,11 +11,10 @@ import { append, $, toggleClass } from 'vs/base/browser/dom';
import { Event, Relay, chain } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
-import { ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
+import { ITreeModel, ITreeNode, ITreeRenderer, ITreeModelOptions } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
-import { IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
-export function createComposedTreeListOptions(options?: IListOptions): IListOptions {
+export function createComposedTreeListOptions(options?: IListOptions): IListOptions | undefined {
if (!options) {
return undefined;
}
@@ -23,18 +22,20 @@ export function createComposedTreeListOptions(optio
let identityProvider: IIdentityProvider | undefined = undefined;
if (options.identityProvider) {
- identityProvider = el => options.identityProvider(el.element);
+ const ip = options.identityProvider;
+ identityProvider = el => ip(el.element);
}
let multipleSelectionController: IMultipleSelectionController | undefined = undefined;
if (options.multipleSelectionController) {
+ const msc = options.multipleSelectionController;
multipleSelectionController = {
isSelectionSingleChangeEvent(e) {
- return options.multipleSelectionController.isSelectionSingleChangeEvent({ ...e, element: e.element } as any);
+ return msc.isSelectionSingleChangeEvent({ ...e, element: e.element } as any);
},
isSelectionRangeChangeEvent(e) {
- return options.multipleSelectionController.isSelectionRangeChangeEvent({ ...e, element: e.element } as any);
+ return msc.isSelectionRangeChangeEvent({ ...e, element: e.element } as any);
}
};
}
@@ -42,9 +43,10 @@ export function createComposedTreeListOptions(optio
let accessibilityProvider: IAccessibilityProvider | undefined = undefined;
if (options.accessibilityProvider) {
+ const ap = options.accessibilityProvider;
accessibilityProvider = {
getAriaLabel(e) {
- return options.accessibilityProvider.getAriaLabel(e.element);
+ return ap.getAriaLabel(e.element);
}
};
}
@@ -168,7 +170,7 @@ function isInputElement(e: HTMLElement): boolean {
return e.tagName === 'INPUT' || e.tagName === 'TEXTAREA';
}
-export interface ITreeOptions extends IListOptions, IIndexTreeModelOptions { }
+export interface ITreeOptions extends IListOptions, ITreeModelOptions { }
export interface ITreeEvent extends IListEvent> { }
export interface ITreeContextMenuEvent extends IListContextMenuEvent> { }
@@ -193,7 +195,7 @@ export abstract class AbstractTree implements IDisposable
container: HTMLElement,
delegate: IListVirtualDelegate,
renderers: ITreeRenderer[],
- options?: ITreeOptions
+ options: ITreeOptions = {}
) {
const treeDelegate = new ComposedTreeDelegate>(delegate);
@@ -302,33 +304,33 @@ export abstract class AbstractTree implements IDisposable
return nodes.map(n => n.element);
}
- setFocus(elements: TRef[]): void {
+ setFocus(elements: TRef[], browserEvent?: UIEvent): void {
const indexes = elements.map(e => this.model.getListIndex(e));
- this.view.setFocus(indexes);
+ this.view.setFocus(indexes, browserEvent);
}
- focusNext(n = 1, loop = false): void {
- this.view.focusNext(n, loop);
+ focusNext(n = 1, loop = false, browserEvent?: UIEvent): void {
+ this.view.focusNext(n, loop, browserEvent);
}
- focusPrevious(n = 1, loop = false): void {
- this.view.focusPrevious(n, loop);
+ focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void {
+ this.view.focusPrevious(n, loop, browserEvent);
}
- focusNextPage(): void {
- this.view.focusNextPage();
+ focusNextPage(browserEvent?: UIEvent): void {
+ this.view.focusNextPage(browserEvent);
}
- focusPreviousPage(): void {
- this.view.focusPreviousPage();
+ focusPreviousPage(browserEvent?: UIEvent): void {
+ this.view.focusPreviousPage(browserEvent);
}
- focusLast(): void {
- this.view.focusLast();
+ focusLast(browserEvent?: UIEvent): void {
+ this.view.focusLast(browserEvent);
}
- focusFirst(): void {
- this.view.focusFirst();
+ focusFirst(browserEvent?: UIEvent): void {
+ this.view.focusFirst(browserEvent);
}
getFocus(): T[] {
@@ -357,8 +359,12 @@ export abstract class AbstractTree implements IDisposable
private onMouseClick(e: IListMouseEvent>): void {
const node = e.element;
- const location = this.model.getNodeLocation(node);
+ if (!node) {
+ return;
+ }
+
+ const location = this.model.getNodeLocation(node);
this.model.toggleCollapsed(location);
}
@@ -437,7 +443,5 @@ export abstract class AbstractTree implements IDisposable
dispose(): void {
this.disposables = dispose(this.disposables);
this.view.dispose();
- this.view = null;
- this.model = null;
}
}
\ No newline at end of file
diff --git a/src/vs/base/browser/ui/tree/dataTree.ts b/src/vs/base/browser/ui/tree/dataTree.ts
index 2c7471795dd..a4b627e3f62 100644
--- a/src/vs/base/browser/ui/tree/dataTree.ts
+++ b/src/vs/base/browser/ui/tree/dataTree.ts
@@ -99,7 +99,7 @@ export class DataTree, TFilterData = void> implements
private tree: ObjectTree, TFilterData>;
private root: IDataTreeNode;
- private nodes = new Map>();
+ private nodes = new Map>();
private _onDidChangeNodeState = new Emitter>();
@@ -112,9 +112,9 @@ export class DataTree, TFilterData = void> implements
private dataSource: IDataSource,
options?: ITreeOptions
) {
- const objectTreeDelegate = new ComposedTreeDelegate>(delegate);
+ const objectTreeDelegate = new ComposedTreeDelegate>(delegate);
const objectTreeRenderers = renderers.map(r => new DataTreeRenderer(r, this._onDidChangeNodeState.event));
- const objectTreeOptions = createComposedTreeListOptions>(options);
+ const objectTreeOptions = createComposedTreeListOptions>(options);
this.tree = new ObjectTree(container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions);
this.root = {
@@ -143,7 +143,7 @@ export class DataTree, TFilterData = void> implements
if (!hasChildren) {
this.tree.setChildren(node === this.root ? null : node);
- return Promise.resolve(null);
+ return Promise.resolve();
} else {
node.state = DataTreeNodeState.Loading;
this._onDidChangeNodeState.fire(node);
diff --git a/src/vs/base/browser/ui/tree/indexTree.ts b/src/vs/base/browser/ui/tree/indexTree.ts
index 86b19455381..02e9b4492bb 100644
--- a/src/vs/base/browser/ui/tree/indexTree.ts
+++ b/src/vs/base/browser/ui/tree/indexTree.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import 'vs/css!./tree';
+import 'vs/css!./media/tree';
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { AbstractTree, ITreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ISpliceable } from 'vs/base/common/sequence';
diff --git a/src/vs/base/browser/ui/tree/indexTreeModel.ts b/src/vs/base/browser/ui/tree/indexTreeModel.ts
index 47f1c37607a..1b4ee5b0c70 100644
--- a/src/vs/base/browser/ui/tree/indexTreeModel.ts
+++ b/src/vs/base/browser/ui/tree/indexTreeModel.ts
@@ -7,7 +7,7 @@ import { ISpliceable } from 'vs/base/common/sequence';
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { Emitter, Event, EventBufferer } from 'vs/base/common/event';
import { tail2 } from 'vs/base/common/arrays';
-import { ITreeFilterDataResult, TreeVisibility, ITreeFilter, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
+import { ITreeFilterDataResult, TreeVisibility, ITreeFilter, ITreeModel, ITreeNode, ITreeElement, ITreeModelOptions } from 'vs/base/browser/ui/tree/tree';
interface IMutableTreeNode extends ITreeNode {
readonly parent: IMutableTreeNode | undefined;
@@ -30,25 +30,19 @@ function treeNodeToElement(node: IMutableTreeNode): ITreeElement {
return { element, children, collapsed };
}
-function getVisibleState(visibility: boolean | TreeVisibility): boolean | undefined {
+function getVisibleState(visibility: boolean | TreeVisibility): TreeVisibility {
switch (visibility) {
- case true: return true;
- case false: return false;
- case TreeVisibility.Hidden: return false;
- case TreeVisibility.Visible: return true;
- case TreeVisibility.Recurse: return undefined;
+ case true: return TreeVisibility.Visible;
+ case false: return TreeVisibility.Hidden;
+ default: return visibility;
}
}
-export interface IIndexTreeModelOptions {
- filter?: ITreeFilter;
-}
-
export class IndexTreeModel implements ITreeModel