diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index d352b823d0..23c94155f3 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -3,7 +3,7 @@
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
-FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-10
+FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-12
ARG TARGET_DISPLAY=":1"
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
index 79fdfb487a..e16795062d 100644
--- a/.devcontainer/README.md
+++ b/.devcontainer/README.md
@@ -6,9 +6,9 @@ This repository includes configuration for a development container for working w
## Quick start - local
-1. Install Docker Desktop or Docker on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.)
+1. Install Docker Desktop or Docker for Linux on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.)
-2. [Docker Desktop] If you are not using the new WSL2 Docker Desktop engine, increase the resources allocated to Docker Desktop to at least **4 Cores and 4 GB of RAM (8 GB recommended)**. Right-click on the Docker status bar item, go to **Preferences/Settings > Resources > Advanced** to do so.
+2. **Important**: Docker needs at least **4 Cores and 6 GB of RAM (8 GB recommended)** to run full build. If you on macOS, or using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item, going to **Preferences/Settings > Resources > Advanced**.
> **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar.
@@ -44,7 +44,7 @@ Next: **[Try it out!](#try-it)**
3. Press Ctrl/Cmd + Shift + P and select **Codespaces: Create New Codespace**.
-4. Use default settings, select a plan, and then enter the repository URL `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box when prompted.
+4. Use default settings (which should include **Standard** 4 core, 8 GB RAM Codespace), select a plan, and then enter the repository URL `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box when prompted.
5. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080) or use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password.
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index b9f3e6d79b..722bace6df 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -12,7 +12,11 @@
}
},
"overrideCommand": false,
- "runArgs": ["--init"],
+ "runArgs": [
+ "--init",
+ // seccomp=unconfined is required for Chrome sandboxing
+ "--security-opt", "seccomp=unconfined"
+ ],
"settings": {
// zsh is also available
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 76f0aeadfa..2cd0a32b9c 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -4,7 +4,6 @@
"recommendations": [
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
- "msjsdiag.debugger-for-chrome",
- "ms-vscode.vscode-github-issue-notebooks"
+ "msjsdiag.debugger-for-chrome"
]
}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 1a19bbf549..04efa7aa70 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -92,6 +92,7 @@
"env": {
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null
},
+ "cleanUp": "wholeBrowser",
"breakOnLoad": false,
"urlFilter": "*workbench.html*",
"runtimeArgs": [
diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues
new file mode 100644
index 0000000000..f36bb39758
--- /dev/null
+++ b/.vscode/notebooks/api.github-issues
@@ -0,0 +1,38 @@
+[
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "#### Config",
+ "editable": true
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2020\"",
+ "editable": true
+ },
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "### Finalization",
+ "editable": true
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repo $milestone label:api-finalization",
+ "editable": true
+ },
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "### Proposals",
+ "editable": true
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repo $milestone is:open label:api-proposal ",
+ "editable": true
+ }
+]
\ No newline at end of file
diff --git a/.vscode/notebooks/inbox.github-issues b/.vscode/notebooks/inbox.github-issues
index 9edd342251..8931e7b0b3 100644
--- a/.vscode/notebooks/inbox.github-issues
+++ b/.vscode/notebooks/inbox.github-issues
@@ -2,12 +2,14 @@
{
"kind": 1,
"language": "markdown",
- "value": "##### `Config`: defines the inbox query"
+ "value": "##### `Config`: defines the inbox query",
+ "editable": true
},
{
"kind": 2,
"language": "github-issues",
- "value": "$inbox=repo:microsoft/vscode is:open no:assignee -label:feature-request -label:testplan-item -label:plan-item "
+ "value": "$inbox=repo:microsoft/vscode is:open no:assignee -label:feature-request -label:testplan-item -label:plan-item ",
+ "editable": true
},
{
"kind": 1,
@@ -18,7 +20,7 @@
{
"kind": 2,
"language": "github-issues",
- "value": "$inbox -label:\"needs more info\"",
+ "value": "$inbox -label:\"needs more info\" -label:emmet",
"editable": true
},
{
@@ -31,6 +33,6 @@
"kind": 2,
"language": "github-issues",
"value": "$inbox",
- "editable": true
+ "editable": false
}
]
\ No newline at end of file
diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues
index c6d2309b39..dc6d33365d 100644
--- a/.vscode/notebooks/my-work.github-issues
+++ b/.vscode/notebooks/my-work.github-issues
@@ -20,7 +20,7 @@
{
"kind": 2,
"language": "github-issues",
- "value": "$repos $milestone assignee:@me is:open\n",
+ "value": "$repos $milestone assignee:@me is:open",
"editable": false
},
{
diff --git a/.vscode/notebooks/verification.github-issues b/.vscode/notebooks/verification.github-issues
new file mode 100644
index 0000000000..6f32df8e07
--- /dev/null
+++ b/.vscode/notebooks/verification.github-issues
@@ -0,0 +1,55 @@
+[
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "### Bug Verification Queries\n\nBefore shipping we want to verify _all_ bugs. That means when a bug is fixed we check that the fix actually works. It's always best to start with bugs that you have filed and the proceed with bugs that have been filed from users outside the development team. ",
+ "editable": true
+ },
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "#### Config: update list of `repos` and the `milestone`",
+ "editable": true
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks \n$milestone=milestone:\"June 2020\"",
+ "editable": true
+ },
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "### Bugs You Filed",
+ "editable": true
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repos $milestone is:closed -assignee:@me label:bug -label:verified -label:*duplicate author:@me",
+ "editable": false
+ },
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "### Bugs From Outside",
+ "editable": true
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repos $milestone is:closed -assignee:@me label:bug -label:verified -label:*duplicate -author:@me -assignee:@me label:bug -label:verified -author:@me -author:aeschli -author:alexdima -author:alexr00 -author:bpasero -author:chrisdias -author:chrmarti -author:connor4312 -author:dbaeumer -author:deepak1556 -author:eamodio -author:egamma -author:gregvanl -author:isidorn -author:JacksonKearl -author:joaomoreno -author:jrieken -author:lramos15 -author:lszomoru -author:misolori -author:mjbvz -author:rebornix -author:RMacfarlane -author:roblourens -author:sana-ajani -author:sandy081 -author:sbatten -author:Tyriar -author:weinand",
+ "editable": false
+ },
+ {
+ "kind": 1,
+ "language": "markdown",
+ "value": "### All"
+ },
+ {
+ "kind": 2,
+ "language": "github-issues",
+ "value": "$repos $milestone is:closed -assignee:@me label:bug -label:verified -label:*duplicate",
+ "editable": false
+ }
+]
\ No newline at end of file
diff --git a/.vscode/searches/es6.code-search b/.vscode/searches/es6.code-search
index c89264a3cf..9cf8cf0b26 100644
--- a/.vscode/searches/es6.code-search
+++ b/.vscode/searches/es6.code-search
@@ -2,7 +2,7 @@
# Flags: CaseSensitive WordMatch
# ContextLines: 2
-16 results - 5 files
+14 results - 4 files
src/vs/base/browser/dom.ts:
81 };
@@ -34,24 +34,11 @@ src/vs/base/common/arrays.ts:
420 */
421 export function first(array: ReadonlyArray, fn: (item: T) => boolean, notFoundValue: T): T;
- 560
- 561 /**
- 562: * @deprecated ES6: use `Array.find`
- 563 */
- 564 export function find(arr: ArrayLike, predicate: (value: T, index: number, arr: ArrayLike) => any): T | undefined {
-
-src/vs/base/common/map.ts:
- 11
- 12 /**
- 13: * @deprecated ES6: use `[...SetOrMap.values()]`
- 14 */
- 15 export function values(set: Set): V[];
-
- 22
- 23 /**
- 24: * @deprecated ES6: use `[...map.keys()]`
- 25 */
- 26 export function keys(map: Map): K[] {
+ 569
+ 570 /**
+ 571: * @deprecated ES6: use `Array.find`
+ 572 */
+ 573 export function find(arr: ArrayLike, predicate: (value: T, index: number, arr: ArrayLike) => any): T | undefined {
src/vs/base/common/objects.ts:
115
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 076129b820..42d0ba0f26 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -3,12 +3,8 @@
"tasks": [
{
"type": "npm",
- "script": "watchd",
- "label": "Build VS Code",
- "group": {
- "kind": "build",
- "isDefault": true
- },
+ "script": "watch-clientd",
+ "label": "Build VS Code Core",
"isBackground": true,
"presentation": {
"reveal": "never"
@@ -31,6 +27,43 @@
}
}
},
+ {
+ "type": "npm",
+ "script": "watch-extensionsd",
+ "label": "Build VS Code Extensions",
+ "isBackground": true,
+ "presentation": {
+ "reveal": "never"
+ },
+ "problemMatcher": {
+ "owner": "typescript",
+ "applyTo": "closedDocuments",
+ "fileLocation": [
+ "absolute"
+ ],
+ "pattern": {
+ "regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$",
+ "file": 1,
+ "location": 2,
+ "message": 3
+ },
+ "background": {
+ "beginsPattern": "Starting compilation",
+ "endsPattern": "Finished compilation"
+ }
+ }
+ },
+ {
+ "label": "Build VS Code",
+ "dependsOn": [
+ "Build VS Code Core",
+ "Build VS Code Extensions"
+ ],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ },
{
"type": "npm",
"script": "strict-vscode-watch",
@@ -55,6 +88,14 @@
},
"problemMatcher": "$tsc"
},
+ {
+ "label": "Kill Build VS Code",
+ "dependsOn": [
+ "Kill Build VS Code Core",
+ "Kill Build VS Code Extensions"
+ ],
+ "group": "build"
+ },
{
"type": "npm",
"script": "watch-webd",
diff --git a/.yarnrc b/.yarnrc
index 135e10442a..4c5125d892 100644
--- a/.yarnrc
+++ b/.yarnrc
@@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
-target "7.3.2"
+target "8.3.3"
runtime "electron"
diff --git a/build/azure-pipelines/sql-product-build.yml b/build/azure-pipelines/sql-product-build.yml
index 53fd68247f..71af90d437 100644
--- a/build/azure-pipelines/sql-product-build.yml
+++ b/build/azure-pipelines/sql-product-build.yml
@@ -1,7 +1,7 @@
resources:
containers:
- container: linux-x64
- image: sqltoolscontainers.azurecr.io/linux-build-agent:1
+ image: sqltoolscontainers.azurecr.io/linux-build-agent:2
endpoint: ContainerRegistry
jobs:
diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js
index 4c7e36bdc8..06dfe2b783 100644
--- a/build/gulpfile.vscode.js
+++ b/build/gulpfile.vscode.js
@@ -36,23 +36,6 @@ const { compileBuildTask } = require('./gulpfile.compile');
const { compileExtensionsBuildTask } = require('./gulpfile.extensions');
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
-const baseModules = Object.keys(process.binding('natives')).filter(n => !/^_|\//.test(n));
-const nodeModules = [ // {{SQL CARBON EDIT}}
- 'electron',
- 'original-fs',
- 'rxjs/Observable',
- 'rxjs/add/observable/fromPromise',
- 'rxjs/Subject',
- 'rxjs/Observer',
- 'slickgrid/lib/jquery.event.drag-2.3.0',
- 'slickgrid/lib/jquery-ui-1.9.2',
- 'slickgrid/slick.core',
- 'slickgrid/slick.grid',
- 'slickgrid/slick.editors',
- 'slickgrid/slick.dataview']
- .concat(Object.keys(product.dependencies || {}))
- .concat(_.uniq(productionDependencies.map(d => d.name)))
- .concat(baseModules);
// Build
const vscodeEntryPoints = _.flatten([
@@ -75,6 +58,7 @@ const vscodeResources = [
'out-build/paths.js',
'out-build/vs/**/*.{svg,png,html}',
'!out-build/vs/code/browser/**/*.html',
+ '!out-build/vs/editor/standalone/**/*.svg',
'out-build/vs/base/common/performance.js',
'out-build/vs/base/node/languagePacks.js',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
@@ -123,7 +107,7 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series(
src: 'out-build',
entryPoints: vscodeEntryPoints,
resources: vscodeResources,
- loaderConfig: common.loaderConfig(nodeModules),
+ loaderConfig: common.loaderConfig(),
out: 'out-vscode',
bundleInfo: undefined
})
@@ -134,12 +118,6 @@ const sourceMappingURLBase = `https://sqlopsbuilds.blob.core.windows.net/sourcem
const minifyVSCodeTask = task.define('minify-vscode', task.series(
optimizeVSCodeTask,
util.rimraf('out-vscode-min'),
- () => {
- const fullpath = path.join(process.cwd(), 'out-vscode/bootstrap-window.js');
- const contents = fs.readFileSync(fullpath).toString();
- const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
- fs.writeFileSync(fullpath, newContents);
- },
common.minifyTask('out-vscode', `${sourceMappingURLBase}/core`)
));
gulp.task(minifyVSCodeTask);
diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js
index 1e0fd4b09a..c19c69bf8e 100644
--- a/build/gulpfile.vscode.win32.js
+++ b/build/gulpfile.vscode.win32.js
@@ -94,8 +94,8 @@ function buildWin32Setup(arch, target) {
IncompatibleTargetAppId: { 'ia32': product.win32AppId, 'x64': product.win32x64AppId, 'arm64': product.win32arm64AppId }[arch],
IncompatibleArchAppId: { 'ia32': x64AppId, 'x64': ia32AppId, 'arm64': ia32AppId }[arch],
AppUserId: product.win32AppUserModelId,
- ArchitecturesAllowed: { 'ia32': '', 'x64': 'x64', 'arm64': '' }[arch],
- ArchitecturesInstallIn64BitMode: { 'ia32': '', 'x64': 'x64', 'arm64': '' }[arch],
+ ArchitecturesAllowed: { 'ia32': '', 'x64': 'x64', 'arm64': 'arm64' }[arch],
+ ArchitecturesInstallIn64BitMode: { 'ia32': '', 'x64': 'x64', 'arm64': 'arm64' }[arch],
SourceDir: sourcePath,
RepoDir: repoPath,
OutputDir: outputPath,
diff --git a/build/lib/compilation.js b/build/lib/compilation.js
index 7a36b15a2e..f8b50731c2 100644
--- a/build/lib/compilation.js
+++ b/build/lib/compilation.js
@@ -18,6 +18,7 @@ const reporter_1 = require("./reporter");
const util = require("./util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
+const os = require("os");
const watch = require('./watch');
const reporter = reporter_1.createReporter();
function getTypeScriptCompilerOptions(src) {
@@ -69,6 +70,9 @@ function createCompile(src, build, emitError) {
}
function compileTask(src, out, build) {
return function () {
+ if (os.totalmem() < 4000000000) {
+ throw new Error('compilation requires 4GB of RAM');
+ }
const compile = createCompile(src, build, true);
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
let generator = new MonacoGenerator(false);
diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts
index 6409322743..4f1260b09a 100644
--- a/build/lib/compilation.ts
+++ b/build/lib/compilation.ts
@@ -18,6 +18,7 @@ import { createReporter } from './reporter';
import * as util from './util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
+import * as os from 'os';
import ts = require('typescript');
const watch = require('./watch');
@@ -81,6 +82,11 @@ function createCompile(src: string, build: boolean, emitError?: boolean) {
export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream {
return function () {
+
+ if (os.totalmem() < 4_000_000_000) {
+ throw new Error('compilation requires 4GB of RAM');
+ }
+
const compile = createCompile(src, build, true);
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
let generator = new MonacoGenerator(false);
diff --git a/build/lib/i18n.js b/build/lib/i18n.js
index 904ef2ab75..b35bf2336b 100644
--- a/build/lib/i18n.js
+++ b/build/lib/i18n.js
@@ -1147,12 +1147,7 @@ function createIslFile(originalFilePath, messages, language, innoSetup) {
if (line.length > 0) {
let firstChar = line.charAt(0);
if (firstChar === '[' || firstChar === ';') {
- if (line === '; *** Inno Setup version 5.5.3+ English messages ***') {
- content.push(`; *** Inno Setup version 5.5.3+ ${innoSetup.defaultInfo.name} messages ***`);
- }
- else {
- content.push(line);
- }
+ content.push(line);
}
else {
let sections = line.split('=');
diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts
index decc7dfd92..38947dd1aa 100644
--- a/build/lib/i18n.ts
+++ b/build/lib/i18n.ts
@@ -1316,11 +1316,7 @@ function createIslFile(originalFilePath: string, messages: Map, language
if (line.length > 0) {
let firstChar = line.charAt(0);
if (firstChar === '[' || firstChar === ';') {
- if (line === '; *** Inno Setup version 5.5.3+ English messages ***') {
- content.push(`; *** Inno Setup version 5.5.3+ ${innoSetup.defaultInfo!.name} messages ***`);
- } else {
- content.push(line);
- }
+ content.push(line);
} else {
let sections: string[] = line.split('=');
let key = sections[0];
diff --git a/build/lib/optimize.js b/build/lib/optimize.js
index 19104ca2d3..df7097a9fe 100644
--- a/build/lib/optimize.js
+++ b/build/lib/optimize.js
@@ -28,14 +28,15 @@ const REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix, message) {
fancyLog(ansiColors.cyan('[' + prefix + ']'), message);
}
-function loaderConfig(emptyPaths) {
+function loaderConfig() {
const result = {
paths: {
'vs': 'out-build/vs',
'sql': 'out-build/sql',
- 'vscode': 'empty:'
+ 'vscode': 'empty:',
+ 'azdata': 'empty:' // {{SQL CARBON EDIT}}
},
- nodeModules: emptyPaths || []
+ amdModulesPattern: /^(vs|sql)\// // {{SQL CARBON EDIT}} include sql in regex
};
result['vs/css'] = { inlineResources: true };
return result;
diff --git a/build/lib/optimize.ts b/build/lib/optimize.ts
index b3e1f95759..828fbca507 100644
--- a/build/lib/optimize.ts
+++ b/build/lib/optimize.ts
@@ -32,14 +32,15 @@ function log(prefix: string, message: string): void {
fancyLog(ansiColors.cyan('[' + prefix + ']'), message);
}
-export function loaderConfig(emptyPaths?: string[]) {
+export function loaderConfig() {
const result: any = {
paths: {
'vs': 'out-build/vs',
'sql': 'out-build/sql', // {{SQL CARBON EDIT}}
- 'vscode': 'empty:'
+ 'vscode': 'empty:',
+ 'azdata': 'empty:' // {{SQL CARBON EDIT}}
},
- nodeModules: emptyPaths || []
+ amdModulesPattern: /^(vs|sql)\// // {{SQL CARBON EDIT}} include sql in regex
};
result['vs/css'] = { inlineResources: true };
diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js
index 9d2734da6d..ff9bb5498b 100644
--- a/build/npm/postinstall.js
+++ b/build/npm/postinstall.js
@@ -33,7 +33,7 @@ function yarnInstall(location, opts) {
yarnInstall('extensions'); // node modules shared by all extensions
-if (!(process.platform === 'win32' && process.env['npm_config_arch'] === 'arm64')) {
+if (!(process.platform === 'win32' && (process.arch === 'arm64' || process.env['npm_config_arch'] === 'arm64'))) {
yarnInstall('remote'); // node modules used by vscode server
yarnInstall('remote/web'); // node modules used by vscode web
}
@@ -73,3 +73,5 @@ yarnInstall('test/automation'); // node modules required for smoketest
yarnInstall('test/smoke'); // node modules required for smoketest
yarnInstall('test/integration/browser'); // node modules required for integration
yarnInstallBuildDependencies(); // node modules for watching, specific to host node version, not electron
+
+cp.execSync('git config pull.rebase true');
diff --git a/build/package.json b/build/package.json
index 09863d4011..044f4c5fa1 100644
--- a/build/package.json
+++ b/build/package.json
@@ -40,7 +40,7 @@
"gulp-bom": "^1.0.0",
"gulp-sourcemaps": "^1.11.0",
"gulp-uglify": "^3.0.0",
- "iconv-lite-umd": "0.6.5",
+ "iconv-lite-umd": "0.6.8",
"mime": "^1.3.4",
"minimatch": "3.0.4",
"minimist": "^1.2.3",
@@ -49,7 +49,7 @@
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"terser": "4.3.8",
- "typescript": "^4.0.0-dev.20200629",
+ "typescript": "^4.0.0-dev.20200708",
"vsce": "1.48.0",
"vscode-telemetry-extractor": "^1.6.0",
"xml2js": "^0.4.17"
diff --git a/build/win32/code.iss b/build/win32/code.iss
index 321f8be01b..81e14a8386 100644
--- a/build/win32/code.iss
+++ b/build/win32/code.iss
@@ -34,6 +34,7 @@ VersionInfoVersion={#RawVersion}
ShowLanguageDialog=auto
ArchitecturesAllowed={#ArchitecturesAllowed}
ArchitecturesInstallIn64BitMode={#ArchitecturesInstallIn64BitMode}
+WizardStyle=modern
#ifdef Sign
SignTool=esrp
@@ -47,7 +48,7 @@ DefaultDirName={pf}\{#DirName}
#endif
[Languages]
-Name: "english"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.isl,{#RepoDir}\build\win32\i18n\messages.en.isl" {#LocalizedLanguageFile}
+Name: "english"; MessagesFile: "compiler:Default.isl,{#RepoDir}\build\win32\i18n\messages.en.isl" {#LocalizedLanguageFile}
Name: "german"; MessagesFile: "compiler:Languages\German.isl,{#RepoDir}\build\win32\i18n\messages.de.isl" {#LocalizedLanguageFile("deu")}
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl,{#RepoDir}\build\win32\i18n\messages.es.isl" {#LocalizedLanguageFile("esp")}
Name: "french"; MessagesFile: "compiler:Languages\French.isl,{#RepoDir}\build\win32\i18n\messages.fr.isl" {#LocalizedLanguageFile("fra")}
@@ -58,7 +59,7 @@ Name: "korean"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.ko.isl,{#Repo
Name: "simplifiedChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-cn.isl,{#RepoDir}\build\win32\i18n\messages.zh-cn.isl" {#LocalizedLanguageFile("chs")}
Name: "traditionalChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-tw.isl,{#RepoDir}\build\win32\i18n\messages.zh-tw.isl" {#LocalizedLanguageFile("cht")}
Name: "brazilianPortuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl,{#RepoDir}\build\win32\i18n\messages.pt-br.isl" {#LocalizedLanguageFile("ptb")}
-Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl,{#RepoDir}\build\win32\i18n\messages.hu.isl" {#LocalizedLanguageFile("hun")}
+Name: "hungarian"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.hu.isl,{#RepoDir}\build\win32\i18n\messages.hu.isl" {#LocalizedLanguageFile("hun")}
Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl,{#RepoDir}\build\win32\i18n\messages.tr.isl" {#LocalizedLanguageFile("trk")}
[InstallDelete]
@@ -147,7 +148,7 @@ begin
Result := True;
#if "user" == InstallTarget
- if not WizardSilent() and IsAdminLoggedOn() then begin
+ if not WizardSilent() and IsAdmin() then begin
if MsgBox('This User Installer is not meant to be run as an Administrator. If you would like to install Azure Data Studio for all users in this system, download the System Installer instead from https://docs.microsoft.com/sql/azure-data-studio/download. Are you sure you want to continue?', mbError, MB_OKCANCEL) = IDCANCEL then begin
Result := False;
end;
diff --git a/build/win32/i18n/Default.hu.isl b/build/win32/i18n/Default.hu.isl
new file mode 100644
index 0000000000..8c57d20a59
--- /dev/null
+++ b/build/win32/i18n/Default.hu.isl
@@ -0,0 +1,366 @@
+;Inno Setup version 6.0.3+ Hungarian messages
+;Based on the translation of Kornél Pál, kornelpal@gmail.com
+;István Szabó, E-mail: istvanszabo890629@gmail.com
+;
+; To download user-contributed translations of this file, go to:
+; http://www.jrsoftware.org/files/istrans/
+;
+; Note: When translating this text, do not add periods (.) to the end of
+; messages that didn't have them already, because on those messages Inno
+; Setup adds the periods automatically (appending a period would result in
+; two periods being displayed).
+
+[LangOptions]
+; The following three entries are very important. Be sure to read and
+; understand the '[LangOptions] section' topic in the help file.
+LanguageName=Magyar
+LanguageID=$040E
+LanguageCodePage=1250
+; If the language you are translating to requires special font faces or
+; sizes, uncomment any of the following entries and change them accordingly.
+;DialogFontName=
+;DialogFontSize=8
+;WelcomeFontName=Verdana
+;WelcomeFontSize=12
+;TitleFontName=Arial CE
+;TitleFontSize=29
+;CopyrightFontName=Arial CE
+;CopyrightFontSize=8
+
+[Messages]
+
+; *** Application titles
+SetupAppTitle=Telepítő
+SetupWindowTitle=%1 - Telepítő
+UninstallAppTitle=Eltávolító
+UninstallAppFullTitle=%1 Eltávolító
+
+; *** Misc. common
+InformationTitle=Információk
+ConfirmTitle=Megerősít
+ErrorTitle=Hiba
+
+; *** SetupLdr messages
+SetupLdrStartupMessage=%1 telepítve lesz. Szeretné folytatni?
+LdrCannotCreateTemp=Átmeneti fájl létrehozása nem lehetséges. A telepítés megszakítva
+LdrCannotExecTemp=Fájl futtatása nem lehetséges az átmeneti könyvtárban. A telepítés megszakítva
+HelpTextNote=
+
+; *** Startup error messages
+LastErrorMessage=%1.%n%nHiba %2: %3
+SetupFileMissing=A(z) %1 fájl hiányzik a telepítő könyvtárából. Kérem hárítsa el a problémát, vagy szerezzen be egy másik példányt a programból!
+SetupFileCorrupt=A telepítési fájlok sérültek. Kérem, szerezzen be új másolatot a programból!
+SetupFileCorruptOrWrongVer=A telepítési fájlok sérültek, vagy inkompatibilisek a telepítő ezen verziójával. Hárítsa el a problémát, vagy szerezzen be egy másik példányt a programból!
+InvalidParameter=A parancssorba átadott paraméter érvénytelen:%n%n%1
+SetupAlreadyRunning=A Telepítő már fut.
+WindowsVersionNotSupported=A program nem támogatja a Windows ezen verzióját.
+WindowsServicePackRequired=A program futtatásához %1 Service Pack %2 vagy újabb szükséges.
+NotOnThisPlatform=Ez a program nem futtatható %1 alatt.
+OnlyOnThisPlatform=Ezt a programot %1 alatt kell futtatni.
+OnlyOnTheseArchitectures=A program kizárólag a következő processzor architektúrákhoz tervezett Windows-on telepíthető:%n%n%1
+WinVersionTooLowError=A program futtatásához %1 %2 verziója vagy későbbi szükséges.
+WinVersionTooHighError=Ez a program nem telepíthető %1 %2 vagy későbbire.
+AdminPrivilegesRequired=Csak rendszergazdai módban telepíthető ez a program.
+PowerUserPrivilegesRequired=Csak rendszergazdaként vagy kiemelt felhasználóként telepíthető ez a program.
+SetupAppRunningError=A telepítő úgy észlelte %1 jelenleg fut.%n%nZárja be az összes példányt, majd kattintson az 'OK'-ra a folytatáshoz, vagy a 'Mégse'-re a kilépéshez.
+UninstallAppRunningError=Az eltávolító úgy észlelte %1 jelenleg fut.%n%nZárja be az összes példányt, majd kattintson az 'OK'-ra a folytatáshoz, vagy a 'Mégse'-re a kilépéshez.
+
+; *** Startup questions
+PrivilegesRequiredOverrideTitle=Telepítési mód kiválasztása
+PrivilegesRequiredOverrideInstruction=Válasszon telepítési módot
+PrivilegesRequiredOverrideText1=%1 telepíthető az összes felhasználónak (rendszergazdai jogok szükségesek), vagy csak magának.
+PrivilegesRequiredOverrideText2=%1 csak magának telepíthető, vagy az összes felhasználónak (rendszergazdai jogok szükségesek).
+PrivilegesRequiredOverrideAllUsers=Telepítés &mindenkinek
+PrivilegesRequiredOverrideAllUsersRecommended=Telepítés &mindenkinek (ajánlott)
+PrivilegesRequiredOverrideCurrentUser=Telepítés csak &nekem
+PrivilegesRequiredOverrideCurrentUserRecommended=Telepítés csak &nekem (ajánlott)
+
+; *** Misc. errors
+ErrorCreatingDir=A Telepítő nem tudta létrehozni a(z) "%1" könyvtárat
+ErrorTooManyFilesInDir=Nem hozható létre fájl a(z) "%1" könyvtárban, mert az már túl sok fájlt tartalmaz
+
+; *** Setup common messages
+ExitSetupTitle=Kilépés a telepítőből
+ExitSetupMessage=A telepítés még folyamatban van. Ha most kilép, a program nem kerül telepítésre.%n%nMásik alkalommal is futtatható a telepítés befejezéséhez%n%nKilép a telepítőből?
+AboutSetupMenuItem=&Névjegy...
+AboutSetupTitle=Telepítő névjegye
+AboutSetupMessage=%1 %2 verzió%n%3%n%nAz %1 honlapja:%n%4
+AboutSetupNote=
+TranslatorNote=
+
+; *** Buttons
+ButtonBack=< &Vissza
+ButtonNext=&Tovább >
+ButtonInstall=&Telepít
+ButtonOK=OK
+ButtonCancel=Mégse
+ButtonYes=&Igen
+ButtonYesToAll=&Mindet
+ButtonNo=&Nem
+ButtonNoToAll=&Egyiket se
+ButtonFinish=&Befejezés
+ButtonBrowse=&Tallózás...
+ButtonWizardBrowse=T&allózás...
+ButtonNewFolder=Új &könyvtár
+
+; *** "Select Language" dialog messages
+SelectLanguageTitle=Telepítő nyelvi beállítás
+SelectLanguageLabel=Válassza ki a telepítés alatt használt nyelvet.
+
+; *** Common wizard text
+ClickNext=A folytatáshoz kattintson a 'Tovább'-ra, a kilépéshez a 'Mégse'-re.
+BeveledLabel=
+BrowseDialogTitle=Válasszon könyvtárt
+BrowseDialogLabel=Válasszon egy könyvtárat az alábbi listából, majd kattintson az 'OK'-ra.
+NewFolderName=Új könyvtár
+
+; *** "Welcome" wizard page
+WelcomeLabel1=Üdvözli a(z) [name] Telepítővarázslója.
+WelcomeLabel2=A(z) [name/ver] telepítésre kerül a számítógépén.%n%nAjánlott minden, egyéb futó alkalmazás bezárása a folytatás előtt.
+
+; *** "Password" wizard page
+WizardPassword=Jelszó
+PasswordLabel1=Ez a telepítés jelszóval védett.
+PasswordLabel3=Kérem adja meg a jelszót, majd kattintson a 'Tovább'-ra. A jelszavak kis- és nagy betű érzékenyek lehetnek.
+PasswordEditLabel=&Jelszó:
+IncorrectPassword=Az ön által megadott jelszó helytelen. Próbálja újra.
+
+; *** "License Agreement" wizard page
+WizardLicense=Licencszerződés
+LicenseLabel=Olvassa el figyelmesen az információkat folytatás előtt.
+LicenseLabel3=Kérem, olvassa el az alábbi licencszerződést. A telepítés folytatásához, el kell fogadnia a szerződést.
+LicenseAccepted=&Elfogadom a szerződést
+LicenseNotAccepted=&Nem fogadom el a szerződést
+
+; *** "Information" wizard pages
+WizardInfoBefore=Információk
+InfoBeforeLabel=Olvassa el a következő fontos információkat a folytatás előtt.
+InfoBeforeClickLabel=Ha készen áll, kattintson a 'Tovább'-ra.
+WizardInfoAfter=Információk
+InfoAfterLabel=Olvassa el a következő fontos információkat a folytatás előtt.
+InfoAfterClickLabel=Ha készen áll, kattintson a 'Tovább'-ra.
+
+; *** "User Information" wizard page
+WizardUserInfo=Felhasználó adatai
+UserInfoDesc=Kérem, adja meg az adatait
+UserInfoName=&Felhasználónév:
+UserInfoOrg=&Szervezet:
+UserInfoSerial=&Sorozatszám:
+UserInfoNameRequired=Meg kell adnia egy nevet.
+
+; *** "Select Destination Location" wizard page
+WizardSelectDir=Válasszon célkönyvtárat
+SelectDirDesc=Hova települjön a(z) [name]?
+SelectDirLabel3=A(z) [name] az alábbi könyvtárba lesz telepítve.
+SelectDirBrowseLabel=A folytatáshoz, kattintson a 'Tovább'-ra. Ha másik könyvtárat választana, kattintson a 'Tallózás'-ra.
+DiskSpaceGBLabel=At least [gb] GB szabad területre van szükség.
+DiskSpaceMBLabel=Legalább [mb] MB szabad területre van szükség.
+CannotInstallToNetworkDrive=A Telepítő nem tud hálózati meghajtóra telepíteni.
+CannotInstallToUNCPath=A Telepítő nem tud hálózati UNC elérési útra telepíteni.
+InvalidPath=Teljes útvonalat adjon meg, a meghajtó betűjelével; például:%n%nC:\Alkalmazás%n%nvagy egy hálózati útvonalat a következő alakban:%n%n\\kiszolgáló\megosztás
+InvalidDrive=A kiválasztott meghajtó vagy hálózati megosztás nem létezik vagy nem elérhető. Válasszon egy másikat.
+DiskSpaceWarningTitle=Nincs elég szabad terület
+DiskSpaceWarning=A Telepítőnek legalább %1 KB szabad lemezterületre van szüksége, viszont a kiválasztott meghajtón csupán %2 KB áll rendelkezésre.%n%nMindenképpen folytatja?
+DirNameTooLong=A könyvtár neve vagy az útvonal túl hosszú.
+InvalidDirName=A könyvtár neve érvénytelen.
+BadDirName32=A könyvtárak nevei ezen karakterek egyikét sem tartalmazhatják:%n%n%1
+DirExistsTitle=A könyvtár már létezik
+DirExists=A könyvtár:%n%n%1%n%nmár létezik. Mindenképp ide akar telepíteni?
+DirDoesntExistTitle=A könyvtár nem létezik
+DirDoesntExist=A könyvtár:%n%n%1%n%nnem létezik. Szeretné létrehozni?
+
+; *** "Select Components" wizard page
+WizardSelectComponents=Összetevők kiválasztása
+SelectComponentsDesc=Mely összetevők kerüljenek telepítésre?
+SelectComponentsLabel2=Jelölje ki a telepítendő összetevőket; törölje a telepíteni nem kívánt összetevőket. Kattintson a 'Tovább'-ra, ha készen áll a folytatásra.
+FullInstallation=Teljes telepítés
+; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
+CompactInstallation=Szokásos telepítés
+CustomInstallation=Egyéni telepítés
+NoUninstallWarningTitle=Létező összetevő
+NoUninstallWarning=A telepítő úgy találta, hogy a következő összetevők már telepítve vannak a számítógépre:%n%n%1%n%nEzen összetevők kijelölésének törlése, nem távolítja el azokat a számítógépről.%n%nMindenképpen folytatja?
+ComponentSize1=%1 KB
+ComponentSize2=%1 MB
+ComponentsDiskSpaceMBLabel=A jelenlegi kijelölés legalább [gb] GB lemezterületet igényel.
+ComponentsDiskSpaceMBLabel=A jelenlegi kijelölés legalább [mb] MB lemezterületet igényel.
+
+; *** "Select Additional Tasks" wizard page
+WizardSelectTasks=További feladatok
+SelectTasksDesc=Mely kiegészítő feladatok kerüljenek végrehajtásra?
+SelectTasksLabel2=Jelölje ki, mely kiegészítő feladatokat hajtsa végre a Telepítő a(z) [name] telepítése során, majd kattintson a 'Tovább'-ra.
+
+; *** "Select Start Menu Folder" wizard page
+WizardSelectProgramGroup=Start Menü könyvtára
+SelectStartMenuFolderDesc=Hova helyezze a Telepítő a program parancsikonjait?
+SelectStartMenuFolderLabel3=A Telepítő a program parancsikonjait a Start menü következő mappájában fogja létrehozni.
+SelectStartMenuFolderBrowseLabel=A folytatáshoz kattintson a 'Tovább'-ra. Ha másik mappát választana, kattintson a 'Tallózás'-ra.
+MustEnterGroupName=Meg kell adnia egy mappanevet.
+GroupNameTooLong=A könyvtár neve vagy az útvonal túl hosszú.
+InvalidGroupName=A könyvtár neve érvénytelen.
+BadGroupName=A könyvtárak nevei ezen karakterek egyikét sem tartalmazhatják:%n%n%1
+NoProgramGroupCheck2=&Ne hozzon létre mappát a Start menüben
+
+; *** "Ready to Install" wizard page
+WizardReady=Készen állunk a telepítésre
+ReadyLabel1=A Telepítő készen áll, a(z) [name] számítógépre telepítéshez.
+ReadyLabel2a=Kattintson a 'Telepítés'-re a folytatáshoz, vagy a "Vissza"-ra a beállítások áttekintéséhez vagy megváltoztatásához.
+ReadyLabel2b=Kattintson a 'Telepítés'-re a folytatáshoz.
+ReadyMemoUserInfo=Felhasználó adatai:
+ReadyMemoDir=Telepítés célkönyvtára:
+ReadyMemoType=Telepítés típusa:
+ReadyMemoComponents=Választott összetevők:
+ReadyMemoGroup=Start menü mappája:
+ReadyMemoTasks=Kiegészítő feladatok:
+
+; *** "Preparing to Install" wizard page
+WizardPreparing=Felkészülés a telepítésre
+PreparingDesc=A Telepítő felkészül a(z) [name] számítógépre történő telepítéshez.
+PreviousInstallNotCompleted=gy korábbi program telepítése/eltávolítása nem fejeződött be. Újra kell indítania a számítógépét a másik telepítés befejezéséhez.%n%nA számítógépe újraindítása után ismét futtassa a Telepítőt a(z) [name] telepítésének befejezéséhez.
+CannotContinue=A telepítés nem folytatható. A kilépéshez kattintson a 'Mégse'-re
+ApplicationsFound=A következő alkalmazások olyan fájlokat használnak, amelyeket a Telepítőnek frissíteni kell. Ajánlott, hogy engedélyezze a Telepítőnek ezen alkalmazások automatikus bezárását.
+ApplicationsFound2=A következő alkalmazások olyan fájlokat használnak, amelyeket a Telepítőnek frissíteni kell. Ajánlott, hogy engedélyezze a Telepítőnek ezen alkalmazások automatikus bezárását. A telepítés befejezése után a Telepítő megkísérli az alkalmazások újraindítását.
+CloseApplications=&Alkalmazások automatikus bezárása
+DontCloseApplications=&Ne zárja be az alkalmazásokat
+ErrorCloseApplications=A Telepítő nem tudott minden alkalmazást automatikusan bezárni. A folytatás előtt ajánlott minden, a Telepítő által frissítendő fájlokat használó alkalmazást bezárni.
+PrepareToInstallNeedsRestart=A telepítőnek újra kell indítania a számítógépet. Újraindítást követően, futtassa újból a telepítőt, a [name] telepítésének befejezéséhez .%n%nÚjra szeretné indítani most a számítógépet?
+
+; *** "Installing" wizard page
+WizardInstalling=Telepítés
+InstallingLabel=Kérem várjon, amíg a(z) [name] telepítése zajlik.
+
+; *** "Setup Completed" wizard page
+FinishedHeadingLabel=A(z) [name] telepítésének befejezése
+FinishedLabelNoIcons=A Telepítő végzett a(z) [name] telepítésével.
+FinishedLabel=A Telepítő végzett a(z) [name] telepítésével. Az alkalmazást a létrehozott ikonok kiválasztásával indíthatja.
+ClickFinish=Kattintson a 'Befejezés'-re a kilépéshez.
+FinishedRestartLabel=A(z) [name] telepítésének befejezéséhez újra kell indítani a számítógépet. Újraindítja most?
+FinishedRestartMessage=A(z) [name] telepítésének befejezéséhez, a Telepítőnek újra kell indítani a számítógépet.%n%nÚjraindítja most?
+ShowReadmeCheck=Igen, szeretném elolvasni a FONTOS fájlt
+YesRadio=&Igen, újraindítás most
+NoRadio=&Nem, később indítom újra
+; used for example as 'Run MyProg.exe'
+RunEntryExec=%1 futtatása
+; used for example as 'View Readme.txt'
+RunEntryShellExec=%1 megtekintése
+
+; *** "Setup Needs the Next Disk" stuff
+ChangeDiskTitle=A Telepítőnek szüksége van a következő lemezre
+SelectDiskLabel2=Helyezze be a(z) %1. lemezt és kattintson az 'OK'-ra.%n%nHa a fájlok a lemez egy a megjelenítettől különböző mappájában találhatók, írja be a helyes útvonalat vagy kattintson a 'Tallózás'-ra.
+PathLabel=Ú&tvonal:
+FileNotInDir2=A(z) "%1" fájl nem található a következő helyen: "%2". Helyezze be a megfelelő lemezt vagy válasszon egy másik mappát.
+SelectDirectoryLabel=Adja meg a következő lemez helyét.
+
+; *** Installation phase messages
+SetupAborted=A telepítés nem fejeződött be.%n%nHárítsa el a hibát és futtassa újból a Telepítőt.
+AbortRetryIgnoreSelectAction=Válasszon műveletet
+AbortRetryIgnoreRetry=&Újra
+AbortRetryIgnoreIgnore=&Hiba elvetése és folytatás
+AbortRetryIgnoreCancel=Telepítés megszakítása
+
+; *** Installation status messages
+StatusClosingApplications=Alkalmazások bezárása...
+StatusCreateDirs=Könyvtárak létrehozása...
+StatusExtractFiles=Fájlok kibontása...
+StatusCreateIcons=Parancsikonok létrehozása...
+StatusCreateIniEntries=INI bejegyzések létrehozása...
+StatusCreateRegistryEntries=Rendszerleíró bejegyzések létrehozása...
+StatusRegisterFiles=Fájlok regisztrálása...
+StatusSavingUninstall=Eltávolító információk mentése...
+StatusRunProgram=Telepítés befejezése...
+StatusRestartingApplications=Alkalmazások újraindítása...
+StatusRollback=Változtatások visszavonása...
+
+; *** Misc. errors
+ErrorInternal2=Belső hiba: %1
+ErrorFunctionFailedNoCode=Sikertelen %1
+ErrorFunctionFailed=Sikertelen %1; kód: %2
+ErrorFunctionFailedWithMessage=Sikertelen %1; kód: %2.%n%3
+ErrorExecutingProgram=Nem hajtható végre a fájl:%n%1
+
+; *** Registry errors
+ErrorRegOpenKey=Nem nyitható meg a rendszerleíró kulcs:%n%1\%2
+ErrorRegCreateKey=Nem hozható létre a rendszerleíró kulcs:%n%1\%2
+ErrorRegWriteKey=Nem módosítható a rendszerleíró kulcs:%n%1\%2
+
+; *** INI errors
+ErrorIniEntry=Bejegyzés létrehozása sikertelen a következő INI fájlban: "%1".
+
+; *** File copying errors
+FileAbortRetryIgnoreSkipNotRecommended=&Fájl kihagyása (nem ajánlott)
+FileAbortRetryIgnoreIgnoreNotRecommended=&Hiba elvetése és folytatás (nem ajánlott)
+SourceIsCorrupted=A forrásfájl megsérült
+SourceDoesntExist=A(z) "%1" forrásfájl nem létezik
+ExistingFileReadOnly2=A fájl csak olvashatóként van jelölve.
+ExistingFileReadOnlyRetry=Csak &olvasható tulajdonság eltávolítása és újra próbálkozás
+ExistingFileReadOnlyKeepExisting=&Létező fájl megtartása
+ErrorReadingExistingDest=Hiba lépett fel a fájl olvasása közben:
+FileExists=A fájl már létezik.%n%nFelül kívánja írni?
+ExistingFileNewer=A létező fájl újabb a telepítésre kerülőnél. Ajánlott a létező fájl megtartása.%n%nMeg kívánja tartani a létező fájlt?
+ErrorChangingAttr=Hiba lépett fel a fájl attribútumának módosítása közben:
+ErrorCreatingTemp=Hiba lépett fel a fájl telepítési könyvtárban történő létrehozása közben:
+ErrorReadingSource=Hiba lépett fel a forrásfájl olvasása közben:
+ErrorCopying=Hiba lépett fel a fájl másolása közben:
+ErrorReplacingExistingFile=Hiba lépett fel a létező fájl cseréje közben:
+ErrorRestartReplace=A fájl cseréje az újraindítás után sikertelen volt:
+ErrorRenamingTemp=Hiba lépett fel fájl telepítési könyvtárban történő átnevezése közben:
+ErrorRegisterServer=Nem lehet regisztrálni a DLL-t/OCX-et: %1
+ErrorRegSvr32Failed=Sikertelen RegSvr32. A visszaadott kód: %1
+ErrorRegisterTypeLib=Nem lehet regisztrálni a típustárat: %1
+
+; *** Uninstall display name markings
+; used for example as 'My Program (32-bit)'
+UninstallDisplayNameMark=%1 (%2)
+; used for example as 'My Program (32-bit, All users)'
+UninstallDisplayNameMarks=%1 (%2, %3)
+UninstallDisplayNameMark32Bit=32-bit
+UninstallDisplayNameMark64Bit=64-bit
+UninstallDisplayNameMarkAllUsers=Minden felhasználó
+UninstallDisplayNameMarkCurrentUser=Jelenlegi felhasználó
+
+; *** Post-installation errors
+ErrorOpeningReadme=Hiba lépett fel a FONTOS fájl megnyitása közben.
+ErrorRestartingComputer=A Telepítő nem tudta újraindítani a számítógépet. Indítsa újra kézileg.
+
+; *** Uninstaller messages
+UninstallNotFound=A(z) "%1" fájl nem létezik. Nem távolítható el.
+UninstallOpenError=A(z) "%1" fájl nem nyitható meg. Nem távolítható el.
+UninstallUnsupportedVer=A(z) "%1" eltávolítási naplófájl formátumát nem tudja felismerni az eltávolító jelen verziója. Az eltávolítás nem folytatható
+UninstallUnknownEntry=Egy ismeretlen bejegyzés (%1) található az eltávolítási naplófájlban
+ConfirmUninstall=Biztosan el kívánja távolítani a(z) %1 programot és minden összetevőjét?
+UninstallOnlyOnWin64=Ezt a telepítést csak 64-bites Windowson lehet eltávolítani.
+OnlyAdminCanUninstall=Ezt a telepítést csak adminisztrációs jogokkal rendelkező felhasználó távolíthatja el.
+UninstallStatusLabel=Legyen türelemmel, amíg a(z) %1 számítógépéről történő eltávolítása befejeződik.
+UninstalledAll=A(z) %1 sikeresen el lett távolítva a számítógépről.
+UninstalledMost=A(z) %1 eltávolítása befejeződött.%n%nNéhány elemet nem lehetett eltávolítani. Törölje kézileg.
+UninstalledAndNeedsRestart=A(z) %1 eltávolításának befejezéséhez újra kell indítania a számítógépét.%n%nÚjraindítja most?
+UninstallDataCorrupted=A(z) "%1" fájl sérült. Nem távolítható el.
+
+; *** Uninstallation phase messages
+ConfirmDeleteSharedFileTitle=Törli a megosztott fájlt?
+ConfirmDeleteSharedFile2=A rendszer azt jelzi, hogy a következő megosztott fájlra már nincs szüksége egyetlen programnak sem. Eltávolítja a megosztott fájlt?%n%nHa más programok még mindig használják a megosztott fájlt, akkor az eltávolítása után lehet, hogy nem fognak megfelelően működni. Ha bizonytalan, válassza a Nemet. A fájl megtartása nem okoz problémát a rendszerben.
+SharedFileNameLabel=Fájlnév:
+SharedFileLocationLabel=Helye:
+WizardUninstalling=Eltávolítás állapota
+StatusUninstalling=%1 eltávolítása...
+
+; *** Shutdown block reasons
+ShutdownBlockReasonInstallingApp=%1 telepítése.
+ShutdownBlockReasonUninstallingApp=%1 eltávolítása.
+
+; The custom messages below aren't used by Setup itself, but if you make
+; use of them in your scripts, you'll want to translate them.
+
+[CustomMessages]
+
+NameAndVersion=%1, verzió: %2
+AdditionalIcons=További parancsikonok:
+CreateDesktopIcon=&Asztali ikon létrehozása
+CreateQuickLaunchIcon=&Gyorsindító parancsikon létrehozása
+ProgramOnTheWeb=%1 az interneten
+UninstallProgram=Eltávolítás - %1
+LaunchProgram=Indítás %1
+AssocFileExtension=A(z) %1 &társítása a(z) %2 fájlkiterjesztéssel
+AssocingFileExtension=A(z) %1 társítása a(z) %2 fájlkiterjesztéssel...
+AutoStartProgramGroupDescription=Indítópult:
+AutoStartProgram=%1 automatikus indítása
+AddonHostProgramNotFound=A(z) %1 nem található a kiválasztott könyvtárban.%n%nMindenképpen folytatja?
diff --git a/build/win32/i18n/Default.isl b/build/win32/i18n/Default.isl
deleted file mode 100644
index 370da6b37c..0000000000
--- a/build/win32/i18n/Default.isl
+++ /dev/null
@@ -1,336 +0,0 @@
-; *** Inno Setup version 5.5.3+ English messages ***
-;
-; To download user-contributed translations of this file, go to:
-; http://www.jrsoftware.org/files/istrans/
-;
-; Note: When translating this text, do not add periods (.) to the end of
-; messages that didn't have them already, because on those messages Inno
-; Setup adds the periods automatically (appending a period would result in
-; two periods being displayed).
-
-[LangOptions]
-; The following three entries are very important. Be sure to read and
-; understand the '[LangOptions] section' topic in the help file.
-LanguageName=English
-LanguageID=$0409
-LanguageCodePage=0
-; If the language you are translating to requires special font faces or
-; sizes, uncomment any of the following entries and change them accordingly.
-;DialogFontName=
-;DialogFontSize=8
-;WelcomeFontName=Verdana
-;WelcomeFontSize=12
-;TitleFontName=Arial
-;TitleFontSize=29
-;CopyrightFontName=Arial
-;CopyrightFontSize=8
-
-[Messages]
-
-; *** Application titles
-SetupAppTitle=Setup
-SetupWindowTitle=Setup - %1
-UninstallAppTitle=Uninstall
-UninstallAppFullTitle=%1 Uninstall
-
-; *** Misc. common
-InformationTitle=Information
-ConfirmTitle=Confirm
-ErrorTitle=Error
-
-; *** SetupLdr messages
-SetupLdrStartupMessage=This will install %1. Do you wish to continue?
-LdrCannotCreateTemp=Unable to create a temporary file. Setup aborted
-LdrCannotExecTemp=Unable to execute file in the temporary directory. Setup aborted
-
-; *** Startup error messages
-LastErrorMessage=%1.%n%nError %2: %3
-SetupFileMissing=The file %1 is missing from the installation directory. Please correct the problem or obtain a new copy of the program.
-SetupFileCorrupt=The setup files are corrupted. Please obtain a new copy of the program.
-SetupFileCorruptOrWrongVer=The setup files are corrupted, or are incompatible with this version of Setup. Please correct the problem or obtain a new copy of the program.
-InvalidParameter=An invalid parameter was passed on the command line:%n%n%1
-SetupAlreadyRunning=Setup is already running.
-WindowsVersionNotSupported=This program does not support the version of Windows your computer is running.
-WindowsServicePackRequired=This program requires %1 Service Pack %2 or later.
-NotOnThisPlatform=This program will not run on %1.
-OnlyOnThisPlatform=This program must be run on %1.
-OnlyOnTheseArchitectures=This program can only be installed on versions of Windows designed for the following processor architectures:%n%n%1
-MissingWOW64APIs=The version of Windows you are running does not include functionality required by Setup to perform a 64-bit installation. To correct this problem, please install Service Pack %1.
-WinVersionTooLowError=This program requires %1 version %2 or later.
-WinVersionTooHighError=This program cannot be installed on %1 version %2 or later.
-AdminPrivilegesRequired=You must be logged in as an administrator when installing this program.
-PowerUserPrivilegesRequired=You must be logged in as an administrator or as a member of the Power Users group when installing this program.
-SetupAppRunningError=Setup has detected that %1 is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
-UninstallAppRunningError=Uninstall has detected that %1 is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.
-
-; *** Misc. errors
-ErrorCreatingDir=Setup was unable to create the directory "%1"
-ErrorTooManyFilesInDir=Unable to create a file in the directory "%1" because it contains too many files
-
-; *** Setup common messages
-ExitSetupTitle=Exit Setup
-ExitSetupMessage=Setup is not complete. If you exit now, the program will not be installed.%n%nYou may run Setup again at another time to complete the installation.%n%nExit Setup?
-AboutSetupMenuItem=&About Setup...
-AboutSetupTitle=About Setup
-AboutSetupMessage=%1 version %2%n%3%n%n%1 home page:%n%4
-AboutSetupNote=
-TranslatorNote=
-
-; *** Buttons
-ButtonBack=< &Back
-ButtonNext=&Next >
-ButtonInstall=&Install
-ButtonOK=OK
-ButtonCancel=Cancel
-ButtonYes=&Yes
-ButtonYesToAll=Yes to &All
-ButtonNo=&No
-ButtonNoToAll=N&o to All
-ButtonFinish=&Finish
-ButtonBrowse=&Browse...
-ButtonWizardBrowse=B&rowse...
-ButtonNewFolder=&Make New Folder
-
-; *** "Select Language" dialog messages
-SelectLanguageTitle=Select Setup Language
-SelectLanguageLabel=Select the language to use during the installation:
-
-; *** Common wizard text
-ClickNext=Click Next to continue, or Cancel to exit Setup.
-BeveledLabel=
-BrowseDialogTitle=Browse For Folder
-BrowseDialogLabel=Select a folder in the list below, then click OK.
-NewFolderName=New Folder
-
-; *** "Welcome" wizard page
-WelcomeLabel1=Welcome to the [name] Setup Wizard
-WelcomeLabel2=This will install [name/ver] on your computer.%n%nIt is recommended that you close all other applications before continuing.
-
-; *** "Password" wizard page
-WizardPassword=Password
-PasswordLabel1=This installation is password protected.
-PasswordLabel3=Please provide the password, then click Next to continue. Passwords are case-sensitive.
-PasswordEditLabel=&Password:
-IncorrectPassword=The password you entered is not correct. Please try again.
-
-; *** "License Agreement" wizard page
-WizardLicense=License Agreement
-LicenseLabel=Please read the following important information before continuing.
-LicenseLabel3=Please read the following License Agreement. You must accept the terms of this agreement before continuing with the installation.
-LicenseAccepted=I &accept the agreement
-LicenseNotAccepted=I &do not accept the agreement
-
-; *** "Information" wizard pages
-WizardInfoBefore=Information
-InfoBeforeLabel=Please read the following important information before continuing.
-InfoBeforeClickLabel=When you are ready to continue with Setup, click Next.
-WizardInfoAfter=Information
-InfoAfterLabel=Please read the following important information before continuing.
-InfoAfterClickLabel=When you are ready to continue with Setup, click Next.
-
-; *** "User Information" wizard page
-WizardUserInfo=User Information
-UserInfoDesc=Please enter your information.
-UserInfoName=&User Name:
-UserInfoOrg=&Organization:
-UserInfoSerial=&Serial Number:
-UserInfoNameRequired=You must enter a name.
-
-; *** "Select Destination Location" wizard page
-WizardSelectDir=Select Destination Location
-SelectDirDesc=Where should [name] be installed?
-SelectDirLabel3=Setup will install [name] into the following folder.
-SelectDirBrowseLabel=To continue, click Next. If you would like to select a different folder, click Browse.
-DiskSpaceMBLabel=At least [mb] MB of free disk space is required.
-CannotInstallToNetworkDrive=Setup cannot install to a network drive.
-CannotInstallToUNCPath=Setup cannot install to a UNC path.
-InvalidPath=You must enter a full path with drive letter; for example:%n%nC:\APP%n%nor a UNC path in the form:%n%n\\server\share
-InvalidDrive=The drive or UNC share you selected does not exist or is not accessible. Please select another.
-DiskSpaceWarningTitle=Not Enough Disk Space
-DiskSpaceWarning=Setup requires at least %1 KB of free space to install, but the selected drive only has %2 KB available.%n%nDo you want to continue anyway?
-DirNameTooLong=The folder name or path is too long.
-InvalidDirName=The folder name is not valid.
-BadDirName32=Folder names cannot include any of the following characters:%n%n%1
-DirExistsTitle=Folder Exists
-DirExists=The folder:%n%n%1%n%nalready exists. Would you like to install to that folder anyway?
-DirDoesntExistTitle=Folder Does Not Exist
-DirDoesntExist=The folder:%n%n%1%n%ndoes not exist. Would you like the folder to be created?
-
-; *** "Select Components" wizard page
-WizardSelectComponents=Select Components
-SelectComponentsDesc=Which components should be installed?
-SelectComponentsLabel2=Select the components you want to install; clear the components you do not want to install. Click Next when you are ready to continue.
-FullInstallation=Full installation
-; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
-CompactInstallation=Compact installation
-CustomInstallation=Custom installation
-NoUninstallWarningTitle=Components Exist
-NoUninstallWarning=Setup has detected that the following components are already installed on your computer:%n%n%1%n%nDeselecting these components will not uninstall them.%n%nWould you like to continue anyway?
-ComponentSize1=%1 KB
-ComponentSize2=%1 MB
-ComponentsDiskSpaceMBLabel=Current selection requires at least [mb] MB of disk space.
-
-; *** "Select Additional Tasks" wizard page
-WizardSelectTasks=Select Additional Tasks
-SelectTasksDesc=Which additional tasks should be performed?
-SelectTasksLabel2=Select the additional tasks you would like Setup to perform while installing [name], then click Next.
-
-; *** "Select Start Menu Folder" wizard page
-WizardSelectProgramGroup=Select Start Menu Folder
-SelectStartMenuFolderDesc=Where should Setup place the program's shortcuts?
-SelectStartMenuFolderLabel3=Setup will create the program's shortcuts in the following Start Menu folder.
-SelectStartMenuFolderBrowseLabel=To continue, click Next. If you would like to select a different folder, click Browse.
-MustEnterGroupName=You must enter a folder name.
-GroupNameTooLong=The folder name or path is too long.
-InvalidGroupName=The folder name is not valid.
-BadGroupName=The folder name cannot include any of the following characters:%n%n%1
-NoProgramGroupCheck2=&Don't create a Start Menu folder
-
-; *** "Ready to Install" wizard page
-WizardReady=Ready to Install
-ReadyLabel1=Setup is now ready to begin installing [name] on your computer.
-ReadyLabel2a=Click Install to continue with the installation, or click Back if you want to review or change any settings.
-ReadyLabel2b=Click Install to continue with the installation.
-ReadyMemoUserInfo=User information:
-ReadyMemoDir=Destination location:
-ReadyMemoType=Setup type:
-ReadyMemoComponents=Selected components:
-ReadyMemoGroup=Start Menu folder:
-ReadyMemoTasks=Additional tasks:
-
-; *** "Preparing to Install" wizard page
-WizardPreparing=Preparing to Install
-PreparingDesc=Setup is preparing to install [name] on your computer.
-PreviousInstallNotCompleted=The installation/removal of a previous program was not completed. You will need to restart your computer to complete that installation.%n%nAfter restarting your computer, run Setup again to complete the installation of [name].
-CannotContinue=Setup cannot continue. Please click Cancel to exit.
-ApplicationsFound=The following applications are using files that need to be updated by Setup. It is recommended that you allow Setup to automatically close these applications.
-ApplicationsFound2=The following applications are using files that need to be updated by Setup. It is recommended that you allow Setup to automatically close these applications. After the installation has completed, Setup will attempt to restart the applications.
-CloseApplications=&Automatically close the applications
-DontCloseApplications=&Do not close the applications
-ErrorCloseApplications=Setup was unable to automatically close all applications. It is recommended that you close all applications using files that need to be updated by Setup before continuing.
-
-; *** "Installing" wizard page
-WizardInstalling=Installing
-InstallingLabel=Please wait while Setup installs [name] on your computer.
-
-; *** "Setup Completed" wizard page
-FinishedHeadingLabel=Completing the [name] Setup Wizard
-FinishedLabelNoIcons=Setup has finished installing [name] on your computer.
-FinishedLabel=Setup has finished installing [name] on your computer. The application may be launched by selecting the installed icons.
-ClickFinish=Click Finish to exit Setup.
-FinishedRestartLabel=To complete the installation of [name], Setup must restart your computer. Would you like to restart now?
-FinishedRestartMessage=To complete the installation of [name], Setup must restart your computer.%n%nWould you like to restart now?
-ShowReadmeCheck=Yes, I would like to view the README file
-YesRadio=&Yes, restart the computer now
-NoRadio=&No, I will restart the computer later
-; used for example as 'Run MyProg.exe'
-RunEntryExec=Run %1
-; used for example as 'View Readme.txt'
-RunEntryShellExec=View %1
-
-; *** "Setup Needs the Next Disk" stuff
-ChangeDiskTitle=Setup Needs the Next Disk
-SelectDiskLabel2=Please insert Disk %1 and click OK.%n%nIf the files on this disk can be found in a folder other than the one displayed below, enter the correct path or click Browse.
-PathLabel=&Path:
-FileNotInDir2=The file "%1" could not be located in "%2". Please insert the correct disk or select another folder.
-SelectDirectoryLabel=Please specify the location of the next disk.
-
-; *** Installation phase messages
-SetupAborted=Setup was not completed.%n%nPlease correct the problem and run Setup again.
-EntryAbortRetryIgnore=Click Retry to try again, Ignore to proceed anyway, or Abort to cancel installation.
-
-; *** Installation status messages
-StatusClosingApplications=Closing applications...
-StatusCreateDirs=Creating directories...
-StatusExtractFiles=Extracting files...
-StatusCreateIcons=Creating shortcuts...
-StatusCreateIniEntries=Creating INI entries...
-StatusCreateRegistryEntries=Creating registry entries...
-StatusRegisterFiles=Registering files...
-StatusSavingUninstall=Saving uninstall information...
-StatusRunProgram=Finishing installation...
-StatusRestartingApplications=Restarting applications...
-StatusRollback=Rolling back changes...
-
-; *** Misc. errors
-ErrorInternal2=Internal error: %1
-ErrorFunctionFailedNoCode=%1 failed
-ErrorFunctionFailed=%1 failed; code %2
-ErrorFunctionFailedWithMessage=%1 failed; code %2.%n%3
-ErrorExecutingProgram=Unable to execute file:%n%1
-
-; *** Registry errors
-ErrorRegOpenKey=Error opening registry key:%n%1\%2
-ErrorRegCreateKey=Error creating registry key:%n%1\%2
-ErrorRegWriteKey=Error writing to registry key:%n%1\%2
-
-; *** INI errors
-ErrorIniEntry=Error creating INI entry in file "%1".
-
-; *** File copying errors
-FileAbortRetryIgnore=Click Retry to try again, Ignore to skip this file (not recommended), or Abort to cancel installation.
-FileAbortRetryIgnore2=Click Retry to try again, Ignore to proceed anyway (not recommended), or Abort to cancel installation.
-SourceIsCorrupted=The source file is corrupted
-SourceDoesntExist=The source file "%1" does not exist
-ExistingFileReadOnly=The existing file is marked as read-only.%n%nClick Retry to remove the read-only attribute and try again, Ignore to skip this file, or Abort to cancel installation.
-ErrorReadingExistingDest=An error occurred while trying to read the existing file:
-FileExists=The file already exists.%n%nWould you like Setup to overwrite it?
-ExistingFileNewer=The existing file is newer than the one Setup is trying to install. It is recommended that you keep the existing file.%n%nDo you want to keep the existing file?
-ErrorChangingAttr=An error occurred while trying to change the attributes of the existing file:
-ErrorCreatingTemp=An error occurred while trying to create a file in the destination directory:
-ErrorReadingSource=An error occurred while trying to read the source file:
-ErrorCopying=An error occurred while trying to copy a file:
-ErrorReplacingExistingFile=An error occurred while trying to replace the existing file:
-ErrorRestartReplace=RestartReplace failed:
-ErrorRenamingTemp=An error occurred while trying to rename a file in the destination directory:
-ErrorRegisterServer=Unable to register the DLL/OCX: %1
-ErrorRegSvr32Failed=RegSvr32 failed with exit code %1
-ErrorRegisterTypeLib=Unable to register the type library: %1
-
-; *** Post-installation errors
-ErrorOpeningReadme=An error occurred while trying to open the README file.
-ErrorRestartingComputer=Setup was unable to restart the computer. Please do this manually.
-
-; *** Uninstaller messages
-UninstallNotFound=File "%1" does not exist. Cannot uninstall.
-UninstallOpenError=File "%1" could not be opened. Cannot uninstall
-UninstallUnsupportedVer=The uninstall log file "%1" is in a format not recognized by this version of the uninstaller. Cannot uninstall
-UninstallUnknownEntry=An unknown entry (%1) was encountered in the uninstall log
-ConfirmUninstall=Are you sure you want to completely remove %1? Extensions and settings will not be removed.
-UninstallOnlyOnWin64=This installation can only be uninstalled on 64-bit Windows.
-OnlyAdminCanUninstall=This installation can only be uninstalled by a user with administrative privileges.
-UninstallStatusLabel=Please wait while %1 is removed from your computer.
-UninstalledAll=%1 was successfully removed from your computer.
-UninstalledMost=%1 uninstall complete.%n%nSome elements could not be removed. These can be removed manually.
-UninstalledAndNeedsRestart=To complete the uninstallation of %1, your computer must be restarted.%n%nWould you like to restart now?
-UninstallDataCorrupted="%1" file is corrupted. Cannot uninstall
-
-; *** Uninstallation phase messages
-ConfirmDeleteSharedFileTitle=Remove Shared File?
-ConfirmDeleteSharedFile2=The system indicates that the following shared file is no longer in use by any programs. Would you like for Uninstall to remove this shared file?%n%nIf any programs are still using this file and it is removed, those programs may not function properly. If you are unsure, choose No. Leaving the file on your system will not cause any harm.
-SharedFileNameLabel=File name:
-SharedFileLocationLabel=Location:
-WizardUninstalling=Uninstall Status
-StatusUninstalling=Uninstalling %1...
-
-; *** Shutdown block reasons
-ShutdownBlockReasonInstallingApp=Installing %1.
-ShutdownBlockReasonUninstallingApp=Uninstalling %1.
-
-; The custom messages below aren't used by Setup itself, but if you make
-; use of them in your scripts, you'll want to translate them.
-
-[CustomMessages]
-
-NameAndVersion=%1 version %2
-AdditionalIcons=Additional icons:
-CreateDesktopIcon=Create a &desktop icon
-CreateQuickLaunchIcon=Create a &Quick Launch icon
-ProgramOnTheWeb=%1 on the Web
-UninstallProgram=Uninstall %1
-LaunchProgram=Launch %1
-AssocFileExtension=&Associate %1 with the %2 file extension
-AssocingFileExtension=Associating %1 with the %2 file extension...
-AutoStartProgramGroupDescription=Startup:
-AutoStartProgram=Automatically start %1
-AddonHostProgramNotFound=%1 could not be located in the folder you selected.%n%nDo you want to continue anyway?
diff --git a/build/win32/i18n/Default.ko.isl b/build/win32/i18n/Default.ko.isl
index a7c38d12b9..0f1b1a7ccf 100644
--- a/build/win32/i18n/Default.ko.isl
+++ b/build/win32/i18n/Default.ko.isl
@@ -1,12 +1,16 @@
-; *** Inno Setup version 5.5.3+ Korean messages ***
-;
-; To download user-contributed translations of this file, go to:
-; http://www.jrsoftware.org/files/istrans/
+; *** Inno Setup version 6.0.0+ Korean messages ***
;
+; ˘Ć 6.0.3+ Translator: SungDong Kim (acroedit@gmail.com)
+; ˘Ć 5.5.3+ Translator: Domddol (domddol@gmail.com)
+; ˘Ć Translation date: MAR 04, 2014
+; ˘Ć Contributors: Hansoo KIM (iryna7@gmail.com), Woong-Jae An (a183393@hanmail.net)
+; ˘Ć Storage: http://www.jrsoftware.org/files/istrans/
+; ˘Ć ŔĚ šřżŞŔş ťőˇÎżî ÇŃąšžî ¸ÂĂăšý ąÔĢŔť ÁŘźöÇŐ´Ď´Ů.
; Note: When translating this text, do not add periods (.) to the end of
; messages that didn't have them already, because on those messages Inno
; Setup adds the periods automatically (appending a period would result in
; two periods being displayed).
+
[LangOptions]
; The following three entries are very important. Be sure to read and
; understand the '[LangOptions] section' topic in the help file.
@@ -23,50 +27,68 @@ LanguageCodePage=949
;TitleFontSize=29
;CopyrightFontName=Arial
;CopyrightFontSize=8
+
[Messages]
+
; *** Application titles
SetupAppTitle=źłÄĄ
-SetupWindowTitle=źłÄĄ - %1
+SetupWindowTitle=%1 źłÄĄ
UninstallAppTitle=ÁڰĹ
UninstallAppFullTitle=%1 ÁڰĹ
+
; *** Misc. common
InformationTitle=Á¤ş¸
ConfirmTitle=ČŽŔÎ
ErrorTitle=żŔˇů
+
; *** SetupLdr messages
-SetupLdrStartupMessage=ą×ˇŻ¸é %1ŔĚ(°Ą) źłÄĄľË´Ď´Ů. °čźÓÇϽðڽŔ´Ďąî?
-LdrCannotCreateTemp=Ŕӽà ĆÄŔĎŔť ¸¸ľé źö žř˝Ŕ´Ď´Ů. źłÄĄ ÇÁˇÎą×ˇĽŔĚ ÁߴܾǞú˝Ŕ´Ď´Ů.
-LdrCannotExecTemp=Ŕӽà ľđˇşĹÍ¸ŽżĄź ĆÄŔĎŔť ˝ÇÇŕÇŇ źö žř˝Ŕ´Ď´Ů. źłÄĄ ÇÁˇÎą×ˇĽŔĚ ÁߴܾǞú˝Ŕ´Ď´Ů.
+SetupLdrStartupMessage=%1Ŕť(¸Ś) źłÄĄÇŐ´Ď´Ů, °čźÓÇϽðڽŔ´Ďąî?
+LdrCannotCreateTemp=Ŕӽà ĆÄŔĎŔť ¸¸ľé źö žř˝Ŕ´Ď´Ů, źłÄĄ¸Ś Áß´ÜÇŐ´Ď´Ů
+LdrCannotExecTemp=Ŕӽà Ćú´őŔÇ ĆÄŔĎŔť ˝ÇÇŕÇŇ źö žř˝Ŕ´Ď´Ů, źłÄĄ¸Ś Áß´ÜÇŐ´Ď´Ů
+HelpTextNote=
+
; *** Startup error messages
LastErrorMessage=%1.%n%nżŔˇů %2: %3
-SetupFileMissing=ĆÄŔĎ %1ŔĚ(°Ą) źłÄĄ ľđˇşĹÍ¸ŽżĄź ´ŠśôľÇžú˝Ŕ´Ď´Ů. šŽÁŚ¸Ś ÇذáÇĎ°ĹłŞ ÇÁˇÎą×ˇĽŔť ťőˇÎ šŢŔ¸źźżä.
-SetupFileCorrupt=źłÄĄ ĆÄŔĎŔĚ źŐťóľÇžú˝Ŕ´Ď´Ů. ÇÁˇÎą×ˇĽŔť ťőˇÎ šŢŔ¸źźżä.
-SetupFileCorruptOrWrongVer=źłÄĄ ĆÄŔĎŔĚ źŐťóľÇžú°ĹłŞ ŔĚ šöŔüŔÇ źłÄĄ ÇÁˇÎą×ˇĽ°ú ČŁČŻľÇÁö žĘ˝Ŕ´Ď´Ů. šŽÁŚ¸Ś ÇذáÇĎ°ĹłŞ ÇÁˇÎą×ˇĽŔť ťőˇÎ šŢŔ¸źźżä.
-InvalidParameter=¸íˇÉÁŮżĄ Ŕ߸řľČ ¸Ĺ°ł şŻźö°Ą Ŕü´ŢľĘ:%n%n%1
-SetupAlreadyRunning=źłÄĄ ÇÁˇÎą×ˇĽŔĚ ŔĚšĚ ˝ÇÇŕ ÁßŔÔ´Ď´Ů.
-WindowsVersionNotSupported=ŔĚ ÇÁˇÎą×ˇĽŔş ÄÄÇťĹÍżĄź ˝ÇÇŕ ÁßŔÎ šöŔüŔÇ Windows¸Ś ÁöżřÇĎÁö žĘ˝Ŕ´Ď´Ů.
-WindowsServicePackRequired=ŔĚ ÇÁˇÎą×ˇĽŔť źłÄĄÇϡÁ¸é %1 źşń˝ş ĆŃ %2 ŔĚťóŔĚ ÇĘżäÇŐ´Ď´Ů.
-NotOnThisPlatform=ŔĚ ÇÁˇÎą×ˇĽŔş %1żĄź ˝ÇÇŕľÇÁö žĘ˝Ŕ´Ď´Ů.
+SetupFileMissing=%1 ĆÄŔĎŔĚ Á¸ŔçÇĎÁö žĘ˝Ŕ´Ď´Ů, šŽÁŚ¸Ś ÇذáÇŘ ş¸°ĹłŞ ťőˇÎżî źłÄĄ ÇÁˇÎą×ˇĽŔť ą¸ÇϽù⠚ٜř´Ď´Ů.
+SetupFileCorrupt=źłÄĄ ĆÄŔĎŔĚ źŐťóľÇžú˝Ŕ´Ď´Ů, ťőˇÎżî źłÄĄ ÇÁˇÎą×ˇĽŔť ą¸ÇϽù⠚ٜř´Ď´Ů.
+SetupFileCorruptOrWrongVer=źłÄĄ ĆÄŔĎŔÇ źŐťóŔĚ°ĹłŞ ŔĚ źłÄĄ šöŔü°ú ČŁČŻľÇÁö žĘ˝Ŕ´Ď´Ů, šŽÁŚ¸Ś ÇذáÇŘ ş¸°ĹłŞ ťőˇÎżî źłÄĄ ÇÁˇÎą×ˇĽŔť ą¸ÇϽù⠚ٜř´Ď´Ů.
+InvalidParameter=Ŕ߸řľČ ¸Ĺ°ł şŻźöŔÔ´Ď´Ů:%n%n%1
+SetupAlreadyRunning=źłÄĄ°Ą ŔĚšĚ ˝ÇÇŕ ÁßŔÔ´Ď´Ů.
+WindowsVersionNotSupported=ŔĚ ÇÁˇÎą×ˇĽŔş ąÍÇĎŔÇ Windows šöŔüŔť ÁöżřÇĎÁö žĘ˝Ŕ´Ď´Ů.
+WindowsServicePackRequired=ŔĚ ÇÁˇÎą×ˇĽŔť ˝ÇÇŕÇϡÁ¸é %1 sp%2 ŔĚťóŔĚžîžß ÇŐ´Ď´Ů.
+NotOnThisPlatform=ŔĚ ÇÁˇÎą×ˇĽŔş %1żĄź ŔŰľżÇĎÁö žĘ˝Ŕ´Ď´Ů.
OnlyOnThisPlatform=ŔĚ ÇÁˇÎą×ˇĽŔş %1żĄź ˝ÇÇŕÇŘžß ÇŐ´Ď´Ů.
-OnlyOnTheseArchitectures=ŔĚ ÇÁˇÎą×ˇĽŔş ÇÁˇÎźźź žĆŰĹŘĂł %n%n%1żëŔ¸ˇÎ źł°čľČ Windows šöŔüżĄź¸¸ źłÄĄÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
-MissingWOW64APIs=˝ÇÇŕ ÁßŔÎ Windows šöŔüżĄ´Â źłÄĄ ÇÁˇÎą×ˇĽżĄź 64şńĆŽ¸Ś źłÄĄÇĎ´Â ľĽ ÇĘżäÇŃ ąâ´ÉŔĚ žř˝Ŕ´Ď´Ů. ŔĚ šŽÁŚ¸Ś ÇذáÇϡÁ¸é źşń˝ş ĆŃ %1Ŕť(¸Ś) źłÄĄÇĎźźżä.
-WinVersionTooLowError=ŔĚ ÇÁˇÎą×ˇĽŔť źłÄĄÇϡÁ¸é %1 šöŔü %2 ŔĚťóŔĚ ÇĘżäÇŐ´Ď´Ů.
-WinVersionTooHighError=ŔĚ ÇÁˇÎą×ˇĽŔş %1 šöŔü %2 Ŕ̝󿥟´Â źłÄĄÇŇ źö žř˝Ŕ´Ď´Ů.
-AdminPrivilegesRequired=ŔĚ ÇÁˇÎą×ˇĽŔť źłÄĄÇŇ ś§´Â °ü¸ŽŔڡΠˇÎą×ŔÎÇŘžß ÇŐ´Ď´Ů.
-PowerUserPrivilegesRequired=ŔĚ ÇÁˇÎą×ˇĽŔť źłÄĄÇŇ ś§´Â °ü¸ŽŔÚłŞ °íąŢ ťçżëŔÚ ą×ˇěŔÇ ą¸źşżřŔ¸ˇÎ ˇÎą×ŔÎÇŘžß ÇŐ´Ď´Ů.
-SetupAppRunningError=źłÄĄ ÇÁˇÎą×ˇĽżĄź %1(ŔĚ)°Ą ÇöŔç ˝ÇÇŕ ÁßŔÓŔť °¨ÁöÇß˝Ŕ´Ď´Ů.%n%nŔĚ Ç׸ńŔÇ ¸đľç ŔνşĹĎ˝ş¸Ś ÁöąÝ ´Ý°í °čźÓÇϡÁ¸é [ČŽŔÎ]Ŕť, ÁžˇáÇϡÁ¸é [ĂëźŇ]¸Ś ĹŹ¸ŻÇĎźźżä.
-UninstallAppRunningError=ÁŚ°Ĺ ŔŰž÷żĄź %1(ŔĚ)°Ą ÇöŔç ˝ÇÇŕ ÁßŔÓŔť °¨ÁöÇß˝Ŕ´Ď´Ů.%n%nŔĚ Ç׸ńŔÇ ¸đľç ŔνşĹĎ˝ş¸Ś ÁöąÝ ´Ý°í °čźÓÇϡÁ¸é [ČŽŔÎ]Ŕť, ÁžˇáÇϡÁ¸é [ĂëźŇ]¸Ś ĹŹ¸ŻÇĎźźżä.
+OnlyOnTheseArchitectures=ŔĚ ÇÁˇÎą×ˇĽŔş žĆˇĄ Ăł¸Ž ą¸ÁśżÍ ČŁČŻľÇ´Â Windows šöŔüżĄ¸¸ źłÄĄÇŇ źö ŔÖ˝Ŕ´Ď´Ů:%n%n%1
+WinVersionTooLowError=ŔĚ ÇÁˇÎą×ˇĽŔş %1 šöŔü %2 ŔĚťóŔĚ ÇĘżäÇŐ´Ď´Ů.
+WinVersionTooHighError=ŔĚ ÇÁˇÎą×ˇĽŔş %1 šöŔü %2 Ŕ̝󿥟 źłÄĄÇŇ źö žř˝Ŕ´Ď´Ů.
+AdminPrivilegesRequired=ŔĚ ÇÁˇÎą×ˇĽŔť źłÄĄÇϡÁ¸é °ü¸ŽŔڡΠˇÎą×ŔÎÇŘžß ÇŐ´Ď´Ů.
+PowerUserPrivilegesRequired=ŔĚ ÇÁˇÎą×ˇĽŔť źłÄĄÇϡÁ¸é °ü¸ŽŔÚ śÇ´Â °íąŢ ťçżëŔڡΠˇÎą×ŔÎÇŘžß ÇŐ´Ď´Ů.
+SetupAppRunningError=ÇöŔç %1ŔĚ(°Ą) ˝ÇÇŕ ÁßŔÔ´Ď´Ů!%n%nÁöąÝ ą×°ÍŔÇ ¸đľç ŔνşĹĎ˝ş¸Ś ´ÝžĆ ÁֽʽÿŔ. ą×ˇą ´ŮŔ˝ °čźÓÇϡÁ¸é "ČŽŔÎ"Ŕť, ÁžˇáÇϡÁ¸é "ĂëźŇ"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
+UninstallAppRunningError=ÇöŔç %1ŔĚ(°Ą) ˝ÇÇŕ ÁßŔÔ´Ď´Ů!%n%nÁöąÝ ą×°ÍŔÇ ¸đľç ŔνşĹĎ˝ş¸Ś ´ÝžĆ ÁֽʽÿŔ. ą×ˇą ´ŮŔ˝ °čźÓÇϡÁ¸é "ČŽŔÎ"Ŕť, ÁžˇáÇϡÁ¸é "ĂëźŇ"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
+
+; *** Startup questions
+PrivilegesRequiredOverrideTitle=źłÄĄ ¸đľĺ źąĹĂ
+PrivilegesRequiredOverrideInstruction=źłÄĄ ¸đľĺ¸Ś źąĹĂÇŘ ÁֽʽÿŔ
+PrivilegesRequiredOverrideText1=%1 Ŕş ¸đľç ťçżëŔÚ(°ü¸ŽŔÚ ąÇÇŃ ÇĘżä) śÇ´Â ÇöŔç ťçżëŔÚżëŔ¸ˇÎ źłÄĄÇŐ´Ď´Ů.
+PrivilegesRequiredOverrideText2=%1 Ŕş ÇöŔç ťçżëŔÚ śÇ´Â ¸đľç ťçżëŔÚ(°ü¸ŽŔÚ ąÇÇŃ ÇĘżä) żëŔ¸ˇÎ źłÄĄÇŐ´Ď´Ů.
+PrivilegesRequiredOverrideAllUsers=¸đľç ťçżëŔÚżëŔ¸ˇÎ źłÄĄ(&A)
+PrivilegesRequiredOverrideAllUsersRecommended=¸đľç ťçżëŔÚżëŔ¸ˇÎ źłÄĄ(&A) (ĂßĂľ)
+PrivilegesRequiredOverrideCurrentUser=ÇöŔç ťçżëŔÚżëŔ¸ˇÎ źłÄĄ(&M)
+PrivilegesRequiredOverrideCurrentUserRecommended=ÇöŔç ťçżëŔÚżëŔ¸ˇÎ źłÄĄ(&M) (ĂßĂľ)
+
; *** Misc. errors
-ErrorCreatingDir=źłÄĄ ÇÁˇÎą×ˇĽżĄź ľđˇşĹÍ¸Ž "%1"Ŕť(¸Ś) ¸¸ľé źö žř˝Ŕ´Ď´Ů.
-ErrorTooManyFilesInDir=ľđˇşĹÍ¸Ž "%1"żĄ ĆÄŔĎŔĚ łĘšŤ ¸šŔ¸šÇˇÎ ŔĚ ľđˇşĹÍ¸ŽżĄ ĆÄŔĎŔť ¸¸ľé źö žř˝Ŕ´Ď´Ů.
+ErrorCreatingDir="%1" Ćú´ő¸Ś ¸¸ľé źö žř˝Ŕ´Ď´Ů.
+ErrorTooManyFilesInDir="%1" Ćú´őżĄ ĆÄŔĎŔĚ łĘšŤ ¸šąâ ś§šŽżĄ ĆÄŔĎŔť ¸¸ľé źö žř˝Ŕ´Ď´Ů.
+
; *** Setup common messages
-ExitSetupTitle=źłÄĄ Ážˇá
-ExitSetupMessage=źłÄĄ°Ą żĎˇáľÇÁö žĘžŇ˝Ŕ´Ď´Ů. ÁöąÝ ÁžˇáÇϸé ÇÁˇÎą×ˇĽŔĚ źłÄĄľÇÁö žĘ˝Ŕ´Ď´Ů.%n%nłŞÁßżĄ źłÄĄ ÇÁˇÎą×ˇĽŔť ´Ů˝Ă ˝ÇÇŕÇĎżŠ źłÄĄ¸Ś łĄłž źö ŔÖ˝Ŕ´Ď´Ů.%n%nźłÄĄ ÇÁˇÎą×ˇĽŔť ÁžˇáÇϽðڽŔ´Ďąî?
-AboutSetupMenuItem=źłÄĄ ÇÁˇÎą×ˇĽ Á¤ş¸(&A)...
-AboutSetupTitle=źłÄĄ ÇÁˇÎą×ˇĽ Á¤ş¸
-AboutSetupMessage=%1 šöŔü %2%n%3%n%n%1 ȨĆäŔĚÁö:%n%4
+ExitSetupTitle=źłÄĄ żĎˇá
+ExitSetupMessage=źłÄĄ°Ą żĎˇáľÇÁö žĘžŇ˝Ŕ´Ď´Ů, żŠąâź źłÄĄ¸Ś ÁžˇáÇϸé ÇÁˇÎą×ˇĽŔş źłÄĄľÇÁö žĘ˝Ŕ´Ď´Ů.%n%nźłÄĄ¸Ś żĎˇáÇϡÁ¸é łŞÁßżĄ ´Ů˝Ă źłÄĄ ÇÁˇÎą×ˇĽŔť ˝ÇÇŕÇŘžß ÇŐ´Ď´Ů.%n%ną×ˇĄľľ źłÄĄ¸Ś ÁžˇáÇϽðڽŔ´Ďąî?
+AboutSetupMenuItem=źłÄĄ Á¤ş¸(&A)...
+AboutSetupTitle=źłÄĄ Á¤ş¸
+AboutSetupMessage=%1 šöŔü %2%n%3%n%n%1 Ȩ ĆäŔĚÁö:%n%4
AboutSetupNote=
TranslatorNote=
+
; *** Buttons
ButtonBack=< ľÚˇÎ(&B)
ButtonNext=´ŮŔ˝(&N) >
@@ -75,224 +97,271 @@ ButtonOK=ČŽ
ButtonCancel=ĂëźŇ
ButtonYes=żš(&Y)
ButtonYesToAll=¸đľÎ żš(&A)
-ButtonNo=žĆ´Ďżä(&N)
-ButtonNoToAll=¸đľÎ žĆ´Ďżä(&O)
-ButtonFinish=¸śÄ§(&F)
+ButtonNo=žĆ´ĎżŔ(&N)
+ButtonNoToAll=¸đľÎ žĆ´ĎżŔ(&O)
+ButtonFinish=Ážˇá(&F)
ButtonBrowse=ĂŁžĆş¸ąâ(&B)...
-ButtonWizardBrowse=ĂŁžĆş¸ąâ(&R)
+ButtonWizardBrowse=ĂŁžĆş¸ąâ(&R)...
ButtonNewFolder=ťő Ćú´ő ¸¸ľéąâ(&M)
+
; *** "Select Language" dialog messages
SelectLanguageTitle=źłÄĄ žđžî źąĹĂ
-SelectLanguageLabel=źłÄĄ ÁßżĄ ťçżëÇŇ žđžî¸Ś źąĹĂÇĎźźżä.
+SelectLanguageLabel=źłÄĄżĄ ťçżëÇŇ žđžî¸Ś źąĹĂÇϽʽÿŔ.
+
; *** Common wizard text
-ClickNext=°čźÓÇϡÁ¸é [´ŮŔ˝]Ŕť ĹŹ¸ŻÇĎ°í źłÄĄ ÇÁˇÎą×ˇĽŔť ÁžˇáÇϡÁ¸é [ĂëźŇ]¸Ś ĹŹ¸ŻÇĎźźżä.
+ClickNext=°čźÓÇϡÁ¸é "´ŮŔ˝"Ŕť ĹŹ¸ŻÇĎ°í źłÄĄ¸Ś ÁžˇáÇϡÁ¸é "ĂëźŇ"¸Ś ĹŹ¸ŻÇŐ´Ď´Ů.
BeveledLabel=
BrowseDialogTitle=Ćú´ő ĂŁžĆş¸ąâ
-BrowseDialogLabel=žĆˇĄ ¸ńˇĎżĄź Ćú´ő¸Ś źąĹĂÇŃ ´ŮŔ˝ [ČŽŔÎ]Ŕť ĹŹ¸ŻÇĎźźżä.
+BrowseDialogLabel=žĆˇĄ ¸ńˇĎżĄź Ćú´ő¸Ś źąĹĂÇŃ ´ŮŔ˝ "ČŽŔÎ"Ŕť ĹŹ¸ŻÇŐ´Ď´Ů.
NewFolderName=ťő Ćú´ő
+
; *** "Welcome" wizard page
WelcomeLabel1=[name] źłÄĄ ¸śšýťç ˝ĂŔŰ
-WelcomeLabel2=ŔĚ ¸śšýťç´Â ÄÄÇťĹÍżĄ [name/ver]Ŕť(¸Ś) źłÄĄÇŐ´Ď´Ů.%n%n°čźÓÇĎąâ ŔüżĄ ´Ů¸Ľ ¸đľç ŔŔżë ÇÁˇÎą×ˇĽŔť ´Ý´Â °ÍŔĚ ÁÁ˝Ŕ´Ď´Ů.
+WelcomeLabel2=ŔĚ ¸śšýťç´Â ąÍÇĎŔÇ ÄÄÇťĹÍżĄ [name/ver]Ŕť(¸Ś) źłÄĄÇŇ °ÍŔÔ´Ď´Ů.%n%nźłÄĄÇĎąâ ŔüżĄ ´Ů¸Ľ ŔŔżëÇÁˇÎą×ˇĽľéŔť ¸đľÎ ´ÝŔ¸˝Ăąâ šŮśř´Ď´Ů.
+
; *** "Password" wizard page
-WizardPassword=žĎČŁ
-PasswordLabel1=ŔĚ źłÄĄ´Â žĎČŁˇÎ ş¸ČŁľÇ°í ŔÖ˝Ŕ´Ď´Ů.
-PasswordLabel3=°čźÓÇϡÁ¸é žĎČŁ¸Ś ŔÔˇÂÇŃ ´ŮŔ˝ [´ŮŔ˝]Ŕť ĹŹ¸ŻÇĎźźżä. žĎČŁ´Â ´ëźŇšŽŔÚ¸Ś ą¸şĐÇŐ´Ď´Ů.
-PasswordEditLabel=žĎČŁ(&P):
-IncorrectPassword=ŔÔˇÂÇŃ žĎČŁ°Ą Ŕ߸řľÇžú˝Ŕ´Ď´Ů. ´Ů˝Ă ˝ĂľľÇĎźźżä.
+WizardPassword=şńšĐ šřČŁ
+PasswordLabel1=ŔĚ źłÄĄ ¸śšýťç´Â şńšĐ šřČŁˇÎ ş¸ČŁľÇžî ŔÖ˝Ŕ´Ď´Ů.
+PasswordLabel3=şńšĐ šřČŁ¸Ś ŔÔˇÂÇϰí "´ŮŔ˝"Ŕť ĹŹ¸ŻÇϽʽÿŔ. şńšĐ šřČŁ´Â ´ëźŇšŽŔÚ¸Ś ą¸şĐÇŘžß ÇŐ´Ď´Ů.
+PasswordEditLabel=şńšĐ šřČŁ(&P):
+IncorrectPassword=şńšĐ šřČŁ°Ą Á¤ČŽÇĎÁö žĘ˝Ŕ´Ď´Ů, ´Ů˝Ă ŔÔˇÂÇϽʽÿŔ.
+
; *** "License Agreement" wizard page
WizardLicense=ťçżëąÇ °čžŕ
-LicenseLabel=°čźÓÇĎąâ ŔüżĄ ´ŮŔ˝ ÁßżäÇŃ Á¤ş¸¸Ś ŔĐžî ş¸źźżä.
-LicenseLabel3=´ŮŔ˝ ťçżëąÇ °čžŕŔť ŔĐžî ÁÖźźżä. źłÄĄ¸Ś °čźÓÇϡÁ¸é ¸ŐŔú ŔĚ °čžŕ Áś°ÇżĄ ľżŔÇÇŘžß ÇŐ´Ď´Ů.
-LicenseAccepted=°čžŕżĄ ľżŔÇÇÔ(&A)
-LicenseNotAccepted=°čžŕżĄ ľżŔÇ žČ ÇÔ(&D)
+LicenseLabel=°čźÓÇĎąâ ŔüżĄ ´ŮŔ˝ŔÇ Áßżä Á¤ş¸¸Ś ŔО˝Ę˝ĂżŔ.
+LicenseLabel3=´ŮŔ˝ ťçżëąÇ °čžŕŔť ŔО˝Ę˝ĂżŔ, źłÄĄ¸Ś °čźÓÇϡÁ¸é ŔĚ °čžŕżĄ ľżŔÇÇŘžß ÇŐ´Ď´Ů.
+LicenseAccepted=ľżŔÇÇŐ´Ď´Ů(&A)
+LicenseNotAccepted=ľżŔÇÇĎÁö žĘ˝Ŕ´Ď´Ů(&D)
+
; *** "Information" wizard pages
WizardInfoBefore=Á¤ş¸
-InfoBeforeLabel=°čźÓÇĎąâ ŔüżĄ ´ŮŔ˝ ÁßżäÇŃ Á¤ş¸¸Ś ŔĐžî ş¸źźżä.
-InfoBeforeClickLabel=źłÄĄ¸Ś °čźÓ ÁřÇŕÇŇ ÁŘşń°Ą ľÇ¸é [´ŮŔ˝]Ŕť ĹŹ¸ŻÇŐ´Ď´Ů.
+InfoBeforeLabel=°čźÓÇĎąâ ŔüżĄ ´ŮŔ˝ŔÇ Áßżä Á¤ş¸¸Ś ŔО˝Ę˝ĂżŔ.
+InfoBeforeClickLabel=źłÄĄ¸Ś °čźÓÇϡÁ¸é "´ŮŔ˝"Ŕť ĹŹ¸ŻÇϽʽÿŔ.
WizardInfoAfter=Á¤ş¸
-InfoAfterLabel=°čźÓÇĎąâ ŔüżĄ ´ŮŔ˝ ÁßżäÇŃ Á¤ş¸¸Ś ŔĐžî ş¸źźżä.
-InfoAfterClickLabel=źłÄĄ¸Ś °čźÓ ÁřÇŕÇŇ ÁŘşń°Ą ľÇ¸é [´ŮŔ˝]Ŕť ĹŹ¸ŻÇŐ´Ď´Ů.
+InfoAfterLabel=°čźÓÇĎąâ ŔüżĄ ´ŮŔ˝ŔÇ Áßżä Á¤ş¸¸Ś ŔО˝Ę˝ĂżŔ.
+InfoAfterClickLabel=źłÄĄ¸Ś °čźÓÇϡÁ¸é "´ŮŔ˝"Ŕť ĹŹ¸ŻÇϽʽÿŔ.
+
; *** "User Information" wizard page
WizardUserInfo=ťçżëŔÚ Á¤ş¸
-UserInfoDesc=Á¤ş¸¸Ś ŔÔˇÂÇĎźźżä.
+UserInfoDesc=ťçżëŔÚ Á¤ş¸¸Ś ŔÔˇÂÇϽʽÿŔ.
UserInfoName=ťçżëŔÚ Ŕ̸§(&U):
UserInfoOrg=ÁśÁ÷(&O):
-UserInfoSerial=Ŕϡà šřČŁ(&S):
-UserInfoNameRequired=Ŕ̸§Ŕť ŔÔˇÂÇŘžß ÇŐ´Ď´Ů.
+UserInfoSerial=˝Ă¸Žžó šřČŁ(&S):
+UserInfoNameRequired=ťçżëŔÚ Ŕ̸§Ŕť ŔÔˇÂÇϽʽÿŔ.
+
; *** "Select Destination Location" wizard page
-WizardSelectDir=´ëťó Ŕ§ÄĄ źąĹĂ
-SelectDirDesc=[name]Ŕť(¸Ś) žîľđżĄ źłÄĄÇϽðڽŔ´Ďąî?
-SelectDirLabel3=źłÄĄ ÇÁˇÎą×ˇĽżĄź [name]Ŕť(¸Ś) ´ŮŔ˝ Ćú´őżĄ źłÄĄÇŐ´Ď´Ů.
-SelectDirBrowseLabel=°čźÓÇϡÁ¸é [´ŮŔ˝]Ŕť ĹŹ¸ŻÇĎźźżä. ´Ů¸Ľ Ćú´ő¸Ś źąĹĂÇϡÁ¸é [ĂŁžĆş¸ąâ]¸Ś ĹŹ¸ŻÇĎźźżä.
-DiskSpaceMBLabel=Ŕűžîľľ [mb]MBŔÇ żŠŔŻ ľđ˝şĹŠ °ř°ŁŔĚ ÇĘżäÇŐ´Ď´Ů.
-CannotInstallToNetworkDrive=źłÄĄ ÇÁˇÎą×ˇĽŔş ł×ĆŽżöĹŠ ľĺśóŔ̺꿥 źłÄĄÇŇ źö žř˝Ŕ´Ď´Ů.
-CannotInstallToUNCPath=źłÄĄ ÇÁˇÎą×ˇĽŔş UNC °ćˇÎżĄ źłÄĄÇŇ źö žř˝Ŕ´Ď´Ů.
-InvalidPath=ľĺśóŔĚşę šŽŔÚżÍ ÇÔ˛˛ ŔüĂź °ćˇÎ¸Ś ŔÔˇÂÇŘžß ÇŐ´Ď´Ů. żš:%n%nC:\APP%n%nśÇ´Â ´ŮŔ˝ ÇüĹÂŔÇ UNC °ćˇÎ:%n%n\\server\share
-InvalidDrive=źąĹĂÇŃ ľĺśóŔ̺곪 UNC °řŔݰĄ žř°ĹłŞ ŔĚ ľÎ Ç׸ńżĄ ž×źź˝şÇŇ źö žř˝Ŕ´Ď´Ů. ´Ů¸Ľ ľĺśóŔ̺곪 UNC °řŔŻ¸Ś źąĹĂÇĎźźżä.
-DiskSpaceWarningTitle=ľđ˝şĹŠ °ř°Ł şÎÁˇ
-DiskSpaceWarning=źłÄĄ ÇÁˇÎą×ˇĽŔť źłÄĄÇϡÁ¸é żŠŔŻ źłÄĄ °ř°ŁŔĚ Ŕűžîľľ %1KB°Ą ÇĘżäÇĎÁö¸¸ źąĹĂÇŃ ľĺśóŔĚşęŔÇ °Ążë °ř°ŁŔş %2KBšŰżĄ žř˝Ŕ´Ď´Ů.%n%ną×ˇĄľľ °čźÓÇϽðڽŔ´Ďąî?
+WizardSelectDir=źłÄĄ Ŕ§ÄĄ źąĹĂ
+SelectDirDesc=[name]ŔÇ źłÄĄ Ŕ§ÄĄ¸Ś źąĹĂÇϽʽÿŔ.
+SelectDirLabel3=´ŮŔ˝ Ćú´őżĄ [name]Ŕť(¸Ś) źłÄĄÇŐ´Ď´Ů.
+SelectDirBrowseLabel=°čźÓÇϡÁ¸é "´ŮŔ˝"Ŕť, ´Ů¸Ľ Ćú´ő¸Ś źąĹĂÇϡÁ¸é "ĂŁžĆş¸ąâ"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
+DiskSpaceGBLabel=ŔĚ ÇÁˇÎą×ˇĽŔş ĂÖźŇ [gb] GBŔÇ ľđ˝şĹŠ żŠŔŻ °ř°ŁŔĚ ÇĘżäÇŐ´Ď´Ů.
+DiskSpaceMBLabel=ŔĚ ÇÁˇÎą×ˇĽŔş ĂÖźŇ [mb] MBŔÇ ľđ˝şĹŠ żŠŔŻ °ř°ŁŔĚ ÇĘżäÇŐ´Ď´Ů.
+CannotInstallToNetworkDrive=ł×ĆŽżöĹŠ ľĺśóŔ̺꿥 źłÄĄÇŇ źö žř˝Ŕ´Ď´Ů.
+CannotInstallToUNCPath=UNC °ćˇÎżĄ źłÄĄÇŇ źö žř˝Ŕ´Ď´Ů.
+InvalidPath=ľĺśóŔĚşę šŽŔÚ¸Ś Ć÷ÇÔÇŃ ŔüĂź °ćˇÎ¸Ś ŔÔˇÂÇϽʽÿŔ.%nĄŘ żš: C:\APP %n%nśÇ´Â, UNC Çü˝ÄŔÇ °ćˇÎ¸Ś ŔÔˇÂÇϽʽÿŔ.%nĄŘ żš: \\server\share
+InvalidDrive=źąĹĂÇŃ ľĺśóŔĚşę śÇ´Â UNC °řŔݰĄ Á¸ŔçÇĎÁö žĘ°ĹłŞ ž×źź˝şÇŇ źö žř˝Ŕ´Ď´Ů, ´Ů¸Ľ °ćˇÎ¸Ś źąĹĂÇϽʽÿŔ.
+DiskSpaceWarningTitle=ľđ˝şĹŠ °ř°ŁŔĚ şÎÁˇÇŐ´Ď´Ů
+DiskSpaceWarning=źłÄĄ ˝Ă ĂÖźŇ %1 KB ľđ˝şĹŠ °ř°ŁŔĚ ÇĘżäÇĎÁö¸¸, źąĹĂÇŃ ľĺśóŔĚşęŔÇ żŠŔŻ °ř°ŁŔş %2 KB šŰżĄ žř˝Ŕ´Ď´Ů.%n%ną×ˇĄľľ °čźÓÇϽðڽŔ´Ďąî?
DirNameTooLong=Ćú´ő Ŕ̸§ śÇ´Â °ćˇÎ°Ą łĘšŤ ąé´Ď´Ů.
-InvalidDirName=Ćú´ő Ŕ̸§ŔĚ Ŕ߸řľÇžú˝Ŕ´Ď´Ů.
-BadDirName32=Ćú´ő Ŕ̸§żĄ´Â %n%n%1 šŽŔÚ¸Ś ťçżëÇŇ źö žř˝Ŕ´Ď´Ů.
-DirExistsTitle=Ćú´ő ŔÖŔ˝
-DirExists=Ćú´ő %n%n%1%n%nŔĚ(°Ą) ŔĚšĚ ŔÖ˝Ŕ´Ď´Ů. ą×ˇĄľľ ÇŘ´ç Ćú´őżĄ źłÄĄÇϽðڽŔ´Ďąî?
-DirDoesntExistTitle=Ćú´ő žřŔ˝
-DirDoesntExist=Ćú´ő %n%n%1%n%nŔĚ(°Ą) žř˝Ŕ´Ď´Ů. Ćú´ő¸Ś ¸¸ľĺ˝Ă°Ú˝Ŕ´Ďąî?
+InvalidDirName=Ćú´ő Ŕ̸§ŔĚ ŔŻČżÇĎÁö žĘ˝Ŕ´Ď´Ů.
+BadDirName32=Ćú´ő Ŕ̸§Ŕş ´ŮŔ˝ šŽŔÚ¸Ś Ć÷ÇÔÇŇ źö žř˝Ŕ´Ď´Ů:%n%n%1
+DirExistsTitle=Ćú´ő°Ą Á¸ŔçÇŐ´Ď´Ů
+DirExists=Ćú´ő %n%n%1%n%nŔĚ(°Ą) ŔĚšĚ Á¸ŔçÇŐ´Ď´Ů, ŔĚ Ćú´őżĄ źłÄĄÇϽðڽŔ´Ďąî?
+DirDoesntExistTitle=Ćú´ő°Ą Á¸ŔçÇĎÁö žĘ˝Ŕ´Ď´Ů
+DirDoesntExist=Ćú´ő %n%n%1%n%nŔĚ(°Ą) Á¸ŔçÇĎÁö žĘ˝Ŕ´Ď´Ů, ťőˇÎ Ćú´ő¸Ś ¸¸ľĺ˝Ă°Ú˝Ŕ´Ďąî?
+
; *** "Select Components" wizard page
WizardSelectComponents=ą¸źş żäźŇ źąĹĂ
-SelectComponentsDesc=žîś˛ ą¸źş żäźŇ¸Ś źłÄĄÇϽðڽŔ´Ďąî?
-SelectComponentsLabel2=źłÄĄÇŇ ą¸źş żäźŇ´Â źąĹĂÇĎ°í źłÄĄÇĎÁö žĘŔť ą¸źş żäźŇ´Â Áöżěźźżä. °čźÓ ÁřÇŕÇŇ ÁŘşń°Ą ľÇ¸é [´ŮŔ˝]Ŕť ĹŹ¸ŻÇĎźźżä.
-FullInstallation=ŔüĂź źłÄĄ
+SelectComponentsDesc=źłÄĄÇŇ ą¸źş żäźŇ¸Ś źąĹĂÇϽʽÿŔ.
+SelectComponentsLabel2=ÇĘżäÇŃ ą¸źş żäźŇ´Â ßŊÇĎ°í şŇÇĘżäÇŃ ą¸źş żäźŇ´Â ßŊ ÇŘÁŚÇŐ´Ď´Ů, °čźÓÇϡÁ¸é "´ŮŔ˝"Ŕť ĹŹ¸ŻÇϽʽÿŔ.
+FullInstallation=¸đľÎ źłÄĄ
; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
-CompactInstallation=Compact źłÄĄ
+CompactInstallation=ĂÖźŇ źłÄĄ
CustomInstallation=ťçżëŔÚ ÁöÁ¤ źłÄĄ
-NoUninstallWarningTitle=ą¸źş żäźŇ°Ą ŔÖŔ˝
-NoUninstallWarning=źłÄĄ ÇÁˇÎą×ˇĽżĄź ą¸źş żäźŇ %n%n%1%n%nŔĚ(°Ą) ÄÄÇťĹÍżĄ ŔĚšĚ źłÄĄľÇžî ŔÖŔ˝Ŕť °¨ÁöÇß˝Ŕ´Ď´Ů. Ŕ̡ŻÇŃ ą¸źş żäźŇ´Â źąĹĂ ĂëźŇÇŘľľ ÁŚ°ĹľÇÁö žĘ˝Ŕ´Ď´Ů.%n%ną×ˇĄľľ °čźÓÇϽðڽŔ´Ďąî?
-ComponentSize1=%1KB
-ComponentSize2=%1MB
-ComponentsDiskSpaceMBLabel=ÇöŔç źąĹĂŔť Ŕ§ÇŘź´Â Ŕűžîľľ [mb]MBŔÇ ľđ˝şĹŠ °ř°ŁŔĚ ÇĘżäÇŐ´Ď´Ů.
+NoUninstallWarningTitle=ą¸źş żäźŇ°Ą Á¸ŔçÇŐ´Ď´Ů
+NoUninstallWarning=´ŮŔ˝ ą¸źş żäźŇ°Ą ŔĚšĚ źłÄĄľÇžî ŔÖ˝Ŕ´Ď´Ů:%n%n%1%n%nŔ§ ą¸źş żäźŇŔť źąĹĂÇĎÁö žĘŔ¸¸é, ÇÁˇÎą×ˇĽ ÁŚ°Ĺ˝Ă ŔĚ ą¸źş żäźŇľéŔş ÁŚ°ĹľÇÁö žĘŔť °Ě´Ď´Ů.%n%ną×ˇĄľľ °čźÓÇϽðڽŔ´Ďąî?
+ComponentSize1=%1 KB
+ComponentSize2=%1 MB
+ComponentsDiskSpaceGBLabel=ÇöŔç źąĹĂŔş ĂÖźŇ [gb] GBŔÇ ľđ˝şĹŠ żŠŔŻ °ř°ŁŔĚ ÇĘżäÇŐ´Ď´Ů.
+ComponentsDiskSpaceMBLabel=ÇöŔç źąĹĂŔş ĂÖźŇ [mb] MBŔÇ ľđ˝şĹŠ żŠŔŻ °ř°ŁŔĚ ÇĘżäÇŐ´Ď´Ů.
+
; *** "Select Additional Tasks" wizard page
WizardSelectTasks=Ăß°Ą ŔŰž÷ źąĹĂ
-SelectTasksDesc=žîś˛ ŔŰž÷Ŕť Ăß°ĄˇÎ źöÇŕÇϽðڽŔ´Ďąî?
-SelectTasksLabel2=źłÄĄ ÇÁˇÎą×ˇĽżĄź [name]Ŕť(¸Ś) źłÄĄÇĎ´Â ľżžČ źöÇŕÇŇ Ăß°Ą ŔŰž÷Ŕť źąĹĂÇŃ ČÄ [´ŮŔ˝]Ŕť ĹŹ¸ŻÇĎźźżä.
+SelectTasksDesc=źöÇŕÇŇ Ăß°Ą ŔŰž÷Ŕť źąĹĂÇϽʽÿŔ.
+SelectTasksLabel2=[name] źłÄĄ °úÁ¤żĄ Ć÷ÇÔÇŇ Ăß°Ą ŔŰž÷Ŕť źąĹĂÇŃ ČÄ, "´ŮŔ˝"Ŕť ĹŹ¸ŻÇϽʽÿŔ.
+
; *** "Select Start Menu Folder" wizard page
WizardSelectProgramGroup=˝ĂŔŰ ¸Ţ´ş Ćú´ő źąĹĂ
-SelectStartMenuFolderDesc=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÇÁˇÎą×ˇĽŔÇ šŮˇÎ °Ąąâ¸Ś žîľđżĄ ¸¸ľéľľˇĎ ÇϽðڽŔ´Ďąî?
-SelectStartMenuFolderLabel3=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÇÁˇÎą×ˇĽŔÇ šŮˇÎ °Ąąâ¸Ś ´ŮŔ˝ ˝ĂŔŰ ¸Ţ´ş Ćú´őżĄ ¸¸ľě´Ď´Ů.
-SelectStartMenuFolderBrowseLabel=°čźÓÇϡÁ¸é [´ŮŔ˝]Ŕť ĹŹ¸ŻÇĎźźżä. ´Ů¸Ľ Ćú´ő¸Ś źąĹĂÇϡÁ¸é [ĂŁžĆş¸ąâ]¸Ś ĹŹ¸ŻÇĎźźżä.
-MustEnterGroupName=Ćú´ő Ŕ̸§Ŕť ŔÔˇÂÇŘžß ÇŐ´Ď´Ů.
+SelectStartMenuFolderDesc=žîľđżĄ ÇÁˇÎą×ˇĽ šŮˇÎ°Ąąâ¸Ś Ŕ§ÄĄÇϰڽŔ´Ďąî?
+SelectStartMenuFolderLabel3=´ŮŔ˝ ˝ĂŔŰ ¸Ţ´ş Ćú´őżĄ ÇÁˇÎą×ˇĽ šŮˇÎ°Ąąâ¸Ś ¸¸ľě´Ď´Ů.
+SelectStartMenuFolderBrowseLabel=°čźÓÇϡÁ¸é "´ŮŔ˝"Ŕť ĹŹ¸ŻÇϰí, ´Ů¸Ľ Ćú´ő¸Ś źąĹĂÇϡÁ¸é "ĂŁžĆş¸ąâ"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
+MustEnterGroupName=Ćú´ő Ŕ̸§Ŕť ŔÔˇÂÇϽʽÿŔ.
GroupNameTooLong=Ćú´ő Ŕ̸§ śÇ´Â °ćˇÎ°Ą łĘšŤ ąé´Ď´Ů.
-InvalidGroupName=Ćú´ő Ŕ̸§ŔĚ Ŕ߸řľÇžú˝Ŕ´Ď´Ů.
-BadGroupName=Ćú´ő Ŕ̸§żĄ´Â %n%n%1 šŽŔÚ¸Ś ťçżëÇŇ źö žř˝Ŕ´Ď´Ů.
+InvalidGroupName=Ćú´ő Ŕ̸§ŔĚ ŔŻČżÇĎÁö žĘ˝Ŕ´Ď´Ů.
+BadGroupName=Ćú´ő Ŕ̸§Ŕş ´ŮŔ˝ šŽŔÚ¸Ś Ć÷ÇÔÇŇ źö žř˝Ŕ´Ď´Ů:%n%n%1
NoProgramGroupCheck2=˝ĂŔŰ ¸Ţ´ş Ćú´ő¸Ś ¸¸ľéÁö žĘŔ˝(&D)
+
; *** "Ready to Install" wizard page
-WizardReady=źłÄĄ ÁŘşńľĘ
-ReadyLabel1=ŔĚÁŚ źłÄĄ ÇÁˇÎą×ˇĽŔĚ ÄÄÇťĹÍżĄ [name] źłÄĄ¸Ś ˝ĂŔŰÇŇ ÁŘşń°Ą ľÇžú˝Ŕ´Ď´Ů.
-ReadyLabel2a=źłÄĄ¸Ś °čźÓÇϡÁ¸é [źłÄĄ]¸Ś ĹŹ¸ŻÇϰí, źłÁ¤Ŕť °ËĹäÇĎ°ĹłŞ şŻ°ćÇϡÁ¸é [ľÚˇÎ]¸Ś ĹŹ¸ŻÇĎźźżä.
-ReadyLabel2b=źłÄĄ¸Ś °čźÓÇϡÁ¸é [źłÄĄ]¸Ś ĹŹ¸ŻÇĎźźżä.
+WizardReady=źłÄĄ ÁŘşń żĎˇá
+ReadyLabel1=ąÍÇĎŔÇ ÄÄÇťĹÍżĄ [name]Ŕť(¸Ś) źłÄĄÇŇ ÁŘşń°Ą ľÇžú˝Ŕ´Ď´Ů.
+ReadyLabel2a=źłÄĄ¸Ś °čźÓÇϡÁ¸é "źłÄĄ"¸Ś, źłÁ¤Ŕť şŻ°ćÇĎ°ĹłŞ °ËĹäÇϡÁ¸é "ľÚˇÎ"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
+ReadyLabel2b=źłÄĄ¸Ś °čźÓÇϡÁ¸é "źłÄĄ"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
ReadyMemoUserInfo=ťçżëŔÚ Á¤ş¸:
-ReadyMemoDir=´ëťó Ŕ§ÄĄ:
+ReadyMemoDir=źłÄĄ Ŕ§ÄĄ:
ReadyMemoType=źłÄĄ ŔŻÇü:
ReadyMemoComponents=źąĹĂÇŃ ą¸źş żäźŇ:
ReadyMemoGroup=˝ĂŔŰ ¸Ţ´ş Ćú´ő:
ReadyMemoTasks=Ăß°Ą ŔŰž÷:
+
; *** "Preparing to Install" wizard page
WizardPreparing=źłÄĄ ÁŘşń Áß
-PreparingDesc=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍżĄ [name] źłÄĄ¸Ś ÁŘşńÇϰí ŔÖ˝Ŕ´Ď´Ů.
-PreviousInstallNotCompleted=ŔĚŔü ÇÁˇÎą×ˇĽŔÇ źłÄĄ/ÁŚ°Ĺ ŔŰž÷ŔĚ żĎˇáľÇÁö žĘžŇ˝Ŕ´Ď´Ů. ÇŘ´ç źłÄĄ¸Ś żĎˇáÇϡÁ¸é ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů.%n%nÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŃ ČÄ [name] źłÄĄ¸Ś żĎˇáÇϡÁ¸é źłÄĄ ÇÁˇÎą×ˇĽŔť ´Ů˝Ă ˝ÇÇŕÇĎźźżä.
-CannotContinue=źłÄĄ ÇÁˇÎą×ˇĽŔť °čźÓÇŇ źö žř˝Ŕ´Ď´Ů. ÁžˇáÇϡÁ¸é [ĂëźŇ]¸Ś ĹŹ¸ŻÇĎźźżä.
-ApplicationsFound=źłÄĄ ÇÁˇÎą×ˇĽżĄź ž÷ľĽŔĚĆŽÇŘžß ÇĎ´Â ĆÄŔĎŔĚ ´ŮŔ˝ ŔŔżë ÇÁˇÎą×ˇĽżĄ ťçżëľÇ°í ŔÖ˝Ŕ´Ď´Ů. źłÄĄ ÇÁˇÎą×ˇĽżĄź Ŕ̡ŻÇŃ ŔŔżë ÇÁˇÎą×ˇĽŔť ŔÚľżŔ¸ˇÎ ´ÝľľˇĎ ÇăżëÇĎ´Â °ÍŔĚ ÁÁ˝Ŕ´Ď´Ů.
-ApplicationsFound2=źłÄĄ ÇÁˇÎą×ˇĽżĄź ž÷ľĽŔĚĆŽÇŘžß ÇĎ´Â ĆÄŔĎŔĚ ´ŮŔ˝ ŔŔżë ÇÁˇÎą×ˇĽżĄ ťçżëľÇ°í ŔÖ˝Ŕ´Ď´Ů. źłÄĄ ÇÁˇÎą×ˇĽżĄź Ŕ̡ŻÇŃ ŔŔżë ÇÁˇÎą×ˇĽŔť ŔÚľżŔ¸ˇÎ ´ÝľľˇĎ ÇăżëÇĎ´Â °ÍŔĚ ÁÁ˝Ŕ´Ď´Ů. źłÄĄ°Ą żĎˇáľÇ¸é źłÄĄ ÇÁˇÎą×ˇĽżĄź ŔŔżë ÇÁˇÎą×ˇĽŔť ´Ů˝Ă ˝ĂŔŰÇϡÁ°í ˝ĂľľÇŐ´Ď´Ů.
-CloseApplications=ŔŔżë ÇÁˇÎą×ˇĽ ŔÚľż ´Ýąâ(&A)
-DontCloseApplications=ŔŔżë ÇÁˇÎą×ˇĽŔť ´ÝÁö žĘŔ˝(&D)
-ErrorCloseApplications=źłÄĄ ÇÁˇÎą×ˇĽżĄź ŔϺΠŔŔżë ÇÁˇÎą×ˇĽŔť ŔÚľżŔ¸ˇÎ ´ÝŔť źö žř˝Ŕ´Ď´Ů. °čźÓÇĎąâ ŔüżĄ źłÄĄ ÇÁˇÎą×ˇĽżĄź ž÷ľĽŔĚĆŽÇŘžß ÇĎ´Â ĆÄŔĎŔť ťçżëÇĎ´Â ŔŔżë ÇÁˇÎą×ˇĽŔť ¸đľÎ ´Ý´Â °ÍŔĚ ÁÁ˝Ŕ´Ď´Ů.
+PreparingDesc=ąÍÇĎŔÇ ÄÄÇťĹÍżĄ [name] źłÄĄ¸Ś ÁŘşńÇĎ´Â ÁßŔÔ´Ď´Ů.
+PreviousInstallNotCompleted=ŔĚŔü ÇÁˇÎą×ˇĽŔÇ źłÄĄ/ÁŚ°Ĺ ŔŰž÷ŔĚ żĎˇáľÇÁö žĘžŇ˝Ŕ´Ď´Ů, żĎˇáÇϡÁ¸é ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů.%n%nÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŃ ČÄ, źłÄĄ ¸śšýťç¸Ś ´Ů˝Ă ˝ÇÇŕÇĎżŠ [name] źłÄĄ¸Ś żĎˇáÇϽù⠚ٜř´Ď´Ů.
+CannotContinue=źłÄĄ¸Ś °čźÓÇŇ źö žř˝Ŕ´Ď´Ů, "ĂëźŇ"¸Ś ĹŹ¸ŻÇĎżŠ źłÄĄ¸Ś ÁžˇáÇϽʽÿŔ.
+ApplicationsFound=´ŮŔ˝ ŔŔżëÇÁˇÎą×ˇĽŔĚ źłÄĄ ž÷ľĽŔĚĆŽ°Ą ÇĘżäÇŃ ĆÄŔĎŔť ťçżëÇϰí ŔÖ˝Ŕ´Ď´Ů, źłÄĄ ¸śšýťç°Ą Ŕ̡ą ŔŔżëÇÁˇÎą×ˇĽŔť ŔÚľżŔ¸ˇÎ ÁžˇáÇŇ źö ŔÖľľˇĎ ÇăżëÇϽù⠚ٜř´Ď´Ů.
+ApplicationsFound2=´ŮŔ˝ ŔŔżëÇÁˇÎą×ˇĽŔĚ źłÄĄ ž÷ľĽŔĚĆŽ°Ą ÇĘżäÇŃ ĆÄŔĎŔť ťçżëÇϰí ŔÖ˝Ŕ´Ď´Ů, źłÄĄ ¸śšýťç°Ą Ŕ̡ą ŔŔżëÇÁˇÎą×ˇĽŔť ŔÚľżŔ¸ˇÎ ÁžˇáÇŇ źö ŔÖľľˇĎ ÇăżëÇϽù⠚ٜř´Ď´Ů. źłÄĄ°Ą żĎˇáľÇ¸é, źłÄĄ ¸śšýťç´Â ŔĚ ŔŔżëÇÁˇÎą×ˇĽŔĚ ´Ů˝Ă ˝ĂŔ۾ǾľˇĎ ˝ĂľľÇŇ °Ě´Ď´Ů.
+CloseApplications=ŔÚľżŔ¸ˇÎ ŔŔżëÇÁˇÎą×ˇĽŔť ÁžˇáÇÔ(&A)
+DontCloseApplications=ŔŔżëÇÁˇÎą×ˇĽŔť ÁžˇáÇĎÁö žĘŔ˝(&D)
+ErrorCloseApplications=źłÄĄ ¸śšýťç°Ą ŔŔżëÇÁˇÎą×ˇĽŔť ŔÚľżŔ¸ˇÎ ÁžˇáÇŇ źö žř˝Ŕ´Ď´Ů, °čźÓÇĎąâ ŔüżĄ źłÄĄ ž÷ľĽŔĚĆŽ°Ą ÇĘżäÇŃ ĆÄŔĎŔť ťçżëÇϰí ŔÖ´Â ŔŔżëÇÁˇÎą×ˇĽŔť ¸đľÎ ÁžˇáÇϽù⠚ٜř´Ď´Ů.
+PrepareToInstallNeedsRestart=źłÄĄ ¸śšýťç´Â ąÍÇĎŔÇ ÄÄÇťĹÍ¸Ś Ŕç˝ĂŔŰÇŘžß ÇŐ´Ď´Ů. [name] źłÄĄ¸Ś żĎˇáÇĎąâ Ŕ§ÇŘ ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŃ ČÄżĄ źłÄĄ ¸śšýťç¸Ś ´Ů˝Ă ˝ÇÇŕÇŘ ÁֽʽÿŔ.%n%nÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
+
; *** "Installing" wizard page
WizardInstalling=źłÄĄ Áß
-InstallingLabel=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍżĄ [name]Ŕť(¸Ś) źłÄĄÇĎ´Â ľżžČ ąâ´ŮˇÁ ÁÖźźżä.
+InstallingLabel=ąÍÇĎŔÇ ÄÄÇťĹÍżĄ [name]Ŕť(¸Ś) źłÄĄÇĎ´Â Áß... Ŕá˝Ă ąâ´ŮˇÁ ÁֽʽÿŔ.
+
; *** "Setup Completed" wizard page
-FinishedHeadingLabel=[name] źłÁ¤ ¸śšýťç¸Ś żĎˇáÇĎ´Â Áß
-FinishedLabelNoIcons=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍżĄ [name]Ŕť(¸Ś) źłÄĄÇß˝Ŕ´Ď´Ů.
-FinishedLabel=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍżĄ [name]Ŕť(¸Ś) źłÄĄÇß˝Ŕ´Ď´Ů. źłÄĄÇŃ šŮˇÎ °Ąąâ¸Ś źąĹĂÇĎżŠ ÇŘ´ç ŔŔżë ÇÁˇÎą×ˇĽŔť ˝ĂŔŰÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
-ClickFinish=źłÄĄ ÇÁˇÎą×ˇĽŔť ÁžˇáÇϡÁ¸é [¸śÄ§]Ŕť ĹŹ¸ŻÇĎźźżä.
-FinishedRestartLabel=[name] źłÄĄ¸Ś żĎˇáÇϡÁ¸é źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů. ÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
-FinishedRestartMessage=[name] źłÄĄ¸Ś żĎˇáÇϡÁ¸é źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů.%n%nÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
-ShowReadmeCheck=żš, README ĆÄŔĎŔť ş¸°Ú˝Ŕ´Ď´Ů.
-YesRadio=żš, ÄÄÇťĹÍ¸Ś ÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϰڽŔ´Ď´Ů(&Y).
-NoRadio=žĆ´Ďżä, ÄÄÇťĹÍ¸Ś łŞÁßżĄ ´Ů˝Ă ˝ĂŔŰÇϰڽŔ´Ď´Ů(&N).
+FinishedHeadingLabel=[name] źłÄĄ ¸śšýťç żĎˇá
+FinishedLabelNoIcons=ąÍÇĎŔÇ ÄÄÇťĹÍżĄ [name]ŔĚ(°Ą) źłÄĄľÇžú˝Ŕ´Ď´Ů.
+FinishedLabel=ąÍÇĎŔÇ ÄÄÇťĹÍżĄ [name]ŔĚ(°Ą) źłÄĄľÇžú˝Ŕ´Ď´Ů, ŔŔżëÇÁˇÎą×ˇĽŔş źłÄĄľČ žĆŔĚÄÜŔť źąĹĂÇĎżŠ ˝ĂŔŰÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
+ClickFinish=źłÄĄ¸Ś łĄłťˇÁ¸é "Ážˇá"¸Ś ĹŹ¸ŻÇϽʽÿŔ.
+FinishedRestartLabel=[name] źłÄĄ¸Ś żĎˇáÇϡÁ¸é, ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů. ÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
+FinishedRestartMessage=[name] źłÄĄ¸Ś żĎˇáÇϡÁ¸é, ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů.%n%nÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
+ShowReadmeCheck=żš, README ĆÄŔĎŔť ÇĽ˝ĂÇŐ´Ď´Ů
+YesRadio=żš, ÁöąÝ ´Ů˝Ă ˝ĂŔŰÇŐ´Ď´Ů(&Y)
+NoRadio=žĆ´ĎżŔ, łŞÁßżĄ ´Ů˝Ă ˝ĂŔŰÇŐ´Ď´Ů(&N)
; used for example as 'Run MyProg.exe'
RunEntryExec=%1 ˝ÇÇŕ
; used for example as 'View Readme.txt'
-RunEntryShellExec=%1 ş¸ąâ
+RunEntryShellExec=%1 ÇĽ˝Ă
+
; *** "Setup Needs the Next Disk" stuff
-ChangeDiskTitle=źłÄĄ ÇÁˇÎą×ˇĽżĄź ´ŮŔ˝ ľđ˝şĹаĄ ÇĘżäÇÔ
-SelectDiskLabel2=ľđ˝şĹŠ %1Ŕť(¸Ś) ťđŔÔÇŃ ´ŮŔ˝ [ČŽŔÎ]Ŕť ĹŹ¸ŻÇĎźźżä.%n%nŔĚ ľđ˝şĹŠŔÇ ĆÄŔĎŔĚ žĆˇĄ ÇĽ˝ĂľČ Ćú´ő°Ą žĆ´Ń ´Ů¸Ľ Ćú´őżĄ ŔÖŔ¸¸é żĂšŮ¸Ľ °ćˇÎ¸Ś ŔÔˇÂÇĎ°ĹłŞ [ĂŁžĆş¸ąâ]¸Ś ĹŹ¸ŻÇĎźźżä.
+ChangeDiskTitle=ľđ˝şĹаĄ ÇĘżäÇŐ´Ď´Ů
+SelectDiskLabel2=ľđ˝şĹŠ %1Ŕť(¸Ś) ťđŔÔÇϰí "ČŽŔÎ"Ŕť ĹŹ¸ŻÇϽʽÿŔ.%n%nŔĚ ľđ˝şĹŠ ťóŔÇ ĆÄŔĎŔĚ žĆˇĄ °ćˇÎ°Ą žĆ´Ń °÷żĄ ŔÖ´Â °ćżě, żĂšŮ¸Ľ °ćˇÎ¸Ś ŔÔˇÂÇĎ°ĹłŞ "ĂŁžĆş¸ąâ"¸Ś ĹŹ¸ŻÇϽù⠚ٜř´Ď´Ů.
PathLabel=°ćˇÎ(&P):
-FileNotInDir2="%2"żĄź ĆÄŔĎ "%1"Ŕť(¸Ś) ĂŁŔť źö žř˝Ŕ´Ď´Ů. żĂšŮ¸Ľ ľđ˝şĹŠ¸Ś ťđŔÔÇĎ°ĹłŞ ´Ů¸Ľ Ćú´ő¸Ś źąĹĂÇĎźźżä.
-SelectDirectoryLabel=´ŮŔ˝ ľđ˝şĹŠŔÇ Ŕ§ÄĄ¸Ś ÁöÁ¤ÇĎźźżä.
+FileNotInDir2=%2żĄ ĆÄŔĎ %1Ŕť(¸Ś) Ŕ§ÄĄÇŇ źö žř˝Ŕ´Ď´Ů, żĂšŮ¸Ľ ľđ˝şĹŠ¸Ś ťđŔÔÇĎ°ĹłŞ ´Ů¸Ľ Ćú´ő¸Ś źąĹĂÇϽʽÿŔ.
+SelectDirectoryLabel=´ŮŔ˝ ľđ˝şĹŠŔÇ Ŕ§ÄĄ¸Ś ÁöÁ¤ÇϽʽÿŔ.
+
; *** Installation phase messages
-SetupAborted=źłÄĄ¸Ś żĎˇáÇĎÁö ¸řÇß˝Ŕ´Ď´Ů.%n%nšŽÁŚ¸Ś ÇذáÇŃ ´ŮŔ˝ źłÄĄ ÇÁˇÎą×ˇĽŔť ´Ů˝Ă ˝ÇÇŕÇĎźźżä.
-EntryAbortRetryIgnore=´Ů˝Ă ˝ĂľľÇϡÁ¸é [´Ů˝Ă ˝Ăľľ]¸Ś, ą×ˇĄľľ °čźÓÇϡÁ¸é [šŤ˝Ă]¸Ś, źłÄĄ¸Ś ĂëźŇÇϡÁ¸é [Áß´Ü]Ŕť ĹŹ¸ŻÇĎźźżä.
+SetupAborted=źłÄĄ°Ą żĎˇáľÇÁö žĘžŇ˝Ŕ´Ď´Ů.%n%nšŽÁŚ¸Ś ÇذáÇŃ ČÄ, ´Ů˝Ă źłÄĄ¸Ś ˝ĂŔŰÇϽʽÿŔ.
+AbortRetryIgnoreSelectAction=ž×źÇŔť źąĹĂÇŘ ÁֽʽÿŔ.
+AbortRetryIgnoreRetry=Ŕç˝Ăľľ(&T)
+AbortRetryIgnoreIgnore=żŔˇů¸Ś šŤ˝ĂÇϰí ÁřÇŕ(&I)
+AbortRetryIgnoreCancel=źłÄĄ ĂëźŇ
+
; *** Installation status messages
-StatusClosingApplications=ŔŔżë ÇÁˇÎą×ˇĽŔť ´Ý´Â Áß...
-StatusCreateDirs=ľđˇşĹÍ¸Ž¸Ś ¸¸ľĺ´Â Áß...
+StatusClosingApplications=ŔŔżëÇÁˇÎą×ˇĽŔť ÁžˇáÇĎ´Â Áß...
+StatusCreateDirs=Ćú´ő¸Ś ¸¸ľĺ´Â Áß...
StatusExtractFiles=ĆÄŔĎŔť ĂßĂâÇĎ´Â Áß...
-StatusCreateIcons=šŮˇÎ °Ąąâ¸Ś ¸¸ľĺ´Â Áß...
+StatusCreateIcons=šŮˇÎ°Ąąâ¸Ś ťýźşÇĎ´Â Áß...
StatusCreateIniEntries=INI Ç׸ńŔť ¸¸ľĺ´Â Áß...
StatusCreateRegistryEntries=ˇšÁö˝şĆŽ¸Ž Ç׸ńŔť ¸¸ľĺ´Â Áß...
StatusRegisterFiles=ĆÄŔĎŔť ľîˇĎÇĎ´Â Áß...
StatusSavingUninstall=ÁŚ°Ĺ Á¤ş¸¸Ś ŔúŔĺÇĎ´Â Áß...
StatusRunProgram=źłÄĄ¸Ś żĎˇáÇĎ´Â Áß...
-StatusRestartingApplications=ŔŔżë ÇÁˇÎą×ˇĽŔť ´Ů˝Ă ˝ĂŔŰÇĎ´Â Áß...
-StatusRollback=şŻ°ć ťçÇ×Ŕť ˇŃšéÇĎ´Â Áß...
+StatusRestartingApplications=ŔŔżëÇÁˇÎą×ˇĽŔť ´Ů˝Ă ˝ĂŔŰÇĎ´Â Áß...
+StatusRollback=şŻ°ćŔť ĂëźŇÇĎ´Â Áß...
+
; *** Misc. errors
ErrorInternal2=łťşÎ żŔˇů: %1
ErrorFunctionFailedNoCode=%1 ˝ÇĆĐ
-ErrorFunctionFailed=%1 ˝ÇĆĐ, ÄÚľĺ %2
-ErrorFunctionFailedWithMessage=%1 ˝ÇĆĐ, ÄÚľĺ %2.%n%3
-ErrorExecutingProgram=ĆÄŔĎŔť ˝ÇÇŕÇŇ źö žřŔ˝:%n%1
+ErrorFunctionFailed=%1 ˝ÇĆĐ; ÄÚľĺ %2
+ErrorFunctionFailedWithMessage=%1 ˝ÇĆĐ, ÄÚľĺ: %2.%n%3
+ErrorExecutingProgram=ĆÄŔĎ ˝ÇÇŕ żŔˇů:%n%1
+
; *** Registry errors
-ErrorRegOpenKey=ˇšÁö˝şĆŽ¸Ž Ĺ°¸Ś żŠ´Â Áß żŔˇů šßťý:%n%1\%2
-ErrorRegCreateKey=ˇšÁö˝şĆŽ¸Ž Ĺ°¸Ś ¸¸ľĺ´Â Áß żŔˇů šßťý:%n%1\%2
-ErrorRegWriteKey=ˇšÁö˝şĆŽ¸Ž Ĺ°żĄ ąâˇĎÇĎ´Â Áß żŔˇů šßťý:%n%1\%2
+ErrorRegOpenKey=ˇšÁö˝şĆŽ¸Ž Ĺ° żąâ żŔˇů:%n%1\%2
+ErrorRegCreateKey=ˇšÁö˝şĆŽ¸Ž Ĺ° ťýźş żŔˇů:%n%1\%2
+ErrorRegWriteKey=ˇšÁö˝şĆŽ¸Ž Ĺ° ž˛ąâ żŔˇů:%n%1\%2
+
; *** INI errors
-ErrorIniEntry=ĆÄŔĎ "%1"żĄ INI Ç׸ńŔť ¸¸ľĺ´Â ÁßżĄ żŔˇů°Ą šßťýÇß˝Ŕ´Ď´Ů.
+ErrorIniEntry=%1 ĆÄŔĎżĄ INI Ç׸ń ¸¸ľéąâ żŔˇůŔÔ´Ď´Ů.
+
; *** File copying errors
-FileAbortRetryIgnore=´Ů˝Ă ˝ĂľľÇϡÁ¸é [´Ů˝Ă ˝Ăľľ]¸Ś, ŔĚ ĆÄŔĎŔť °ÇłĘśŮˇÁ¸é [šŤ˝Ă](ąÇŔĺľÇÁö žĘŔ˝)¸Ś, źłÄĄ¸Ś ĂëźŇÇϡÁ¸é [Áß´Ü]Ŕť ĹŹ¸ŻÇĎźźżä.
-FileAbortRetryIgnore2=´Ů˝Ă ˝ĂľľÇϡÁ¸é [´Ů˝Ă ˝Ăľľ]¸Ś, ą×ˇĄľľ °čźÓÇϡÁ¸é [šŤ˝Ă](ąÇŔĺľÇÁö žĘŔ˝)¸Ś, źłÄĄ¸Ś ĂëźŇÇϡÁ¸é [Áß´Ü]Ŕť ĹŹ¸ŻÇĎźźżä.
-SourceIsCorrupted=żřşť ĆÄŔĎŔĚ źŐťóľÇžú˝Ŕ´Ď´Ů.
-SourceDoesntExist=żřşť ĆÄŔĎ "%1"ŔĚ(°Ą) žř˝Ŕ´Ď´Ů.
-ExistingFileReadOnly=ąâÁ¸ ĆÄŔĎŔĚ ŔĐąâ ŔüżëŔ¸ˇÎ ÇĽ˝ĂľÇžî ŔÖ˝Ŕ´Ď´Ů.%n%nŔĐąâ Ŕüżë ĆŻźşŔť ÁڰĹÇĎ°í ´Ů˝Ă ˝ĂľľÇϡÁ¸é [´Ů˝Ă ˝Ăľľ]¸Ś, ŔĚ ĆÄŔĎŔť °ÇłĘśŮˇÁ¸é [šŤ˝Ă]¸Ś, źłÄĄ¸Ś ĂëźŇÇϡÁ¸é [Áß´Ü]Ŕť ĹŹ¸ŻÇĎźźżä.
-ErrorReadingExistingDest=ąâÁ¸ ĆÄŔĎŔť ŔĐ´Â Áß żŔˇů šßťý:
-FileExists=ÇŘ´ç ĆÄŔĎŔĚ ŔĚšĚ ŔÖ˝Ŕ´Ď´Ů.%n%nźłÄĄ ÇÁˇÎą×ˇĽżĄź ŔĚ ĆÄŔĎŔť ľ¤žîž˛ľľˇĎ ÇϽðڽŔ´Ďąî?
-ExistingFileNewer=ąâÁ¸ ĆÄŔĎŔĚ źłÄĄ ÇÁˇÎą×ˇĽżĄź źłÄĄÇϡÁ´Â ĆÄŔĎş¸´Ů ĂÖ˝ĹŔÔ´Ď´Ů. ąâÁ¸ ĆÄŔĎŔť ŔŻÁöÇŇ °ÍŔť ąÇŔĺÇŐ´Ď´Ů.%n%nąâÁ¸ ĆÄŔĎŔť ŔŻÁöÇϽðڽŔ´Ďąî?
-ErrorChangingAttr=ąâÁ¸ ĆÄŔĎŔÇ ĆŻźşŔť şŻ°ćÇĎ´Â Áß żŔˇů šßťý:
-ErrorCreatingTemp=´ëťó ľđˇşĹÍ¸ŽżĄ ĆÄŔĎŔť ¸¸ľĺ´Â Áß żŔˇů šßťý:
-ErrorReadingSource=żřşť ĆÄŔĎŔť ŔĐ´Â Áß żŔˇů šßťý:
-ErrorCopying=ĆÄŔĎŔť şšťçÇĎ´Â Áß żŔˇů šßťý:
-ErrorReplacingExistingFile=ąâÁ¸ ĆÄŔĎŔť šŮ˛Ů´Â Áß żŔˇů šßťý:
+FileAbortRetryIgnoreSkipNotRecommended=ŔĚ ĆÄŔĎŔť °ÇłĘśę(&S) (ąÇŔĺÇĎÁö žĘ˝Ŕ´Ď´Ů)
+FileAbortRetryIgnoreIgnoreNotRecommended=żŔˇů¸Ś šŤ˝ĂÇϰí ÁřÇŕ(&I) (ąÇŔĺÇĎÁö žĘ˝Ŕ´Ď´Ů)
+SourceIsCorrupted=żřşť ĆÄŔĎŔĚ źŐťóľĘ
+SourceDoesntExist=żřşť ĆÄŔĎ %1ŔĚ(°Ą) Á¸ŔçÇĎÁö žĘŔ˝
+ExistingFileReadOnly2=ąâÁ¸ ĆÄŔĎŔş ŔĐąâ ŔüżëŔĚąâś§šŽżĄ ´ëĂźÇŇ źö žř˝Ŕ´Ď´Ů.
+ExistingFileReadOnlyRetry=ŔĐąâ Ŕüżë źÓźşŔť ÇŘÁŚÇĎ°í ´Ů˝Ă ˝ĂľľÇϡÁ¸é(&R)
+ExistingFileReadOnlyKeepExisting=ąâÁ¸ ĆÄŔĎŔť ŔŻÁö(&K)
+ErrorReadingExistingDest=ąâÁ¸ ĆÄŔĎŔť ŔĐ´Â ľżžČ żŔˇů šßťý:
+FileExists=ĆÄŔĎŔĚ ŔĚšĚ Á¸ŔçÇŐ´Ď´Ů.%n%nĆÄŔĎŔť ľ¤žîž˛˝Ă°Ú˝Ŕ´Ďąî?
+ExistingFileNewer=ąâÁ¸ ĆÄŔĎŔĚ źłÄĄÇϡÁ°í ÇĎ´Â ĆÄŔĎş¸´Ů ťő ĆÄŔĎŔÔ´Ď´Ů, ąâÁ¸ ĆÄŔĎŔť ŔŻÁöÇϽù⠚ٜř´Ď´Ů.%n%nąâÁ¸ ĆÄŔĎŔť ŔŻÁöÇϽðڽŔ´Ďąî?
+ErrorChangingAttr=ąâÁ¸ ĆÄŔĎŔÇ źÓźşŔť şŻ°ćÇĎ´Â ľżžČ żŔˇů šßťý:
+ErrorCreatingTemp=´ëťó Ćú´őżĄ ĆÄŔĎŔť ¸¸ľĺ´Â ľżžČ żŔˇů šßťý:
+ErrorReadingSource=żřşť ĆÄŔĎŔť ŔĐ´Â ľżžČ żŔˇů šßťý:
+ErrorCopying=ĆÄŔĎŔť şšťçÇĎ´Â ľżžČ żŔˇů šßťý:
+ErrorReplacingExistingFile=ąâÁ¸ ĆÄŔĎŔť ąłĂźÇĎ´Â ľżžČ żŔˇů šßťý:
ErrorRestartReplace=RestartReplace ˝ÇĆĐ:
-ErrorRenamingTemp=´ëťó ľđˇşĹÍ¸ŽżĄ ŔÖ´Â ĆÄŔĎ Ŕ̸§Ŕť šŮ˛Ů´Â Áß żŔˇů šßťý:
-ErrorRegisterServer=DLL/OCX¸Ś ľîˇĎÇŇ źö žřŔ˝: %1
-ErrorRegSvr32Failed=Ážˇá ÄÚľĺ %1°ú(żÍ) ÇÔ˛˛ RegSvr32 ˝ÇĆĐ
-ErrorRegisterTypeLib=Çü˝Ä śóŔ̺ꡯ¸Ž¸Ś ľîˇĎÇŇ źö žřŔ˝: %1
+ErrorRenamingTemp=´ëťó Ćú´ő łťŔÇ ĆÄŔĎ Ŕ̸§Ŕť šŮ˛Ů´Â ľżžČ żŔˇů šßťý:
+ErrorRegisterServer=DLL/OCX ľîˇĎ ˝ÇĆĐ: %1
+ErrorRegSvr32Failed=RegSvr32°Ą ´ŮŔ˝ Ážˇá ÄÚľĺˇÎ ˝ÇĆĐ: %1
+ErrorRegisterTypeLib=´ŮŔ˝ ŔŻÇüŔÇ śóŔ̺ꡯ¸Ž ľîˇĎżĄ ˝ÇĆĐ: %1
+
+; *** Uninstall display name markings
+; used for example as 'My Program (32-bit)'
+UninstallDisplayNameMark=%1 (%2)
+; used for example as 'My Program (32-bit, All users)'
+UninstallDisplayNameMarks=%1 (%2, %3)
+UninstallDisplayNameMark32Bit=32şńĆŽ
+UninstallDisplayNameMark64Bit=64şńĆŽ
+UninstallDisplayNameMarkAllUsers=¸đľç ťçżëŔÚ
+UninstallDisplayNameMarkCurrentUser=ÇöŔç ťçżëŔÚ
+
; *** Post-installation errors
-ErrorOpeningReadme=README ĆÄŔĎŔť żŠ´Â ÁßżĄ żŔˇů°Ą šßťýÇß˝Ŕ´Ď´Ů.
-ErrorRestartingComputer=źłÄĄ ÇÁˇÎą×ˇĽżĄź ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŇ źö žř˝Ŕ´Ď´Ů. źöľżŔ¸ˇÎ ÁřÇŕÇĎźźżä.
+ErrorOpeningReadme=README ĆÄŔĎŔť żŠ´Â Áß żŔˇů°Ą šßťýÇß˝Ŕ´Ď´Ů.
+ErrorRestartingComputer=ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŇ źö žř˝Ŕ´Ď´Ů, źöľżŔ¸ˇÎ ´Ů˝Ă ˝ĂŔŰÇϽʽÿŔ.
+
; *** Uninstaller messages
-UninstallNotFound=ĆÄŔĎ "%1"ŔĚ(°Ą) žř˝Ŕ´Ď´Ů. ÁڰĹÇŇ źö žř˝Ŕ´Ď´Ů.
-UninstallOpenError=ĆÄŔĎ "%1"Ŕť(¸Ś) ż źö žř˝Ŕ´Ď´Ů. ÁڰĹÇŇ źö žř˝Ŕ´Ď´Ů.
-UninstallUnsupportedVer=ÁŚ°Ĺ ˇÎą× ĆÄŔĎ "%1"ŔĚ(°Ą) ŔĚ šöŔüŔÇ ÁŚ°Ĺ ÇÁˇÎą×ˇĽżĄź ŔνÄÇĎÁö ¸řÇĎ´Â Çü˝ÄŔÔ´Ď´Ů. ÁڰĹÇŇ źö žř˝Ŕ´Ď´Ů.
-UninstallUnknownEntry=ÁŚ°Ĺ ˇÎą×żĄź žË źö žř´Â Ç׸ń(%1)ŔĚ šß°ßľÇžú˝Ŕ´Ď´Ů.
-ConfirmUninstall=%1°ú(żÍ) ÇŘ´ç ą¸źş żäźŇ¸Ś ¸đľÎ żĎŔüČ÷ ÁڰĹÇϽðڽŔ´Ďąî?
-UninstallOnlyOnWin64=ŔĚ źłÄĄ´Â 64şńĆŽ WindowsżĄź¸¸ ÁڰĹÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
-OnlyAdminCanUninstall=ŔĚ źłÄĄ´Â °ü¸ŽŔÚ ąÇÇŃŔĚ ŔÖ´Â ťçżëŔÚ¸¸ ÁڰĹÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
-UninstallStatusLabel=ÄÄÇťĹÍżĄź %1Ŕť(¸Ś) ÁڰĹÇĎ´Â ľżžČ ąâ´ŮˇÁ ÁÖźźżä.
-UninstalledAll=ÄÄÇťĹÍżĄź %1Ŕť(¸Ś) ÁڰĹÇß˝Ŕ´Ď´Ů.
-UninstalledMost=%1 ÁŚ°Ĺ°Ą żĎˇáľÇžú˝Ŕ´Ď´Ů.%n%nŔϺΠżäźŇ´Â ÁڰĹÇŇ źö žř˝Ŕ´Ď´Ů. Ŕ̡ŻÇŃ Ç׸ńŔş źöľżŔ¸ˇÎ ÁڰĹÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
-UninstalledAndNeedsRestart=%1 ÁŚ°Ĺ¸Ś żĎˇáÇϡÁ¸é ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů.%n%nÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
-UninstallDataCorrupted="%1" ĆÄŔĎŔĚ źŐťóľÇžú˝Ŕ´Ď´Ů. ÁڰĹÇŇ źö žř˝Ŕ´Ď´Ů.
+UninstallNotFound=ĆÄŔĎ %1ŔĚ(°Ą) Á¸ŔçÇĎÁö žĘąâ ś§šŽżĄ, ÁŚ°Ĺ¸Ś ˝ÇÇŕÇŇ źö žř˝Ŕ´Ď´Ů.
+UninstallOpenError=ĆÄŔĎ %1Ŕť(¸Ś) ż źö žřąâ ś§šŽżĄ, ÁŚ°Ĺ¸Ś ˝ÇÇŕÇŇ źö žř˝Ŕ´Ď´Ů.
+UninstallUnsupportedVer=ťčÁŚ ˇÎą× ĆÄŔĎ "%1"Ŕş(´Â) ŔĚ ťčÁŚ ¸śšýťçˇÎ ŔνÄÇŇ źö žř´Â Çü˝ÄŔĚąâ ś§šŽżĄ, ÁŚ°Ĺ¸Ś ˝ÇÇŕÇŇ źö žř˝Ŕ´Ď´Ů.
+UninstallUnknownEntry=žË źö žř´Â Ç׸ń %1ŔĚ(°Ą) ťčÁŚ ˇÎą×żĄ Ć÷ÇԾǞî ŔÖ˝Ŕ´Ď´Ů.
+ConfirmUninstall=Á¤¸ť %1żÍ(°ú) ą× ą¸źş żäźŇ¸Ś ¸đľÎ ÁڰĹÇϽðڽŔ´Ďąî?
+UninstallOnlyOnWin64=ŔĚ ÇÁˇÎą×ˇĽŔş 64şńĆŽ WindowsżĄź¸¸ ÁڰĹÇŇ źö ŔÖ˝Ŕ´Ď´Ů.
+OnlyAdminCanUninstall=ŔĚ ÇÁˇÎą×ˇĽŔť ÁڰĹÇϡÁ¸é °ü¸ŽŔÚ ąÇÇŃŔĚ ÇĘżäÇŐ´Ď´Ů.
+UninstallStatusLabel=ąÍÇĎŔÇ ÄÄÇťĹÍżĄź %1Ŕť(¸Ś) ÁڰĹÇĎ´Â Áß... Ŕá˝Ă ąâ´ŮˇÁ ÁֽʽÿŔ.
+UninstalledAll=%1ŔĚ(°Ą) źş°řŔűŔ¸ˇÎ ÁŚ°ĹľÇžú˝Ŕ´Ď´Ů!
+UninstalledMost=%1 ÁŚ°Ĺ°Ą żĎˇáľÇžú˝Ŕ´Ď´Ů.%n%nŔϺΠżäźŇ´Â ťčÁŚÇŇ źö žřŔ¸´Ď, źöľżŔ¸ˇÎ ÁڰĹÇϽù⠚ٜř´Ď´Ů.
+UninstalledAndNeedsRestart=%1ŔÇ ÁŚ°Ĺ¸Ś żĎˇáÇϡÁ¸é, ÄÄÇťĹÍ¸Ś ´Ů˝Ă ˝ĂŔŰÇŘžß ÇŐ´Ď´Ů.%n%nÁöąÝ ´Ů˝Ă ˝ĂŔŰÇϽðڽŔ´Ďąî?
+UninstallDataCorrupted=ĆÄŔĎ "%1"ŔĚ(°Ą) źŐťóľÇžúąâ ś§šŽżĄ, ÁŚ°Ĺ¸Ś ˝ÇÇŕÇŇ źö žř˝Ŕ´Ď´Ů.
+
; *** Uninstallation phase messages
ConfirmDeleteSharedFileTitle=°řŔŻ ĆÄŔĎŔť ÁڰĹÇϽðڽŔ´Ďąî?
-ConfirmDeleteSharedFile2=˝Ă˝şĹŰżĄź´Â ŔĚÁŚ ´ŮŔ˝ °řŔŻ ĆÄŔĎŔť ťçżëÇĎ´Â ÇÁˇÎą×ˇĽŔĚ žř´Â °ÍŔ¸ˇÎ ÇĽ˝ĂľË´Ď´Ů. ÁŚ°Ĺ ŔŰž÷Ŕť ĹëÇŘ ŔĚ °řŔŻ ĆÄŔĎŔť ÁڰĹÇϽðڽŔ´Ďąî?%n%nžĆÁ÷ ŔĚ ĆÄŔĎŔť ťçżëÇĎ´Â ÇÁˇÎą×ˇĽŔĚ ŔÖ´ÂľĽ ŔĚ ĆÄŔĎŔť ÁڰĹÇϸé ÇŘ´ç ÇÁˇÎą×ˇĽŔĚ żĂšŮ¸Ł°Ô ŔŰľżÇĎÁö žĘŔť źö ŔÖ˝Ŕ´Ď´Ů. Ŕß ¸đ¸Ł´Â °ćżě [žĆ´Ďżä]¸Ś źąĹĂÇĎźźżä. ˝Ă˝şĹŰżĄ ĆÄŔĎŔť ą×´ëˇÎ ľÎžîľľ žĆšŤˇą šŽÁڰĄ šßťýÇĎÁö žĘ˝Ŕ´Ď´Ů.
+ConfirmDeleteSharedFile2=˝Ă˝şĹŰŔÇ žîś˛ ÇÁˇÎą×ˇĽľľ ´ŮŔ˝ °řŔŻ ĆÄŔĎŔť ťçżëÇĎÁö žĘ˝Ŕ´Ď´Ů, ŔĚ °řŔŻ ĆÄŔĎŔť ťčÁŚÇϽðڽŔ´Ďąî?%n%nŔĚ ĆÄŔĎŔť ´Ů¸Ľ ÇÁˇÎą×ˇĽŔĚ °řŔŻÇϰí ŔÖ´Â ťóĹÂżĄź ŔĚ ĆÄŔĎŔť ÁڰĹÇŇ °ćżě, ÇŘ´ç ÇÁˇÎą×ˇĽŔĚ ÁŚ´ëˇÎ ŔŰľżÇĎÁö žĘŔť źö ŔÖŔ¸´Ď, ČŽ˝ĹŔĚ žřŔ¸¸é "žĆ´ĎżŔ"¸Ś źąĹĂÇϟžľ ľË´Ď´Ů. ˝Ă˝şĹŰżĄ ĆÄŔĎŔĚ ł˛žĆ ŔÖžîľľ šŽÁڰĄ ľÇÁř žĘ˝Ŕ´Ď´Ů.
SharedFileNameLabel=ĆÄŔĎ Ŕ̸§:
SharedFileLocationLabel=Ŕ§ÄĄ:
WizardUninstalling=ÁŚ°Ĺ ťóĹÂ
StatusUninstalling=%1Ŕť(¸Ś) ÁڰĹÇĎ´Â Áß...
+
; *** Shutdown block reasons
ShutdownBlockReasonInstallingApp=%1Ŕť(¸Ś) źłÄĄÇĎ´Â ÁßŔÔ´Ď´Ů.
ShutdownBlockReasonUninstallingApp=%1Ŕť(¸Ś) ÁڰĹÇĎ´Â ÁßŔÔ´Ď´Ů.
+
; The custom messages below aren't used by Setup itself, but if you make
; use of them in your scripts, you'll want to translate them.
+
[CustomMessages]
+
NameAndVersion=%1 šöŔü %2
-AdditionalIcons=Ăß°Ą šŮˇÎ °Ąąâ:
-CreateDesktopIcon=šŮĹÁ Č¸é šŮˇÎ °Ąąâ ¸¸ľéąâ(&D)
-CreateQuickLaunchIcon=şü¸Ľ ˝ÇÇŕ šŮˇÎ °Ąąâ ¸¸ľéąâ(&Q)
-ProgramOnTheWeb=%1 ŔĽ Á¤ş¸
+AdditionalIcons=žĆŔĚÄÜ Ăß°Ą:
+CreateDesktopIcon=šŮĹÁ ȸ鿥 šŮˇÎ°Ąąâ ¸¸ľéąâ(&D)
+CreateQuickLaunchIcon=şü¸Ľ ˝ÇÇŕ žĆŔĚÄÜ ¸¸ľéąâ(&Q)
+ProgramOnTheWeb=%1 ŔĽĆäŔĚÁö
UninstallProgram=%1 ÁڰĹ
-LaunchProgram=%1 ˝ĂŔŰ
-AssocFileExtension=%1Ŕť(¸Ś) %2 ĆÄŔĎ ČŽŔĺ¸í°ú żŹ°á(&A)
-AssocingFileExtension=%1Ŕť(¸Ś) %2 ĆÄŔĎ ČŽŔĺ¸í°ú żŹ°á Áß...
+LaunchProgram=%1 ˝ÇÇŕ
+AssocFileExtension=ĆÄŔĎ ČŽŔĺŔÚ %2Ŕť(¸Ś) %1żĄ żŹ°áÇŐ´Ď´Ů.
+AssocingFileExtension=ĆÄŔĎ ČŽŔĺŔÚ %2Ŕť(¸Ś) %1żĄ żŹ°áÇĎ´Â Áß...
AutoStartProgramGroupDescription=˝ĂŔŰ:
-AutoStartProgram=%1 ŔÚľż ˝ĂŔŰ
-AddonHostProgramNotFound=źąĹĂÇŃ Ćú´őżĄź %1Ŕť(¸Ś) ĂŁŔť źö žř˝Ŕ´Ď´Ů.%n%ną×ˇĄľľ °čźÓÇϽðڽŔ´Ďąî?
\ No newline at end of file
+AutoStartProgram=%1Ŕť(¸Ś) ŔÚľżŔ¸ˇÎ ˝ĂŔŰ
+AddonHostProgramNotFound=%1Ŕş(´Â) źąĹĂÇŃ Ćú´őżĄ Ŕ§ÄĄÇŇ źö žř˝Ŕ´Ď´Ů.%n%ną×ˇĄľľ °čźÓÇϽðڽŔ´Ďąî?
diff --git a/build/win32/i18n/Default.zh-cn.isl b/build/win32/i18n/Default.zh-cn.isl
index e384e83d30..5c5df9a166 100644
--- a/build/win32/i18n/Default.zh-cn.isl
+++ b/build/win32/i18n/Default.zh-cn.isl
@@ -1,16 +1,17 @@
-; *** Inno Setup version 5.5.3+ Simplified Chinese messages ***
+ďťż; *** Inno Setup version 6.0.3+ Chinese Simplified messages ***
;
-; To download user-contributed translations of this file, go to:
-; http://www.jrsoftware.org/files/istrans/
+; Maintained by Zhenghan Yang
+; Email: 847320916@QQ.com
+; Translation based on network resource
+; The latest Translation is on https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation
;
-; Note: When translating this text, do not add periods (.) to the end of
-; messages that didn't have them already, because on those messages Inno
-; Setup adds the periods automatically (appending a period would result in
-; two periods being displayed).
+
[LangOptions]
; The following three entries are very important. Be sure to read and
; understand the '[LangOptions] section' topic in the help file.
-LanguageName=Simplified Chinese
+LanguageName=çŽä˝ä¸ć
+; If Language Name display incorrect, uncomment next line
+; LanguageName=<7B80><4F53><4E2D><6587>
LanguageID=$0804
LanguageCodePage=936
; If the language you are translating to requires special font faces or
@@ -23,276 +24,342 @@ LanguageCodePage=936
;TitleFontSize=29
;CopyrightFontName=Arial
;CopyrightFontSize=8
+
[Messages]
-; *** Application titles
-SetupAppTitle=°˛×°łĚĐň
-SetupWindowTitle=°˛×°łĚĐň - %1
-UninstallAppTitle=ĐśÔŘ
-UninstallAppFullTitle=%1 ĐśÔŘ
+
+; *** ĺşç¨ç¨ĺşć é˘
+SetupAppTitle=ĺŽčŁ
+SetupWindowTitle=ĺŽčŁ
- %1
+UninstallAppTitle=ĺ¸č˝˝
+UninstallAppFullTitle=%1 ĺ¸č˝˝
+
; *** Misc. common
-InformationTitle=ĐĹϢ
-ConfirmTitle=ȡČĎ
-ErrorTitle=´íÎó
+InformationTitle=俥ćŻ
+ConfirmTitle=祎莤
+ErrorTitle=é误
+
; *** SetupLdr messages
-SetupLdrStartupMessage=Ő⽍°˛×° %1ĄŁĘǡńŇŞźĚĐř?
-LdrCannotCreateTemp=Îޡ¨´´˝¨ÁŮĘąÎÄźţĄŁ°˛×°łĚĐňŇŃÖĐÖš
-LdrCannotExecTemp=Îޡ¨ÔÚÁŮʹĿŸÖĐÖ´ĐĐÎÄźţĄŁ°˛×°łĚĐňŇŃÖĐÖš
-; *** Startup error messages
-LastErrorMessage=%1ĄŁ%n%n´íÎó %2: %3
-SetupFileMissing=°˛×°ÄżÂźČąĘ§ÎÄźţ %1ĄŁÇë¸üŐý¸ĂÎĘĚâťňťńČĄ¸ĂÎĘĚâľÄĐÂ¸ąąžĄŁ
-SetupFileCorrupt=°˛×°łĚĐňÎÄźţźĐŇŃË𝾥ŁÇëťńČĄ¸ĂłĚĐňľÄĐÂ¸ąąžĄŁ
-SetupFileCorruptOrWrongVer=°˛×°łĚĐňÎÄźţźĐŇŃËđťľťňÓë´Ë°˛×°łĚĐň°ćąž˛ťźćČÝĄŁÇë¸üŐý¸ĂÎĘĚâťňťńČĄ¸ĂłĚĐňľÄĐÂ¸ąąžĄŁ
-InvalidParameter=ĂüÁîĐĐ %n%n%1 ÉĎ´ŤľÝÁËŇť¸öÎŢЧ˛ÎĘý
-SetupAlreadyRunning=°˛×°łĚĐňŇŃÔÚÔËĐĐĄŁ
-WindowsVersionNotSupported=´ËłĚĐň˛ťÖ§łÖÄăźĆËăťúŐýÔËĐĐľÄ Windows °ćąžĄŁ
-WindowsServicePackRequired=´ËłĚĐňĐčŇŞ %1 ˇţÎń°ü %2 ťň¸ü¸ß°ćąžĄŁ
-NotOnThisPlatform=´ËłĚĐň˝Ť˛ťÔÚ %1 ÉĎÔËĐĐĄŁ
-OnlyOnThisPlatform=´ËłĚĐňąŘĐëÔÚ %1 ÉĎÔËĐĐĄŁ
-OnlyOnTheseArchitectures=´ËłĚĐň˝öżÉ°˛×°ÔÚÎŞŇÔĎ´ŚŔíĆ÷ĚĺĎľ˝áššÉčźĆľÄ Windows °ćąžÉĎ:%n%n%1
-MissingWOW64APIs=ÄăŐýÔËĐĐľÄ Windows °ćąž˛ť°üşŹ°˛×°łĚĐňÖ´ĐĐ 64 Îť°˛×°ËůĐčľÄšŚÄÜĄŁŇ޸üŐý´ËÎĘĚ⣏Ç밲װˇţÎń°ü %1ĄŁ
-WinVersionTooLowError=´ËłĚĐňĐčŇŞ %1 °ćąž %2 ťň¸ü¸ß°ćąžĄŁ
-WinVersionTooHighError=´ËłĚĐň˛ťÄܰ˛×°ÔÚ %1 °ćąž %2 ťň¸ü¸ßľÄ°ćąžÉĎĄŁ
-AdminPrivilegesRequired=ÔÚ°˛×°´ËłĚĐňĘąąŘĐë×÷ÎŞšÜŔíÔąľÇÂźĄŁ
-PowerUserPrivilegesRequired=°˛×°´ËłĚĐňĘąąŘĐëŇÔšÜŔíÔąťň Power User ×éłÉÔąÉíˇÝľÇÂźĄŁ
-SetupAppRunningError=°˛×°łĚĐňźě˛âľ˝ %1 ľąÇ°ŐýÔÚÔËĐĐĄŁ%n%nÇëÁ˘ź´šŘąŐËüľÄËůÓĐĘľŔýŁŹČťşóľĽť÷Ą°Čˇś¨ĄąŇÔźĚĐřŁŹťňľĽť÷Ą°ČĄĎűĄąŇÔÍËłöĄŁ
-UninstallAppRunningError=ĐśÔŘźě˛âľ˝ %1 ľąÇ°ŐýÔÚÔËĐĐĄŁ%n%nÇëÁ˘ź´šŘąŐËüľÄËůÓĐĘľŔýŁŹČťşóľĽť÷Ą°Čˇś¨ĄąŇÔźĚĐřťňľĽť÷Ą°ČĄĎűĄąŇÔÍËłöĄŁ
-; *** Misc. errors
-ErrorCreatingDir=°˛×°łĚĐňÎޡ¨´´˝¨ÄżÂźĄ°%1Ąą
-ErrorTooManyFilesInDir=Îޡ¨ÔÚĿŸĄ°%1ĄąÖĐ´´˝¨ÎÄźţŁŹŇňÎŞËü°üşŹĚŤśŕÎÄźţ
-; *** Setup common messages
-ExitSetupTitle=ÍËłö°˛×°łĚĐň
-ExitSetupMessage=°˛×°łĚĐňδÍęłÉĄŁČçšűÁ˘ź´ÍËłöŁŹ˝Ť˛ťťá°˛×°¸ĂłĚĐňĄŁ%n%nżÉÔÚĆäËűĘąźäÔŮ´ÎÔËĐа˛×°łĚĐňŇÔÍęłÉ°˛×°ĄŁ%n%nĘǡńÍËłö°˛×°łĚĐň?
-AboutSetupMenuItem=šŘÓÚ°˛×°łĚĐň(&A)...
-AboutSetupTitle=šŘÓÚ°˛×°łĚĐň
-AboutSetupMessage=%1 °ćąž %2%n%3%n%n%1 Ö÷Ňł:%n%4
+SetupLdrStartupMessage=ç°ĺ¨ĺ°ĺŽčŁ
%1ăć¨ćłčŚçť§çťĺďź
+LdrCannotCreateTemp=ä¸č˝ĺ坺临ćśćäťśăĺŽčŁ
ä¸ćă
+LdrCannotExecTemp=ä¸č˝ć§čĄä¸´ćśçŽĺ˝ä¸çćäťśăĺŽčŁ
ä¸ćă
+HelpTextNote=
+
+; *** ĺŻĺ¨é误ćśćŻ
+LastErrorMessage=%1.%n%né误 %2: %3
+SetupFileMissing=ĺŽčŁ
çŽĺ˝ä¸çćäťś %1 丢夹ă诡俎ćŁčżä¸ŞéŽé˘ćčˇĺä¸ä¸Şć°çç¨ĺşĺŻćŹă
+SetupFileCorrupt=ĺŽčŁ
ć䝜塲ćĺă诡čˇĺä¸ä¸Şć°çç¨ĺşĺŻćŹă
+SetupFileCorruptOrWrongVer=ĺŽčŁ
ć䝜塲ćĺďźććŻä¸čżä¸ŞĺŽčŁ
ç¨ĺşççćŹä¸ĺ
źĺŽšă诡俎ćŁčżä¸ŞéŽé˘ćčˇĺć°çç¨ĺşĺŻćŹă
+InvalidParameter=ć ćçĺ˝äť¤čĄĺć°: %n%n%1
+SetupAlreadyRunning=ĺŽčŁ
ç¨ĺşćŁĺ¨čżčĄă
+WindowsVersionNotSupported=čżä¸Şç¨ĺşä¸ćŻć诼çćŹç莥çŽćşčżčĄă
+WindowsServicePackRequired=čżä¸Şç¨ĺşčŚćą%1ćĺĄĺ
%1ćć´éŤă
+NotOnThisPlatform=čżä¸Şç¨ĺşĺ°ä¸č˝čżčĄäş %1ă
+OnlyOnThisPlatform=čżä¸Şç¨ĺşĺż
饝čżčĄäş %1ă
+OnlyOnTheseArchitectures=čżä¸Şç¨ĺşĺŞč˝ĺ¨ä¸şä¸ĺĺ¤çĺ¨çťć莞莥ç Windows çćŹä¸čżčĄĺŽčŁ
:%n%n%1
+WinVersionTooLowError=čżä¸Şç¨ĺşéčŚ %1 çćŹ %2 ćć´éŤă
+WinVersionTooHighError=čżä¸Şç¨ĺşä¸č˝ĺŽčŁ
äş %1 çćŹ %2 ćć´éŤă
+AdminPrivilegesRequired=ĺ¨ĺŽčŁ
čżä¸Şç¨ĺşćść¨ĺż
饝䝼玥çĺ躍䝽çťĺ˝ă
+PowerUserPrivilegesRequired=ĺ¨ĺŽčŁ
čżä¸Şç¨ĺşćść¨ĺż
饝䝼玥çĺ躍䝽ćććéçç¨ćˇçťčşŤäť˝çťĺ˝ă
+SetupAppRunningError=ĺŽčŁ
ç¨ĺşĺç° %1 ĺ˝ĺćŁĺ¨čżčĄă%n%n诡ĺ
ĺ
łéććčżčĄççŞĺŁďźçśĺĺĺťâ祎ĺŽâçť§çťďźććâĺćśâéĺşă
+UninstallAppRunningError=ĺ¸č˝˝ç¨ĺşĺç° %1 ĺ˝ĺćŁĺ¨čżčĄă%n%n诡ĺ
ĺ
łéććčżčĄççŞĺŁďźçśĺĺĺťâ祎ĺŽâçť§çťďźććâĺćśâéĺşă
+
+; *** ĺŻĺ¨éŽé˘
+PrivilegesRequiredOverrideTitle=éćŠĺŽčŁ
ç¨ĺşć¨Ąĺź
+PrivilegesRequiredOverrideInstruction=éćŠĺŽčŁ
樥ĺź
+PrivilegesRequiredOverrideText1=%1 ĺŻäťĽä¸şććç¨ćˇĺŽčŁ
(éčŚçŽĄçĺćé)ďźćäť
为ć¨ĺŽčŁ
ă
+PrivilegesRequiredOverrideText2=%1 ĺŞč˝ä¸şć¨ĺŽčŁ
ďźć为ććç¨ćˇĺŽčŁ
(éčŚçŽĄçĺćé)ă
+PrivilegesRequiredOverrideAllUsers=为ććç¨ćˇĺŽčŁ
(&A)
+PrivilegesRequiredOverrideAllUsersRecommended=为ććç¨ćˇĺŽčŁ
(坺莎é饚)(&A)
+PrivilegesRequiredOverrideCurrentUser=ĺŞä¸şćĺŽčŁ
(&M)
+PrivilegesRequiredOverrideCurrentUserRecommended=ĺŞä¸şćĺŽčŁ
(坺莎é饚)(&M)
+
+; *** ĺ
śĺŽé误
+ErrorCreatingDir=ĺŽčŁ
ç¨ĺşä¸č˝ĺĺťşçŽĺ˝â%1âă
+ErrorTooManyFilesInDir=ä¸č˝ĺ¨çŽĺ˝â%1âä¸ĺĺťşćäťśďźĺ 为éé˘çć䝜太ĺ¤
+
+; *** ĺŽčŁ
ç¨ĺşĺ
Źĺ
ąćśćŻ
+ExitSetupTitle=éĺşĺŽčŁ
ç¨ĺş
+ExitSetupMessage=ĺŽčŁ
ç¨ĺşćŞĺŽćĺŽčŁ
ăĺŚćć¨ç°ĺ¨éĺşďźć¨çç¨ĺşĺ°ä¸č˝ĺŽčŁ
ă%n%nć¨ĺŻäťĽäťĽĺĺčżčĄĺŽčŁ
ç¨ĺşĺŽćĺŽčŁ
ă%n%néĺşĺŽčŁ
ç¨ĺşĺďź
+AboutSetupMenuItem=ĺ
łäşĺŽčŁ
ç¨ĺş(&A)...
+AboutSetupTitle=ĺ
łäşĺŽčŁ
ç¨ĺş
+AboutSetupMessage=%1 çćŹ %2%n%3%n%n%1 丝饾:%n%4
AboutSetupNote=
TranslatorNote=
-; *** Buttons
-ButtonBack=< ÉĎŇť˛˝(&B)
-ButtonNext=ĎÂŇť˛˝(&N) >
-ButtonInstall=°˛×°(&I)
-ButtonOK=ȡś¨
-ButtonCancel=ČĄĎű
-ButtonYes=ĘÇ(&Y)
-ButtonYesToAll=˝ÓĘÜČŤ˛ż(&A)
-ButtonNo=ˇń(&N)
-ButtonNoToAll=ˇńś¨ČŤ˛ż(&O)
-ButtonFinish=ÍęłÉ(&F)
-ButtonBrowse=äŻŔŔ(&B)...
-ButtonWizardBrowse=äŻŔŔ(&R)...
-ButtonNewFolder=Đ½¨ÎÄźţźĐ(&M)
-; *** "Select Language" dialog messages
-SelectLanguageTitle=ŃĄÔń°˛×°łĚĐňÓďŃÔ
-SelectLanguageLabel=ŃĄÔń°˛×°ĘąŇŞĘšÓĂľÄÓďŃÔ:
-; *** Common wizard text
-ClickNext=ľĽť÷Ą°ĎÂŇť˛˝ĄąŇÔźĚĐřŁŹťňľĽť÷Ą°ČĄĎűĄąŇÔÍËłö°˛×°łĚĐňĄŁ
+
+; *** ćéŽ
+ButtonBack=< ä¸ä¸ćĽ(&B)
+ButtonNext=ä¸ä¸ćĽ(&N) >
+ButtonInstall=ĺŽčŁ
(&I)
+ButtonOK=祎ĺŽ
+ButtonCancel=ĺćś
+ButtonYes=ćŻ(&Y)
+ButtonYesToAll=ĺ
¨ćŻ(&A)
+ButtonNo=ĺŚ(&N)
+ButtonNoToAll=ĺ
¨ĺŚ(&O)
+ButtonFinish=ĺŽć(&F)
+ButtonBrowse=ćľč§(&B)...
+ButtonWizardBrowse=ćľč§(&R)...
+ButtonNewFolder=ć°ĺťşć䝜多(&M)
+
+; *** âéćŠčŻč¨â寚čŻćĄćśćŻ
+SelectLanguageTitle=éćŠĺŽčŁ
čŻč¨
+SelectLanguageLabel=éćŠĺŽčŁ
ćśčŚä˝żç¨çčŻč¨ă
+
+; *** ĺ
Źĺ
ąĺ察ćĺ
+ClickNext=ĺĺťâä¸ä¸ćĽâçť§çťďźćĺĺťâĺćśâéĺşĺŽčŁ
ç¨ĺşă
BeveledLabel=
-BrowseDialogTitle=äŻŔŔ˛éŐŇÎÄźţźĐ
-BrowseDialogLabel=ÔÚŇÔĎÂÁĐąíÖĐŃĄÔńŇť¸öÎÄźţźĐŁŹČťşóľĽť÷Ą°Čˇś¨ĄąĄŁ
-NewFolderName=Đ½¨ÎÄźţźĐ
-; *** "Welcome" wizard page
-WelcomeLabel1=ťśÓĘšÓĂ [name] °˛×°Ďňľź
-WelcomeLabel2=Ő⽍ÔÚźĆËăťúÉϰ˛×° [name/ver]ĄŁ%n%n˝¨ŇéšŘąŐËůÓĐĆäËűÓŚÓĂłĚĐňÔŮźĚĐřĄŁ
-; *** "Password" wizard page
-WizardPassword=ĂÜÂë
-PasswordLabel1=´Ë°˛×°ĘÜĂÜÂ빣ť¤ĄŁ
-PasswordLabel3=ÇëĚᚊĂÜÂ룏ȝşóľĽť÷Ą°ĎÂŇť˛˝ĄąŇÔźĚĐřĄŁĂÜÂëÇřˇÖ´óĐĄĐ´ĄŁ
-PasswordEditLabel=ĂÜÂë(&P):
-IncorrectPassword=ĘäČëľÄĂÜÂ벝ŐýȡĄŁÇëÖŘĘÔĄŁ
-; *** "License Agreement" wizard page
-WizardLicense=ĐíżÉĐŇé
-LicenseLabel=ÇëÔÚźĚĐř˛Ů×÷ǰÔÄśÁŇÔĎÂÖŘŇŞĐĹϢĄŁ
-LicenseLabel3=ÇëÔÄśÁŇÔĎÂĐíżÉĐŇ饣ąŘĐë˝ÓĘÜ´ËĐŇéĚőżî˛ĹżÉźĚĐř°˛×°ĄŁ
-LicenseAccepted=ÎŇ˝ÓĘÜĐŇé(&A)
-LicenseNotAccepted=ÎҲť˝ÓĘÜĐŇé(&D)
-; *** "Information" wizard pages
-WizardInfoBefore=ĐĹϢ
-InfoBeforeLabel=ÇëÔÚźĚĐř˛Ů×÷ǰÔÄśÁŇÔĎÂÖŘŇŞĐĹϢĄŁ
-InfoBeforeClickLabel=×źą¸şĂźĚĐř°˛×°şóŁŹľĽť÷Ą°ĎÂŇť˛˝ĄąĄŁ
-WizardInfoAfter=ĐĹϢ
-InfoAfterLabel=ÇëÔÚźĚĐř˛Ů×÷ǰÔÄśÁŇÔĎÂÖŘŇŞĐĹϢĄŁ
-InfoAfterClickLabel=×źą¸şĂźĚĐř°˛×°şóŁŹľĽť÷Ą°ĎÂŇť˛˝ĄąĄŁ
-; *** "User Information" wizard page
-WizardUserInfo=ÓĂť§ĐĹϢ
-UserInfoDesc=ÇëĘäČëÄăľÄĐĹϢĄŁ
-UserInfoName=ÓĂť§Ăű(&U):
-UserInfoOrg=×éÖŻ(&O):
-UserInfoSerial=ĐňÁĐşĹ(&S):
-UserInfoNameRequired=ąŘĐëĘäČëĂűłĆĄŁ
-; *** "Select Destination Location" wizard page
-WizardSelectDir=ŃĄÔńÄżąęÎťÖĂ
-SelectDirDesc=ÓŚ˝Ť [name] °˛×°ľ˝ÄÄŔď?
-SelectDirLabel3=°˛×°łĚĐňťá˝Ť [name] °˛×°ľ˝ŇÔĎÂÎÄźţźĐĄŁ
-SelectDirBrowseLabel=ČôŇŞźĚĐřŁŹľĽť÷Ą°ĎÂŇť˛˝ĄąĄŁČçšűĎëŃĄÔńĆäËűÎÄźţźĐŁŹľĽť÷Ą°äŻŔŔĄąĄŁ
-DiskSpaceMBLabel=ĐčŇŞÖÁÉŮ [mb] MB żÉÓĂ´ĹĹ̿՟䥣
-CannotInstallToNetworkDrive=°˛×°łĚĐňÎޡ¨°˛×°ľ˝ÍřÂçÇýśŻĆ÷ĄŁ
-CannotInstallToUNCPath=°˛×°łĚĐňÎޡ¨°˛×°ľ˝ UNC ¡žśĄŁ
-InvalidPath=ąŘĐëĘäČë´řÇýśŻĆ÷şĹľÄÍęŐű¡žś(ŔýČç:%n%nC:\APP%n%n)ťňŇÔϸńĘ˝ľÄ UNC ¡žś:%n%n\\server\share
-InvalidDrive=ËůŃĄÇýśŻĆ÷ťň UNC š˛Ďí˛ť´ćÔÚťň˛ťżÉˇĂÎĘĄŁÇëÁíÍâŃĄÔńĄŁ
-DiskSpaceWarningTitle=´ĹĹ̿՟䲝×ă
-DiskSpaceWarning=°˛×°łĚĐňĐčŇŞÖÁÉŮ %1 KB żÉÓĂżŐźäŔ´°˛×°ŁŹľŤËůŃĄÇýśŻĆ÷˝öÓĐ %2 KB żÉÓÿ՟䥣%n%nĘǡńČÔŇŞźĚĐř?
-DirNameTooLong=ÎÄźţźĐĂűłĆťň¡žśĚŤł¤ĄŁ
-InvalidDirName=ÎÄźţźĐĂűłĆÎŢЧĄŁ
-BadDirName32=ÎÄźţźĐĂű˛ťÄܰüşŹŇÔĎÂČÎŇť×Öˇű:%n%n%1
-DirExistsTitle=ÎÄźţźĐ´ćÔÚ
-DirExists=ÎÄźţźĐ:%n%n%1%n%nŇŃ´ćÔÚĄŁĘǡńČÔŇŞ°˛×°ľ˝¸ĂÎÄźţźĐ?
-DirDoesntExistTitle=ÎÄźţźĐ˛ť´ćÔÚ
-DirDoesntExist=ÎÄźţźĐ:%n%n%1%n%n˛ť´ćÔÚĄŁĘǡńŇŞ´´˝¨¸ĂÎÄźţźĐ?
-; *** "Select Components" wizard page
-WizardSelectComponents=ŃĄÔń×éźţ
-SelectComponentsDesc=ÓŚ°˛×°ÄÄĐŠ×éźţ?
-SelectComponentsLabel2=ŃĄÔńĎŁÍű°˛×°ľÄ×éźţŁťÇĺłý˛ťĎŁÍű°˛×°ľÄ×éźţĄŁ×źą¸žÍĐ÷şóľĽť÷Ą°ĎÂŇť˛˝ĄąŇÔźĚĐřĄŁ
-FullInstallation=ÍęČŤ°˛×°
+BrowseDialogTitle=ćľč§ć䝜多
+BrowseDialogLabel=ĺ¨ä¸ĺĺ襨ä¸éćŠä¸ä¸Şć䝜多ďźçśĺĺĺťâ祎ĺŽâă
+NewFolderName=ć°ĺťşć䝜多
+
+; *** â揢čżâĺ察饾
+WelcomeLabel1=揢čżä˝żç¨ [name] ĺŽčŁ
ĺ察
+WelcomeLabel2=ç°ĺ¨ĺ°ĺŽčŁ
[name/ver] ĺ°ć¨ççľčä¸ă%n%nć¨čć¨ĺ¨çť§çťĺŽčŁ
ĺĺ
łéććĺ
śĺŽĺşç¨ç¨ĺşă
+
+; *** âĺŻç âĺ察饾
+WizardPassword=ĺŻç
+PasswordLabel1=čżä¸ŞĺŽčŁ
ç¨ĺşćĺŻç äżć¤ă
+PasswordLabel3=诡čžĺ
ĽĺŻç ďźçśĺĺĺťâä¸ä¸ćĽâçť§çťăĺŻç ĺşĺ大ĺ°ĺă
+PasswordEditLabel=ĺŻç (&P):
+IncorrectPassword=ć¨čžĺ
ĽçĺŻç ä¸ćŁçĄŽďźčݎéčŻă
+
+; *** â莸ĺŻĺ莎âĺ察饾
+WizardLicense=莸ĺŻĺ莎
+LicenseLabel=çť§çťĺŽčŁ
ĺ诡é
话ä¸ĺéčŚäżĄćŻă
+LicenseLabel3=诡äťçťé
话ä¸ĺ莸ĺŻĺ莎ăć¨ĺ¨çť§çťĺŽčŁ
ĺĺż
饝ĺćčżäşĺ莎ćĄćŹžă
+LicenseAccepted=ćĺćć¤ĺ莎(&A)
+LicenseNotAccepted=ćä¸ĺćć¤ĺ莎(&D)
+
+; *** â俥ćŻâĺ察饾
+WizardInfoBefore=俥ćŻ
+InfoBeforeLabel=诡ĺ¨çť§çťĺŽčŁ
ĺé
话ä¸ĺéčŚäżĄćŻă
+InfoBeforeClickLabel=ĺŚćć¨ćłçť§çťĺŽčŁ
ďźĺĺťâä¸ä¸ćĽâă
+WizardInfoAfter=俥ćŻ
+InfoAfterLabel=诡ĺ¨çť§çťĺŽčŁ
ĺé
话ä¸ĺéčŚäżĄćŻă
+InfoAfterClickLabel=ĺŚćć¨ćłçť§çťĺŽčŁ
ďźĺĺťâä¸ä¸ćĽâă
+
+; *** âç¨ćˇäżĄćŻâĺ察饾
+WizardUserInfo=ç¨ćˇäżĄćŻ
+UserInfoDesc=诡čžĺ
Ľć¨ç俥ćŻă
+UserInfoName=ç¨ćˇĺ(&U):
+UserInfoOrg=çťçť(&O):
+UserInfoSerial=ĺşĺĺˇ(&S):
+UserInfoNameRequired=ć¨ĺż
饝čžĺ
Ľĺĺă
+
+; *** âéćŠçŽć çŽĺ˝âĺ察é˘
+WizardSelectDir=éćŠçŽć ä˝ç˝Ž
+SelectDirDesc=ć¨ćłĺ° [name] ĺŽčŁ
ĺ¨äťäšĺ°ćšďź
+SelectDirLabel3=ĺŽčŁ
ç¨ĺşĺ°ĺŽčŁ
[name] ĺ°ä¸ĺć䝜多ä¸ă
+SelectDirBrowseLabel=ĺĺťâä¸ä¸ćĽâçť§çťăĺŚćć¨ćłéćŠĺ
śĺŽć䝜多ďźĺĺťâćľč§âă
+DiskSpaceGBLabel=čłĺ°éčŚć [gb] GB çĺŻç¨çŁç犺é´ă
+DiskSpaceMBLabel=čłĺ°éčŚć [mb] MB çĺŻç¨çŁç犺é´ă
+CannotInstallToNetworkDrive=ĺŽčŁ
ç¨ĺşć ćłĺŽčŁ
ĺ°ä¸ä¸Şç˝çťéŠąĺ¨ĺ¨ă
+CannotInstallToUNCPath=ĺŽčŁ
ç¨ĺşć ćłĺŽčŁ
ĺ°ä¸ä¸ŞUNC衯ĺžă
+InvalidPath=ć¨ĺż
饝čžĺ
Ľä¸ä¸Şĺ¸ŚéŠąĺ¨ĺ¨ĺˇć çĺŽć´čˇŻĺžďźäžĺŚ:%n%nC:\APP%n%nćä¸ĺ形ĺźç UNC 衯ĺž:%n%n\\server\share
+InvalidDrive=ć¨éĺŽç銹ĺ¨ĺ¨ć UNC ĺ
ąäşŤä¸ĺĺ¨ćä¸č˝čŽżéŽă诡ééćŠĺ
śĺŽä˝ç˝Žă
+DiskSpaceWarningTitle=沥ćčśłĺ¤ççŁç犺é´
+DiskSpaceWarning=ĺŽčŁ
ç¨ĺşčłĺ°éčŚ %1 KB çĺŻç¨çŠşé´ćč˝ĺŽčŁ
ďźä˝éĺŽéŠąĺ¨ĺ¨ĺŞć %2 KB çĺŻç¨çŠşé´ă%n%nć¨ä¸ĺŽčŚçť§çťĺďź
+DirNameTooLong=ć䝜多ĺć衯ĺžĺ¤Şéżă
+InvalidDirName=ć䝜多ĺćŻć ćçă
+BadDirName32=ć䝜多ĺä¸č˝ĺ
ĺŤä¸ĺäťťä˝ĺ珌:%n%n%1
+DirExistsTitle=ć䝜多ĺĺ¨
+DirExists=ć䝜多:%n%n%1%n%n塲çťĺĺ¨ăć¨ä¸ĺŽčŚĺŽčŁ
ĺ°čżä¸Şć䝜多ä¸ĺďź
+DirDoesntExistTitle=ć䝜多ä¸ĺĺ¨
+DirDoesntExist=ć䝜多:%n%n%1%n%nä¸ĺĺ¨ăć¨ćłčŚĺĺťşć¤çŽĺ˝ĺďź
+
+; *** âéćŠçťäťśâĺ察饾
+WizardSelectComponents=éćŠçťäťś
+SelectComponentsDesc=ć¨ćłĺŽčŁ
ĺŞäşç¨ĺşççťäťśďź
+SelectComponentsLabel2=éćŠć¨ćłčŚĺŽčŁ
ççťäťśďźć¸
é¤ć¨ä¸ćłĺŽčŁ
ççťäťśăçśĺĺĺťâä¸ä¸ćĽâçť§çťă
+FullInstallation=ĺŽĺ
¨ĺŽčŁ
; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
-CompactInstallation=źň˝ŕ°˛×°
-CustomInstallation=×Ôś¨Ň尲װ
-NoUninstallWarningTitle=×éźţ´ćÔÚ
-NoUninstallWarning=°˛×°łĚĐňźě˛âľ˝źĆËăťúÉĎŇѰ˛×°ŇÔĎÂ×éźţ:%n%n%1%n%nČĄĎűŃĄÔńŐâĐŠ×éźţ˝Ť˛ťťáĐśÔŘËüĂÇĄŁ%n%nĘǡńČÔŇŞźĚĐř?
+CompactInstallation=çŽć´ĺŽčŁ
+CustomInstallation=čŞĺŽäšĺŽčŁ
+NoUninstallWarningTitle=çťäťśĺĺ¨
+NoUninstallWarning=ĺŽčŁ
ç¨ĺşäžŚćľĺ°ä¸ĺçťäťśĺˇ˛ĺ¨ć¨ççľčä¸ĺŽčŁ
ă:%n%n%1%n%nĺćśéĺŽčżäşçťäťśĺ°ä¸č˝ĺ¸č˝˝ĺŽäťŹă%n%nć¨ä¸ĺŽčŚçť§çťĺďź
ComponentSize1=%1 KB
ComponentSize2=%1 MB
-ComponentsDiskSpaceMBLabel=ľąÇ°ŃĄÔńĐčŇŞÖÁÉŮ [mb] MB ´ĹĹ̿՟䥣
-; *** "Select Additional Tasks" wizard page
-WizardSelectTasks=ŃĄÔńĆäËűČÎÎń
-SelectTasksDesc=ÓŚÖ´ĐĐÄÄĐŠĆäËűČÎÎń?
-SelectTasksLabel2=ŃĄÔń°˛×° [name] ʹϣÍű°˛×°łĚĐňŔ´Ö´ĐĐľÄĆäËűČÎÎńŁŹČťşóľĽť÷Ą°ĎÂŇť˛˝ĄąĄŁ
-; *** "Select Start Menu Folder" wizard page
-WizardSelectProgramGroup=ŃĄÔńżŞĘź˛ËľĽÎÄźţźĐ
-SelectStartMenuFolderDesc=°˛×°łĚĐňÓŚ˝ŤłĚĐňľÄżě˝Ýˇ˝Ę˝ˇĹÖĂľ˝ÄÄŔď?
-SelectStartMenuFolderLabel3=°˛×°łĚĐň˝ŤÔÚŇÔĎÂżŞĘź˛ËľĽÎÄźţźĐÖĐ´´˝¨¸ĂłĚĐňľÄżě˝Ýˇ˝Ę˝ĄŁ
-SelectStartMenuFolderBrowseLabel=ČôŇŞźĚĐřŁŹľĽť÷Ą°ĎÂŇť˛˝ĄąĄŁČçšűĎëŃĄÔńĆäËűÎÄźţźĐŁŹľĽť÷Ą°äŻŔŔĄąĄŁ
-MustEnterGroupName=ąŘĐëĘäČëÎÄźţźĐĂűĄŁ
-GroupNameTooLong=ÎÄźţźĐĂűłĆťň¡žśĚŤł¤ĄŁ
-InvalidGroupName=ÎÄźţźĐĂűłĆÎŢЧĄŁ
-BadGroupName=ÎÄźţźĐĂű˛ťÄÜąŁť¤ŇÔĎÂČÎŇť×Öˇű:%n%n%1
-NoProgramGroupCheck2=˛ť´´˝¨żŞĘź˛ËľĽÎÄźţźĐ(&D)
-; *** "Ready to Install" wizard page
-WizardReady=°˛×°×źą¸žÍĐ÷
-ReadyLabel1=°˛×°łĚĐňĎÖŇŃ×źą¸şĂÔÚźĆËăťúÉϰ˛×° [name]ĄŁ
-ReadyLabel2a=ľĽť÷Ą°°˛×°ĄąŇÔźĚĐř°˛×°ŁŹČçĎë˛éż´ťň¸ü¸ÄČÎşÎÉčÖĂÔňľĽť÷"ˇľťŘ"ĄŁ
-ReadyLabel2b=ľĽť÷Ą°°˛×°ĄąŇÔźĚĐř°˛×°ĄŁ
-ReadyMemoUserInfo=ÓĂť§ĐĹϢ:
-ReadyMemoDir=ÄżąęÎťÖĂ:
-ReadyMemoType=°˛×°łĚĐňŔŕĐÍ:
-ReadyMemoComponents=ËůŃĄ×éźţ:
-ReadyMemoGroup=żŞĘź˛ËľĽÎÄźţźĐ:
-ReadyMemoTasks=ĆäËűČÎÎń:
-; *** "Preparing to Install" wizard page
-WizardPreparing=ŐýÔÚ×źą¸°˛×°
-PreparingDesc=°˛×°łĚĐňŐýןą¸ÔÚźĆËăťúÉϰ˛×° [name]ĄŁ
-PreviousInstallNotCompleted=ÉĎŇť¸öłĚĐňľÄ°˛×°/ÉžłýδÍęłÉĄŁĐčÖŘĆôźĆËăťúŇÔÍęłÉ¸Ă°˛×°ĄŁ%n%nÖŘĆôźĆËăťúşóŁŹÖŘĐÂÔËĐа˛×°łĚĐňŇÔÍęłÉ [name] ľÄ°˛×°ĄŁ
-CannotContinue=°˛×°łĚĐňÎޡ¨źĚĐřĄŁÇ뾼ť÷"ČĄĎű"ŇÔÍËłöĄŁ
-ApplicationsFound=ŇÔĎÂÓŚÓĂłĚĐňŐýÔÚĘšÓĂĐčҪͨšý°˛×°łĚĐň˝řĐиüĐÂľÄÎÄźţĄŁ˝¨ŇéÔĘĐí°˛×°łĚĐň×ÔśŻšŘąŐŐâĐŠÓŚÓĂłĚĐňĄŁ
-ApplicationsFound2=ŇÔĎÂÓŚÓĂłĚĐňŐýÔÚĘšÓĂĐčҪͨšý°˛×°łĚĐň˝řĐиüĐÂľÄÎÄźţĄŁ˝¨ŇéÔĘĐí°˛×°łĚĐň×ÔśŻšŘąŐŐâĐŠÓŚÓĂłĚĐňĄŁÍęłÉ°˛×°şóŁŹ°˛×°łĚĐň˝Ťł˘ĘÔÖŘĆôÓŚÓĂłĚĐňĄŁ
-CloseApplications=×ÔśŻšŘąŐÓŚÓĂłĚĐň(&A)
-DontCloseApplications=˛ťšŘąŐÓŚÓĂłĚĐň(&D)
-ErrorCloseApplications=°˛×°łĚĐňÎޡ¨×ÔśŻšŘąŐËůÓĐÓŚÓĂłĚĐňĄŁ˝¨ŇéÔÚźĚĐř˛Ů×÷֎ǰĎȚعŐËůÓĐĘšÓĂĐčͨšý°˛×°łĚĐň˝řĐиüĐÂľÄÎÄźţľÄÓŚÓĂłĚĐňĄŁ
-; *** "Installing" wizard page
-WizardInstalling=ŐýÔÚ°˛×°
-InstallingLabel=°˛×°łĚĐňŐýÔÚźĆËăťúÉϰ˛×° [name]ŁŹÇëÉԾȥŁ
-; *** "Setup Completed" wizard page
-FinishedHeadingLabel=ÍęłÉ [name] °˛×°Ďňľź
-FinishedLabelNoIcons=°˛×°łĚĐňŇŃÔÚźĆËăťúÉĎÍęłÉ°˛×° [name]ĄŁ
-FinishedLabel=°˛×°łĚĐňŇŃÔÚźĆËăťúÉĎÍęłÉ°˛×° [name]ĄŁÍ¨šýŃĄÔń°˛×°ľÄżě˝Ýˇ˝Ę˝żÉŇÔĆôśŻ¸ĂÓŚÓĂłĚĐňĄŁ
-ClickFinish=ľĽť÷Ą°ÍęłÉĄąŇÔÍËłö°˛×°łĚĐňĄŁ
-FinishedRestartLabel=ŇŞÍęłÉ [name] ľÄ°˛×°ŁŹ°˛×°łĚĐňąŘĐëÖŘĆôźĆËăťúĄŁĘǡńŇŞÁ˘ź´ÖŘĆô?
-FinishedRestartMessage=ŇŞÍęłÉ [name] ľÄ°˛×°ŁŹ°˛×°łĚĐňąŘĐëÖŘĆôźĆËăťúĄŁ%n%nĘǡńŇŞÁ˘ź´ÖŘĆô?
-ShowReadmeCheck=ĘÇŁŹÎŇĎŁÍű˛éż´ README ÎÄźţ
-YesRadio=ĘÇŁŹÁ˘ź´ÖŘĆôźĆËăťú(&Y)
-NoRadio=ˇńŁŹÎŇ˝ŤÉÔşóÖŘĆôźĆËăťú(&N)
-; used for example as 'Run MyProg.exe'
-RunEntryExec=ÔËĐĐ %1
-; used for example as 'View Readme.txt'
-RunEntryShellExec=˛éż´ %1
-; *** "Setup Needs the Next Disk" stuff
-ChangeDiskTitle=°˛×°łĚĐňĐčŇŞĎÂŇť¸ö´ĹĹĚ
-SelectDiskLabel2=Çë˛ĺČë´ĹĹĚ %1 ˛˘ľăť÷Ą°Čˇś¨ĄąĄŁ%n%nČçšű´Ë´ĹĹĚÉĎľÄÎÄźţżÉÔÚŇÔĎÂÎÄźţźĐÍâľÄĆäËűÎÄźţźĐÖĐŐŇľ˝ŁŹÇëĘäČëŐýȡ¡žśťňľĽť÷Ą°äŻŔŔĄąĄŁ
-PathLabel=¡žś(&P):
-FileNotInDir2=ÔÚĄ°%2ĄąÖĐÎޡ¨ś¨ÎťÎÄźţĄ°%1ĄąĄŁÇë˛ĺČëŐýȡľÄ´ĹĹĚťňŃĄÔńĆäËűÎÄźţźĐĄŁ
-SelectDirectoryLabel=ÇëÖ¸ś¨ĎÂŇť¸ö´ĹĹĚľÄÎťÖĂĄŁ
-; *** Installation phase messages
-SetupAborted=°˛×°łĚĐňδÍęłÉĄŁ%n%nÇë¸üŐýÎĘĚⲢÖŘĐÂÔËĐа˛×°łĚĐňĄŁ
-EntryAbortRetryIgnore=ľĽť÷Ą°ÖŘĘÔĄąŇÔÔŮ´Îł˘ĘÔŁŹľĽť÷Ą°şöÂÔĄąŇÔźĚĐřŁŹťňľĽť÷Ą°ÖĐÖšĄąŇÔČĄĎű°˛×°ĄŁ
-; *** Installation status messages
-StatusClosingApplications=ŐýÔښعŐÓŚÓĂłĚĐň...
-StatusCreateDirs=ŐýÔÚ´´˝¨ÄżÂź...
-StatusExtractFiles=ŐýÔÚ˝âŃšËőÎÄźţ...
-StatusCreateIcons=ŐýÔÚ´´˝¨żě˝Ýˇ˝Ę˝...
-StatusCreateIniEntries=ŐýÔÚ´´˝¨ INI Ďî...
-StatusCreateRegistryEntries=ŐýÔÚ´´˝¨×˘˛áąíĎî...
-StatusRegisterFiles=ŐýÔÚע˛áÎÄźţ...
-StatusSavingUninstall=ŐýÔÚąŁ´ćĐśÔŘĐĹϢ...
-StatusRunProgram=ŐýÔÚÍęłÉ°˛×°...
-StatusRestartingApplications=ŐýÔÚÖŘĆôÓŚÓĂłĚĐň...
-StatusRollback=ŐýÔÚťŘÍ˸ü¸Ä...
-; *** Misc. errors
-ErrorInternal2=ÄÚ˛ż´íÎó: %1
-ErrorFunctionFailedNoCode=%1 ʧ°Ü
-ErrorFunctionFailed=%1 ʧ°ÜŁť´úÂë %2
-ErrorFunctionFailedWithMessage=%1 ʧ°ÜŁť´úÂë %2ĄŁ%n%3
-ErrorExecutingProgram=Îޡ¨Ö´ĐĐÎÄźţ:%n%1
-; *** Registry errors
-ErrorRegOpenKey=´ňżŞ×˘˛áąíĎîĘąłö´í:%n%1\%2
-ErrorRegCreateKey=´´˝¨×˘˛áąíĎîĘąłö´í:%n%1\%2
-ErrorRegWriteKey=Đ´Čëע˛áąíĎîĘąłö´í:%n%1\%2
-; *** INI errors
-ErrorIniEntry=ÔÚÎÄźţĄ°%1ĄąÖĐ´´˝¨ INI ĎîĘąłö´íĄŁ
-; *** File copying errors
-FileAbortRetryIgnore=ľĽť÷Ą°ÖŘĘÔĄąŇÔÔٴβŮ×÷ŁŹľĽť÷Ą°şöÂÔĄąŇÔĚřšý´ËÎÄźţ(˛ť˝¨Ňé´Ë˛Ů×÷)ŁŹťňľĽť÷Ą°ÖĐÖšĄąŇÔČĄĎű°˛×°ĄŁ
-FileAbortRetryIgnore2=ľĽť÷Ą°ÖŘĘÔĄąŇÔÔٴβŮ×÷ŁŹľĽť÷Ą°şöÂÔĄąŇÔźĚĐř(˛ť˝¨Ňé´Ë˛Ů×÷)ŁŹťňľĽť÷Ą°ÖĐÖšĄąŇÔČĄĎű°˛×°ĄŁ
-SourceIsCorrupted=Ô´ÎÄźţŇŃËđťľ
-SourceDoesntExist=Ô´ÎÄźţĄ°%1Ąą˛ť´ćÔÚ
-ExistingFileReadOnly=ĎÖÓĐÎÄźţąťąęźÇÎŞÖťśÁ×´ĚŹĄŁ%n%nľĽť÷Ą°ÖŘĘÔĄąŇÔÉžłýÖťśÁĚŘĐÔ˛˘ÖŘĘÔŁŹľĽť÷Ą°şöÂÔĄąŇÔĚřšý´ËÎÄźţŁŹťňľĽť÷Ą°ÖĐÖšĄąŇÔČĄĎű°˛×°ĄŁ
-ErrorReadingExistingDest=ł˘ĘÔśÁČĄĎÖÓĐÎÄźţĘąłö´í:
-FileExists=¸ĂÎÄźţŇŃ´ćÔÚĄŁ%n%nĘǡńŇŞ°˛×°łĚĐň¸˛¸ÇËü?
-ExistingFileNewer=ĎÖÓĐÎÄźţąČ°˛×°łĚĐňŐýł˘ĘÔ°˛×°ľÄÎÄźţ¸üĐÂĄŁ˝¨Ň鹣ÁôĎÖÓĐÎÄźţĄŁ%n%nĘǡńŇŞąŁÁôĎÖÓĐÎÄźţ?
-ErrorChangingAttr=ł˘ĘÔ¸ü¸ÄĎÖÓĐÎÄźţĚŘĐÔłö´í:
-ErrorCreatingTemp=ł˘ĘÔÔÚÄżąęĿŸ´´˝¨ÎÄźţĘąłö´í:
-ErrorReadingSource=ł˘ĘÔśÁČĄÔ´ÎÄźţĘąłö´í:
-ErrorCopying=ł˘ĘÔ¸´ÖĆÎÄźţĘąłö´í:
-ErrorReplacingExistingFile=ł˘ĘÔĚćťťĎÖÓĐÎÄźţĘąłö´í:
-ErrorRestartReplace=RestartReplace ʧ°Ü:
-ErrorRenamingTemp=ł˘ĘÔÔÚÄżąęĿŸÖŘĂüĂűÎÄźţĘąłö´í:
-ErrorRegisterServer=Îޡ¨×˘˛á DLL/OCX: %1
-ErrorRegSvr32Failed=RegSvr32 ʧ°ÜŁŹÍËłö´úÂëÎŞ %1
-ErrorRegisterTypeLib=Îޡ¨×˘˛áŔŕĐÍżâ: %1
-; *** Post-installation errors
-ErrorOpeningReadme=ł˘ĘÔ´ňżŞ README ÎÄźţĘąłö´íĄŁ
-ErrorRestartingComputer=°˛×°łĚĐňÎޡ¨ÖŘĆôźĆËăťúĄŁÇëĘÖśŻÖ´Đд˲Ů×÷ĄŁ
-; *** Uninstaller messages
-UninstallNotFound=ÎÄźţĄ°%1Ąą˛ť´ćÔÚĄŁÎޡ¨°˛×°ĄŁ
-UninstallOpenError=Îޡ¨´ňżŞÎÄźţĄ°%1ĄąĄŁÎޡ¨ĐśÔŘ
-UninstallUnsupportedVer=ĐśÔŘČŐÖžĄ°%1ĄąľÄ¸ńĘ˝Îޡ¨ąť´Ë°ćąžľÄĐśÔŘłĚĐňĘśąđĄŁÎޡ¨ĐśÔŘ
-UninstallUnknownEntry=ĐśÔŘČŐÖžÖС˘ĎÖδ֪ĚőÄż(%1)
-ConfirmUninstall=ȡś¨ŇŞłšľ×Éžłý %1 şÍź°ĆäČŤ˛ż×éźţ?
-UninstallOnlyOnWin64=˝öżÉÔÚ 64 Îť Windows ÉĎĐśÔش˰˛×°ĄŁ
-OnlyAdminCanUninstall=˝öžßÓĐšÜŔíȨĎŢľÄÓĂť§˛ĹżÉĐśÔش˰˛×°ĄŁ
-UninstallStatusLabel=Őý´ÓźĆËăťúÉžłý %1ŁŹÇëÉԾȥŁ
-UninstalledAll=ŇŃłÉšŚ´ÓźĆËăťúÉĎÉžłý %1ĄŁ
-UninstalledMost=%1 ĐśÔŘÍęłÉĄŁ%n%nÎޡ¨ÉžłýҝЊԪËŘĄŁżÉ˝ŤĆäĘÖśŻÉžłýĄŁ
-UninstalledAndNeedsRestart=ŇŞÍęłÉ %1 ľÄĐśÔŘŁŹąŘĐëÖŘĆôźĆËăťúĄŁ%n%nĘǡńŇŞÁ˘ź´ÖŘĆô?
-UninstallDataCorrupted=Ą°%1ĄąÎÄźţŇŃË𝾥ŁÎޡ¨ĐśÔŘ
-; *** Uninstallation phase messages
-ConfirmDeleteSharedFileTitle=Éžłýš˛ĎíÎÄźţ?
-ConfirmDeleteSharedFile2=ϾͳąíĘžŇÔĎš˛ĎíÎÄźţ˛ťÔŮąťČκγĚĐňĘšÓĂĄŁĘǡńŇŞĐśÔŘÉžłý´Ëš˛ĎíÎÄźţ?%n%nČçšűÔÚÓĐłĚĐňČÔÔÚĘšÓĂ´ËÎÄźţśřËüąťÉžłýŁŹÔňłĚĐňżÉÄܲťťáŐýłŁÔËĐĐĄŁČçšű˛ťČˇś¨ŁŹÇëŃĄÔńĄ°ˇńĄąĄŁ˝ŤÎÄźţÁôץϾͳÉϲťťáÔěłÉČÎşÎÎĘĚ⥣
-SharedFileNameLabel=ÎÄźţĂű:
-SharedFileLocationLabel=ÎťÖĂ:
-WizardUninstalling=ĐśÔŘ×´ĚŹ
-StatusUninstalling=ŐýÔÚĐśÔŘ %1...
+ComponentsDiskSpaceGBLabel=ĺ˝ĺéćŠççťäťśčłĺ°éčŚ [gb] GB ççŁç犺é´ă
+ComponentsDiskSpaceMBLabel=ĺ˝ĺéćŠççťäťśčłĺ°éčŚ [mb] MB ççŁç犺é´ă
+
+; *** âéćŠéĺ äťťĺĄâĺ察饾
+WizardSelectTasks=éćŠéĺ äťťĺĄ
+SelectTasksDesc=ć¨ćłčŚĺŽčŁ
ç¨ĺşć§čĄĺŞäşéĺ äťťĺĄďź
+SelectTasksLabel2=éćŠć¨ćłčŚĺŽčŁ
ç¨ĺşĺ¨ĺŽčŁ
[name] ćść§čĄçéĺ äťťĺĄďźçśĺĺĺťâä¸ä¸ćĽâă
+
+; *** âéćŠĺźĺ§čĺć䝜多âĺ察饾
+WizardSelectProgramGroup=éćŠĺźĺ§čĺć䝜多
+SelectStartMenuFolderDesc=ć¨ćłĺ¨ĺŞéćžç˝Žç¨ĺşç忍ćˇćšĺźďź
+SelectStartMenuFolderLabel3=ĺŽčŁ
ç¨ĺşç°ĺ¨ĺ°ĺ¨ä¸ĺĺźĺ§čĺć䝜多ä¸ĺĺťşç¨ĺşç忍ćˇćšĺźă
+SelectStartMenuFolderBrowseLabel=ĺĺťâä¸ä¸ćĽâçť§çťăĺŚćć¨ćłéćŠĺ
śĺŽć䝜多ďźĺĺťâćľč§âă
+MustEnterGroupName=ć¨ĺż
饝čžĺ
Ľä¸ä¸Şć䝜多ĺă
+GroupNameTooLong=ć䝜多ĺć衯ĺžĺ¤Şéżă
+InvalidGroupName=ć䝜多ĺćŻć ćçă
+BadGroupName=ć䝜多ĺä¸č˝ĺ
ĺŤä¸ĺäťťä˝ĺ珌:%n%n%1
+NoProgramGroupCheck2=ä¸ĺĺťşĺźĺ§čĺć䝜多(&D)
+
+; *** âĺĺ¤ĺŽčŁ
âĺ察饾
+WizardReady=ĺĺ¤ĺŽčŁ
+ReadyLabel1=ĺŽčŁ
ç¨ĺşç°ĺ¨ĺĺ¤ĺźĺ§ĺŽčŁ
[name] ĺ°ć¨ççľčä¸ă
+ReadyLabel2a=ĺĺťâĺŽčŁ
âçť§çťć¤ĺŽčŁ
ç¨ĺşăĺŚćć¨ćłčŚĺ饞ććšĺ莞罎ďźčݎĺĺťâä¸ä¸ćĽâă
+ReadyLabel2b=ĺĺťâĺŽčŁ
âçť§çťć¤ĺŽčŁ
ç¨ĺş?
+ReadyMemoUserInfo=ç¨ćˇäżĄćŻ:
+ReadyMemoDir=çŽć ä˝ç˝Ž:
+ReadyMemoType=ĺŽčŁ
çąťĺ:
+ReadyMemoComponents=éĺŽçťäťś:
+ReadyMemoGroup=ĺźĺ§čĺć䝜多:
+ReadyMemoTasks=éĺ äťťĺĄ:
+
+; *** âćŁĺ¨ĺĺ¤ĺŽčŁ
âĺ察饾
+WizardPreparing=ćŁĺ¨ĺĺ¤ĺŽčŁ
+PreparingDesc=ĺŽčŁ
ç¨ĺşćŁĺ¨ĺĺ¤ĺŽčŁ
[name] ĺ°ć¨ççľčä¸ă
+PreviousInstallNotCompleted=ĺ
ĺç¨ĺşçĺŽčŁ
/ĺ¸č˝˝ćŞĺŽćăć¨éčŚéć°ĺŻĺ¨ć¨ççľčćč˝ĺŽćĺŽčŁ
ă%n%nĺ¨éć°ĺŻĺ¨çľčĺďźĺčżčĄĺŽčŁ
ĺŽć [name] çĺŽčŁ
ă
+CannotContinue=ĺŽčŁ
ç¨ĺşä¸č˝çť§çťă诡ĺĺťâĺćśâéĺşă
+ApplicationsFound=ä¸ĺĺşç¨ç¨ĺşćŁĺ¨ä˝żç¨çćäťśéčŚć´ć°čŽžç˝ŽăĺŽćŻĺťşčŽŽć¨ĺ
莸ĺŽčŁ
ç¨ĺşčŞĺ¨ĺ
łéčżäşĺşç¨ç¨ĺşă
+ApplicationsFound2=ä¸ĺĺşç¨ç¨ĺşćŁĺ¨ä˝żç¨çćäťśéčŚć´ć°čŽžç˝ŽăĺŽćŻĺťşčŽŽć¨ĺ
莸ĺŽčŁ
ç¨ĺşčŞĺ¨ĺ
łéčżäşĺşç¨ç¨ĺşăĺŽčŁ
ĺŽćĺďźĺŽčŁ
ç¨ĺşĺ°ĺ°čŻéć°ĺŻĺ¨ĺşç¨ç¨ĺşă
+CloseApplications=čŞĺ¨ĺ
łé诼ĺşç¨ç¨ĺş(&A)
+DontCloseApplications=ä¸čŚĺ
łé诼ĺşç¨ç¨ĺş(D)
+ErrorCloseApplications=ĺŽčŁ
ç¨ĺşć ćłčŞĺ¨ĺ
łéććĺşç¨ç¨ĺşăĺ¨çť§çťäšĺďźć䝏坺莎ć¨ĺ
łéćć使ç¨éčŚć´ć°çĺŽčŁ
ç¨ĺşćäťśă
+PrepareToInstallNeedsRestart=ĺŽčŁ
ç¨ĺşĺż
饝éć°ĺŻĺ¨čŽĄçŽćşăéć°ĺŻĺ¨čŽĄçŽćşĺďźčݎĺ揥čżčĄĺŽčŁ
ç¨ĺşäťĽĺŽć [name] çĺŽčŁ
ă%n%nćŻĺŚçŤĺłéć°ĺŻĺ¨ďź
+
+; *** âćŁĺ¨ĺŽčŁ
âĺ察饾
+WizardInstalling=ćŁĺ¨ĺŽčŁ
+InstallingLabel=ĺŽčŁ
ç¨ĺşćŁĺ¨ĺŽčŁ
[name] ĺ°ć¨ççľčä¸ďźčݎç¨çă
+
+; *** âĺŽčŁ
ĺŽćâĺ察饾
+FinishedHeadingLabel=[name] ĺŽčŁ
ĺŽć
+FinishedLabelNoIcons=ĺŽčŁ
ç¨ĺşĺˇ˛ĺ¨ć¨ççľčä¸ĺŽčŁ
äş [name]ă
+FinishedLabel=ĺŽčŁ
ç¨ĺşĺˇ˛ĺ¨ć¨ççľčä¸ĺŽčŁ
äş [name]ăć¤ĺşç¨ç¨ĺşĺŻäťĽéčżéćŠĺŽčŁ
ç忍ćˇćšĺźčżčĄă
+ClickFinish=ĺĺťâĺŽćâéĺşĺŽčŁ
ç¨ĺşă
+FinishedRestartLabel=čŚĺŽć [name] çĺŽčŁ
ďźĺŽčŁ
ç¨ĺşĺż
饝éć°ĺŻĺ¨ć¨ççľčăć¨ćłç°ĺ¨éć°ĺŻĺ¨ĺďź
+FinishedRestartMessage=čŚĺŽć [name] çĺŽčŁ
ďźĺŽčŁ
ç¨ĺşĺż
饝éć°ĺŻĺ¨ć¨ççľčă%n%nć¨ćłç°ĺ¨éć°ĺŻĺ¨ĺďź
+ShowReadmeCheck=ćŻďźć¨ćłćĽé
čŞčż°ćäťś
+YesRadio=ćŻďźçŤĺłéć°ĺŻĺ¨çľč(&Y)
+NoRadio=ĺŚďźç¨ĺéć°ĺŻĺ¨çľč(&N)
+; ç¨äşčąĄâčżčĄ MyProg.exeâ
+RunEntryExec=čżčĄ %1
+; ç¨äşčąĄâćĽé
Readme.txtâ
+RunEntryShellExec=ćĽé
%1
+
+; *** âĺŽčŁ
ç¨ĺşéčŚä¸ä¸ĺź çŁçâć示
+ChangeDiskTitle=ĺŽčŁ
ç¨ĺşéčŚä¸ä¸ĺź çŁç
+SelectDiskLabel2=诡ćĺ
ĽçŁç %1 ĺšśĺĺťâ祎ĺŽâă%n%nĺŚćčżä¸ŞçŁçä¸çćäťśä¸č˝ĺ¨ä¸ĺäşä¸ĺćžç¤şçć䝜多ä¸ćžĺ°ďźčžĺ
ĽćŁçĄŽç衯ĺžćĺĺťâćľč§âă
+PathLabel=衯ĺž(&P):
+FileNotInDir2=ćäťśâ%1âä¸č˝ĺ¨â%2âĺŽä˝ă诡ćĺ
ĽćŁçĄŽççŁçćéćŠĺ
śĺŽć䝜多ă
+SelectDirectoryLabel=诡ćĺŽä¸ä¸ĺź çŁççä˝ç˝Žă
+
+; *** ĺŽčŁ
çśććśćŻ
+SetupAborted=ĺŽčŁ
ç¨ĺşćŞĺŽćĺŽčŁ
ă%n%n诡俎ćŁčżä¸ŞéŽé˘ĺšśéć°čżčĄĺŽčŁ
ç¨ĺşă
+AbortRetryIgnoreSelectAction=é饚
+AbortRetryIgnoreRetry=éčŻ(&T)
+AbortRetryIgnoreIgnore=ĺż˝çĽé误嚜睧çť(&I)
+AbortRetryIgnoreCancel=ĺ
łéĺŽčŁ
ç¨ĺş
+
+; *** ĺŽčŁ
çśććśćŻ
+StatusClosingApplications=ćŁĺ¨ĺ
łéĺşç¨ç¨ĺş...
+StatusCreateDirs=ćŁĺ¨ĺĺťşçŽĺ˝...
+StatusExtractFiles=ćŁĺ¨č§Łĺ矊ćäťś...
+StatusCreateIcons=ćŁĺ¨ĺ坺忍ćˇćšĺź...
+StatusCreateIniEntries=ćŁĺ¨ĺĺťş INI ćĄçŽ...
+StatusCreateRegistryEntries=ćŁĺ¨ĺ坺注ĺ襨ćĄçŽ...
+StatusRegisterFiles=ćŁĺ¨ćł¨ĺćäťś...
+StatusSavingUninstall=ćŁĺ¨äżĺĺ¸č˝˝äżĄćŻ...
+StatusRunProgram=ćŁĺ¨ĺŽćĺŽčŁ
...
+StatusRestartingApplications=ćŁĺ¨éĺŻĺşç¨ç¨ĺş...
+StatusRollback=ćŁĺ¨ć¤éć´ćš...
+
+; *** ĺ
śĺŽé误
+ErrorInternal2=ĺ
é¨é误: %1
+ErrorFunctionFailedNoCode=%1 夹贼
+ErrorFunctionFailed=%1 夹贼ďźé误䝣ç %2
+ErrorFunctionFailedWithMessage=%1 夹贼ďźé误䝣ç %2.%n%3
+ErrorExecutingProgram=ä¸č˝ć§čĄćäťś:%n%1
+
+; *** 注ĺ襨é误
+ErrorRegOpenKey=ćĺźćł¨ĺ襨饚ćśĺşé:%n%1\%2
+ErrorRegCreateKey=ĺ坺注ĺ襨饚ćśĺşé:%n%1\%2
+ErrorRegWriteKey=ĺĺ
Ľćł¨ĺ襨饚ćśĺşé:%n%1\%2
+
+; *** INI é误
+ErrorIniEntry=ĺ¨ćäťśâ%1âĺĺťş INI 饚çŽé误ă
+
+; *** ćäťśĺ¤ĺśé误
+FileAbortRetryIgnoreSkipNotRecommended=衳čżčżä¸Şćäťś (ä¸ć¨č)(&S)
+FileAbortRetryIgnoreIgnoreNotRecommended=ĺż˝çĽéčŻŻĺšśçť§çť (ä¸ć¨č)(&I)
+SourceIsCorrupted=ćşć䝜塲ćĺ
+SourceDoesntExist=ćşćäťśâ%1âä¸ĺĺ¨
+ExistingFileReadOnly2=ć ćłćżć˘ç°ććäťśďźĺ 为ĺŽćŻĺŞčŻťçă
+ExistingFileReadOnlyRetry=ç§ťé¤ĺŞčŻťĺąć§ĺšśéčŻ(&R)
+ExistingFileReadOnlyKeepExisting=äżçç°ććäťś(&K)
+ErrorReadingExistingDest=ĺ°čŻčŻťĺç°ććäťśćśĺçä¸ä¸Şé误:
+FileExists=ć䝜塲çťĺĺ¨ă%n%nć¨ćłčŚĺŽčŁ
ç¨ĺşčŚçĺŽĺďź
+ExistingFileNewer=ç°ćçćäťść°ä¸ĺŽčŁ
ç¨ĺşčŚĺŽčŁ
çćäťśăć¨čć¨äżçç°ććäťśă%n%nć¨ćłčŚäżçç°ćçćäťśĺďź
+ErrorChangingAttr=ĺ°čŻćšĺä¸ĺç°ćçćäťśçĺąć§ćśĺçä¸ä¸Şé误:
+ErrorCreatingTemp=ĺ°čŻĺ¨çŽć çŽĺ˝ĺĺťşćäťśćśĺçä¸ä¸Şé误:
+ErrorReadingSource=ĺ°čŻčŻťĺä¸ĺćşćäťśćśĺçä¸ä¸Şé误:
+ErrorCopying=ĺ°čŻĺ¤ĺśä¸ĺćäťśćśĺçä¸ä¸Şé误:
+ErrorReplacingExistingFile=ĺ°čŻćżć˘ç°ćçćäťśćśĺçé误:
+ErrorRestartReplace=éĺŻçľčĺćżć˘ć䝜夹贼:
+ErrorRenamingTemp=ĺ°čŻéć°ĺ˝ĺ䝼ä¸çŽć çŽĺ˝ä¸çä¸ä¸Şćäťśćśĺçé误:
+ErrorRegisterServer=ä¸č˝ćł¨ĺ DLL/OCX: %1
+ErrorRegSvr32Failed=RegSvr32 夹贼ďźéĺşäťŁç %1
+ErrorRegisterTypeLib=ä¸č˝ćł¨ĺçąťĺĺş: %1
+
+; *** ĺ¸č˝˝ćžç¤şĺĺć 莰
+; used for example as 'My Program (32-bit)'
+UninstallDisplayNameMark=%1 (%2)
+; used for example as 'My Program (32-bit, All users)'
+UninstallDisplayNameMarks=%1 (%2, %3)
+UninstallDisplayNameMark32Bit=32ä˝
+UninstallDisplayNameMark64Bit=64ä˝
+UninstallDisplayNameMarkAllUsers=ććç¨ćˇ
+UninstallDisplayNameMarkCurrentUser=ĺ˝ĺç¨ćˇ
+
+; *** ĺŽčŁ
ĺé误
+ErrorOpeningReadme=ĺ˝ĺ°čŻćĺźčŞčż°ćäťśćśĺçä¸ä¸Şé误ă
+ErrorRestartingComputer=ĺŽčŁ
ç¨ĺşä¸č˝éć°ĺŻĺ¨çľčďźčݎćĺ¨éĺŻă
+
+; *** ĺ¸č˝˝ćśćŻ
+UninstallNotFound=ćäťśâ%1âä¸ĺĺ¨ăä¸č˝ĺ¸č˝˝ă
+UninstallOpenError=ćäťśâ%1âä¸č˝ćĺźăä¸č˝ĺ¸č˝˝ă
+UninstallUnsupportedVer=ĺ¸č˝˝ćĽĺżćäťśâ%1âććŞč˘Ťčżä¸ŞçćŹçĺ¸č˝˝ĺ¨ćżčޤçć źĺźăä¸č˝ĺ¸č˝˝
+UninstallUnknownEntry=ĺ¨ĺ¸č˝˝ćĽĺżä¸éĺ°ä¸ä¸ŞćŞçĽçćĄçŽ (%1)
+ConfirmUninstall=ć¨çĄŽčޤćłčŚĺŽĺ
¨ĺ é¤ %1 ĺĺŽçććçťäťśĺďź
+UninstallOnlyOnWin64=čżä¸ŞĺŽčŁ
ç¨ĺşĺŞč˝ĺ¨ 64 ä˝ Windows ä¸čżčĄĺ¸č˝˝ă
+OnlyAdminCanUninstall=čżä¸ŞĺŽčŁ
çç¨ĺşĺŞč˝ćŻć玥çĺćéçç¨ćˇćč˝ĺ¸č˝˝ă
+UninstallStatusLabel=ćŁĺ¨äťć¨ççľčä¸ĺ é¤ %1ďźčݎçĺž
ă
+UninstalledAll=%1 塲饺ĺŠĺ°äťć¨ççľčä¸ĺ é¤ă
+UninstalledMost=%1 ĺ¸č˝˝ĺŽćă%n%nćä¸äşĺ
厚ä¸č˝č˘Ťĺ é¤ăć¨ĺŻäťĽć塼ĺ é¤ĺŽäťŹă
+UninstalledAndNeedsRestart=čŚĺŽć %1 çĺ¸č˝˝ďźć¨ççľčĺż
饝éć°ĺŻĺ¨ă%n%nć¨ç°ĺ¨ćłéć°ĺŻĺ¨çľčĺďź
+UninstallDataCorrupted=â%1âćäťśč˘Ťç ´ĺďźä¸č˝ĺ¸č˝˝
+
+; *** ĺ¸č˝˝çśććśćŻ
+ConfirmDeleteSharedFileTitle=ĺ é¤ĺ
ąäşŤćäťśĺďź
+ConfirmDeleteSharedFile2=çłťçťä¸ĺ
ĺŤçä¸ĺĺ
ąäşŤć䝜塲çťä¸č˘Ťĺ
śĺŽç¨ĺşä˝żç¨ăć¨ćłčŚĺ¸č˝˝ç¨ĺşĺ é¤čżäşĺ
ąäşŤćäťśĺďź%n%nĺŚćčżäşć䝜袍ĺ é¤ďźä˝čżćç¨ĺşćŁĺ¨ä˝żç¨čżäşćäťśďźčżäşç¨ĺşĺŻč˝ä¸č˝ćŁçĄŽć§čĄăĺŚćć¨ä¸č˝çĄŽĺŽďźéćŠâĺŚâăćčżäşćäťśäżçĺ¨çłťçťä¸äťĽĺ
ĺźčľˇéŽé˘ă
+SharedFileNameLabel=ćäťśĺ:
+SharedFileLocationLabel=ä˝ç˝Ž:
+WizardUninstalling=ĺ¸č˝˝çść
+StatusUninstalling=ćŁĺ¨ĺ¸č˝˝ %1...
+
; *** Shutdown block reasons
-ShutdownBlockReasonInstallingApp=ŐýÔÚ°˛×° %1ĄŁ
-ShutdownBlockReasonUninstallingApp=ŐýÔÚĐśÔŘ %1ĄŁ
+ShutdownBlockReasonInstallingApp=ćŁĺ¨ĺŽčŁ
%1.
+ShutdownBlockReasonUninstallingApp=ćŁĺ¨ĺ¸č˝˝ %1.
+
; The custom messages below aren't used by Setup itself, but if you make
; use of them in your scripts, you'll want to translate them.
+
[CustomMessages]
-NameAndVersion=%1 °ćąž %2
-AdditionalIcons=ĆäËűżě˝Ýˇ˝Ę˝:
-CreateDesktopIcon=´´˝¨×ŔĂćżě˝Ýˇ˝Ę˝(&D)
-CreateQuickLaunchIcon=´´˝¨żěËŮĆôśŻżě˝Ýˇ˝Ę˝(&Q)
-ProgramOnTheWeb=Web ÉĎľÄ %1
-UninstallProgram=ĐśÔŘ %1
-LaunchProgram=ĆôśŻ %1
-AssocFileExtension=˝Ť %1 Óë %2 ÎÄźţŔŠŐšĂűšŘÁŞ(&A)
-AssocingFileExtension=Őý˝Ť %1 Óë %2 ÎÄźţŔŠŐšĂűšŘÁŞ...
-AutoStartProgramGroupDescription=ĆôśŻ:
-AutoStartProgram=×ÔśŻĆôśŻ %1
-AddonHostProgramNotFound=Îޡ¨ÔÚËůŃĄÎÄźţźĐÖĐś¨Îť %1ĄŁ%n%nĘǡńČÔŇŞźĚĐř?
\ No newline at end of file
+
+NameAndVersion=%1 çćŹ %2
+AdditionalIcons=éĺ 忍ćˇćšĺź:
+CreateDesktopIcon=ĺĺťşćĄé˘ĺżŤćˇćšĺź(&D)
+CreateQuickLaunchIcon=ĺ坺忍éčżčĄć 忍ćˇćšĺź(&Q)
+ProgramOnTheWeb=%1 ç˝çŤ
+UninstallProgram=ĺ¸č˝˝ %1
+LaunchProgram=čżčĄ %1
+AssocFileExtension=ĺ° %2 ćäťśćŠĺąĺä¸ %1 ĺťşçŤĺ
łč(&A)
+AssocingFileExtension=ćŁĺ¨ĺ° %2 ćäťśćŠĺąĺä¸ %1 ĺťşçŤĺ
łč...
+AutoStartProgramGroupDescription=ĺŻĺ¨çť:
+AutoStartProgram=čŞĺ¨ĺŻĺ¨ %1
+AddonHostProgramNotFound=%1ć ćłćžĺ°ć¨ćéćŠçć䝜多ă%n%nć¨ćłčŚçť§çťĺďź
+
diff --git a/build/win32/i18n/Default.zh-tw.isl b/build/win32/i18n/Default.zh-tw.isl
index 4746349e19..fb748761f9 100644
--- a/build/win32/i18n/Default.zh-tw.isl
+++ b/build/win32/i18n/Default.zh-tw.isl
@@ -1,298 +1,359 @@
-; *** Inno Setup version 5.5.3+ Traditional Chinese messages ***
+ďťż; *** Inno Setup version 6.0.0+ Chinese Traditional messages ***
;
-; To download user-contributed translations of this file, go to:
-; http://www.jrsoftware.org/files/istrans/
+; Name: John Wu, mr.johnwu@gmail.com
+; Base on 5.5.3+ translations by Samuel Lee, Email: 751555749@qq.com
+; Translation based on network resource
;
-; Note: When translating this text, do not add periods (.) to the end of
-; messages that didn't have them already, because on those messages Inno
-; Setup adds the periods automatically (appending a period would result in
-; two periods being displayed).
+
[LangOptions]
; The following three entries are very important. Be sure to read and
; understand the '[LangOptions] section' topic in the help file.
-LanguageName=Traditional Chinese
+; If Language Name display incorrect, uncomment next line
+LanguageName=<7e41><9ad4><4e2d><6587>
LanguageID=$0404
-LanguageCodePage=950
+LanguageCodepage=950
; If the language you are translating to requires special font faces or
; sizes, uncomment any of the following entries and change them accordingly.
-;DialogFontName=
-;DialogFontSize=8
-;WelcomeFontName=Verdana
-;WelcomeFontSize=12
-;TitleFontName=Arial
-;TitleFontSize=29
-;CopyrightFontName=Arial
-;CopyrightFontSize=8
+DialogFontName=ć°ç´°ćéŤ
+DialogFontSize=9
+TitleFontName=Arial
+TitleFontSize=28
+WelcomeFontName=ć°ç´°ćéŤ
+WelcomeFontSize=12
+CopyrightFontName=ć°ç´°ćéŤ
+CopyrightFontSize=9
+
[Messages]
+
; *** Application titles
-SetupAppTitle=Św¸Ëľ{ŚĄ
-SetupWindowTitle=Św¸Ëľ{ŚĄ - %1
-UninstallAppTitle=¸Ń°ŁŚw¸Ë
-UninstallAppFullTitle=%1 ¸Ń°ŁŚw¸Ë
+SetupAppTitle=ĺŽčŁç¨ĺź
+SetupWindowTitle=%1 ĺŽčŁç¨ĺź
+UninstallAppTitle=č§Łé¤ĺŽčŁ
+UninstallAppFullTitle=č§Łé¤ĺŽčŁ %1
+
; *** Misc. common
-InformationTitle=¸ę°T
-ConfirmTitle=˝Tť{
-ErrorTitle=żůť~
+InformationTitle=č¨ćŻ
+ConfirmTitle=確čŞ
+ErrorTitle=éŻčޤ
+
; *** SetupLdr messages
-SetupLdrStartupMessage=łoˇ|Św¸Ë %1ĄCnÄ~ÄňśÜ?
-LdrCannotCreateTemp=ľLŞkŤŘĽßźČŚsŔÉĄCŚw¸Ë¤w¤¤¤î
-LdrCannotExecTemp=ľLŞk°őŚćźČŚsĽŘżý¤¤ŞşŔɎץCŚw¸Ë¤w¤¤¤î
+SetupLdrStartupMessage=éĺ°ćĺŽčŁ %1ăć¨ćłčŚçšźçşĺ?
+LdrCannotCreateTemp=çĄćłĺťşçŤćŤĺćŞćĄăĺŽčŁç¨ĺźĺ°ćçľćă
+LdrCannotExecTemp=çĄćłĺˇčĄćŤĺćŞćĄăĺŽčŁç¨ĺźĺ°ćçľćă
+HelpTextNote=
+
; *** Startup error messages
-LastErrorMessage=%1ĄC%n%nżůť~ %2: %3
-SetupFileMissing=Św¸ËĽŘżý¤¤ŻĘ¤ÖŔÉŽ× %1ĄC˝Đ׼ż°ÝĂDĄAŠÎŤˇs¨úąoľ{ŚĄŞşˇs˝ĆĽťĄC
-SetupFileCorrupt=Św¸Ëľ{ŚĄŔɎפwˇlˇ´ĄC˝ĐŤˇs¨úąo¸Óľ{ŚĄŞş˝ĆĽťĄC
-SetupFileCorruptOrWrongVer=Św¸Ëľ{ŚĄŔɎפwˇlˇ´ĄAŠÎ¤ŁŹŰŽeŠóťPŚšŞŠŞşŚw¸Ëľ{ŚĄĄC˝Đ׼ż°ÝĂDĄAŠÎŤˇs¨úąoľ{ŚĄŞşˇs˝ĆĽťĄC
-InvalidParameter=ŚbŠRĽOŚC¤WśÇťź¤FľLŽÄŞş°ŃźĆ:%n%n%1
-SetupAlreadyRunning=Św¸Ëľ{ŚĄ¤wŚb°őŚć¤¤ĄC
-WindowsVersionNotSupported=Śšľ{ŚĄ¤Ł¤ä´Ššq¸ŁŠŇ°őŚćŞş Windows ŞŠĽťĄC
-WindowsServicePackRequired=Śšľ{ŚĄťÝn %1 Service Pack %2 ŠÎ§óˇsŞŠĽťĄC
-NotOnThisPlatform=Śšľ{ŚĄ¤Łˇ|Śb %1 ¤W°őŚćĄC
-OnlyOnThisPlatform=Śšľ{ŚĄĽ˛śˇŚb %1 ¤W°őŚćĄC
-OnlyOnTheseArchitectures=Śšľ{ŚĄĽuĽiŚw¸ËŚbąMʰ¤UŚCłB˛zžšŹ[şcł]pŞş Windows ŞŠĽť¤W:%n%n%1
-MissingWOW64APIs=ąz°őŚćŞş Windows ŞŠĽť¤Ł§tŚw¸Ëľ{ŚĄ°őŚć 64 Śě¤¸Św¸ËŠŇťÝŞşĽ\ŻŕĄCYn׼żŚš°ÝĂDĄA˝ĐŚw¸Ë Service Pack %1ĄC
-WinVersionTooLowError=Śšľ{ŚĄťÝn %1 ŞŠ %2 ŠÎ§óˇsŞŠĽťĄC
-WinVersionTooHighError=Śšľ{ŚĄľLŞkŚw¸ËŚb %1 ŞŠ %2 ŠÎ§óˇsŞŠĽť¤WĄC
-AdminPrivilegesRequired=Św¸ËŚšľ{ŚĄŽÉĄAĽ˛śˇĽH¨t˛ÎşŢ˛zű¨¤Ŕľn¤JĄC
-PowerUserPrivilegesRequired=ˇíązŚw¸ËŚšľ{ŚĄŽÉĄAĽ˛śˇĽH¨t˛ÎşŢ˛zűŠÎ Power Users ¸s˛ŐŞşŚ¨ű¨¤Ŕľn¤JĄC
-SetupAppRunningError=Św¸ËŽÉ°ť´ú¨ě %1 ĽŘŤeĽżŚb°őŚć¤¤ĄC%n%n˝ĐĽß§YĂöłŹ¨äŠŇŚł°őŚćÓĹéĄCYnÄ~ÄňĄA˝ĐŤö¤@¤U [˝TŠw]; Ynľ˛§ôĄA˝ĐŤö¤@¤U [¨úŽř]ĄC
-UninstallAppRunningError=¸Ń°ŁŚw¸ËŽÉ°ť´ú¨ě %1 ĽŘŤeĽżŚb°őŚć¤¤ĄC%n%n˝ĐĽß§YĂöłŹ¨äŠŇŚł°őŚćÓĹéĄCYnÄ~ÄňĄA˝ĐŤö¤@¤U [˝TŠw]; Ynľ˛§ôĄA˝ĐŤö¤@¤U [¨úŽř]ĄC
+LastErrorMessage=%1%n%néŻčޤ %2: %3
+SetupFileMissing=ĺŽčŁčłć夞ä¸éşĺ¤ąćŞćĄ %1ăčŤäżŽćŁć¤ĺéĄćéć°ĺĺžć¤čťéŤă
+SetupFileCorrupt=ĺŽčŁćŞćĄĺˇ˛çśććŻăčŤéć°ĺĺžć¤čťéŤă
+SetupFileCorruptOrWrongVer=ĺŽčŁćŞćĄĺˇ˛çśććŻďźćčĺŽčŁç¨ĺźççćŹä¸çŹŚăčŤéć°ĺĺžć¤čťéŤă
+InvalidParameter=ćĺçĄćçčŽé塲袍ĺłéĺ°äşĺ˝äť¤ĺ:%n%n%1
+SetupAlreadyRunning=ĺŽčŁç¨ĺźĺˇ˛çśĺ¨ĺˇčĄă
+WindowsVersionNotSupported=ćŹĺŽčŁç¨ĺźä¸Śä¸ćŻć´çŽĺĺ¨éťč
ŚćéčĄç Windows çćŹă
+WindowsServicePackRequired=ćŹĺŽčŁç¨ĺźéčŚ %1 Service Pack %2 ćć´ć°ă
+NotOnThisPlatform=éĺç¨ĺźçĄćłĺ¨ %1 ĺˇčĄă
+OnlyOnThisPlatform=éĺç¨ĺźĺż
é ĺ¨ %1 ĺˇčĄă
+OnlyOnTheseArchitectures=éĺç¨ĺźĺŞč˝ĺ¨ĺ°éçşäťĽä¸čçĺ¨ćść§čč¨č¨ç Windows ä¸ĺŽčŁ:%n%n%1
+WinVersionTooLowError=éĺç¨ĺźĺż
é ĺ¨ %1 çćŹ %2 ć䝼ä¸ççłťçľąĺˇčĄă
+WinVersionTooHighError=éĺç¨ĺźçĄćłĺŽčŁĺ¨ %1 çćŹ %2 ć䝼ä¸ççłťçľąă
+AdminPrivilegesRequired=ć¨ĺż
é çťĺ
Ľć糝羹玥çĺĄäťĽĺŽčŁéĺç¨ĺźă
+PowerUserPrivilegesRequired=ć¨ĺż
é çťĺ
Ľćĺ
ˇć糝羹玥çĺĄć Power User ćŹéç使ç¨č
䝼ĺŽčŁéĺç¨ĺźă
+SetupAppRunningError=ĺŽčŁç¨ĺźĺľć¸Źĺ° %1 ćŁĺ¨ĺˇčĄă%n%nčŤéé芲ç¨ĺźĺžć [確ĺŽ] çšźçşďźćć [ĺćś] é˘éă
+UninstallAppRunningError=č§Łé¤ĺŽčŁç¨ĺźĺľć¸Źĺ° %1 ćŁĺ¨ĺˇčĄă%n%nčŤéé芲ç¨ĺźĺžć [確ĺŽ] çšźçşďźćć [ĺćś] é˘éă
+
+; *** Startup questions
+PrivilegesRequiredOverrideTitle=é¸ćĺŽčŁç¨ĺźĺŽčŁć¨Ąĺź
+PrivilegesRequiredOverrideInstruction=é¸ćĺŽčŁć¨Ąĺź
+PrivilegesRequiredOverrideText1=ĺŻäťĽçşćć使ç¨č
ĺŽčŁ %1 (éčŚçłťçľąçŽĄçćŹé)ďźććŻĺ
çşć¨ĺŽčŁă
+PrivilegesRequiredOverrideText2=ĺŻäťĽĺ
çşć¨ĺŽčŁ %1ďźććŻçşćć使ç¨č
ĺŽčŁ (éčŚçłťçľąçŽĄçćŹé)ă
+PrivilegesRequiredOverrideAllUsers=çşćć使ç¨č
ĺŽčŁ (&A)
+PrivilegesRequiredOverrideAllUsersRecommended=çşćć使ç¨č
ĺŽčŁ (ĺťşč°é¸é
) (&A)
+PrivilegesRequiredOverrideCurrentUser=ĺ
çşćĺŽčŁ (&M)
+PrivilegesRequiredOverrideCurrentUserRecommended=ĺ
çşćĺŽčŁ (ĺťşč°é¸é
) (&M)
+
; *** Misc. errors
-ErrorCreatingDir=Św¸Ëľ{ŚĄľLŞkŤŘĽßĽŘżý "%1"
-ErrorTooManyFilesInDir=Ś]ʰĽŘżý "%1" Ľ]§t¤ÓŚhŔɎץAŠŇĽHľLŞkŚb¨ä¤¤ŤŘĽßŔÉŽ×
+ErrorCreatingDir=ĺŽčŁç¨ĺźçĄćłĺťşçŤčłć夞â%1âă
+ErrorTooManyFilesInDir=çĄćłĺ¨čłć夞â%1âĺ
§ĺťşçŤćŞćĄďźĺ çşčłć夞ĺ
§ć太ĺ¤çćŞćĄă
+
; *** Setup common messages
-ExitSetupTitle=ľ˛§ôŚw¸Ë
-ExitSetupMessage=Św¸ËĽź§šŚ¨ĄCYĽß§Yľ˛§ôĄAąN¤Łˇ|Św¸Ëľ{ŚĄĄC%n%nązĽiĽHľyŤáŚA°őŚćŚw¸Ëľ{ŚĄ¨Ó§šŚ¨Św¸ËĄC%n%nnľ˛§ôŚw¸ËśÜ?
-AboutSetupMenuItem=ĂöŠóŚw¸Ëľ{ŚĄ(&A)...
-AboutSetupTitle=ĂöŠóŚw¸Ëľ{ŚĄ
-AboutSetupMessage=%1 ŞŠ %2%n%3%n%n%1 şś:%n%4
+ExitSetupTitle=çľćĺŽčŁç¨ĺź
+ExitSetupMessage=ĺŽčŁĺ°ćŞĺŽćăĺŚćć¨çžĺ¨çľćĺŽčŁç¨ĺźďźéĺç¨ĺźĺ°ä¸ć袍ĺŽčŁă%n%nć¨ĺŻäťĽç¨ĺžĺĺˇčĄĺŽčŁç¨ĺźäťĽĺŽćĺŽčŁç¨ĺşăć¨çžĺ¨čŚçľćĺŽčŁç¨ĺźĺ?
+AboutSetupMenuItem=éćźĺŽčŁç¨ĺź(&A)...
+AboutSetupTitle=éćźĺŽčŁç¨ĺź
+AboutSetupMessage=%1 çćŹ %2%n%3%n%n%1 眲ĺ:%n%4
AboutSetupNote=
TranslatorNote=
+
; *** Buttons
-ButtonBack=< ¤W¤@¨B(&B)
-ButtonNext=¤U¤@¨B(&N) >
-ButtonInstall=Św¸Ë(&I)
-ButtonOK=˝TŠw
-ButtonCancel=¨úŽř
-ButtonYes=ŹO(&Y)
-ButtonYesToAll=ĽţłĄŹŇŹO(&A)
-ButtonNo=§_(&N)
-ButtonNoToAll=ĽţłĄŹŇ§_(&O)
-ButtonFinish=§šŚ¨(&F)
-ButtonBrowse=ÂsÄý(&B)...
-ButtonWizardBrowse=ÂsÄý(&R)...
-ButtonNewFolder=ŤŘĽßˇs¸ęŽĆ§¨(&M)
+ButtonBack=< ä¸ä¸ćĽ(&B)
+ButtonInstall=ĺŽčŁ(&I)
+ButtonNext=ä¸ä¸ćĽ(&N) >
+ButtonOK=確ĺŽ
+ButtonCancel=ĺćś
+ButtonYes=ćŻ(&Y)
+ButtonYesToAll=ĺ
¨é¨çćŻ(&A)
+ButtonNo=ĺŚ(&N)
+ButtonNoToAll=ĺ
¨é¨çĺŚ(&O)
+ButtonFinish=ĺŽć(&F)
+ButtonBrowse=ç茽(&B)...
+ButtonWizardBrowse=ç茽(&R)...
+ButtonNewFolder=ĺťşçŤć°čłć夞(&M)
+
; *** "Select Language" dialog messages
-SelectLanguageTitle=żď¨úŚw¸Ëľ{ŚĄťy¨Ľ
-SelectLanguageLabel=żď¨úŚw¸Ë´ÁśĄŠŇn¨ĎĽÎŞşťy¨Ľ:
+SelectLanguageTitle=é¸ćĺŽčŁčŞč¨
+SelectLanguageLabel=é¸ćĺ¨ĺŽčŁéç¨ä¸ä˝żç¨çčŞč¨:
+
; *** Common wizard text
-ClickNext=YnÄ~ÄňĄA˝ĐŤö¤@¤U [¤U¤@¨B]; Ynľ˛§ôŚw¸ËĄA˝ĐŤö¤@¤U [¨úŽř]ĄC
+ClickNext=ć [ä¸ä¸ćĽ] çšźçşĺŽčŁďźćć [ĺćś] çľćĺŽčŁç¨ĺźă
BeveledLabel=
-BrowseDialogTitle=ÂsÄý¸ęŽĆ§¨
-BrowseDialogLabel=˝Đąq¤UŚC˛Młć¤¤żď¨ú¸ęŽĆ§¨ĄAľMŤáŤö¤@¤U [˝TŠw]ĄC
-NewFolderName=ˇsźW¸ęŽĆ§¨
+BrowseDialogTitle=ç茽čłć夞
+BrowseDialogLabel=ĺ¨ä¸é˘çčłć夞ĺ襨ä¸é¸ćä¸ĺčłć夞ďźçśĺžć [確ĺŽ]ă
+NewFolderName=ć°čłć夞
+
; *** "Welcome" wizard page
-WelcomeLabel1=ĹwŞď¨ĎĽÎ [name] Św¸ËşëĆF
-WelcomeLabel2=łoˇ|ŚbązŞşšq¸Ł¤WŚw¸Ë [name/ver]ĄC%n%nŤŘÄłązĽýĂöłŹŠŇŚł¨äĽLŔłĽÎľ{ŚĄĄAľMŤáŚAÄ~ÄňĄC
+WelcomeLabel1=ćĄčżä˝żç¨ [name] ĺŽčŁç¨ĺź
+WelcomeLabel2=éĺĺŽčŁç¨ĺźĺ°ćĺŽčŁ [name/ver] ĺ°ć¨çéťč
Śă%n%nćĺ埡çĺťşč°ć¨ĺ¨ĺŽčŁéç¨ä¸ééĺ
śĺŽçćç¨ç¨ĺźďźäťĽéżĺ
čĺŽčŁç¨ĺźçźçć˛çŞă
+
; *** "Password" wizard page
-WizardPassword=ąK˝X
-PasswordLabel1=ŚšŚw¸Ë¨üąK˝XŤOĹ@ĄC
-PasswordLabel3=˝Đ´Ł¨ŃąK˝XĄAľMŤáŤö¤@¤U [¤U¤@¨B] ĽHÄ~ÄňĄCąK˝X°Ď¤Ŕ¤j¤pźgĄC
-PasswordEditLabel=ąK˝X(&P):
-IncorrectPassword=żé¤JŞşąK˝X¤ŁĽż˝TĄC˝ĐŚA¸Ő¤@ڏĄC
+WizardPassword=ĺŻç˘ź
+PasswordLabel1=éĺĺŽčŁç¨ĺźĺ
ˇćĺŻç˘źäżčˇă
+PasswordLabel3=čŤčź¸ĺ
ĽĺŻç˘źďźçśĺžć [ä¸ä¸ćĽ] çšźçşăĺŻç˘źćŻĺĺ大ĺ°ĺŻŤçă
+PasswordEditLabel=ĺŻç˘ź(&P):
+IncorrectPassword=ć¨čź¸ĺ
ĽçĺŻç˘źä¸ćŁç˘şďźčŤéć°čź¸ĺ
Ľă
+
; *** "License Agreement" wizard page
-WizardLicense=ąÂĹvŚXŹů
-LicenseLabel=˝ĐĽýž\ĹŞ¤UŚCŤn¸ę°TŚAÄ~ÄňĄC
-LicenseLabel3=˝Đž\ĹŞ¤UŚCąÂĹvŚXŹůĄCązĽ˛śˇąľ¨üŚšŚXŹůąř´ÚĄA¤~ŻŕÄ~ÄňŚw¸ËĄC
-LicenseAccepted=§Úąľ¨üŚXŹů(&A)
-LicenseNotAccepted=§Ú¤Łąľ¨üŚXŹů(&D)
+WizardLicense=ććŹĺç´
+LicenseLabel=čŤéąčŽäťĽä¸ććŹĺç´ă
+LicenseLabel3=čŤéąčŽäťĽä¸ććŹĺç´ďźć¨ĺż
é ćĽĺĺç´çĺé
ć˘ćŹžćč˝çšźçşĺŽčŁă
+LicenseAccepted=ćĺć(&A)
+LicenseNotAccepted=ćä¸ĺć(&D)
+
; *** "Information" wizard pages
-WizardInfoBefore=¸ę°T
-InfoBeforeLabel=˝ĐĽýž\ĹŞ¤UŚCŤn¸ę°TŚAÄ~ÄňĄC
-InfoBeforeClickLabel=ˇíązˇÇłĆŚnnÄ~ÄňŚw¸ËŽÉĄA˝ĐŤö¤@¤U [¤U¤@¨B]ĄC
-WizardInfoAfter=¸ę°T
-InfoAfterLabel=˝ĐĽýž\ĹŞ¤UŚCŤn¸ę°TŚAÄ~ÄňĄC
-InfoAfterClickLabel=ˇíązˇÇłĆŚnnÄ~ÄňŚw¸ËŽÉĄA˝ĐŤö¤@¤U [¤U¤@¨B]ĄC
+WizardInfoBefore=č¨ćŻ
+InfoBeforeLabel=ĺ¨çšźçşĺŽčŁäšĺčŤéąčŽäťĽä¸éčŚčłč¨ă
+InfoBeforeClickLabel=çść¨ćşĺ弽皟çşĺŽčŁďźčŤć [ä¸ä¸ćĽ]ă
+WizardInfoAfter=č¨ćŻ
+InfoAfterLabel=ĺ¨çšźçşĺŽčŁäšĺčŤéąčŽäťĽä¸éčŚčłč¨ă
+InfoAfterClickLabel=çść¨ćşĺ弽皟çşĺŽčŁďźčŤć [ä¸ä¸ćĽ]ă
+
; *** "User Information" wizard page
-WizardUserInfo=¨ĎĽÎŞĚ¸ę°T
-UserInfoDesc=˝Đżé¤JązŞş¸ę°TĄC
-UserInfoName=¨ĎĽÎŞĚŚWşŮ(&U):
-UserInfoOrg=˛Ő´(&O):
-UserInfoSerial=§Ç¸š(&S):
-UserInfoNameRequired=Ľ˛śˇżé¤JŚWşŮĄC
+WizardUserInfo=使ç¨č
čłč¨
+UserInfoDesc=čŤčź¸ĺ
Ľć¨çčłćă
+UserInfoName=使ç¨č
ĺ稹(&U):
+UserInfoOrg=çľçš(&O):
+UserInfoSerial=ĺşč(&S):
+UserInfoNameRequired=ć¨ĺż
é 蟸ĺ
Ľć¨çĺ稹ă
+
; *** "Select Destination Location" wizard page
-WizardSelectDir=żď¨úĽŘŞşŚaŚě¸m
-SelectDirDesc=ŔłąN [name] Św¸ËŚbŚółB?
-SelectDirLabel3=Św¸Ëľ{ŚĄˇ|ąN [name] Św¸ËŚb¤UŚC¸ęŽĆ§¨¤¤ĄC
-SelectDirBrowseLabel=YnÄ~ÄňĄA˝ĐŤö¤@¤U [¤U¤@¨B]ĄCYązˇQżď¨ú¤ŁŚPŞş¸ęŽĆ§¨ĄA˝ĐŤö¤@¤U [ÂsÄý]ĄC
-DiskSpaceMBLabel=ŚÜ¤ÖśˇŚł [mb] MB ŞşĽiĽÎşĎşĐŞĹśĄĄC
-CannotInstallToNetworkDrive=Św¸Ëľ{ŚĄľLŞkŚw¸Ë¨ěşô¸ôşĎşĐž÷ĄC
-CannotInstallToUNCPath=Św¸Ëľ{ŚĄľLŞkŚw¸Ë¨ě UNC ¸ôŽ|ĄC
-InvalidPath=Ľ˛śˇżé¤JĽ]§tşĎşĐž÷ĽN¸šŞş§šžă¸ôŽ|ĄA¨ŇŚp:%n%nC:\APP%n%nŠÎżé¤J¤UŚCŽćŚĄŞş UNC ¸ôŽ|:%n%n\\ŚřŞAžš\Ś@ĽÎ
-InvalidDrive=żď¨úŞşşĎşĐž÷ŠÎ UNC Ś@ĽÎ¤ŁŚsŚbŠÎľLŞkŚs¨úĄC˝Đżď¨ú¨äĽLşĎşĐž÷ŠÎ UNC Ś@ĽÎĄC
-DiskSpaceWarningTitle=şĎşĐŞĹśĄ¤Ł¨Ź
-DiskSpaceWarning=Św¸Ëľ{ŚĄŚÜ¤ÖťÝn %1 KB ŞşĽiĽÎŞĹśĄ¤~ŻŕŚw¸ËĄAŚýŠŇżďşĎşĐž÷ŞşĽiĽÎŞĹśĄĽuŚł %2 KBĄC%n%n¤´nÄ~ÄňśÜ?
-DirNameTooLong=¸ęŽĆ§¨ŚWşŮŠÎ¸ôŽ|šLŞřĄC
-InvalidDirName=Śš¸ęŽĆ§¨ŚWşŮľLŽÄĄC
-BadDirName32=¸ęŽĆ§¨ŚWşŮ¤ŁąoĽ]§t¤UŚCĽô¤@Śr¤¸:%n%n%1
-DirExistsTitle=¸ęŽĆ§¨¤wŚsŚb
-DirExists=¤wŚł¸ęŽĆ§¨ %n%n%1%n%nĄC¤´nŚw¸Ë¨ě¸Ó¸ęŽĆ§¨śÜ?
-DirDoesntExistTitle=¸ęŽĆ§¨¤ŁŚsŚb
-DirDoesntExist=¸ęŽĆ§¨ %n%n%1%n%n ¤ŁŚsŚbĄCnŤŘĽß¸Ó¸ęŽĆ§¨śÜ?
+WizardSelectDir=é¸ćçŽçčłć夞
+SelectDirDesc=é¸ćĺŽčŁç¨ĺźĺŽčŁ [name] çä˝ç˝Žă
+SelectDirLabel3=ĺŽčŁç¨ĺźĺ°ćć [name] ĺŽčŁĺ°ä¸é˘çčłć夞ă
+SelectDirBrowseLabel=ć [ä¸ä¸ćĽ] çšźçşďźĺŚćć¨ćłé¸ćĺŚä¸ĺčłć夞ďźčŤć [ç茽]ă
+DiskSpaceMBLabel=ćĺ°éčŚ [mb] MB çŁç˘çŠşéă
+CannotInstallToNetworkDrive=ĺŽčŁç¨ĺźçĄćłĺŽčŁćźçś˛çľĄçŁç˘ćŠă
+CannotInstallToUNCPath=ĺŽčŁç¨ĺźçĄćłĺŽčŁćź UNC 衯ĺžă
+InvalidPath=ć¨ĺż
é 蟸ĺ
ĽĺŽć´ç衯ĺžĺ稹ĺçŁç˘ćŠäťŁç˘źă%n%näžĺŚ C:\App ć UNC 衯ĺžć źĺź \\äźşćĺ¨\ĺ
ąç¨čłć夞ă
+InvalidDrive=ć¨é¸ĺççŁç˘ćŠć UNC ĺ稹ä¸ĺĺ¨ćçĄćłĺĺďźčŤé¸ćĺ
śäťççŽçĺ°ă
+DiskSpaceWarningTitle=çŁç˘çŠşéä¸čśł
+DiskSpaceWarning=ĺŽčŁç¨ĺźéčŚčłĺ° %1 KB ççŁç˘çŠşéďźć¨ćé¸ĺççŁç˘ĺŞć %2 KB ĺŻç¨çŠşéă%n%nć¨čŚçšźçşĺŽčŁĺ?
+DirNameTooLong=čłć夞ĺ稹ć衯ĺžĺ¤Şéˇă
+InvalidDirName=čłć夞ĺ稹ä¸ćŁç˘şă
+BadDirName32=čłć夞ĺ稹ä¸ĺžĺ
ĺŤäťĽä¸çšćŽĺĺ
:%n%n%1
+DirExistsTitle=čłć夞塲çśĺĺ¨
+DirExists=čłć夞ďź%n%n%1%n%n 塲çśĺĺ¨ăäťčŚĺŽčŁĺ°čОčłć夞ĺďź
+DirDoesntExistTitle=čłć夞ä¸ĺĺ¨
+DirDoesntExist=čłć夞ďź%n%n%1%n%n ä¸ĺĺ¨ăčŚĺťşçŤčОčłć夞ĺďź
+
; *** "Select Components" wizard page
-WizardSelectComponents=żď¨ú¤¸Ľó
-SelectComponentsDesc=ŔłŚw¸Ëţ¨Ç¤¸Ľó?
-SelectComponentsLabel2=żď¨úąznŚw¸ËŞş¤¸Ľó; ˛M°Łąz¤ŁnŚw¸ËŞş¤¸ĽóĄCˇíązˇÇłĆŚnnÄ~ÄňŽÉĄA˝ĐŤö¤@¤U [¤U¤@¨B]ĄC
-FullInstallation=§šžăŚw¸Ë
+WizardSelectComponents=é¸ćĺ
äťś
+SelectComponentsDesc=é¸ćĺ°ć袍ĺŽčŁçĺ
äťśă
+SelectComponentsLabel2=é¸ćć¨ćłčŚĺŽčŁçĺ
äťśďźć¸
é¤ć¨ä¸ćłĺŽčŁçĺ
äťśăçśĺžć [ä¸ä¸ćĽ] çšźçşĺŽčŁă
+FullInstallation=ĺŽć´ĺŽčŁ
; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
-CompactInstallation=şë²Św¸Ë
-CustomInstallation=ŚŰqŚw¸Ë
-NoUninstallWarningTitle=¤wŚłŚš¤¸Ľó
-NoUninstallWarning=Św¸Ëľ{ŚĄ°ť´ú¨ěązŞşšq¸Ł¤wŚw¸Ë¤F¤UŚC¤¸Ľó:%n%n%1%n%nąNło¨Ç¤¸Ľó¨úŽřżď¨ú¨Ă¤Łˇ|¨Ď¤¸Ľó¸Ń°ŁŚw¸ËĄC%n%n¤´nÄ~ÄňśÜ?
+CompactInstallation=ćĺ°ĺŽčŁ
+CustomInstallation=čŞč¨ĺŽčŁ
+NoUninstallWarningTitle=ĺ
䝜塲ĺĺ¨
+NoUninstallWarning=ĺŽčŁç¨ĺźĺľć¸Źĺ°äťĽä¸ĺ
䝜塲çśĺŽčŁĺ¨ć¨çéťč
Śä¸:%n%n%1%n%nĺćśé¸ćéäşĺ
äťśĺ°ä¸ćç§ťé¤ĺŽĺă%n%nć¨äťçśčŚçšźçşĺ?
ComponentSize1=%1 KB
ComponentSize2=%1 MB
-ComponentsDiskSpaceMBLabel=ĽŘŤeŞşżďžÜŚÜ¤ÖťÝn [mb] MB ŞşşĎşĐŞĹśĄĄC
+ComponentsDiskSpaceMBLabel=çŽĺçé¸ćéčŚčłĺ° [mb] MB çŁç˘çŠşéă
+
; *** "Select Additional Tasks" wizard page
-WizardSelectTasks=żď¨ú¨äĽL¤u§@
-SelectTasksDesc=ÁŮśˇ°őŚćţ¨Ç¨äĽL¤u§@?
-SelectTasksLabel2=˝Đżď¨úŚw¸Ëľ{ŚĄŚbŚw¸Ë [name] ŽÉĄAśˇĂBĽ~°őŚćŞş¨äĽL¤u§@ĄAľMŤáŤö¤@¤U [¤U¤@¨B]ĄC
+WizardSelectTasks=é¸ćéĺ ç塼ä˝
+SelectTasksDesc=é¸ćčŚĺˇčĄçéĺ 塼ä˝ă
+SelectTasksLabel2=é¸ćĺŽčŁç¨ĺźĺ¨ĺŽčŁ [name] ćčŚĺˇčĄçéĺ 塼ä˝ďźçśĺžć [ä¸ä¸ćĽ]ă
+
; *** "Select Start Menu Folder" wizard page
-WizardSelectProgramGroup=żď¨ú [ś}Šl] Ľ\ŻŕŞí¸ęŽĆ§¨
-SelectStartMenuFolderDesc=Św¸Ëľ{ŚĄŔłąNľ{ŚĄąśŽ|¸mŠóŚółB?
-SelectStartMenuFolderLabel3=Św¸Ëľ{ŚĄąNŚb¤UŚC [ś}Šl] Ľ\ŻŕŞí¸ęŽĆ§¨¤¤ŤŘĽßľ{ŚĄąśŽ|ĄC
-SelectStartMenuFolderBrowseLabel=YnÄ~ÄňĄA˝ĐŤö¤@¤U [¤U¤@¨B]ĄCYązˇQżď¨ú¤ŁŚPŞş¸ęŽĆ§¨ĄA˝ĐŤö¤@¤U [ÂsÄý]ĄC
-MustEnterGroupName=Ľ˛śˇżé¤J¸ęŽĆ§¨ŚWşŮĄC
-GroupNameTooLong=¸ęŽĆ§¨ŚWşŮŠÎ¸ôŽ|šLŞřĄC
-InvalidGroupName=Śš¸ęŽĆ§¨ŚWşŮľLŽÄĄC
-BadGroupName=¸ęŽĆ§¨ŚWşŮ¤ŁąoĽ]§t¤UŚCĽô¤@Śr¤¸:%n%n%1
-NoProgramGroupCheck2=¤ŁnŤŘĽß [ś}Šl] Ľ\ŻŕŞí¸ęŽĆ§¨(&D)
+WizardSelectProgramGroup=é¸ćăéĺ§ăĺč˝čĄ¨çčłć夞
+SelectStartMenuFolderDesc=é¸ćĺŽčŁç¨ĺźĺťşçŤç¨ĺźçćˇĺžçä˝ç˝Žă
+SelectStartMenuFolderLabel3=ĺŽčŁç¨ĺźĺ°ććç¨ĺźçćˇĺžĺťşçŤĺ¨ä¸é˘çăéĺ§ăĺč˝čĄ¨čłć夞ă
+SelectStartMenuFolderBrowseLabel=ć [ä¸ä¸ćĽ] çšźçşďźĺŚćć¨ćłé¸ćĺŚä¸ĺčłć夞ďźčŤć [ç茽]ă
+MustEnterGroupName=ć¨ĺż
é 蟸ĺ
Ľä¸ĺčłć夞çĺ稹ă
+GroupNameTooLong=čłć夞ĺ稹ć衯ĺžĺ¤Şéˇă
+InvalidGroupName=čłć夞ĺ稹ä¸ćŁç˘şă
+BadGroupName=čłć夞ĺ稹ä¸ĺžĺ
ĺŤä¸ĺĺĺ
:%n%n%1
+NoProgramGroupCheck2=ä¸čŚĺ¨ăéĺ§ăĺč˝čĄ¨ä¸ĺťşçŤčłć夞(&D)
+
; *** "Ready to Install" wizard page
-WizardReady=¤wĽiś}ŠlŚw¸Ë
-ReadyLabel1=Św¸Ëľ{ŚĄ˛{Śb¤wĽiś}ŠląN [name] Św¸Ë¨ěązŞşšq¸Ł¤WĄC
-ReadyLabel2a=YnÄ~ÄňŚw¸ËĄA˝ĐŤö¤@¤U [Św¸Ë]; YnŔËž\ŠÎĹܧóĽôŚół]ŠwĄA˝ĐŤö¤@¤U [¤W¤@¨B]ĄC
-ReadyLabel2b=YnÄ~ÄňŚw¸ËĄA˝ĐŤö¤@¤U [Św¸Ë]ĄC
-ReadyMemoUserInfo=¨ĎĽÎŞĚ¸ę°T:
-ReadyMemoDir=ĽŘŞşŚaŚě¸m:
-ReadyMemoType=Św¸ËĂţŤŹ:
-ReadyMemoComponents=żď¨úŞş¤¸Ľó:
-ReadyMemoGroup=[ś}Šl] Ľ\ŻŕŞí¸ęŽĆ§¨:
-ReadyMemoTasks=¨äĽL¤u§@:
+WizardReady=ćşĺĺŽčŁ
+ReadyLabel1=ĺŽčŁç¨ĺźĺ°éĺ§ĺŽčŁ [name] ĺ°ć¨çéťč
Śä¸ă
+ReadyLabel2a=ćä¸ [ĺŽčŁ] çšźçşĺŽčŁďźćć [ä¸ä¸ćĽ] éć°ćŞ˘čŚćč¨ĺŽĺé¸é
çĺ
§ĺŽšă
+ReadyLabel2b=ćä¸ [ĺŽčŁ] çšźçşĺŽčŁă
+ReadyMemoUserInfo=使ç¨č
čłč¨
+ReadyMemoDir=çŽçčłć夞:
+ReadyMemoType=ĺŽčŁĺć
:
+ReadyMemoComponents=é¸ćçĺ
äťś:
+ReadyMemoGroup=ăéĺ§ăĺč˝čĄ¨čłć夞:
+ReadyMemoTasks=éĺ 塼ä˝:
+
; *** "Preparing to Install" wizard page
-WizardPreparing=ĽżŚbˇÇłĆŚw¸Ë
-PreparingDesc=Św¸Ëľ{ŚĄĽżŚbˇÇłĆąN [name] Św¸Ë¨ěązŞşšq¸Ł¤WĄC
-PreviousInstallNotCompleted=¤W¤@Óľ{ŚĄŞşŚw¸Ë/˛ž°ŁŠ|Ľź§šŚ¨ĄCĽ˛śˇŤˇsąŇ°Ęšq¸ŁĄA¤~Żŕ§šŚ¨¸ÓŚw¸ËĄC%n%n˝ĐŚbŤˇsąŇ°Ęšq¸Ł¤§ŤáĄAŤˇs°őŚćŚw¸Ëľ{ŚĄĄAĽH§šŚ¨ [name] ŞşŚw¸ËĄC
-CannotContinue=Św¸Ëľ{ŚĄľLŞkÄ~ÄňĄC˝ĐŤö¤@¤U [¨úŽř] ĽHľ˛§ôĄC
-ApplicationsFound=Św¸Ëľ{ŚĄĽ˛śˇ§óˇs¤UŚCŔłĽÎľ{ŚĄĽżŚb¨ĎĽÎŞş¤@¨ÇŔɎץCŤŘÄłąz¤šł\Św¸Ëľ{ŚĄŚŰ°ĘĂöłŹło¨ÇŔłĽÎľ{ŚĄĄC
-ApplicationsFound2=Św¸Ëľ{ŚĄĽ˛śˇ§óˇs¤UŚCŔłĽÎľ{ŚĄĽżŚb¨ĎĽÎŞş¤@¨ÇŔɎץCŤŘÄłąz¤šł\Św¸Ëľ{ŚĄŚŰ°ĘĂöłŹło¨ÇŔłĽÎľ{ŚĄĄCˇíŚw¸Ë§šŚ¨¤§ŤáĄAŚw¸Ëľ{ŚĄąNˇ|šÁ¸ŐŤˇsąŇ°Ęło¨ÇŔłĽÎľ{ŚĄĄC
-CloseApplications=ŚŰ°ĘĂöłŹŔłĽÎľ{ŚĄ(&A)
-DontCloseApplications=¤ŁnĂöłŹŔłĽÎľ{ŚĄ(&D)
-ErrorCloseApplications=Św¸Ëľ{ŚĄľLŞkŚŰ°ĘĂöłŹŠŇŚłŔłĽÎľ{ŚĄĄCŤŘÄłązĂöłŹŠŇŚłĽżŚb¨ĎĽÎŚw¸Ëľ{ŚĄĽ˛śˇ§óˇs¤§ŔɎתşŔłĽÎľ{ŚĄĄAľMŤáŚAÄ~ÄňĄC
+WizardPreparing=ćşĺĺŽčŁç¨ĺź
+PreparingDesc=ĺŽčŁç¨ĺźćşĺĺ° [name] ĺŽčŁĺ°ć¨çéťč
Śä¸ă
+PreviousInstallNotCompleted=ĺ
ĺçĺŽčŁ/ č§Łé¤ĺŽčŁĺ°ćŞĺŽćďźć¨ĺż
é éć°ĺĺéťč
ŚäťĽĺŽć芲ĺŽčŁă%n%nĺ¨éć°ĺĺéťč
ŚäšĺžďźčŤĺĺˇčĄéĺç¨ĺźäžĺŽčŁ [name]ă
+CannotContinue=ĺŽčŁç¨ĺźçĄćłçšźçşăčŤć [ĺćś] é˘éă
+ApplicationsFound=ä¸é˘çćç¨ç¨ĺźćŁĺ¨ä˝żç¨ĺŽčŁç¨ĺźćéčŚć´ć°çććŞăĺťşč°ć¨ĺ
訹ĺŽčŁç¨ĺźčŞĺéééäşćç¨ç¨ĺźă
+ApplicationsFound2=ä¸é˘çćç¨ç¨ĺźćŁĺ¨ä˝żç¨ĺŽčŁç¨ĺźćéčŚć´ć°çććŞăĺťşč°ć¨ĺ
訹ĺŽčŁç¨ĺźčŞĺéééäşćç¨ç¨ĺźăçśĺŽčŁéç¨çľćĺžďźćŹĺŽčŁç¨ĺźĺ°ćĺ芌éć°éĺ芲ćç¨ç¨ĺźă
+CloseApplications=ééćç¨ç¨ĺź(&A)
+DontCloseApplications=ä¸čŚééćç¨ç¨ĺź (&D)
+ErrorCloseApplications=ĺŽčŁç¨ĺźçĄćłčŞĺééćććç¨ç¨ĺźăĺťşč°ć¨ĺ¨çšźçşĺĺ
ééćććç¨ç¨ĺźä˝żç¨çćŞćĄă
+
; *** "Installing" wizard page
-WizardInstalling=Św¸Ë¤¤
-InstallingLabel=˝ĐľyÔĄAŚw¸Ëľ{ŚĄĽżŚbąN [name] Św¸Ë¨ěązŞşšq¸Ł¤WĄC
+WizardInstalling=ćŁĺ¨ĺŽčŁ
+InstallingLabel=čŤç¨ĺďźĺŽčŁç¨ĺźćŁĺ¨ĺ° [name] ĺŽčŁĺ°ć¨çéťč
Śä¸
+
; *** "Setup Completed" wizard page
-FinishedHeadingLabel=ĽżŚb§šŚ¨ [name] Św¸ËşëĆF
-FinishedLabelNoIcons=Św¸Ëľ{ŚĄ¤w§šŚ¨ązšq¸Ł¤W [name] ŞşŚw¸ËĄC
-FinishedLabel=Św¸Ëľ{ŚĄ¤w§šŚ¨ązšq¸Ł¤W [name] ŞşŚw¸ËĄCązĽiĽHżď¨úŠŇŚw¸ËŞşąśŽ|¨ÓąŇ°ĘŔłĽÎľ{ŚĄĄC
-ClickFinish=˝ĐŤö¤@¤U [§šŚ¨]ĄAĽHľ˛§ôŚw¸ËĄC
-FinishedRestartLabel=Św¸Ëľ{ŚĄĽ˛śˇŤˇsąŇ°ĘązŞşšq¸ŁĄA¤~Żŕ§šŚ¨ [name] ŞşŚw¸ËĄCnĽß§YŤˇsąŇ°ĘśÜ?
-FinishedRestartMessage=Św¸Ëľ{ŚĄĽ˛śˇŤˇsąŇ°ĘązŞşšq¸ŁĄA¤~Żŕ§šŚ¨ [name] ŞşŚw¸ËĄC%n%nnĽß§YŤˇsąŇ°ĘśÜ?
-ShowReadmeCheck=ŹOĄA§ÚnŔËľřĹŞ§ÚŔÉŽ×
-YesRadio=ŹOĄAĽß§YŤˇsąŇ°Ęšq¸Ł(&Y)
-NoRadio=§_ĄAľyÔŚAŤˇsąŇ°Ęšq¸Ł(&N)
+FinishedHeadingLabel=ĺŽčŁĺŽć
+FinishedLabelNoIcons=ĺŽčŁç¨ĺźĺˇ˛çśĺ° [name] ĺŽčŁĺ¨ć¨çéťč
Śä¸ă
+FinishedLabel=ĺŽčŁç¨ĺźĺˇ˛çśĺ° [name] ĺŽčŁĺ¨ć¨çéťč
Śä¸ďźć¨ĺŻäťĽé¸ćç¨ĺźçĺ示äžĺˇčĄčОćç¨ç¨ĺźă
+ClickFinish=ć [ĺŽć] 䝼çľćĺŽčŁç¨ĺźă
+FinishedRestartLabel=čŚĺŽć [name] çĺŽčŁďźĺŽčŁç¨ĺźĺż
é éć°ĺĺć¨çéťč
Śăć¨ćłčŚçžĺ¨éć°ĺĺéťč
Śĺ?
+FinishedRestartMessage=čŚĺŽć [name] çĺŽčŁďźĺŽčŁç¨ĺźĺż
é éć°ĺĺć¨çéťč
Śă%n%nć¨ćłčŚçžĺ¨éć°ĺĺéťč
Śĺ?
+ShowReadmeCheck=ćŻďźćčŚéąčŽčŽććŞćĄă
+YesRadio=ćŻďźçŤĺłéć°ĺĺéťč
Ś(&Y)
+NoRadio=ĺŚďźćç¨ĺžéć°ĺĺéťč
Ś(&N)
; used for example as 'Run MyProg.exe'
-RunEntryExec=°őŚć %1
+RunEntryExec=ĺˇčĄ %1
; used for example as 'View Readme.txt'
-RunEntryShellExec=ŔËľř %1
-; *** "Setup Needs the Next Disk" stuff
-ChangeDiskTitle=Św¸Ëľ{ŚĄťÝn¤U¤@ąişĎ¤ůĄC
-SelectDiskLabel2=˝Đ´Ą¤JşĎ¤ů %1ĄAľMŤáŤö¤@¤U [˝TŠw]ĄC%n%nYŚšşĎ¤ů¤WŞşŔɎ׼iĽHŚb¤UŚCĹăĽÜ¤§¸ęŽĆ§¨ĽHĽ~Şş¸ęŽĆ§¨¤¤§ä¨ěĄA˝Đżé¤JĽż˝TŞş¸ôŽ|ĄAŠÎŤö¤@¤U [ÂsÄý]ĄC
-PathLabel=¸ôŽ|(&P):
-FileNotInDir2=Śb "%2" ¤¤§ä¤Ł¨ěŔÉŽ× "%1"ĄC˝Đ´Ą¤JĽż˝TŞşşĎ¤ůĄAŠÎżď¨ú¨äĽL¸ęŽĆ§¨ĄC
-SelectDirectoryLabel=˝ĐŤüŠw¤U¤@ąişĎ¤ůŞşŚě¸mĄC
+RunEntryShellExec=ćŞ˘čŚ %1
+
+; *** "Setup Needs the Next Disk"
+ChangeDiskTitle=ĺŽčŁç¨ĺźéčŚä¸ä¸ĺźľçŁç
+SelectDiskLabel2=čŤćĺ
ĽçŁç %1ďźçśĺžć [確ĺŽ]ă%n%nĺŚććŞćĄä¸ĺ¨äťĽä¸ć饯示çčłć夞äšä¸ďźčŤčź¸ĺ
ĽćŁç˘şçčłć夞ĺ稹ćć [ç茽] é¸ĺă
+PathLabel=衯ĺž(&P):
+FileNotInDir2=ćŞćĄâ%1âçĄćłĺ¨â%2âćžĺ°ăčŤćĺ
ĽćŁç˘şççŁçćé¸ćĺ
śĺŽçčłć夞ă
+SelectDirectoryLabel=čŤćĺŽä¸ä¸ĺźľçŁççä˝ç˝Žă
+
; *** Installation phase messages
-SetupAborted=Św¸ËĽźŚwڍĄC%n%n˝Đ׼ż°ÝĂDĄAŚAŤˇs°őŚćŚw¸Ëľ{ŚĄĄC
-EntryAbortRetryIgnore=YnŚA¸Ő¤@ڏĄA˝ĐŤö¤@¤U [Ť¸Ő]; YnÄ~ÄňĄA˝ĐŤö¤@¤U [Šż˛¤]; Yn¨úŽřŚw¸ËĄA˝ĐŤö¤@¤U [¤¤¤î]ĄC
+SetupAborted=ĺŽčŁć˛ćĺŽćă%n%nčŤć´ćŁĺéĄĺžéć°ĺŽčŁä¸ćŹĄă
+AbortRetryIgnoreSelectAction=é¸ĺĺä˝
+AbortRetryIgnoreRetry=čŤĺ芌ä¸ćŹĄ (&T)
+AbortRetryIgnoreIgnore=çĽééŻčŞ¤ä¸Śçšźçş (&I)
+AbortRetryIgnoreCancel=ĺćśĺŽčŁ
+
; *** Installation status messages
-StatusClosingApplications=ĽżŚbĂöłŹŔłĽÎľ{ŚĄ...
-StatusCreateDirs=ĽżŚbŤŘĽßĽŘżý...
-StatusExtractFiles=ĽżŚb¸ŃŔŁÁYŔÉŽ×...
-StatusCreateIcons=ĽżŚbŤŘĽßąśŽ|...
-StatusCreateIniEntries=ĽżŚbŤŘĽß INI śľĽŘ...
-StatusCreateRegistryEntries=ĽżŚbŤŘĽßľnżýśľĽŘ...
-StatusRegisterFiles=ĽżŚbľnżýŔÉŽ×...
-StatusSavingUninstall=ĽżŚbŔxŚs¸Ń°ŁŚw¸Ë¸ę°T...
-StatusRunProgram=ĽżŚb§šŚ¨Św¸Ë...
-StatusRestartingApplications=ĽżŚbŤˇsąŇ°ĘŔłĽÎľ{ŚĄ...
-StatusRollback=ĽżŚb´_ěĹܧó...
+StatusClosingApplications=ćŁĺ¨ééćç¨ç¨ĺź...
+StatusCreateDirs=ćŁĺ¨ĺťşçŤčłć夞...
+StatusExtractFiles=ćŁĺ¨č§ŁĺŁç¸ŽćŞćĄ...
+StatusCreateIcons=ćŁĺ¨ĺťşçŤç¨ĺźéĺ示...
+StatusCreateIniEntries=寍ĺ
Ľ INI ćŞćĄçé
çŽ...
+StatusCreateRegistryEntries=ćŁĺ¨ć´ć°çłťçľąçťé...
+StatusRegisterFiles=ćŁĺ¨çťéćŞćĄ...
+StatusSavingUninstall=ĺ˛ĺč§Łé¤ĺŽčŁčłč¨...
+StatusRunProgram=ćŁĺ¨ĺŽćĺŽčŁ...
+StatusRestartingApplications=ćŁĺ¨éć°éĺćç¨ç¨ĺź...
+StatusRollback=ćŁĺ¨ĺžŠĺčŽć´...
+
; *** Misc. errors
-ErrorInternal2=¤şłĄżůť~: %1
-ErrorFunctionFailedNoCode=%1 Ľ˘ąŃ
-ErrorFunctionFailed=%1 Ľ˘ąŃ; ĽN˝X %2
-ErrorFunctionFailedWithMessage=%1 Ľ˘ąŃ; ĽN˝X %2ĄC%n%3
-ErrorExecutingProgram=ľLŞk°őŚćŔÉŽ×:%n%1
+ErrorInternal2=ĺ
§é¨éŻčޤ: %1
+ErrorFunctionFailedNoCode=%1 夹ć
+ErrorFunctionFailed=%1 夹ćďźäťŁç˘ź %2
+ErrorFunctionFailedWithMessage=%1 夹ćďźäťŁç˘ź %2.%n%3
+ErrorExecutingProgram=çĄćłĺˇčĄćŞćĄ:%n%1
+
; *** Registry errors
-ErrorRegOpenKey=ś}ąŇľnżýž÷˝XŽÉľoĽÍżůť~:%n%1\%2
-ErrorRegCreateKey=ŤŘĽßľnżýž÷˝XŽÉľoĽÍżůť~:%n%1\%2
-ErrorRegWriteKey=źg¤Jľnżýž÷˝XŽÉľoĽÍżůť~:%n%1\%2
+ErrorRegOpenKey=çĄćłéĺçťééľ:%n%1\%2
+ErrorRegCreateKey=çĄćłĺťşçŤçťéé
çŽ:%n%1\%2
+ErrorRegWriteKey=çĄćłčŽć´çťéé
çŽ:%n%1\%2
+
; *** INI errors
-ErrorIniEntry=ŚbŔÉŽ× "%1" ¤¤ŤŘĽß INI śľĽŘŽÉľoĽÍżůť~ĄC
+ErrorIniEntry=ĺ¨ćŞćĄâ%1âĺťşçŤ INI é
çŽéŻčޤă
+
; *** File copying errors
-FileAbortRetryIgnore=YnŚA¸Ő¤@ڏĄA˝ĐŤö¤@¤U [Ť¸Ő]; Yn˛¤šLŚšŔɎץA˝ĐŤö¤@¤U [Šż˛¤] (¤ŁŤŘÄł¨ĎĽÎ); Yn¨úŽřŚw¸ËĄA˝ĐŤö¤@¤U [¤¤¤î]ĄC
-FileAbortRetryIgnore2=YnŚA¸Ő¤@ڏĄA˝ĐŤö¤@¤U [Ť¸Ő]; YnÄ~ÄňĄA˝ĐŤö¤@¤U [Šż˛¤] (¤ŁŤŘÄł¨ĎĽÎ); Yn¨úŽřŚw¸ËĄA˝ĐŤö¤@¤U [¤¤¤î]ĄC
-SourceIsCorrupted=ěŠlľ{ŚĄŔɤwˇlˇ´
-SourceDoesntExist=ěŠlľ{ŚĄŔÉ "%1" ¤ŁŚsŚb
-ExistingFileReadOnly=˛{ŚłŔɎפwźĐ°Oʰ°ßĹŞĄC%n%nYn˛ž°Ł°ßĹŞÄÝŠĘĄAľMŤáŚA¸Ő¤@ڏĄA˝ĐŤö¤@¤U [Ť¸Ő]; Yn˛¤šLŚšŔɎץA˝ĐŤö¤@¤U [Šż˛¤]; Yn¨úŽřŚw¸ËĄA˝ĐŤö¤@¤U [¤¤¤î]ĄC
-ErrorReadingExistingDest=šÁ¸ŐĹŞ¨ú˛{ŚłŔɎ׎ɾoĽÍżůť~:
-FileExists=¤wŚłŚšŔɎץC%n%nnĽŃŚw¸Ëľ{ŚĄĽ[ĽHÂĐźgśÜ?
-ExistingFileNewer=˛{ŚłŔɎ׸űŚw¸Ëľ{ŚĄšÁ¸ŐŚw¸ËŞşŔɎסsĄCŤŘÄłązŤOŻd˛{ŚłŔɎץC%n%nnŤOŻd˛{ŚłŞşŔɎלÜ?
-ErrorChangingAttr=šÁ¸ŐĹܧó˛{ŚłŔɎתşÄÝŠĘŽÉľoĽÍżůť~:
-ErrorCreatingTemp=šÁ¸ŐŚbĽŘŞşŚaĽŘżý¤¤ŤŘĽßŔɎ׎ɾoĽÍżůť~:
-ErrorReadingSource=šÁ¸ŐĹŞ¨úěŠlľ{ŚĄŔÉŽÉľoĽÍżůť~:
-ErrorCopying=šÁ¸Ő˝ĆťsŔɎ׎ɾoĽÍżůť~:
-ErrorReplacingExistingFile=šÁ¸Ő¨úĽN˛{ŚłŔɎ׎ɾoĽÍżůť~:
-ErrorRestartReplace=RestartReplace Ľ˘ąŃ:
-ErrorRenamingTemp=šÁ¸ŐŤˇsŠRŚWĽŘŞşŚaĽŘżý¤¤ŞşŔɎ׎ɾoĽÍżůť~:
-ErrorRegisterServer=ľLŞkľnżý DLL/OCX: %1
-ErrorRegSvr32Failed=RegSvr32 Ľ˘ąŃĄAľ˛§ôĽN˝Xʰ %1
-ErrorRegisterTypeLib=ľLŞkľnżýĂţŤŹľ{ŚĄŽw: %1
+FileAbortRetryIgnoreSkipNotRecommended=çĽééĺćŞćĄ (ä¸ĺťşč°) (&S)
+FileAbortRetryIgnoreIgnoreNotRecommended=çĽééŻčŞ¤ä¸Śçšźçş (ä¸ĺťşč°) (&I)
+SourceDoesntExist=äžćşćŞćĄâ%1âä¸ĺĺ¨ă
+SourceIsCorrupted=äžćşćŞćĄĺˇ˛çśććŻă
+ExistingFileReadOnly2=çĄćłĺ䝣çžććŞćĄďźĺ çşćŞćĄĺˇ˛ć¨ç¤şçşĺŻčŽă
+ExistingFileReadOnlyRetry=ç§ťé¤ĺŻčŽĺąŹć§ä¸Śé芌 (&R)
+ExistingFileReadOnlyKeepExisting=äżççžććŞćĄ (&K)
+ErrorReadingExistingDest=čŽĺä¸ĺ塲ĺĺ¨çćŞćĄćçźçéŻčޤ:
+FileExists=ćŞćĄĺˇ˛çśĺĺ¨ă%n%n čŚčŽĺŽčŁç¨ĺźĺ 䝼čŚĺŻŤĺ?
+ExistingFileNewer=ĺĺ¨çćŞćĄçćŹćŻčźć°ďźĺťşč°ć¨äżççŽĺ塲ĺĺ¨çćŞćĄă%n%nć¨čŚäżççŽĺ塲ĺĺ¨çćŞćĄĺ?
+ErrorChangingAttr=ĺ¨čŽć´ćŞćĄĺąŹć§ćçźçéŻčޤ:
+ErrorCreatingTemp=ĺ¨çŽçčłć夞ä¸ĺťşçŤćŞćĄćçźçéŻčޤ:
+ErrorReadingSource=čŽĺĺĺ§ćŞćĄćçźçéŻčޤ:
+ErrorCopying=垊ĺśćŞćĄćçźçéŻčޤ:
+ErrorReplacingExistingFile=ĺ䝣ćŞćĄćçźçéŻčޤ:
+ErrorRestartReplace=éć°ĺĺéťč
Śĺžĺ䝣ćŞćĄĺ¤ąć:
+ErrorRenamingTemp=ĺ¨çŽçčłć夞čŽć´ćŞćĄĺ稹ćçźçéŻčޤ:
+ErrorRegisterServer=çĄćłćł¨ĺ DLL/OCX ćŞćĄ: %1ă
+ErrorRegSvr32Failed=RegSvr32 夹ćďźéĺşäťŁç˘ź %1
+ErrorRegisterTypeLib=çĄćłćł¨ĺéĄĺ庍: %1ă
+
+; *** Uninstall display name markings
+; used for example as 'My Program (32-bit)'
+UninstallDisplayNameMark=%1 (%2)
+; used for example as 'My Program (32-bit, All users)'
+UninstallDisplayNameMarks=%1 (%2, %3)
+UninstallDisplayNameMark32Bit=32-bit
+UninstallDisplayNameMark64Bit=64-bit
+UninstallDisplayNameMarkAllUsers=ćć使ç¨č
+UninstallDisplayNameMarkCurrentUser=çŽĺ使ç¨č
+
; *** Post-installation errors
-ErrorOpeningReadme=šÁ¸Őś}ąŇĹŞ§ÚŔɎ׎ɾoĽÍżůť~ĄC
-ErrorRestartingComputer=Św¸Ëľ{ŚĄľLŞkŤˇsąŇ°Ęšq¸ŁĄC˝Đ¤â°Ę°őŚćŚš§@ˇ~ĄC
+ErrorOpeningReadme=éĺčŽććŞćĄćçźçéŻčޤă
+ErrorRestartingComputer=ĺŽčŁç¨ĺźçĄćłéć°ĺĺéťč
ŚďźčŤäťĽćĺćšĺźčŞčĄéć°ĺĺéťč
Śă
+
; *** Uninstaller messages
-UninstallNotFound=¨SŚłŔÉŽ× "%1"ĄCľLŞk¸Ń°ŁŚw¸ËĄC
-UninstallOpenError=ľLŞkś}ąŇŔÉŽ× "%1"ĄCľLŞk¸Ń°ŁŚw¸Ë
-UninstallUnsupportedVer=ŚšŞŠ¸Ń°ŁŚw¸Ëľ{ŚĄľLŞkżëĂŃ¸Ń°ŁŚw¸Ë°OżýŔÉ "%1" ŞşŽćŚĄĄCľLŞk¸Ń°ŁŚw¸Ë
-UninstallUnknownEntry=Śb¸Ń°ŁŚw¸Ë°Ożý¤¤§ä¨ě¤ŁŠúŞşśľĽŘ (%1)
-ConfirmUninstall=˝TŠwn§šĽţ˛ž°Ł %1 ¤Î¨äŠŇŚł¤¸ĽóśÜ?
-UninstallOnlyOnWin64=ĽuĽiŚb 64 Śě¤¸ Windows ¤W¸Ń°ŁŚw¸ËŚšŚw¸ËĄC
-OnlyAdminCanUninstall=ĽuŚł¨ăłĆ¨t˛ÎşŢ˛zĹvŞş¨ĎĽÎŞĚĄA¤~Żŕ¸Ń°ŁŚw¸ËŚšŚw¸ËĄC
-UninstallStatusLabel=ĽżŚbąqązŞşšq¸Ł˛ž°Ł %1ĄA˝ĐľyÔĄC
-UninstalledAll=¤wڍĽ\ąqązŞşšq¸Ł˛ž°Ł %1ĄC
-UninstalledMost=¸Ń°ŁŚw¸Ë %1 ¤w§šŚ¨ĄC%n%nŚłłĄ¤ŔśľĽŘľLŞk˛ž°ŁĄCązĽiĽH¤â°ĘĽ[ĽH˛ž°ŁĄC
-UninstalledAndNeedsRestart=Yn§šŚ¨ %1 Şş¸Ń°ŁŚw¸ËĄAĽ˛śˇŤˇsąŇ°ĘązŞşšq¸ŁĄC%n%nnĽß§YŤˇsąŇ°ĘśÜ?
-UninstallDataCorrupted="%1" ŔɎפwˇlˇ´ĄCľLŞk¸Ń°ŁŚw¸Ë
+UninstallNotFound=ćŞćĄâ%1âä¸ĺĺ¨ďźçĄćłç§ťé¤ç¨ĺźă
+UninstallOpenError=çĄćłéĺćŞćĄâ%1âďźçĄćłç§ťé¤ç¨ĺźă
+UninstallUnsupportedVer=éĺçćŹçč§Łé¤ĺŽčŁç¨ĺźçĄćłčž¨čč¨éćŞ â%1â äšć źĺźďźçĄćłč§Łé¤ĺŽčŁă
+UninstallUnknownEntry=č§Łé¤ĺŽčŁč¨éćŞä¸çźçžćŞçĽçč¨é (%1)ă
+ConfirmUninstall=ć¨ç˘şĺŽčŚĺŽĺ
¨ç§ťé¤ %1 ĺĺ
śç¸éçćŞćĄĺ?
+UninstallOnlyOnWin64=éĺç¨ĺźĺŞč˝ĺ¨ 64 ä˝ĺ
ç Windows ä¸č§Łé¤ĺŽčŁă
+OnlyAdminCanUninstall=éĺç¨ĺźčŚĺ
ˇĺ糝羹玥çĺĄćŹéç使ç¨č
ćšĺŻč§Łé¤ĺŽčŁă
+UninstallStatusLabel=ćŁĺ¨ĺžć¨çéťč
Śç§ťé¤ %1 ä¸ďźčŤç¨ĺ...
+UninstalledAll=%1 塲çśćĺĺžć¨çéťč
Śä¸ç§ťé¤ă
+UninstalledMost=%1 č§Łé¤ĺŽčŁĺŽćă%n%nćäşćŞćĄĺĺ
äťśçĄćłç§ťé¤ďźć¨ĺŻäťĽčŞčĄĺŞé¤éäşćŞćĄă
+UninstalledAndNeedsRestart=čŚĺŽć %1 çč§Łé¤ĺŽčŁç¨ĺşďźć¨ĺż
é éć°ĺĺéťč
Śă%n%nć¨ćłčŚçžĺ¨éć°ĺĺéťč
Śĺ?
+UninstallDataCorrupted=ćŞćĄâ%1â塲çśććŻďźçĄćłč§Łé¤ĺŽčŁă
+
; *** Uninstallation phase messages
-ConfirmDeleteSharedFileTitle=n˛ž°ŁŚ@ĽÎŔɎלÜ?
-ConfirmDeleteSharedFile2=¨t˛ÎŤüĽX¤wľLĽôŚóľ{ŚĄŚb¨ĎĽÎ¤UŚCŚ@ĽÎŔɎץCązn¸Ń°ŁŚw¸ËĄAĽH˛ž°ŁŚšŚ@ĽÎŔɎלÜ?%n%nŚpŚłĽôŚóľ{ŚĄ¤´Śb¨ĎĽÎŚšŔɎ׌ӹN¸ÓŔɎײž°ŁĄAło¨Çľ{ŚĄĽiŻŕľLŞkĽżą`šB§@ĄCY¤Ł˝TŠwĄA˝ĐżďžÜ [§_]ĄCąNŔɎ׍OŻdŚb¨t˛Î¤W¨Ă¤Łˇ|łyڍĽôŚó¤Ł¨}źvĹTĄC
-SharedFileNameLabel=ŔɎ׌WşŮ:
-SharedFileLocationLabel=Śě¸m:
-WizardUninstalling=¸Ń°ŁŚw¸ËŞŹşA
-StatusUninstalling=ĽżŚb¸Ń°ŁŚw¸Ë %1...
+ConfirmDeleteSharedFileTitle=ç§ťé¤ĺ
ąç¨ćŞćĄ
+ConfirmDeleteSharedFile2=糝羹饯示ä¸ĺĺ
ąç¨ćŞćĄĺˇ˛ä¸ĺ袍䝝ä˝ç¨ĺźć使ç¨ďźć¨čŚç§ťé¤éäşćŞćĄĺ?%n%n%1%n%nĺčĽć¨ç§ťé¤äşäťĽä¸ćŞćĄä˝äťćç¨ĺźéčŚä˝żç¨ĺŽĺďźĺ°é ćéäşç¨ĺźçĄćłćŁĺ¸¸ĺˇčĄďźĺ ć¤ć¨čĽçĄćłç˘şĺŽčŤé¸ć [ĺŚ]ăäżçéäşćŞćĄĺ¨ć¨ççłťçľąä¸ä¸ćé ćäťťä˝ć厳ă
+SharedFileNameLabel=ćŞćĄĺ稹:
+SharedFileLocationLabel=ä˝ç˝Ž:
+WizardUninstalling=č§Łé¤ĺŽčŁçć
+StatusUninstalling=ćŁĺ¨č§Łé¤ĺŽčŁ %1...
+
; *** Shutdown block reasons
-ShutdownBlockReasonInstallingApp=ĽżŚbŚw¸Ë %1ĄC
-ShutdownBlockReasonUninstallingApp=ĽżŚb¸Ń°ŁŚw¸Ë %1ĄC
+ShutdownBlockReasonInstallingApp=ćŁĺ¨ĺŽčŁ %1.
+ShutdownBlockReasonUninstallingApp=ćŁĺ¨č§Łé¤ĺŽčŁ %1.
+
; The custom messages below aren't used by Setup itself, but if you make
; use of them in your scripts, you'll want to translate them.
+
[CustomMessages]
-NameAndVersion=%1 ŞŠ %2
-AdditionalIcons=¨äĽLąśŽ|:
-CreateDesktopIcon=ŤŘĽßŽŕąąśŽ|(&D)
-CreateQuickLaunchIcon=ŤŘĽß§ÖłtąŇ°ĘąśŽ|(&Q)
-ProgramOnTheWeb=Web ¤WŞş %1
-UninstallProgram=¸Ń°ŁŚw¸Ë %1
-LaunchProgram=ąŇ°Ę %1
-AssocFileExtension=ĂöÁp %1 ťP %2 °ĆŔÉŚW(&A)
-AssocingFileExtension=ĽżŚbŤŘĽß %1 ťP %2 °ĆŔÉŚWŞşĂöÁpĄK
-AutoStartProgramGroupDescription=ąŇ°Ę:
-AutoStartProgram=ŚŰ°ĘąŇ°Ę %1
-AddonHostProgramNotFound=Śbżď¨úŞş¸ęŽĆ§¨¤¤§ä¤Ł¨ě %1ĄC%n%n¤´nÄ~ÄňśÜ?
\ No newline at end of file
+
+NameAndVersion=%1 çćŹ %2
+AdditionalIcons=éĺ ĺ示:
+CreateDesktopIcon=ĺťşçŤćĄé˘ĺ示(&D)
+CreateQuickLaunchIcon=ĺťşçŤĺżŤéĺĺĺ示(&Q)
+ProgramOnTheWeb=%1 ç眲çŤ
+UninstallProgram=č§Łé¤ĺŽčŁ %1
+LaunchProgram=ĺĺ %1
+AssocFileExtension=ĺ° %1 čćŞćĄĺŻćŞĺ %2 ç˘çéčŻ(&A)
+AssocingFileExtension=ćŁĺ¨ĺ° %1 čćŞćĄĺŻćŞĺ %2 ç˘çéčŻ...
+AutoStartProgramGroupDescription=éĺ:
+AutoStartProgram=čŞĺéĺ %1
+AddonHostProgramNotFound=%1 çĄćłĺ¨ć¨ćé¸çčłć夞ä¸ćžĺ°ă%n%nć¨ćŻĺŚéčŚçšźçşďź
diff --git a/build/win32/i18n/messages.en.isl b/build/win32/i18n/messages.en.isl
index 12189c080d..986eba00d3 100644
--- a/build/win32/i18n/messages.en.isl
+++ b/build/win32/i18n/messages.en.isl
@@ -1,4 +1,11 @@
+[Messages]
+FinishedLabel=Setup has finished installing [name] on your computer. The application may be launched by selecting the installed shortcuts.
+ConfirmUninstall=Are you sure you want to completely remove %1 and all of its components?
+
[CustomMessages]
+AdditionalIcons=Additional icons:
+CreateDesktopIcon=Create a &desktop icon
+CreateQuickLaunchIcon=Create a &Quick Launch icon
AddContextMenuFiles=Add "Open with %1" action to Windows Explorer file context menu
AddContextMenuFolders=Add "Open with %1" action to Windows Explorer directory context menu
AssociateWithFiles=Register %1 as an editor for supported file types
diff --git a/build/yarn.lock b/build/yarn.lock
index 00b79cc4a9..fefcc4c40a 100644
--- a/build/yarn.lock
+++ b/build/yarn.lock
@@ -1817,10 +1817,10 @@ https-proxy-agent@^4.0.0:
agent-base "5"
debug "4"
-iconv-lite-umd@0.6.5:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.5.tgz#6a1f621a3b4d125f72feff813a9839e1ebd6c722"
- integrity sha512-WDegH4al+e3n3jTOStRvm+jzDA3JMUQGgzdAsMxAgcgB0Oi72HjfdsoX08ieKsy3rKexXVjWZr41aOIUaCZnMg==
+iconv-lite-umd@0.6.8:
+ version "0.6.8"
+ resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
+ integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
iconv-lite@^0.4.4:
version "0.4.24"
@@ -3539,10 +3539,10 @@ typescript@^3.0.1:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
-typescript@^4.0.0-dev.20200629:
- version "4.0.0-dev.20200629"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-dev.20200629.tgz#4631667ebffe3a340beee885a4bebe3a73b6f18e"
- integrity sha512-c4DUu7KvTcx4x7V8sBWexYNkCfioiH1huOJL6WFAA8Oot0Gr/+PlKKDBS9fYjsadEv1JI1qboJKobwLQn0kQXw==
+typescript@^4.0.0-dev.20200708:
+ version "4.0.0-dev.20200708"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-dev.20200708.tgz#9cf526945590456f34b158b180a6f8a2e0b57306"
+ integrity sha512-A1brZPJRwkm2pxOSTIOVqLvrhF1swfLvDAgN+jRP/yUWNn+0OqbfunuY/jvRbtkEP4/AWZ+M2P625Y+JDN/j2A==
typical@^4.0.0:
version "4.0.0"
diff --git a/cgmanifest.json b/cgmanifest.json
index 25178f2f20..1fb78691e7 100644
--- a/cgmanifest.json
+++ b/cgmanifest.json
@@ -6,7 +6,7 @@
"git": {
"name": "chromium",
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
- "commitHash": "e4745133a1d3745f066e068b8033c6a269b59caf"
+ "commitHash": "052d3b44972e6d94ef40054d46c150b7cdd7a5d8"
}
},
"licenseDetail": [
@@ -40,7 +40,7 @@
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"isOnlyProductionDependency": true,
- "version": "78.0.3904.130"
+ "version": "80.0.3987.165"
},
{
"component": {
@@ -48,11 +48,11 @@
"git": {
"name": "nodejs",
"repositoryUrl": "https://github.com/nodejs/node",
- "commitHash": "787378879acfb212ed4ff824bf9f767a24a5cb43a"
+ "commitHash": "42cce5a9d0fd905bf4ad7a2528c36572dfb8b5ad"
}
},
"isOnlyProductionDependency": true,
- "version": "12.8.1"
+ "version": "12.13.0"
},
{
"component": {
@@ -60,12 +60,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
- "commitHash": "5f93e889020d279d5a9cd1ecab080ab467312447"
+ "commitHash": "87fd06bc96bce8f46ca05b8315657fd230bcac85"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
- "version": "7.3.2"
+ "version": "8.3.3"
},
{
"component": {
@@ -533,7 +533,7 @@
"git": {
"name": "ripgrep",
"repositoryUrl": "https://github.com/BurntSushi/ripgrep",
- "commitHash": "8a7db1a918e969b85cd933d8ed9fa5285b281ba4"
+ "commitHash": "973de50c9ef451da2cfcdfa86f2b2711d8d6ff48"
}
},
"isOnlyProductionDependency": true,
diff --git a/extensions/extension-editing/extension-browser.webpack.config.js b/extensions/extension-editing/extension-browser.webpack.config.js
new file mode 100644
index 0000000000..5870e94564
--- /dev/null
+++ b/extensions/extension-editing/extension-browser.webpack.config.js
@@ -0,0 +1,21 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+//@ts-check
+
+'use strict';
+
+const withBrowserDefaults = require('../shared.webpack.config').browser;
+
+module.exports = withBrowserDefaults({
+ context: __dirname,
+ entry: {
+ extension: './src/extensionEditingBrowserMain.ts'
+ },
+ output: {
+ filename: 'extensionEditingBrowserMain.js'
+ }
+});
+
diff --git a/extensions/extension-editing/extension.webpack.config.js b/extensions/extension-editing/extension.webpack.config.js
index 887933358e..9fcce7e999 100644
--- a/extensions/extension-editing/extension.webpack.config.js
+++ b/extensions/extension-editing/extension.webpack.config.js
@@ -12,7 +12,7 @@ const withDefaults = require('../shared.webpack.config');
module.exports = withDefaults({
context: __dirname,
entry: {
- extension: './src/extension.ts',
+ extension: './src/extensionEditingMain.ts',
},
externals: {
'../../../product.json': 'commonjs ../../../product.json',
diff --git a/extensions/extension-editing/package.json b/extensions/extension-editing/package.json
index 75d77925b0..bdd02d870a 100644
--- a/extensions/extension-editing/package.json
+++ b/extensions/extension-editing/package.json
@@ -13,7 +13,8 @@
"onLanguage:markdown",
"onLanguage:typescript"
],
- "main": "./out/extension",
+ "main": "./out/extensionEditingMain",
+ "browser": "./dist/browser/extensionEditingBrowserMain",
"scripts": {
"compile": "gulp compile-extension:extension-editing",
"watch": "gulp watch-extension:extension-editing"
diff --git a/extensions/extension-editing/src/extensionEditingBrowserMain.ts b/extensions/extension-editing/src/extensionEditingBrowserMain.ts
new file mode 100644
index 0000000000..fea2db000f
--- /dev/null
+++ b/extensions/extension-editing/src/extensionEditingBrowserMain.ts
@@ -0,0 +1,21 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as vscode from 'vscode';
+import { PackageDocument } from './packageDocumentHelper';
+
+export function activate(context: vscode.ExtensionContext) {
+ //package.json suggestions
+ context.subscriptions.push(registerPackageDocumentCompletions());
+
+}
+
+function registerPackageDocumentCompletions(): vscode.Disposable {
+ return vscode.languages.registerCompletionItemProvider({ language: 'json', pattern: '**/package.json' }, {
+ provideCompletionItems(document, position, token) {
+ return new PackageDocument(document).provideCompletionItems(position, token);
+ }
+ });
+}
diff --git a/extensions/extension-editing/src/extension.ts b/extensions/extension-editing/src/extensionEditingMain.ts
similarity index 100%
rename from extensions/extension-editing/src/extension.ts
rename to extensions/extension-editing/src/extensionEditingMain.ts
diff --git a/extensions/git/package.json b/extensions/git/package.json
index e5e78fd3d8..e96ef36aba 100644
--- a/extensions/git/package.json
+++ b/extensions/git/package.json
@@ -1789,8 +1789,8 @@
"diff"
],
"extensions": [
- ".patch",
".diff",
+ ".patch",
".rej"
],
"configuration": "./languages/diff.language-configuration.json"
@@ -1878,8 +1878,8 @@
"dependencies": {
"byline": "^5.0.0",
"file-type": "^7.2.0",
- "iconv-lite-umd": "0.6.5",
- "jschardet": "2.1.1",
+ "iconv-lite-umd": "0.6.8",
+ "jschardet": "2.2.1",
"vscode-extension-telemetry": "0.1.1",
"vscode-nls": "^4.0.0",
"vscode-uri": "^2.0.0",
diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts
index f7326a39f2..5e3a8b69ce 100644
--- a/extensions/git/src/api/api1.ts
+++ b/extensions/git/src/api/api1.ts
@@ -5,10 +5,12 @@
import { Model } from '../model';
import { Repository as BaseRepository, Resource } from '../repository';
-import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, GitExtension, RefType, RemoteSourceProvider, CredentialsProvider, BranchQuery } from './git';
+import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, RefType, RemoteSourceProvider, CredentialsProvider, BranchQuery, PushErrorHandler } from './git';
import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands } from 'vscode';
import { mapEvent } from '../util';
import { toGitUri } from '../uri';
+import { pickRemoteSource, PickRemoteSourceOptions } from '../remoteSource';
+import { GitExtensionImpl } from './extension';
class ApiInputBox implements InputBox {
set value(value: string) { this._inputBox.value = value; }
@@ -271,6 +273,10 @@ export class ApiImpl implements API {
return this._model.registerCredentialsProvider(provider);
}
+ registerPushErrorHandler(handler: PushErrorHandler): Disposable {
+ return this._model.registerPushErrorHandler(handler);
+ }
+
constructor(private _model: Model) { }
}
@@ -308,41 +314,51 @@ function getStatus(status: Status): string {
return 'UNKNOWN';
}
-export function registerAPICommands(extension: GitExtension): Disposable {
- return Disposable.from(
- commands.registerCommand('git.api.getRepositories', () => {
- const api = extension.getAPI(1);
- return api.repositories.map(r => r.rootUri.toString());
- }),
+export function registerAPICommands(extension: GitExtensionImpl): Disposable {
+ const disposables: Disposable[] = [];
- commands.registerCommand('git.api.getRepositoryState', (uri: string) => {
- const api = extension.getAPI(1);
- const repository = api.getRepository(Uri.parse(uri));
+ disposables.push(commands.registerCommand('git.api.getRepositories', () => {
+ const api = extension.getAPI(1);
+ return api.repositories.map(r => r.rootUri.toString());
+ }));
- if (!repository) {
- return null;
- }
+ disposables.push(commands.registerCommand('git.api.getRepositoryState', (uri: string) => {
+ const api = extension.getAPI(1);
+ const repository = api.getRepository(Uri.parse(uri));
- const state = repository.state;
+ if (!repository) {
+ return null;
+ }
- const ref = (ref: Ref | undefined) => (ref && { ...ref, type: getRefType(ref.type) });
- const change = (change: Change) => ({
- uri: change.uri.toString(),
- originalUri: change.originalUri.toString(),
- renameUri: change.renameUri?.toString(),
- status: getStatus(change.status)
- });
+ const state = repository.state;
- return {
- HEAD: ref(state.HEAD),
- refs: state.refs.map(ref),
- remotes: state.remotes,
- submodules: state.submodules,
- rebaseCommit: state.rebaseCommit,
- mergeChanges: state.mergeChanges.map(change),
- indexChanges: state.indexChanges.map(change),
- workingTreeChanges: state.workingTreeChanges.map(change)
- };
- })
- );
+ const ref = (ref: Ref | undefined) => (ref && { ...ref, type: getRefType(ref.type) });
+ const change = (change: Change) => ({
+ uri: change.uri.toString(),
+ originalUri: change.originalUri.toString(),
+ renameUri: change.renameUri?.toString(),
+ status: getStatus(change.status)
+ });
+
+ return {
+ HEAD: ref(state.HEAD),
+ refs: state.refs.map(ref),
+ remotes: state.remotes,
+ submodules: state.submodules,
+ rebaseCommit: state.rebaseCommit,
+ mergeChanges: state.mergeChanges.map(change),
+ indexChanges: state.indexChanges.map(change),
+ workingTreeChanges: state.workingTreeChanges.map(change)
+ };
+ }));
+
+ disposables.push(commands.registerCommand('git.api.getRemoteSources', (opts?: PickRemoteSourceOptions) => {
+ if (!extension.model) {
+ return;
+ }
+
+ return pickRemoteSource(extension.model, opts);
+ }));
+
+ return Disposable.from(...disposables);
}
diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts
index b74925145e..73c8638caa 100644
--- a/extensions/git/src/api/extension.ts
+++ b/extensions/git/src/api/extension.ts
@@ -7,7 +7,6 @@ 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') {
@@ -26,17 +25,27 @@ export class GitExtensionImpl implements GitExtension {
enabled: boolean = false;
private _onDidChangeEnablement = new EventEmitter();
- readonly onDidChangeEnablement: Event = latchEvent(this._onDidChangeEnablement.event);
+ readonly onDidChangeEnablement: Event = this._onDidChangeEnablement.event;
private _model: Model | undefined = undefined;
set model(model: Model | undefined) {
this._model = model;
- this.enabled = !!model;
+ const enabled = !!model;
+
+ if (this.enabled === enabled) {
+ return;
+ }
+
+ this.enabled = enabled;
this._onDidChangeEnablement.fire(this.enabled);
}
+ get model(): Model | undefined {
+ return this._model;
+ }
+
constructor(model?: Model) {
if (model) {
this.enabled = true;
@@ -73,4 +82,4 @@ export class GitExtensionImpl implements GitExtension {
return new ApiImpl(this._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 6f7c8eb674..9593d8bc70 100644
--- a/extensions/git/src/api/git.d.ts
+++ b/extensions/git/src/api/git.d.ts
@@ -223,6 +223,10 @@ export interface CredentialsProvider {
getCredentials(host: Uri): ProviderResult;
}
+export interface PushErrorHandler {
+ handlePushError(repository: Repository, remote: Remote, refspec: string, error: Error & { gitErrorCode: GitErrorCodes }): Promise;
+}
+
export type APIState = 'uninitialized' | 'initialized';
export interface API {
@@ -239,6 +243,7 @@ export interface API {
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
registerCredentialsProvider(provider: CredentialsProvider): Disposable;
+ registerPushErrorHandler(handler: PushErrorHandler): Disposable;
}
export interface GitExtension {
@@ -276,6 +281,7 @@ export const enum GitErrorCodes {
CantOpenResource = 'CantOpenResource',
GitNotFound = 'GitNotFound',
CantCreatePipe = 'CantCreatePipe',
+ PermissionDenied = 'PermissionDenied',
CantAccessRemote = 'CantAccessRemote',
RepositoryNotFound = 'RepositoryNotFound',
RepositoryIsLocked = 'RepositoryIsLocked',
diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts
index 4450cc36df..ce80a053fc 100644
--- a/extensions/git/src/commands.ts
+++ b/extensions/git/src/commands.ts
@@ -6,10 +6,10 @@
import { lstat, Stats } from 'fs';
import * as os from 'os';
import * as path from 'path';
-import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, QuickPick } from 'vscode';
+import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env } from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
-import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourceProvider, RemoteSource } from './api/git';
+import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourceProvider } from './api/git';
import { ForcePushMode, Git, Stash } from './git';
import { Model } from './model';
import { Repository, Resource, ResourceGroupType } from './repository';
@@ -18,8 +18,8 @@ import { fromGitUri, toGitUri, isGitUri } from './uri';
import { grep, isDescendant, pathEquals } from './util';
import { Log, LogLevel } from './log';
import { GitTimelineItem } from './timelineProvider';
-import { throttle, debounce } from './decorators';
import { ApiRepository } from './api/api1';
+import { pickRemoteSource } from './remoteSource';
const localize = nls.loadMessageBundle();
@@ -240,72 +240,6 @@ interface PushOptions {
silent?: boolean;
}
-async function getQuickPickResult(quickpick: QuickPick): Promise {
- const result = await new Promise(c => {
- quickpick.onDidAccept(() => c(quickpick.selectedItems[0]));
- quickpick.onDidHide(() => c(undefined));
- quickpick.show();
- });
-
- quickpick.hide();
- return result;
-}
-
-class RemoteSourceProviderQuickPick {
-
- private quickpick: QuickPick;
-
- constructor(private provider: RemoteSourceProvider) {
- this.quickpick = window.createQuickPick();
- this.quickpick.ignoreFocusOut = true;
-
- if (provider.supportsQuery) {
- this.quickpick.placeholder = localize('type to search', "Repository name (type to search)");
- this.quickpick.onDidChangeValue(this.onDidChangeValue, this);
- } else {
- this.quickpick.placeholder = localize('type to filter', "Repository name");
- }
- }
-
- @debounce(300)
- onDidChangeValue(): void {
- this.query();
- }
-
- @throttle
- async query(): Promise {
- this.quickpick.busy = true;
-
- try {
- const remoteSources = await this.provider.getRemoteSources(this.quickpick.value) || [];
-
- if (remoteSources.length === 0) {
- this.quickpick.items = [{
- label: localize('none found', "No remote repositories found."),
- alwaysShow: true
- }];
- } else {
- this.quickpick.items = remoteSources.map(remoteSource => ({
- label: remoteSource.name,
- description: remoteSource.description || (typeof remoteSource.url === 'string' ? remoteSource.url : remoteSource.url[0]),
- remoteSource
- }));
- }
- } catch (err) {
- this.quickpick.items = [{ label: localize('error', "$(error) Error: {0}", err.message), alwaysShow: true }];
- console.error(err);
- } finally {
- this.quickpick.busy = false;
- }
- }
-
- async pick(): Promise {
- this.query();
- const result = await getQuickPickResult(this.quickpick);
- return result?.remoteSource;
- }
-}
-
export class CommandCenter {
private disposables: Disposable[];
@@ -527,51 +461,10 @@ export class CommandCenter {
@command('git.clone')
async clone(url?: string, parentPath?: string): Promise {
if (!url) {
- const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider, url?: string })>();
- quickpick.ignoreFocusOut = true;
-
- const providers = this.model.getRemoteProviders()
- .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('clonefrom', "Clone from {0}", provider.name), alwaysShow: true, provider }));
-
- quickpick.placeholder = providers.length === 0
- ? localize('provide url', "Provide repository URL")
- : localize('provide url or pick', "Provide repository URL or pick a repository source.");
-
- const updatePicks = (value?: string) => {
- if (value) {
- quickpick.items = [{
- label: localize('repourl', "Clone from URL"),
- description: value,
- alwaysShow: true,
- url: value
- },
- ...providers];
- } else {
- quickpick.items = providers;
- }
- };
-
- quickpick.onDidChangeValue(updatePicks);
- updatePicks();
-
- const result = await getQuickPickResult(quickpick);
-
- if (result) {
- if (result.url) {
- url = result.url;
- } else if (result.provider) {
- const quickpick = new RemoteSourceProviderQuickPick(result.provider);
- const remote = await quickpick.pick();
-
- if (remote) {
- if (typeof remote.url === 'string') {
- url = remote.url;
- } else if (remote.url.length > 0) {
- url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") });
- }
- }
- }
- }
+ url = await pickRemoteSource(this.model, {
+ providerLabel: provider => localize('clonefrom', "Clone from {0}", provider.name),
+ urlLabel: localize('repourl', "Clone from URL")
+ });
}
if (!url) {
@@ -845,7 +738,7 @@ export class CommandCenter {
try {
document = await workspace.openTextDocument(uri);
} catch (error) {
- await commands.executeCommand('vscode.open', uri, opts);
+ await commands.executeCommand('vscode.open', uri, opts);
continue;
}
@@ -858,7 +751,7 @@ export class CommandCenter {
const editor = await window.showTextDocument(document, opts);
editor.revealRange(previousVisibleRanges[0]);
} else {
- await window.showTextDocument(document, opts);
+ await commands.executeCommand('vscode.open', uri, opts);
}
}
}
@@ -2146,52 +2039,10 @@ export class CommandCenter {
@command('git.addRemote', { repository: true })
async addRemote(repository: Repository): Promise {
- const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider, url?: string })>();
- quickpick.ignoreFocusOut = true;
-
- const providers = this.model.getRemoteProviders()
- .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('addfrom', "Add remote from {0}", provider.name), alwaysShow: true, provider }));
-
- quickpick.placeholder = providers.length === 0
- ? localize('provide url', "Provide repository URL")
- : localize('provide url or pick', "Provide repository URL or pick a repository source.");
-
- const updatePicks = (value?: string) => {
- if (value) {
- quickpick.items = [{
- label: localize('addFrom', "Add remote from URL"),
- description: value,
- alwaysShow: true,
- url: value
- },
- ...providers];
- } else {
- quickpick.items = providers;
- }
- };
-
- quickpick.onDidChangeValue(updatePicks);
- updatePicks();
-
- const result = await getQuickPickResult(quickpick);
- let url: string | undefined;
-
- if (result) {
- if (result.url) {
- url = result.url;
- } else if (result.provider) {
- const quickpick = new RemoteSourceProviderQuickPick(result.provider);
- const remote = await quickpick.pick();
-
- if (remote) {
- if (typeof remote.url === 'string') {
- url = remote.url;
- } else if (remote.url.length > 0) {
- url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") });
- }
- }
- }
- }
+ const url = await pickRemoteSource(this.model, {
+ providerLabel: provider => localize('addfrom', "Add remote from {0}", provider.name),
+ urlLabel: localize('addFrom', "Add remote from URL")
+ });
if (!url) {
return;
@@ -2533,8 +2384,7 @@ export class CommandCenter {
@command('git.timeline.openDiff', { repository: false })
async timelineOpenDiff(item: TimelineItem, uri: Uri | undefined, _source: string) {
- // eslint-disable-next-line eqeqeq
- if (uri == null || !GitTimelineItem.is(item)) {
+ if (uri === undefined || uri === null || !GitTimelineItem.is(item)) {
return undefined;
}
diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts
index 326bc19e4e..938b81b2f4 100644
--- a/extensions/git/src/git.ts
+++ b/extensions/git/src/git.ts
@@ -419,7 +419,7 @@ export class Git {
}
async getRepositoryRoot(repositoryPath: string): Promise {
- const result = await this.exec(repositoryPath, ['rev-parse', '--show-toplevel']);
+ const result = await this.exec(repositoryPath, ['rev-parse', '--show-toplevel'], { log: false });
// Keep trailing spaces which are part of the directory name
const repoPath = path.normalize(result.stdout.trimLeft().replace(/[\r\n]+$/, ''));
@@ -437,8 +437,7 @@ export class Git {
try {
const networkPath = await new Promise(resolve =>
realpath.native(`${letter}:`, { encoding: 'utf8' }, (err, resolvedPath) =>
- // eslint-disable-next-line eqeqeq
- resolve(err != null ? undefined : resolvedPath),
+ resolve(err !== null ? undefined : resolvedPath),
),
);
if (networkPath !== undefined) {
@@ -1628,6 +1627,8 @@ export class Repository {
err.gitErrorCode = GitErrorCodes.RemoteConnectionError;
} else if (/^fatal: The current branch .* has no upstream branch/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoUpstreamBranch;
+ } else if (/Permission.*denied/.test(err.stderr || '')) {
+ err.gitErrorCode = GitErrorCodes.PermissionDenied;
}
throw err;
diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts
index 456b485cb7..8102413024 100644
--- a/extensions/git/src/main.ts
+++ b/extensions/git/src/main.ts
@@ -128,7 +128,7 @@ async function warnAboutMissingGit(): Promise {
}
}*/
-export async function _activate(context: ExtensionContext): Promise {
+export async function _activate(context: ExtensionContext): Promise {
const disposables: Disposable[] = [];
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
@@ -176,8 +176,7 @@ export async function activate(context: ExtensionContext): Promise
return result;
}
-// @ts-expect-error
-async function checkGitVersion(info: IGit): Promise {
+async function checkGitv1(info: IGit): Promise {
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get('ignoreLegacyWarning') === true;
@@ -204,3 +203,28 @@ async function checkGitVersion(info: IGit): Promise {
await config.update('ignoreLegacyWarning', true, true);
}
}
+
+async function checkGitWindows(info: IGit): Promise {
+ if (!/^2\.(25|26)\./.test(info.version)) {
+ return;
+ }
+
+ const update = localize('updateGit', "Update Git");
+ const choice = await window.showWarningMessage(
+ localize('git2526', "There are known issues with the installed Git {0}. Please update to Git >= 2.27 for the git features to work correctly.", info.version),
+ update
+ );
+
+ if (choice === update) {
+ commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
+ }
+}
+
+// @ts-expect-error
+async function checkGitVersion(info: IGit): Promise {
+ await checkGitv1(info);
+
+ if (process.platform === 'win32') {
+ await checkGitWindows(info);
+ }
+}
diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts
index d41e202ebf..8f4e1ac6a3 100644
--- a/extensions/git/src/model.ts
+++ b/extensions/git/src/model.ts
@@ -12,9 +12,10 @@ import * as path from 'path';
import * as fs from 'fs';
import * as nls from 'vscode-nls';
import { fromGitUri } from './uri';
-import { APIState as State, RemoteSourceProvider, CredentialsProvider } from './api/git';
+import { APIState as State, RemoteSourceProvider, CredentialsProvider, PushErrorHandler } from './api/git';
import { Askpass } from './askpass';
import { IRemoteSourceProviderRegistry } from './remoteProvider';
+import { IPushErrorHandlerRegistry } from './pushError';
const localize = nls.loadMessageBundle();
@@ -46,7 +47,7 @@ interface OpenRepository extends Disposable {
repository: Repository;
}
-export class Model implements IRemoteSourceProviderRegistry {
+export class Model implements IRemoteSourceProviderRegistry, IPushErrorHandlerRegistry {
private _onDidOpenRepository = new EventEmitter();
readonly onDidOpenRepository: Event = this._onDidOpenRepository.event;
@@ -94,6 +95,8 @@ export class Model implements IRemoteSourceProviderRegistry {
private _onDidRemoveRemoteSourceProvider = new EventEmitter();
readonly onDidRemoveRemoteSourceProvider = this._onDidRemoveRemoteSourceProvider.event;
+ private pushErrorHandlers = new Set();
+
private disposables: Disposable[] = [];
constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannel: OutputChannel) {
@@ -269,7 +272,7 @@ export class Model implements IRemoteSourceProviderRegistry {
}
const dotGit = await this.git.getRepositoryDotGit(repositoryRoot);
- const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this.globalState, this.outputChannel);
+ const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this.globalState, this.outputChannel);
this.open(repository);
await repository.status();
@@ -485,6 +488,15 @@ export class Model implements IRemoteSourceProviderRegistry {
return [...this.remoteSourceProviders.values()];
}
+ registerPushErrorHandler(handler: PushErrorHandler): Disposable {
+ this.pushErrorHandlers.add(handler);
+ return toDisposable(() => this.pushErrorHandlers.delete(handler));
+ }
+
+ getPushErrorHandlers(): PushErrorHandler[] {
+ return [...this.pushErrorHandlers];
+ }
+
dispose(): void {
const openRepositories = [...this.openRepositories];
openRepositories.forEach(r => r.dispose());
diff --git a/extensions/git/src/pushError.ts b/extensions/git/src/pushError.ts
new file mode 100644
index 0000000000..ddecb6d7e1
--- /dev/null
+++ b/extensions/git/src/pushError.ts
@@ -0,0 +1,12 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { Disposable } from 'vscode';
+import { PushErrorHandler } from './api/git';
+
+export interface IPushErrorHandlerRegistry {
+ registerPushErrorHandler(provider: PushErrorHandler): Disposable;
+ getPushErrorHandlers(): PushErrorHandler[];
+}
diff --git a/extensions/git/src/remoteSource.ts b/extensions/git/src/remoteSource.ts
new file mode 100644
index 0000000000..f8361eb6a2
--- /dev/null
+++ b/extensions/git/src/remoteSource.ts
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { QuickPickItem, window, QuickPick } from 'vscode';
+import * as nls from 'vscode-nls';
+import { RemoteSourceProvider, RemoteSource } from './api/git';
+import { Model } from './model';
+import { throttle, debounce } from './decorators';
+
+const localize = nls.loadMessageBundle();
+
+async function getQuickPickResult(quickpick: QuickPick): Promise {
+ const result = await new Promise(c => {
+ quickpick.onDidAccept(() => c(quickpick.selectedItems[0]));
+ quickpick.onDidHide(() => c(undefined));
+ quickpick.show();
+ });
+
+ quickpick.hide();
+ return result;
+}
+
+class RemoteSourceProviderQuickPick {
+
+ private quickpick: QuickPick;
+
+ constructor(private provider: RemoteSourceProvider) {
+ this.quickpick = window.createQuickPick();
+ this.quickpick.ignoreFocusOut = true;
+
+ if (provider.supportsQuery) {
+ this.quickpick.placeholder = localize('type to search', "Repository name (type to search)");
+ this.quickpick.onDidChangeValue(this.onDidChangeValue, this);
+ } else {
+ this.quickpick.placeholder = localize('type to filter', "Repository name");
+ }
+ }
+
+ @debounce(300)
+ private onDidChangeValue(): void {
+ this.query();
+ }
+
+ @throttle
+ private async query(): Promise {
+ this.quickpick.busy = true;
+
+ try {
+ const remoteSources = await this.provider.getRemoteSources(this.quickpick.value) || [];
+
+ if (remoteSources.length === 0) {
+ this.quickpick.items = [{
+ label: localize('none found', "No remote repositories found."),
+ alwaysShow: true
+ }];
+ } else {
+ this.quickpick.items = remoteSources.map(remoteSource => ({
+ label: remoteSource.name,
+ description: remoteSource.description || (typeof remoteSource.url === 'string' ? remoteSource.url : remoteSource.url[0]),
+ remoteSource
+ }));
+ }
+ } catch (err) {
+ this.quickpick.items = [{ label: localize('error', "$(error) Error: {0}", err.message), alwaysShow: true }];
+ console.error(err);
+ } finally {
+ this.quickpick.busy = false;
+ }
+ }
+
+ async pick(): Promise {
+ this.query();
+ const result = await getQuickPickResult(this.quickpick);
+ return result?.remoteSource;
+ }
+}
+
+export interface PickRemoteSourceOptions {
+ readonly providerLabel?: (provider: RemoteSourceProvider) => string;
+ readonly urlLabel?: string;
+}
+
+export async function pickRemoteSource(model: Model, options: PickRemoteSourceOptions = {}): Promise {
+ const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider, url?: string })>();
+ quickpick.ignoreFocusOut = true;
+
+ const providers = model.getRemoteProviders()
+ .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + (options.providerLabel ? options.providerLabel(provider) : provider.name), alwaysShow: true, provider }));
+
+ quickpick.placeholder = providers.length === 0
+ ? localize('provide url', "Provide repository URL")
+ : localize('provide url or pick', "Provide repository URL or pick a repository source.");
+
+ const updatePicks = (value?: string) => {
+ if (value) {
+ quickpick.items = [{
+ label: options.urlLabel ?? localize('url', "URL"),
+ description: value,
+ alwaysShow: true,
+ url: value
+ },
+ ...providers];
+ } else {
+ quickpick.items = providers;
+ }
+ };
+
+ quickpick.onDidChangeValue(updatePicks);
+ updatePicks();
+
+ const result = await getQuickPickResult(quickpick);
+
+ if (result) {
+ if (result.url) {
+ return result.url;
+ } else if (result.provider) {
+ const quickpick = new RemoteSourceProviderQuickPick(result.provider);
+ const remote = await quickpick.pick();
+
+ if (remote) {
+ if (typeof remote.url === 'string') {
+ return remote.url;
+ } else if (remote.url.length > 0) {
+ return await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") });
+ }
+ }
+ }
+ }
+
+ return undefined;
+}
diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts
index ea3feabd01..8217d2037e 100644
--- a/extensions/git/src/repository.ts
+++ b/extensions/git/src/repository.ts
@@ -17,6 +17,8 @@ import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable,
import { IFileWatcher, watch } from './watch';
import { Log, LogLevel } from './log';
import { IRemoteSourceProviderRegistry } from './remoteProvider';
+import { IPushErrorHandlerRegistry } from './pushError';
+import { ApiRepository } from './api/api1';
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
@@ -683,6 +685,7 @@ export class Repository implements Disposable {
constructor(
private readonly repository: BaseRepository,
remoteSourceProviderRegistry: IRemoteSourceProviderRegistry,
+ private pushErrorHandlerRegistry: IPushErrorHandlerRegistry,
globalState: Memento,
outputChannel: OutputChannel
) {
@@ -865,7 +868,7 @@ export class Repository implements Disposable {
}
async getInputTemplate(): Promise {
- const commitMessage = (await Promise.all([this.repository.getMergeMessage(), this.repository.getSquashMessage()])).find(msg => msg !== undefined);
+ const commitMessage = (await Promise.all([this.repository.getMergeMessage(), this.repository.getSquashMessage()])).find(msg => !!msg);
if (commitMessage) {
return commitMessage;
@@ -1181,15 +1184,15 @@ export class Repository implements Disposable {
branch = `${head.name}:${head.upstream.name}`;
}
- await this.run(Operation.Push, () => this.repository.push(remote, branch, undefined, undefined, forcePushMode));
+ await this.run(Operation.Push, () => this._push(remote, branch, undefined, undefined, forcePushMode));
}
async pushTo(remote?: string, name?: string, setUpstream: boolean = false, forcePushMode?: ForcePushMode): Promise {
- await this.run(Operation.Push, () => this.repository.push(remote, name, setUpstream, undefined, forcePushMode));
+ await this.run(Operation.Push, () => this._push(remote, name, setUpstream, undefined, forcePushMode));
}
async pushFollowTags(remote?: string, forcePushMode?: ForcePushMode): Promise {
- await this.run(Operation.Push, () => this.repository.push(remote, undefined, false, true, forcePushMode));
+ await this.run(Operation.Push, () => this._push(remote, undefined, false, true, forcePushMode));
}
async blame(path: string): Promise {
@@ -1249,7 +1252,7 @@ export class Repository implements Disposable {
const shouldPush = this.HEAD && (typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true);
if (shouldPush) {
- await this.repository.push(remoteName, pushBranch);
+ await this._push(remoteName, pushBranch);
}
});
});
@@ -1411,6 +1414,31 @@ export class Repository implements Disposable {
return ignored;
}
+ private async _push(remote?: string, refspec?: string, setUpstream: boolean = false, tags = false, forcePushMode?: ForcePushMode): Promise {
+ try {
+ await this.repository.push(remote, refspec, setUpstream, tags, forcePushMode);
+ } catch (err) {
+ if (!remote || !refspec) {
+ throw err;
+ }
+
+ const repository = new ApiRepository(this);
+ const remoteObj = repository.state.remotes.find(r => r.name === remote);
+
+ if (!remoteObj) {
+ throw err;
+ }
+
+ for (const handler of this.pushErrorHandlerRegistry.getPushErrorHandlers()) {
+ if (await handler.handlePushError(repository, remoteObj, refspec, err)) {
+ return;
+ }
+ }
+
+ throw err;
+ }
+ }
+
private async run(operation: Operation, runOperation: () => Promise = () => Promise.resolve(null)): Promise {
if (this.state !== RepositoryState.Idle) {
throw new Error('Repository not initialized');
diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts
index 221f2a65a2..23e8f9f8b7 100644
--- a/extensions/git/src/util.ts
+++ b/extensions/git/src/util.ts
@@ -44,18 +44,6 @@ export function filterEvent(event: Event, filter: (e: T) => boolean): Even
return (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => 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: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => {
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 35277c4713..b56e76c37a 100644
--- a/extensions/git/yarn.lock
+++ b/extensions/git/yarn.lock
@@ -425,10 +425,10 @@ https-proxy-agent@^2.2.1:
agent-base "^4.3.0"
debug "^3.1.0"
-iconv-lite-umd@0.6.5:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.5.tgz#6a1f621a3b4d125f72feff813a9839e1ebd6c722"
- integrity sha512-WDegH4al+e3n3jTOStRvm+jzDA3JMUQGgzdAsMxAgcgB0Oi72HjfdsoX08ieKsy3rKexXVjWZr41aOIUaCZnMg==
+iconv-lite-umd@0.6.8:
+ version "0.6.8"
+ resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
+ integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
inflight@^1.0.4:
version "1.0.6"
@@ -468,10 +468,10 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-jschardet@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184"
- integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q==
+jschardet@2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.2.1.tgz#03b0264669a90c7a5c436a68c5a7d4e4cb0c9823"
+ integrity sha512-Ks2JNuUJoc7PGaZ7bVFtSEvOcr0rBq6Q1J5/7+zKWLT+g+4zziL63O0jg7y2jxhzIa1LVsHUbPXrbaWmz9iwDw==
json-schema-traverse@^0.4.1:
version "0.4.1"
diff --git a/extensions/github-authentication/src/extension.ts b/extensions/github-authentication/src/extension.ts
index d5c8d203c0..9d4fa10b10 100644
--- a/extensions/github-authentication/src/extension.ts
+++ b/extensions/github-authentication/src/extension.ts
@@ -24,19 +24,27 @@ export async function activate(context: vscode.ExtensionContext) {
vscode.authentication.registerAuthenticationProvider({
id: 'github',
- displayName: 'GitHub',
+ label: 'GitHub',
supportsMultipleAccounts: false,
onDidChangeSessions: onDidChangeSessions.event,
getSessions: () => Promise.resolve(loginService.sessions),
login: async (scopeList: string[]) => {
try {
+ /* __GDPR__
+ "login" : { }
+ */
telemetryReporter.sendTelemetryEvent('login');
+
const session = await loginService.login(scopeList.sort().join(' '));
Logger.info('Login success!');
onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] });
return session;
} catch (e) {
+ /* __GDPR__
+ "loginFailed" : { }
+ */
telemetryReporter.sendTelemetryEvent('loginFailed');
+
vscode.window.showErrorMessage(`Sign in failed: ${e}`);
Logger.error(e);
throw e;
@@ -44,11 +52,19 @@ export async function activate(context: vscode.ExtensionContext) {
},
logout: async (id: string) => {
try {
+ /* __GDPR__
+ "logout" : { }
+ */
telemetryReporter.sendTelemetryEvent('logout');
+
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
} catch (e) {
+ /* __GDPR__
+ "logoutFailed" : { }
+ */
telemetryReporter.sendTelemetryEvent('logoutFailed');
+
vscode.window.showErrorMessage(`Sign out failed: ${e}`);
Logger.error(e);
throw e;
diff --git a/extensions/github-authentication/src/github.ts b/extensions/github-authentication/src/github.ts
index f86092fbd0..55376dcdfa 100644
--- a/extensions/github-authentication/src/github.ts
+++ b/extensions/github-authentication/src/github.ts
@@ -14,7 +14,8 @@ export const onDidChangeSessions = new vscode.EventEmitter {
const userInfo = await this._githubServer.getUserInfo(token);
- return new vscode.AuthenticationSession(uuid(), token, { displayName: userInfo.accountName, id: userInfo.id }, scopes);
+ return new vscode.AuthenticationSession(uuid(), token, { label: userInfo.accountName, id: userInfo.id }, scopes);
}
private async setToken(session: vscode.AuthenticationSession): Promise {
diff --git a/extensions/github-browser/package.json b/extensions/github-browser/package.json
index 6e3c071b70..9938e25ed5 100644
--- a/extensions/github-browser/package.json
+++ b/extensions/github-browser/package.json
@@ -21,6 +21,11 @@
"main": "./out/extension.js",
"contributes": {
"commands": [
+ {
+ "command": "githubBrowser.openRepository",
+ "title": "Open GitHub Repository...",
+ "category": "GitHub Browser"
+ },
{
"command": "githubBrowser.commit",
"title": "Commit",
@@ -48,6 +53,10 @@
],
"menus": {
"commandPalette": [
+ {
+ "command": "githubBrowser.openRepository",
+ "when": "config.githubBrowser.openRepository"
+ },
{
"command": "githubBrowser.commit",
"when": "false"
diff --git a/extensions/github-browser/src/changeStore.ts b/extensions/github-browser/src/changeStore.ts
index 26ba7f1071..516eee7c38 100644
--- a/extensions/github-browser/src/changeStore.ts
+++ b/extensions/github-browser/src/changeStore.ts
@@ -47,31 +47,17 @@ function fromSerialized(operations: StoredOperation): Operation {
return { ...operations, uri: Uri.parse(operations.uri) };
}
-interface CreatedFileChangeStoreEvent {
- type: 'created';
+export interface ChangeStoreEvent {
+ type: 'created' | 'changed' | 'deleted';
rootUri: Uri;
uri: Uri;
}
-interface ChangedFileChangeStoreEvent {
- type: 'changed';
- rootUri: Uri;
- uri: Uri;
-}
-
-interface DeletedFileChangeStoreEvent {
- type: 'deleted';
- rootUri: Uri;
- uri: Uri;
-}
-
-type ChangeStoreEvent = CreatedFileChangeStoreEvent | ChangedFileChangeStoreEvent | DeletedFileChangeStoreEvent;
-
function toChangeStoreEvent(operation: Operation | StoredOperation, rootUri: Uri, uri?: Uri): ChangeStoreEvent {
return {
type: operation.type,
rootUri: rootUri,
- uri: uri ?? (typeof operation.uri === 'string' ? Uri.parse(operation.uri) : operation.uri)
+ uri: uri ?? (typeof operation.uri === 'string' ? Uri.parse(operation.uri) : operation.uri),
};
}
@@ -82,6 +68,8 @@ export interface IChangeStore {
discard(uri: Uri): Promise;
discardAll(rootUri: Uri): Promise;
+ hasChanges(rootUri: Uri): boolean;
+
getChanges(rootUri: Uri): Operation[];
getContent(uri: Uri): string | undefined;
@@ -116,9 +104,15 @@ export class ChangeStore implements IChangeStore, IWritableChangeStore {
await this.saveWorkingOperations(rootUri, undefined);
+ const events: ChangeStoreEvent[] = [];
+
for (const operation of operations) {
await this.discardWorkingContent(operation.uri);
- this._onDidChange.fire(toChangeStoreEvent(operation, rootUri));
+ events.push(toChangeStoreEvent(operation, rootUri));
+ }
+
+ for (const e of events) {
+ this._onDidChange.fire(e);
}
}
@@ -143,7 +137,7 @@ export class ChangeStore implements IChangeStore, IWritableChangeStore {
this._onDidChange.fire({
type: operation.type === 'created' ? 'deleted' : operation.type === 'deleted' ? 'created' : 'changed',
rootUri: rootUri,
- uri: uri
+ uri: uri,
});
}
@@ -152,9 +146,15 @@ export class ChangeStore implements IChangeStore, IWritableChangeStore {
await this.saveWorkingOperations(rootUri, undefined);
+ const events: ChangeStoreEvent[] = [];
+
for (const operation of operations) {
await this.discardWorkingContent(operation.uri);
- this._onDidChange.fire(toChangeStoreEvent(operation, rootUri));
+ events.push(toChangeStoreEvent(operation, rootUri));
+ }
+
+ for (const e of events) {
+ this._onDidChange.fire(e);
}
}
diff --git a/extensions/github-browser/src/contextStore.ts b/extensions/github-browser/src/contextStore.ts
index f0f418da36..f53d635dd2 100644
--- a/extensions/github-browser/src/contextStore.ts
+++ b/extensions/github-browser/src/contextStore.ts
@@ -4,9 +4,13 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
-import { Event, EventEmitter, Memento, Uri } from 'vscode';
+import { Event, EventEmitter, Memento, Uri, workspace } from 'vscode';
-export const contextKeyPrefix = 'github.context|';
+export interface WorkspaceFolderContext {
+ context: T;
+ name: string;
+ folderUri: Uri;
+}
export class ContextStore {
private _onDidChange = new EventEmitter();
@@ -14,23 +18,36 @@ export class ContextStore {
return this._onDidChange.event;
}
- constructor(private readonly memento: Memento, private readonly scheme: string) { }
+ constructor(
+ private readonly scheme: string,
+ private readonly originalScheme: string,
+ private readonly memento: Memento,
+ ) { }
delete(uri: Uri) {
return this.set(uri, undefined);
}
get(uri: Uri): T | undefined {
- return this.memento.get(`${contextKeyPrefix}${uri.toString()}`);
+ return this.memento.get(`${this.originalScheme}.context|${this.getOriginalResource(uri).toString()}`);
}
+ getForWorkspace(): WorkspaceFolderContext[] {
+ const folders = workspace.workspaceFolders?.filter(f => f.uri.scheme === this.scheme || f.uri.scheme === this.originalScheme) ?? [];
+ return folders.map(f => ({ context: this.get(f.uri)!, name: f.name, folderUri: f.uri })).filter(c => c.context !== undefined);
+ }
async set(uri: Uri, context: T | undefined) {
- if (uri.scheme !== this.scheme) {
- throw new Error(`Invalid context scheme: ${uri.scheme}`);
- }
-
- await this.memento.update(`${contextKeyPrefix}${uri.toString()}`, context);
+ uri = this.getOriginalResource(uri);
+ await this.memento.update(`${this.originalScheme}.context|${uri.toString()}`, context);
this._onDidChange.fire(uri);
}
+
+ getOriginalResource(uri: Uri): Uri {
+ return uri.with({ scheme: this.originalScheme });
+ }
+
+ getWorkspaceResource(uri: Uri): Uri {
+ return uri.with({ scheme: this.scheme });
+ }
}
diff --git a/extensions/github-browser/src/extension.ts b/extensions/github-browser/src/extension.ts
index d0df7d647a..d0f551b0c7 100644
--- a/extensions/github-browser/src/extension.ts
+++ b/extensions/github-browser/src/extension.ts
@@ -3,48 +3,50 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { ExtensionContext, Uri, workspace } from 'vscode';
+import { commands, ExtensionContext, Uri, window, workspace } from 'vscode';
import { ChangeStore } from './changeStore';
import { ContextStore } from './contextStore';
import { VirtualFS } from './fs';
import { GitHubApiContext, GitHubApi } from './github/api';
import { GitHubFS } from './github/fs';
import { VirtualSCM } from './scm';
+import { StatusBar } from './statusbar';
-// const repositoryRegex = /^(?:(?:https:\/\/)?github.com\/)?([^\/]+)\/([^\/]+?)(?:\/|.git|$)/i;
+const repositoryRegex = /^(?:(?:https:\/\/)?github.com\/)?([^\/]+)\/([^\/]+?)(?:\/|.git|$)/i;
-export function activate(context: ExtensionContext) {
- const contextStore = new ContextStore(context.workspaceState, GitHubFS.scheme);
+export async function activate(context: ExtensionContext) {
+ const contextStore = new ContextStore('codespace', GitHubFS.scheme, context.workspaceState);
const changeStore = new ChangeStore(context.workspaceState);
const githubApi = new GitHubApi(contextStore);
const gitHubFS = new GitHubFS(githubApi);
- const virtualFS = new VirtualFS('codespace', GitHubFS.scheme, contextStore, changeStore, gitHubFS);
+ const virtualFS = new VirtualFS('codespace', contextStore, changeStore, gitHubFS);
context.subscriptions.push(
githubApi,
gitHubFS,
virtualFS,
- new VirtualSCM(GitHubFS.scheme, githubApi, changeStore)
+ new VirtualSCM(GitHubFS.scheme, githubApi, changeStore),
+ new StatusBar(contextStore, changeStore),
);
- // commands.registerCommand('githubBrowser.openRepository', async () => {
- // const value = await window.showInputBox({
- // placeHolder: 'e.g. https://github.com/microsoft/vscode',
- // prompt: 'Enter a GitHub repository url',
- // validateInput: value => repositoryRegex.test(value) ? undefined : 'Invalid repository url'
- // });
+ commands.registerCommand('githubBrowser.openRepository', async () => {
+ const value = await window.showInputBox({
+ placeHolder: 'e.g. https://github.com/microsoft/vscode',
+ prompt: 'Enter a GitHub repository url',
+ validateInput: value => repositoryRegex.test(value) ? undefined : 'Invalid repository url'
+ });
- // if (value) {
- // const match = repositoryRegex.exec(value);
- // if (match) {
- // const [, owner, repo] = match;
+ if (value) {
+ const match = repositoryRegex.exec(value);
+ if (match) {
+ const [, owner, repo] = match;
- // const uri = Uri.parse(`codespace://HEAD/${owner}/${repo}`);
- // openWorkspace(uri, repo, 'currentWindow');
- // }
- // }
- // });
+ const uri = Uri.parse(`codespace://HEAD/${owner}/${repo}`);
+ openWorkspace(uri, repo, 'currentWindow');
+ }
+ }
+ });
}
export function getRelativePath(rootUri: Uri, uri: Uri) {
@@ -63,11 +65,16 @@ export function isDescendent(folderPath: string, filePath: string) {
return folderPath.length === 0 || filePath.startsWith(folderPath.endsWith('/') ? folderPath : `${folderPath}/`);
}
-// function openWorkspace(uri: Uri, name: string, location: 'currentWindow' | 'newWindow' | 'addToCurrentWorkspace') {
-// if (location === 'addToCurrentWorkspace') {
-// const count = (workspace.workspaceFolders && workspace.workspaceFolders.length) || 0;
-// return workspace.updateWorkspaceFolders(count, 0, { uri: uri, name: name });
-// }
+const shaRegex = /^[0-9a-f]{40}$/;
+export function isSha(ref: string) {
+ return shaRegex.test(ref);
+}
-// return commands.executeCommand('vscode.openFolder', uri, location === 'newWindow');
-// }
+function openWorkspace(uri: Uri, name: string, location: 'currentWindow' | 'newWindow' | 'addToCurrentWorkspace') {
+ if (location === 'addToCurrentWorkspace') {
+ const count = (workspace.workspaceFolders && workspace.workspaceFolders.length) || 0;
+ return workspace.updateWorkspaceFolders(count, 0, { uri: uri, name: name });
+ }
+
+ return commands.executeCommand('vscode.openFolder', uri, location === 'newWindow');
+}
diff --git a/extensions/github-browser/src/fs.ts b/extensions/github-browser/src/fs.ts
index cb163c85b2..0a0ca250ee 100644
--- a/extensions/github-browser/src/fs.ts
+++ b/extensions/github-browser/src/fs.ts
@@ -43,26 +43,22 @@ export class VirtualFS implements FileSystemProvider, FileSearchProvider, TextSe
constructor(
readonly scheme: string,
- private readonly originalScheme: string,
- contextStore: ContextStore,
+ private readonly contextStore: ContextStore,
private readonly changeStore: IWritableChangeStore,
private readonly fs: FileSystemProvider & FileSearchProvider & TextSearchProvider
) {
// TODO@eamodio listen for workspace folder changes
- for (const folder of workspace.workspaceFolders ?? []) {
- const uri = this.getOriginalResource(folder.uri);
-
+ for (const context of contextStore.getForWorkspace()) {
// If we have a saved context, but no longer have any changes, reset the context
// We only do this on startup/reload to keep things consistent
- if (contextStore.get(uri) !== undefined && !changeStore.hasChanges(folder.uri)) {
- contextStore.delete(uri);
+ if (!changeStore.hasChanges(context.folderUri)) {
+ console.log('Clear context', context.folderUri.toString());
+ contextStore.delete(context.folderUri);
}
}
this.disposable = Disposable.from(
- workspace.registerFileSystemProvider(scheme, this, {
- isCaseSensitive: true,
- }),
+ workspace.registerFileSystemProvider(scheme, this, { isCaseSensitive: true }),
workspace.registerFileSearchProvider(scheme, this),
workspace.registerTextSearchProvider(scheme, this),
changeStore.onDidChange(e => {
@@ -86,11 +82,11 @@ export class VirtualFS implements FileSystemProvider, FileSearchProvider, TextSe
}
private getOriginalResource(uri: Uri): Uri {
- return uri.with({ scheme: this.originalScheme });
+ return this.contextStore.getOriginalResource(uri);
}
- private getVirtualResource(uri: Uri): Uri {
- return uri.with({ scheme: this.scheme });
+ private getWorkspaceResource(uri: Uri): Uri {
+ return this.contextStore.getWorkspaceResource(uri);
}
//#region FileSystemProvider
@@ -211,7 +207,7 @@ export class VirtualFS implements FileSystemProvider, FileSearchProvider, TextSe
return this.fs.provideTextSearchResults(
query,
{ ...options, folder: this.getOriginalResource(options.folder) },
- { report: (result: TextSearchResult) => progress.report({ ...result, uri: this.getVirtualResource(result.uri) }) },
+ { report: (result: TextSearchResult) => progress.report({ ...result, uri: this.getWorkspaceResource(result.uri) }) },
token
);
}
diff --git a/extensions/github-browser/src/github/api.ts b/extensions/github-browser/src/github/api.ts
index 7fffb4a6b7..186eb1a223 100644
--- a/extensions/github-browser/src/github/api.ts
+++ b/extensions/github-browser/src/github/api.ts
@@ -6,14 +6,16 @@
import { authentication, AuthenticationSession, Disposable, Event, EventEmitter, Range, Uri } from 'vscode';
import { graphql } from '@octokit/graphql';
import { Octokit } from '@octokit/rest';
-import { fromGitHubUri } from './fs';
import { ContextStore } from '../contextStore';
+import { fromGitHubUri } from './fs';
+import { isSha } from '../extension';
import { Iterables } from '../iterables';
-export const shaRegex = /^[0-9a-f]{40}$/;
-
export interface GitHubApiContext {
- sha: string;
+ requestRef: string;
+
+ branch: string;
+ sha: string | undefined;
timestamp: number;
}
@@ -73,7 +75,7 @@ export class GitHubApi implements Disposable {
if (!providers.includes('github')) {
await new Promise(resolve => {
authentication.onDidChangeAuthenticationProviders(e => {
- if (e.added.includes('github')) {
+ if (e.added.find(provider => provider.id === 'github')) {
resolve();
}
});
@@ -110,19 +112,12 @@ export class GitHubApi implements Disposable {
}
async commit(rootUri: Uri, message: string, operations: CommitOperation[]): Promise {
- let { owner, repo, ref } = fromGitHubUri(rootUri);
+ const { owner, repo } = fromGitHubUri(rootUri);
try {
- if (ref === undefined || ref === 'HEAD') {
- ref = await this.defaultBranchQuery(rootUri);
- if (ref === undefined) {
- throw new Error('Cannot commit â invalid ref');
- }
- }
-
const context = await this.getContext(rootUri);
if (context.sha === undefined) {
- throw new Error('Cannot commit â invalid context');
+ throw new Error(`Cannot commit to Uri(${rootUri.toString(true)}); Invalid context sha`);
}
const hasDeletes = operations.some(op => op.type === 'deleted');
@@ -204,14 +199,14 @@ export class GitHubApi implements Disposable {
parents: [context.sha]
});
- this.updateContext(rootUri, { sha: resp.data.sha, timestamp: Date.now() });
+ this.updateContext(rootUri, { ...context, sha: resp.data.sha, timestamp: Date.now() });
// TODO@eamodio need to send a file change for any open files
await github.git.updateRef({
owner: owner,
repo: repo,
- ref: `heads/${ref}`,
+ ref: `heads/${context.branch}`,
sha: resp.data.sha
});
@@ -256,7 +251,7 @@ export class GitHubApi implements Disposable {
owner: owner,
repo: repo,
recursive: '1',
- tree_sha: context?.sha ?? ref ?? 'HEAD',
+ tree_sha: context?.sha ?? ref,
});
return Iterables.filterMap(resp.data.tree, p => p.type === 'blob' ? p.path : undefined);
} catch (ex) {
@@ -283,7 +278,7 @@ export class GitHubApi implements Disposable {
}>(query, {
owner: owner,
repo: repo,
- path: `${context.sha ?? ref ?? 'HEAD'}:${path}`,
+ path: `${context.sha ?? ref}:${path}`,
});
return rsp?.repository?.object ?? undefined;
} catch (ex) {
@@ -295,7 +290,7 @@ export class GitHubApi implements Disposable {
const { owner, repo, ref } = fromGitHubUri(uri);
try {
- if (ref === undefined || ref === 'HEAD') {
+ if (ref === 'HEAD') {
const query = `query latest($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
defaultBranchRef {
@@ -322,6 +317,7 @@ export class GitHubApi implements Disposable {
oid
}
}
+ }
}`;
const rsp = await this.gqlQuery<{
@@ -345,7 +341,7 @@ export class GitHubApi implements Disposable {
const { owner, repo, ref } = fromGitHubUri(uri);
// If we have a specific ref, don't try to search, because GitHub search only works against the default branch
- if (ref === undefined) {
+ if (ref !== 'HEAD') {
return { matches: [], limitHit: true };
}
@@ -436,29 +432,46 @@ export class GitHubApi implements Disposable {
private readonly rootUriToContextMap = new Map();
private async getContextCore(rootUri: Uri): Promise {
- let context = this.rootUriToContextMap.get(rootUri.toString());
- if (context === undefined) {
- const { ref } = fromGitHubUri(rootUri);
- if (ref !== undefined && shaRegex.test(ref)) {
- context = { sha: ref, timestamp: Date.now() };
- } else {
- context = this.context.get(rootUri);
- if (context?.sha === undefined) {
- const sha = await this.latestCommitQuery(rootUri);
- if (sha !== undefined) {
- context = { sha: sha, timestamp: Date.now() };
- } else {
- context = undefined;
- }
- }
- }
+ const key = rootUri.toString();
+ let context = this.rootUriToContextMap.get(key);
- if (context !== undefined) {
- this.updateContext(rootUri, context);
- }
+ // Check if we have a cached a context
+ if (context?.sha !== undefined) {
+ return context;
}
- return context ?? { sha: rootUri.authority, timestamp: Date.now() };
+ // Check if we have a saved context
+ context = this.context.get(rootUri);
+ if (context?.sha !== undefined) {
+ this.rootUriToContextMap.set(key, context);
+
+ return context;
+ }
+
+ const { ref } = fromGitHubUri(rootUri);
+
+ // If the requested ref looks like a sha, then use it
+ if (isSha(ref)) {
+ context = { requestRef: ref, branch: ref, sha: ref, timestamp: Date.now() };
+ } else {
+ let branch;
+ if (ref === 'HEAD') {
+ branch = await this.defaultBranchQuery(rootUri);
+ if (branch === undefined) {
+ throw new Error(`Cannot get context for Uri(${rootUri.toString(true)}); unable to get default branch`);
+ }
+ } else {
+ branch = ref;
+ }
+
+ // Query for the latest sha for the give ref
+ const sha = await this.latestCommitQuery(rootUri);
+ context = { requestRef: ref, branch: branch, sha: sha, timestamp: Date.now() };
+ }
+
+ this.updateContext(rootUri, context);
+
+ return context;
}
private updateContext(rootUri: Uri, context: GitHubApiContext) {
diff --git a/extensions/github-browser/src/github/fs.ts b/extensions/github-browser/src/github/fs.ts
index 9149a69b3a..389f3cc00e 100644
--- a/extensions/github-browser/src/github/fs.ts
+++ b/extensions/github-browser/src/github/fs.ts
@@ -299,7 +299,7 @@ function typenameToFileType(typename: string | undefined | null) {
}
}
-type RepoInfo = { owner: string; repo: string; path: string | undefined; ref?: string };
+type RepoInfo = { owner: string; repo: string; path: string | undefined; ref: string };
export function fromGitHubUri(uri: Uri): RepoInfo {
const [, owner, repo, ...rest] = uri.path.split('/');
@@ -311,7 +311,7 @@ export function fromGitHubUri(uri: Uri): RepoInfo {
ref = 'HEAD';
}
}
- return { owner: owner, repo: repo, path: rest.join('/'), ref: ref };
+ return { owner: owner, repo: repo, path: rest.join('/'), ref: ref ?? 'HEAD' };
}
function getHashCode(s: string): number {
diff --git a/extensions/github-browser/src/iterables.ts b/extensions/github-browser/src/iterables.ts
index 0545b2bd70..502750caf9 100644
--- a/extensions/github-browser/src/iterables.ts
+++ b/extensions/github-browser/src/iterables.ts
@@ -12,8 +12,9 @@ export namespace Iterables {
): Iterable {
for (const item of source) {
const mapped = predicateMapper(item);
- // eslint-disable-next-line eqeqeq
- if (mapped != null) { yield mapped; }
+ if (mapped !== undefined && mapped !== null) {
+ yield mapped;
+ }
}
}
diff --git a/extensions/github-browser/src/scm.ts b/extensions/github-browser/src/scm.ts
index f1e039dc2c..ce0519d935 100644
--- a/extensions/github-browser/src/scm.ts
+++ b/extensions/github-browser/src/scm.ts
@@ -32,17 +32,15 @@ export class VirtualSCM implements Disposable {
// TODO@eamodio listen for workspace folder changes
for (const folder of workspace.workspaceFolders ?? []) {
this.createScmProvider(folder.uri, folder.name);
+
+ for (const operation of changeStore.getChanges(folder.uri)) {
+ this.update(folder.uri, operation.uri);
+ }
}
this.disposable = Disposable.from(
changeStore.onDidChange(e => this.update(e.rootUri, e.uri)),
);
-
- for (const { uri } of workspace.workspaceFolders ?? []) {
- for (const operation of changeStore.getChanges(uri)) {
- this.update(uri, operation.uri);
- }
- }
}
dispose() {
@@ -50,7 +48,18 @@ export class VirtualSCM implements Disposable {
}
private registerCommands() {
- commands.registerCommand('githubBrowser.commit', (...args: any[]) => this.commitChanges(args[0]));
+ commands.registerCommand('githubBrowser.commit', (sourceControl: SourceControl | undefined) => {
+ // TODO@eamodio remove this hack once I figure out why the args are missing
+ if (sourceControl === undefined && this.providers.length === 1) {
+ sourceControl = this.providers[0].sourceControl;
+ }
+
+ if (sourceControl === undefined) {
+ return;
+ }
+
+ this.commitChanges(sourceControl);
+ });
commands.registerCommand('githubBrowser.discardChanges', (resourceState: SourceControlResourceState) =>
this.discardChanges(resourceState.resourceUri)
diff --git a/extensions/github-browser/src/statusbar.ts b/extensions/github-browser/src/statusbar.ts
new file mode 100644
index 0000000000..d949a95f7c
--- /dev/null
+++ b/extensions/github-browser/src/statusbar.ts
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+import { Disposable, StatusBarAlignment, StatusBarItem, Uri, window, workspace } from 'vscode';
+import { ChangeStoreEvent, IChangeStore } from './changeStore';
+import { GitHubApiContext } from './github/api';
+import { isSha } from './extension';
+import { ContextStore, WorkspaceFolderContext } from './contextStore';
+
+export class StatusBar implements Disposable {
+ private readonly disposable: Disposable;
+
+ private readonly items = new Map();
+
+ constructor(
+ private readonly contextStore: ContextStore,
+ private readonly changeStore: IChangeStore
+ ) {
+ this.disposable = Disposable.from(
+ contextStore.onDidChange(this.onContextsChanged, this),
+ changeStore.onDidChange(this.onChanged, this)
+ );
+
+ for (const context of this.contextStore.getForWorkspace()) {
+ this.createOrUpdateStatusBarItem(context);
+ }
+ }
+
+ dispose() {
+ this.disposable?.dispose();
+ this.items.forEach(i => i.dispose());
+ }
+
+ private createOrUpdateStatusBarItem(wc: WorkspaceFolderContext) {
+ let item = this.items.get(wc.folderUri.toString());
+ if (item === undefined) {
+ item = window.createStatusBarItem({
+ id: `githubBrowser.branch:${wc.folderUri.toString()}`,
+ name: `GitHub Browser: ${wc.name}`,
+ alignment: StatusBarAlignment.Left,
+ priority: 1000
+ });
+ }
+
+ if (isSha(wc.context.branch)) {
+ item.text = `$(git-commit) ${wc.context.branch.substr(0, 8)}`;
+ item.tooltip = `${wc.name} \u2022 ${wc.context.branch.substr(0, 8)}`;
+ } else {
+ item.text = `$(git-branch) ${wc.context.branch}`;
+ item.tooltip = `${wc.name} \u2022 ${wc.context.branch}${wc.context.sha ? ` @ ${wc.context.sha?.substr(0, 8)}` : ''}`;
+ }
+
+ const hasChanges = this.changeStore.hasChanges(wc.folderUri);
+ if (hasChanges) {
+ item.text += '*';
+ }
+
+ item.show();
+
+ this.items.set(wc.folderUri.toString(), item);
+ }
+
+ private onContextsChanged(uri: Uri) {
+ const folder = workspace.getWorkspaceFolder(this.contextStore.getWorkspaceResource(uri));
+ if (folder === undefined) {
+ return;
+ }
+
+ const context = this.contextStore.get(uri);
+ if (context === undefined) {
+ return;
+ }
+
+ this.createOrUpdateStatusBarItem({
+ context: context,
+ name: folder.name,
+ folderUri: folder.uri,
+ });
+ }
+
+ private onChanged(e: ChangeStoreEvent) {
+ const item = this.items.get(e.rootUri.toString());
+ if (item !== undefined) {
+ const hasChanges = this.changeStore.hasChanges(e.rootUri);
+ if (hasChanges) {
+ if (!item.text.endsWith('*')) {
+ item.text += '*';
+ }
+ } else {
+ if (item.text.endsWith('*')) {
+ item.text = item.text.substr(0, item.text.length - 1);
+ }
+ }
+ }
+ }
+}
diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts
index 1a3fd851c0..1baf1a85d3 100644
--- a/extensions/github/src/commands.ts
+++ b/extensions/github/src/commands.ts
@@ -6,9 +6,10 @@
import * as vscode from 'vscode';
import { API as GitAPI } from './typings/git';
import { publishRepository } from './publish';
+import { combinedDisposable } from './util';
-export function registerCommands(gitAPI: GitAPI): vscode.Disposable[] {
- const disposables = [];
+export function registerCommands(gitAPI: GitAPI): vscode.Disposable {
+ const disposables: vscode.Disposable[] = [];
disposables.push(vscode.commands.registerCommand('github.publish', async () => {
try {
@@ -18,5 +19,5 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable[] {
}
}));
- return disposables;
+ return combinedDisposable(disposables);
}
diff --git a/extensions/github/src/extension.ts b/extensions/github/src/extension.ts
index ae43f9177f..982468853a 100644
--- a/extensions/github/src/extension.ts
+++ b/extensions/github/src/extension.ts
@@ -3,23 +3,43 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as vscode from 'vscode';
+import { Disposable, ExtensionContext, extensions } from 'vscode';
import { GithubRemoteSourceProvider } from './remoteSourceProvider';
import { GitExtension } from './typings/git';
import { registerCommands } from './commands';
import { GithubCredentialProviderManager } from './credentialProvider';
+import { dispose, combinedDisposable } from './util';
+import { GithubPushErrorHandler } from './pushErrorHandler';
-export async function activate(context: vscode.ExtensionContext) {
- const gitExtension = vscode.extensions.getExtension('vscode.git')!.exports;
+export function activate(context: ExtensionContext): void {
+ const disposables = new Set();
+ context.subscriptions.push(combinedDisposable(disposables));
- try {
- const gitAPI = gitExtension.getAPI(1);
+ const init = () => {
+ try {
+ const gitAPI = gitExtension.getAPI(1);
- context.subscriptions.push(...registerCommands(gitAPI));
- context.subscriptions.push(gitAPI.registerRemoteSourceProvider(new GithubRemoteSourceProvider(gitAPI)));
- context.subscriptions.push(new GithubCredentialProviderManager(gitAPI));
- } catch (err) {
- console.error('Could not initialize GitHub extension');
- console.warn(err);
- }
+ disposables.add(registerCommands(gitAPI));
+ disposables.add(gitAPI.registerRemoteSourceProvider(new GithubRemoteSourceProvider(gitAPI)));
+ disposables.add(new GithubCredentialProviderManager(gitAPI));
+ disposables.add(gitAPI.registerPushErrorHandler(new GithubPushErrorHandler()));
+ } catch (err) {
+ console.error('Could not initialize GitHub extension');
+ console.warn(err);
+ }
+ };
+
+ const onDidChangeGitExtensionEnablement = (enabled: boolean) => {
+ if (!enabled) {
+ dispose(disposables);
+ disposables.clear();
+ } else {
+ init();
+ }
+ };
+
+
+ const gitExtension = extensions.getExtension('vscode.git')!.exports;
+ context.subscriptions.push(gitExtension.onDidChangeEnablement(onDidChangeGitExtensionEnablement));
+ onDidChangeGitExtensionEnablement(gitExtension.enabled);
}
diff --git a/extensions/github/src/publish.ts b/extensions/github/src/publish.ts
index fdb3bd90e9..d9ee2cff3b 100644
--- a/extensions/github/src/publish.ts
+++ b/extensions/github/src/publish.ts
@@ -5,10 +5,10 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
-import * as path from 'path';
-import { promises as fs } from 'fs';
import { API as GitAPI, Repository } from './typings/git';
import { getOctokit } from './auth';
+import { TextEncoder } from 'util';
+import { basename } from 'path';
const localize = nls.loadMessageBundle();
@@ -28,10 +28,12 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository)
return;
}
- let folder: vscode.WorkspaceFolder;
+ let folder: vscode.Uri;
- if (vscode.workspace.workspaceFolders.length === 1) {
- folder = vscode.workspace.workspaceFolders[0];
+ if (repository) {
+ folder = repository.rootUri;
+ } else if (vscode.workspace.workspaceFolders.length === 1) {
+ folder = vscode.workspace.workspaceFolders[0].uri;
} else {
const picks = vscode.workspace.workspaceFolders.map(folder => ({ label: folder.name, folder }));
const placeHolder = localize('pick folder', "Pick a folder to publish to GitHub");
@@ -41,14 +43,14 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository)
return;
}
- folder = pick.folder;
+ folder = pick.folder.uri;
}
let quickpick = vscode.window.createQuickPick();
quickpick.ignoreFocusOut = true;
quickpick.placeholder = 'Repository Name';
- quickpick.value = folder.name;
+ quickpick.value = basename(folder.fsPath);
quickpick.show();
quickpick.busy = true;
@@ -97,37 +99,49 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository)
return;
}
- quickpick = vscode.window.createQuickPick();
- quickpick.placeholder = localize('ignore', "Select which files should be included in the repository.");
- quickpick.canSelectMany = true;
- quickpick.show();
+ if (!repository) {
+ const gitignore = vscode.Uri.joinPath(folder, '.gitignore');
+ let shouldGenerateGitignore = false;
- try {
- quickpick.busy = true;
-
- const repositoryPath = folder.uri.fsPath;
- const currentPath = path.join(repositoryPath);
- const children = await fs.readdir(currentPath);
- quickpick.items = children.map(name => ({ label: name }));
- quickpick.selectedItems = quickpick.items;
- quickpick.busy = false;
-
- const result = await Promise.race([
- new Promise(c => quickpick.onDidAccept(() => c(quickpick.selectedItems))),
- new Promise(c => quickpick.onDidHide(() => c(undefined)))
- ]);
-
- if (!result) {
- return;
+ try {
+ await vscode.workspace.fs.stat(gitignore);
+ } catch (err) {
+ shouldGenerateGitignore = true;
}
- const ignored = new Set(children);
- result.forEach(c => ignored.delete(c.label));
+ if (shouldGenerateGitignore) {
+ quickpick = vscode.window.createQuickPick();
+ quickpick.placeholder = localize('ignore', "Select which files should be included in the repository.");
+ quickpick.canSelectMany = true;
+ quickpick.show();
- const raw = [...ignored].map(i => `/${i}`).join('\n');
- await fs.writeFile(path.join(repositoryPath, '.gitignore'), raw, 'utf8');
- } finally {
- quickpick.dispose();
+ try {
+ quickpick.busy = true;
+
+ const children = (await vscode.workspace.fs.readDirectory(folder)).map(([name]) => name);
+ quickpick.items = children.map(name => ({ label: name }));
+ quickpick.selectedItems = quickpick.items;
+ quickpick.busy = false;
+
+ const result = await Promise.race([
+ new Promise(c => quickpick.onDidAccept(() => c(quickpick.selectedItems))),
+ new Promise(c => quickpick.onDidHide(() => c(undefined)))
+ ]);
+
+ if (!result) {
+ return;
+ }
+
+ const ignored = new Set(children);
+ result.forEach(c => ignored.delete(c.label));
+
+ const raw = [...ignored].map(i => `/${i}`).join('\n');
+ const encoder = new TextEncoder();
+ await vscode.workspace.fs.writeFile(gitignore, encoder.encode(raw));
+ } finally {
+ quickpick.dispose();
+ }
+ }
}
const githubRepository = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, cancellable: false, title: 'Publish to GitHub' }, async progress => {
@@ -143,7 +157,7 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository)
progress.report({ message: 'Creating first commit', increment: 25 });
if (!repository) {
- repository = await gitAPI.init(folder.uri) || undefined;
+ repository = await gitAPI.init(folder) || undefined;
if (!repository) {
return;
diff --git a/extensions/github/src/pushErrorHandler.ts b/extensions/github/src/pushErrorHandler.ts
new file mode 100644
index 0000000000..bc585d18b6
--- /dev/null
+++ b/extensions/github/src/pushErrorHandler.ts
@@ -0,0 +1,120 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { PushErrorHandler, GitErrorCodes, Repository, Remote } from './typings/git';
+import { window, ProgressLocation, commands, Uri } from 'vscode';
+import * as nls from 'vscode-nls';
+import { getOctokit } from './auth';
+
+const localize = nls.loadMessageBundle();
+
+async function handlePushError(repository: Repository, remote: Remote, refspec: string, owner: string, repo: string): Promise {
+ const yes = localize('create a fork', "Create Fork");
+ const no = localize('no', "No");
+
+ const answer = await window.showInformationMessage(localize('fork', "You don't have permissions to push to '{0}/{1}' on GitHub. Would you like to create a fork and push to it instead?", owner, repo), yes, no);
+
+ if (answer === no) {
+ return;
+ }
+
+ const match = /^([^:]*):([^:]*)$/.exec(refspec);
+ const localName = match ? match[1] : refspec;
+ const remoteName = match ? match[2] : refspec;
+
+ const [octokit, ghRepository] = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: localize('create fork', 'Create GitHub fork') }, async progress => {
+ progress.report({ message: localize('forking', "Forking '{0}/{1}'...", owner, repo), increment: 33 });
+
+ const octokit = await getOctokit();
+
+ // Issue: what if the repo already exists?
+ const res = await octokit.repos.createFork({ owner, repo });
+ const ghRepository = res.data;
+
+ progress.report({ message: localize('pushing', "Pushing changes..."), increment: 33 });
+
+ // Issue: what if there's already an `upstream` repo?
+ await repository.renameRemote(remote.name, 'upstream');
+
+ // Issue: what if there's already another `origin` repo?
+ await repository.addRemote('origin', ghRepository.clone_url);
+ await repository.fetch('origin', remoteName);
+ await repository.setBranchUpstream(localName, `origin/${remoteName}`);
+ await repository.push('origin', localName, true);
+
+ return [octokit, ghRepository];
+ });
+
+ // yield
+ (async () => {
+ const openInGitHub = localize('openingithub', "Open In GitHub");
+ const createPR = localize('createpr', "Create PR");
+ const action = await window.showInformationMessage(localize('done', "The fork '{0}' was successfully created on GitHub.", ghRepository.full_name), openInGitHub, createPR);
+
+ if (action === openInGitHub) {
+ await commands.executeCommand('vscode.open', Uri.parse(ghRepository.html_url));
+ } else if (action === createPR) {
+ const pr = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: localize('createghpr', "Creating GitHub Pull Request...") }, async _ => {
+ let title = `Update ${remoteName}`;
+ const head = repository.state.HEAD?.name;
+
+ if (head) {
+ const commit = await repository.getCommit(head);
+ title = commit.message.replace(/\n.*$/m, '');
+ }
+
+ const res = await octokit.pulls.create({
+ owner,
+ repo,
+ title,
+ head: `${ghRepository.owner.login}:${remoteName}`,
+ base: remoteName
+ });
+
+ await repository.setConfig(`branch.${localName}.remote`, 'upstream');
+ await repository.setConfig(`branch.${localName}.merge`, `refs/heads/${remoteName}`);
+ await repository.setConfig(`branch.${localName}.github-pr-owner-number`, `${owner}#${repo}#${pr.number}`);
+
+ return res.data;
+ });
+
+ const openPR = localize('openpr', "Open PR");
+ const action = await window.showInformationMessage(localize('donepr', "The PR '{0}/{1}#{2}' was successfully created on GitHub.", owner, repo, pr.number), openPR);
+
+ if (action === openPR) {
+ await commands.executeCommand('vscode.open', Uri.parse(pr.html_url));
+ }
+ }
+ })();
+}
+
+export class GithubPushErrorHandler implements PushErrorHandler {
+
+ async handlePushError(repository: Repository, remote: Remote, refspec: string, error: Error & { gitErrorCode: GitErrorCodes }): Promise {
+ if (error.gitErrorCode !== GitErrorCodes.PermissionDenied) {
+ return false;
+ }
+
+ if (!remote.pushUrl) {
+ return false;
+ }
+
+ const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\.git/i.exec(remote.pushUrl)
+ || /^git@github\.com:([^/]+)\/([^/]+)\.git/i.exec(remote.pushUrl);
+
+ if (!match) {
+ return false;
+ }
+
+ if (/^:/.test(refspec)) {
+ return false;
+ }
+
+ const [, owner, repo] = match;
+ await handlePushError(repository, remote, refspec, owner, repo);
+
+ return true;
+ }
+}
diff --git a/extensions/github/src/typings/git.d.ts b/extensions/github/src/typings/git.d.ts
index 2a8d1cdf9b..9593d8bc70 100644
--- a/extensions/github/src/typings/git.d.ts
+++ b/extensions/github/src/typings/git.d.ts
@@ -134,6 +134,8 @@ export interface CommitOptions {
export interface BranchQuery {
readonly remote?: boolean;
+ readonly pattern?: string;
+ readonly count?: number;
readonly contains?: string;
}
@@ -221,6 +223,10 @@ export interface CredentialsProvider {
getCredentials(host: Uri): ProviderResult;
}
+export interface PushErrorHandler {
+ handlePushError(repository: Repository, remote: Remote, refspec: string, error: Error & { gitErrorCode: GitErrorCodes }): Promise;
+}
+
export type APIState = 'uninitialized' | 'initialized';
export interface API {
@@ -237,6 +243,7 @@ export interface API {
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
registerCredentialsProvider(provider: CredentialsProvider): Disposable;
+ registerPushErrorHandler(handler: PushErrorHandler): Disposable;
}
export interface GitExtension {
@@ -274,6 +281,7 @@ export const enum GitErrorCodes {
CantOpenResource = 'CantOpenResource',
GitNotFound = 'GitNotFound',
CantCreatePipe = 'CantCreatePipe',
+ PermissionDenied = 'PermissionDenied',
CantAccessRemote = 'CantAccessRemote',
RepositoryNotFound = 'RepositoryNotFound',
RepositoryIsLocked = 'RepositoryIsLocked',
diff --git a/extensions/github/src/util.ts b/extensions/github/src/util.ts
new file mode 100644
index 0000000000..982ad7f07b
--- /dev/null
+++ b/extensions/github/src/util.ts
@@ -0,0 +1,24 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as vscode from 'vscode';
+
+export function dispose(arg: vscode.Disposable | Iterable): void {
+ if (arg instanceof vscode.Disposable) {
+ arg.dispose();
+ } else {
+ for (const disposable of arg) {
+ disposable.dispose();
+ }
+ }
+}
+
+export function combinedDisposable(disposables: Iterable): vscode.Disposable {
+ return {
+ dispose() {
+ dispose(disposables);
+ }
+ };
+}
diff --git a/extensions/json/package.json b/extensions/json/package.json
index af713956bf..73902a8ec4 100644
--- a/extensions/json/package.json
+++ b/extensions/json/package.json
@@ -48,14 +48,14 @@
"JSON with Comments"
],
"extensions": [
- ".hintrc",
- ".babelrc",
".jsonc",
".eslintrc",
".eslintrc.json",
".jsfmtrc",
".jshintrc",
- ".swcrc"
+ ".swcrc",
+ ".hintrc",
+ ".babelrc"
],
"configuration": "./language-configuration.json"
}
diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json
index 0df87e91d3..e8feaa75fa 100644
--- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json
+++ b/extensions/markdown-basics/syntaxes/markdown.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/vscode-markdown-tm-grammar/commit/a7e4475626a505472c76d18e0a1b3cfcf46f9cf9",
+ "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/4be9cb335581f3559166c319607dac9100103083",
"name": "Markdown",
"scopeName": "text.html.markdown",
"patterns": [
@@ -1963,12 +1963,12 @@
"name": "markup.fenced_code.block.markdown"
},
"heading": {
- "match": "(?:^|\\G)[ ]{0,3}((#{1,6})\\s+(?=[\\S[^#]]).*?\\s*(#{1,6})?)$\\n?",
+ "match": "(?:^|\\G)[ ]{0,3}(#{1,6}\\s+(.*?)(\\s+#{1,6})?\\s*)$",
"captures": {
"1": {
"patterns": [
{
- "match": "(#{6})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?",
+ "match": "(#{6})\\s+(.*?)(?:\\s+(#+))?\\s*$",
"name": "heading.6.markdown",
"captures": {
"1": {
@@ -1983,7 +1983,7 @@
}
},
{
- "match": "(#{5})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?",
+ "match": "(#{5})\\s+(.*?)(?:\\s+(#+))?\\s*$",
"name": "heading.5.markdown",
"captures": {
"1": {
@@ -1998,7 +1998,7 @@
}
},
{
- "match": "(#{4})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?",
+ "match": "(#{4})\\s+(.*?)(?:\\s+(#+))?\\s*$",
"name": "heading.4.markdown",
"captures": {
"1": {
@@ -2013,7 +2013,7 @@
}
},
{
- "match": "(#{3})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?",
+ "match": "(#{3})\\s+(.*?)(?:\\s+(#+))?\\s*$",
"name": "heading.3.markdown",
"captures": {
"1": {
@@ -2028,7 +2028,7 @@
}
},
{
- "match": "(#{2})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?",
+ "match": "(#{2})\\s+(.*?)(?:\\s+(#+))?\\s*$",
"name": "heading.2.markdown",
"captures": {
"1": {
@@ -2043,7 +2043,7 @@
}
},
{
- "match": "(#{1})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?",
+ "match": "(#{1})\\s+(.*?)(?:\\s+(#+))?\\s*$",
"name": "heading.1.markdown",
"captures": {
"1": {
diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json
index 6963f66e79..1fee128741 100644
--- a/extensions/markdown-basics/test/colorize-results/test_md.json
+++ b/extensions/markdown-basics/test/colorize-results/test_md.json
@@ -33,7 +33,18 @@
}
},
{
- "c": " #",
+ "c": " ",
+ "t": "text.html.markdown markup.heading.markdown heading.1.markdown",
+ "r": {
+ "dark_plus": "markup.heading: #569CD6",
+ "light_plus": "markup.heading: #800000",
+ "dark_vs": "markup.heading: #569CD6",
+ "light_vs": "markup.heading: #800000",
+ "hc_black": "markup.heading: #6796E6"
+ }
+ },
+ {
+ "c": "#",
"t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
@@ -77,7 +88,18 @@
}
},
{
- "c": " ##",
+ "c": " ",
+ "t": "text.html.markdown markup.heading.markdown heading.2.markdown",
+ "r": {
+ "dark_plus": "markup.heading: #569CD6",
+ "light_plus": "markup.heading: #800000",
+ "dark_vs": "markup.heading: #569CD6",
+ "light_vs": "markup.heading: #800000",
+ "hc_black": "markup.heading: #6796E6"
+ }
+ },
+ {
+ "c": "##",
"t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
@@ -2189,7 +2211,18 @@
}
},
{
- "c": " ##",
+ "c": " ",
+ "t": "text.html.markdown markup.heading.markdown heading.2.markdown",
+ "r": {
+ "dark_plus": "markup.heading: #569CD6",
+ "light_plus": "markup.heading: #800000",
+ "dark_vs": "markup.heading: #569CD6",
+ "light_vs": "markup.heading: #800000",
+ "hc_black": "markup.heading: #6796E6"
+ }
+ },
+ {
+ "c": "##",
"t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
@@ -2343,7 +2376,18 @@
}
},
{
- "c": " ##",
+ "c": " ",
+ "t": "text.html.markdown markup.heading.markdown heading.2.markdown",
+ "r": {
+ "dark_plus": "markup.heading: #569CD6",
+ "light_plus": "markup.heading: #800000",
+ "dark_vs": "markup.heading: #569CD6",
+ "light_vs": "markup.heading: #800000",
+ "hc_black": "markup.heading: #6796E6"
+ }
+ },
+ {
+ "c": "##",
"t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown",
"r": {
"dark_plus": "markup.heading: #569CD6",
diff --git a/extensions/markdown-language-features/media/markdown.css b/extensions/markdown-language-features/media/markdown.css
index 64414ab281..c10a0198f2 100644
--- a/extensions/markdown-language-features/media/markdown.css
+++ b/extensions/markdown-language-features/media/markdown.css
@@ -11,6 +11,21 @@ html, body {
word-wrap: break-word;
}
+body {
+ padding-top: 1em;
+}
+
+/* Reset margin top for elements */
+h1, h2, h3, h4, h5, h6,
+p, ol, ul, pre {
+ margin-top: 0;
+}
+
+h2, h3, h4, h5, h6 {
+ font-weight: normal;
+ margin-bottom: 0.2em;
+}
+
#code-csp-warning {
position: fixed;
top: 0;
@@ -112,6 +127,20 @@ textarea:focus {
outline-offset: -1px;
}
+p {
+ margin-bottom: 1.5em;
+}
+
+/* don't space 2 paragraphs too far apart */
+p + p {
+ margin-top: -0.8em;
+}
+
+ul,
+ol {
+ margin-bottom: 1.5em;
+}
+
hr {
border: 0;
height: 2px;
@@ -123,9 +152,6 @@ h1 {
line-height: 1.2;
border-bottom-width: 1px;
border-bottom-style: solid;
-}
-
-h1, h2, h3 {
font-weight: normal;
}
diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json
index becb8ad271..0cdddf075d 100644
--- a/extensions/markdown-language-features/package.json
+++ b/extensions/markdown-language-features/package.json
@@ -79,7 +79,7 @@
"editor/title": [
{
"command": "markdown.showPreviewToSide",
- "when": "editorLangId == markdown",
+ "when": "editorLangId == markdown && !notebookEditorFocused",
"alt": "markdown.showPreview",
"group": "navigation"
},
@@ -115,23 +115,23 @@
{
"command": "markdown.showPreview",
"when": "resourceLangId == markdown",
- "group": "navigation"
+ "group": "1_open"
}
],
"commandPalette": [
{
"command": "markdown.showPreview",
- "when": "editorLangId == markdown",
+ "when": "editorLangId == markdown && !notebookEditorFocused",
"group": "navigation"
},
{
"command": "markdown.showPreviewToSide",
- "when": "editorLangId == markdown",
+ "when": "editorLangId == markdown && !notebookEditorFocused",
"group": "navigation"
},
{
"command": "markdown.showLockedPreviewToSide",
- "when": "editorLangId == markdown",
+ "when": "editorLangId == markdown && !notebookEditorFocused",
"group": "navigation"
},
{
@@ -141,7 +141,7 @@
},
{
"command": "markdown.showPreviewSecuritySelector",
- "when": "editorLangId == markdown"
+ "when": "editorLangId == markdown && !notebookEditorFocused"
},
{
"command": "markdown.showPreviewSecuritySelector",
@@ -153,7 +153,7 @@
},
{
"command": "markdown.preview.refresh",
- "when": "editorLangId == markdown"
+ "when": "editorLangId == markdown && !notebookEditorFocused"
},
{
"command": "markdown.preview.refresh",
@@ -166,13 +166,13 @@
"command": "markdown.showPreview",
"key": "shift+ctrl+v",
"mac": "shift+cmd+v",
- "when": "editorLangId == markdown"
+ "when": "editorLangId == markdown && !notebookEditorFocused"
},
{
"command": "markdown.showPreviewToSide",
"key": "ctrl+k v",
"mac": "cmd+k v",
- "when": "editorLangId == markdown"
+ "when": "editorLangId == markdown && !notebookEditorFocused"
}
],
"configuration": {
diff --git a/extensions/markdown-language-features/src/commands/openDocumentLink.ts b/extensions/markdown-language-features/src/commands/openDocumentLink.ts
index 7bc765259b..8b9e50c85d 100644
--- a/extensions/markdown-language-features/src/commands/openDocumentLink.ts
+++ b/extensions/markdown-language-features/src/commands/openDocumentLink.ts
@@ -13,9 +13,9 @@ import { isMarkdownFile } from '../util/file';
export interface OpenDocumentLinkArgs {
- readonly path: string;
+ readonly path: {};
readonly fragment: string;
- readonly fromResource: any;
+ readonly fromResource: {};
}
enum OpenMarkdownLinks {
@@ -29,13 +29,22 @@ export class OpenDocumentLinkCommand implements Command {
public static createCommandUri(
fromResource: vscode.Uri,
- path: string,
+ path: vscode.Uri,
fragment: string,
): vscode.Uri {
+ const toJson = (uri: vscode.Uri) => {
+ return {
+ scheme: uri.scheme,
+ authority: uri.authority,
+ path: uri.path,
+ fragment: uri.fragment,
+ query: uri.query,
+ };
+ };
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify({
- path: encodeURIComponent(path),
+ path: toJson(path),
fragment,
- fromResource: encodeURIComponent(fromResource.toString(true)),
+ fromResource: toJson(fromResource),
}))}`);
}
@@ -43,26 +52,29 @@ export class OpenDocumentLinkCommand implements Command {
private readonly engine: MarkdownEngine
) { }
- public execute(args: OpenDocumentLinkArgs) {
- const fromResource = vscode.Uri.parse(decodeURIComponent(args.fromResource));
- const targetPath = decodeURIComponent(args.path);
- const column = this.getViewColumn(fromResource);
- return this.tryOpen(targetPath, args, column).catch(() => {
- if (targetPath && extname(targetPath) === '') {
- return this.tryOpen(targetPath + '.md', args, column);
- }
- const targetResource = vscode.Uri.file(targetPath);
- return Promise.resolve(undefined)
- .then(() => vscode.commands.executeCommand('vscode.open', targetResource, column))
- .then(() => undefined);
- });
+ public async execute(args: OpenDocumentLinkArgs) {
+ return OpenDocumentLinkCommand.execute(this.engine, args);
}
- private async tryOpen(path: string, args: OpenDocumentLinkArgs, column: vscode.ViewColumn) {
- const resource = vscode.Uri.file(path);
+ public static async execute(engine: MarkdownEngine, args: OpenDocumentLinkArgs) {
+ const fromResource = vscode.Uri.parse('').with(args.fromResource);
+ const targetResource = vscode.Uri.parse('').with(args.path);
+ const column = this.getViewColumn(fromResource);
+ try {
+ return await this.tryOpen(engine, targetResource, args, column);
+ } catch {
+ if (extname(targetResource.path) === '') {
+ return this.tryOpen(engine, targetResource.with({ path: targetResource.path + '.md' }), args, column);
+ }
+ await vscode.commands.executeCommand('vscode.open', targetResource, column);
+ return undefined;
+ }
+ }
+
+ private static async tryOpen(engine: MarkdownEngine, resource: vscode.Uri, args: OpenDocumentLinkArgs, column: vscode.ViewColumn) {
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document)) {
- if (!path || vscode.window.activeTextEditor.document.uri.fsPath === resource.fsPath) {
- return this.tryRevealLine(vscode.window.activeTextEditor, args.fragment);
+ if (vscode.window.activeTextEditor.document.uri.fsPath === resource.fsPath) {
+ return this.tryRevealLine(engine, vscode.window.activeTextEditor, args.fragment);
}
}
@@ -73,10 +85,10 @@ export class OpenDocumentLinkCommand implements Command {
return vscode.workspace.openTextDocument(resource)
.then(document => vscode.window.showTextDocument(document, column))
- .then(editor => this.tryRevealLine(editor, args.fragment));
+ .then(editor => this.tryRevealLine(engine, editor, args.fragment));
}
- private getViewColumn(resource: vscode.Uri): vscode.ViewColumn {
+ private static getViewColumn(resource: vscode.Uri): vscode.ViewColumn {
const config = vscode.workspace.getConfiguration('markdown', resource);
const openLinks = config.get('links.openLocation', OpenMarkdownLinks.currentGroup);
switch (openLinks) {
@@ -88,18 +100,22 @@ export class OpenDocumentLinkCommand implements Command {
}
}
- private async tryRevealLine(editor: vscode.TextEditor, fragment?: string) {
+ private static async tryRevealLine(engine: MarkdownEngine, editor: vscode.TextEditor, fragment?: string) {
if (editor && fragment) {
- const toc = new TableOfContentsProvider(this.engine, editor.document);
+ const toc = new TableOfContentsProvider(engine, editor.document);
const entry = await toc.lookup(fragment);
if (entry) {
- return editor.revealRange(new vscode.Range(entry.line, 0, entry.line, 0), vscode.TextEditorRevealType.AtTop);
+ const lineStart = new vscode.Range(entry.line, 0, entry.line, 0);
+ editor.selection = new vscode.Selection(lineStart.start, lineStart.end);
+ return editor.revealRange(lineStart, vscode.TextEditorRevealType.AtTop);
}
const lineNumberFragment = fragment.match(/^L(\d+)$/i);
if (lineNumberFragment) {
const line = +lineNumberFragment[1] - 1;
if (!isNaN(line)) {
- return editor.revealRange(new vscode.Range(line, 0, line, 0), vscode.TextEditorRevealType.AtTop);
+ const lineStart = new vscode.Range(line, 0, line, 0);
+ editor.selection = new vscode.Selection(lineStart.start, lineStart.end);
+ return editor.revealRange(lineStart, vscode.TextEditorRevealType.AtTop);
}
}
}
diff --git a/extensions/markdown-language-features/src/extension.ts b/extensions/markdown-language-features/src/extension.ts
index 9c3f4b7f81..0317d61698 100644
--- a/extensions/markdown-language-features/src/extension.ts
+++ b/extensions/markdown-language-features/src/extension.ts
@@ -15,9 +15,9 @@ import MarkdownWorkspaceSymbolProvider from './features/workspaceSymbolProvider'
import { Logger } from './logger';
import { MarkdownEngine } from './markdownEngine';
import { getMarkdownExtensionContributions } from './markdownExtensions';
-import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector, ContentSecurityPolicyArbiter } from './security';
-import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter';
+import { ContentSecurityPolicyArbiter, ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './security';
import { githubSlugifier } from './slugify';
+import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter';
export function activate(context: vscode.ExtensionContext) {
@@ -33,7 +33,7 @@ export function activate(context: vscode.ExtensionContext) {
const contentProvider = new MarkdownContentProvider(engine, context, cspArbiter, contributions, logger);
const symbolProvider = new MDDocumentSymbolProvider(engine);
- const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions);
+ const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions, engine);
context.subscriptions.push(previewManager);
context.subscriptions.push(registerMarkdownLanguageFeatures(symbolProvider, engine));
diff --git a/extensions/markdown-language-features/src/features/documentLinkProvider.ts b/extensions/markdown-language-features/src/features/documentLinkProvider.ts
index e601c59b84..346d9e25ab 100644
--- a/extensions/markdown-language-features/src/features/documentLinkProvider.ts
+++ b/extensions/markdown-language-features/src/features/documentLinkProvider.ts
@@ -14,8 +14,7 @@ const localize = nls.loadMessageBundle();
function parseLink(
document: vscode.TextDocument,
link: string,
- base: string
-): { uri: vscode.Uri, tooltip?: string } {
+): { uri: vscode.Uri, tooltip?: string } | undefined {
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
if (externalSchemeUri) {
// Normalize VS Code links to target currently running version
@@ -29,24 +28,43 @@ function parseLink(
// Use a fake scheme to avoid parse warnings
const tempUri = vscode.Uri.parse(`vscode-resource:${link}`);
- let resourcePath = tempUri.path;
- if (!tempUri.path && document.uri.scheme === 'file') {
- resourcePath = document.uri.path;
+ let resourceUri: vscode.Uri | undefined;
+ if (!tempUri.path) {
+ resourceUri = document.uri;
} else if (tempUri.path[0] === '/') {
- const root = vscode.workspace.getWorkspaceFolder(document.uri);
+ const root = getWorkspaceFolder(document);
if (root) {
- resourcePath = path.join(root.uri.fsPath, tempUri.path);
+ resourceUri = vscode.Uri.joinPath(root, tempUri.path);
}
} else {
- resourcePath = base ? path.join(base, tempUri.path) : tempUri.path;
+ if (document.uri.scheme === Schemes.untitled) {
+ const root = getWorkspaceFolder(document);
+ if (root) {
+ resourceUri = vscode.Uri.joinPath(root, tempUri.path);
+ }
+ } else {
+ const base = document.uri.with({ path: path.dirname(document.uri.fsPath) });
+ resourceUri = vscode.Uri.joinPath(base, tempUri.path);
+ }
}
+ if (!resourceUri) {
+ return undefined;
+ }
+
+ resourceUri = resourceUri.with({ fragment: tempUri.fragment });
+
return {
- uri: OpenDocumentLinkCommand.createCommandUri(document.uri, resourcePath, tempUri.fragment),
+ uri: OpenDocumentLinkCommand.createCommandUri(document.uri, resourceUri, tempUri.fragment),
tooltip: localize('documentLink.tooltip', 'Follow link')
};
}
+function getWorkspaceFolder(document: vscode.TextDocument) {
+ return vscode.workspace.getWorkspaceFolder(document.uri)?.uri
+ || vscode.workspace.workspaceFolders?.[0]?.uri;
+}
+
function matchAll(
pattern: RegExp,
text: string
@@ -62,7 +80,6 @@ function matchAll(
function extractDocumentLink(
document: vscode.TextDocument,
- base: string,
pre: number,
link: string,
matchIndex: number | undefined
@@ -71,11 +88,14 @@ function extractDocumentLink(
const linkStart = document.positionAt(offset);
const linkEnd = document.positionAt(offset + link.length);
try {
- const { uri, tooltip } = parseLink(document, link, base);
+ const linkData = parseLink(document, link);
+ if (!linkData) {
+ return undefined;
+ }
const documentLink = new vscode.DocumentLink(
new vscode.Range(linkStart, linkEnd),
- uri);
- documentLink.tooltip = tooltip;
+ linkData.uri);
+ documentLink.tooltip = linkData.tooltip;
return documentLink;
} catch (e) {
return undefined;
@@ -91,27 +111,25 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
document: vscode.TextDocument,
_token: vscode.CancellationToken
): vscode.DocumentLink[] {
- const base = document.uri.scheme === 'file' ? path.dirname(document.uri.fsPath) : '';
const text = document.getText();
return [
- ...this.providerInlineLinks(text, document, base),
- ...this.provideReferenceLinks(text, document, base)
+ ...this.providerInlineLinks(text, document),
+ ...this.provideReferenceLinks(text, document)
];
}
private providerInlineLinks(
text: string,
document: vscode.TextDocument,
- base: string
): vscode.DocumentLink[] {
const results: vscode.DocumentLink[] = [];
for (const match of matchAll(this.linkPattern, text)) {
- const matchImage = match[4] && extractDocumentLink(document, base, match[3].length + 1, match[4], match.index);
+ const matchImage = match[4] && extractDocumentLink(document, match[3].length + 1, match[4], match.index);
if (matchImage) {
results.push(matchImage);
}
- const matchLink = extractDocumentLink(document, base, match[1].length, match[5], match.index);
+ const matchLink = extractDocumentLink(document, match[1].length, match[5], match.index);
if (matchLink) {
results.push(matchLink);
}
@@ -122,7 +140,6 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
private provideReferenceLinks(
text: string,
document: vscode.TextDocument,
- base: string
): vscode.DocumentLink[] {
const results: vscode.DocumentLink[] = [];
@@ -159,8 +176,10 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
for (const definition of definitions.values()) {
try {
- const { uri } = parseLink(document, definition.link, base);
- results.push(new vscode.DocumentLink(definition.linkRange, uri));
+ const linkData = parseLink(document, definition.link);
+ if (linkData) {
+ results.push(new vscode.DocumentLink(definition.linkRange, linkData.uri));
+ }
} catch (e) {
// noop
}
diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts
index 13adb641a6..54296ad5f0 100644
--- a/extensions/markdown-language-features/src/features/preview.ts
+++ b/extensions/markdown-language-features/src/features/preview.ts
@@ -3,20 +3,20 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import * as vscode from 'vscode';
import * as path from 'path';
-
-import { Logger } from '../logger';
-import { MarkdownContentProvider } from './previewContentProvider';
-import { Disposable } from '../util/dispose';
-
+import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
+import { OpenDocumentLinkCommand, resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
+import { Logger } from '../logger';
+import { MarkdownContributionProvider } from '../markdownExtensions';
+import { Disposable } from '../util/dispose';
+import { isMarkdownFile } from '../util/file';
+import { normalizeResource, WebviewResourceProvider } from '../util/resources';
import { getVisibleLine, TopmostLineMonitor } from '../util/topmostLineMonitor';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
-import { MarkdownContributionProvider } from '../markdownExtensions';
-import { isMarkdownFile } from '../util/file';
-import { resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
-import { WebviewResourceProvider, normalizeResource } from '../util/resources';
+import { MarkdownContentProvider } from './previewContentProvider';
+import { MarkdownEngine } from '../markdownEngine';
+
const localize = nls.loadMessageBundle();
interface WebviewMessage {
@@ -123,6 +123,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
resource: vscode.Uri,
startingScroll: StartingScrollLocation | undefined,
private readonly delegate: MarkdownPreviewDelegate,
+ private readonly engine: MarkdownEngine,
private readonly _contentProvider: MarkdownContentProvider,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
private readonly _logger: Logger,
@@ -407,7 +408,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
}
}
- vscode.commands.executeCommand('_markdown.openDocumentLink', { path: hrefPath, fragment, fromResource: this.resource });
+ OpenDocumentLinkCommand.execute(this.engine, { path: hrefPath, fragment, fromResource: this.resource.toJSON() });
}
//#region WebviewResourceProvider
@@ -452,8 +453,9 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger,
contributionProvider: MarkdownContributionProvider,
+ engine: MarkdownEngine,
): StaticMarkdownPreview {
- return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, logger, contributionProvider);
+ return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, logger, contributionProvider, engine);
}
private readonly preview: MarkdownPreview;
@@ -465,13 +467,14 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger,
contributionProvider: MarkdownContributionProvider,
+ engine: MarkdownEngine,
) {
super();
this.preview = this._register(new MarkdownPreview(this._webviewPanel, resource, undefined, {
getAdditionalState: () => { return {}; },
openPreviewLinkToMarkdownFile: () => { /* todo */ }
- }, contentProvider, _previewConfigurations, logger, contributionProvider));
+ }, engine, contentProvider, _previewConfigurations, logger, contributionProvider));
this._register(this._webviewPanel.onDidDispose(() => {
this.dispose();
@@ -548,9 +551,10 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
logger: Logger,
topmostLineMonitor: TopmostLineMonitor,
contributionProvider: MarkdownContributionProvider,
+ engine: MarkdownEngine,
): DynamicMarkdownPreview {
return new DynamicMarkdownPreview(webview, input,
- contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider);
+ contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine);
}
public static create(
@@ -560,7 +564,8 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger,
topmostLineMonitor: TopmostLineMonitor,
- contributionProvider: MarkdownContributionProvider
+ contributionProvider: MarkdownContributionProvider,
+ engine: MarkdownEngine,
): DynamicMarkdownPreview {
const webview = vscode.window.createWebviewPanel(
DynamicMarkdownPreview.viewType,
@@ -568,7 +573,7 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
previewColumn, { enableFindWidget: true, });
return new DynamicMarkdownPreview(webview, input,
- contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider);
+ contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine);
}
private constructor(
@@ -579,6 +584,7 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
private readonly _logger: Logger,
private readonly _topmostLineMonitor: TopmostLineMonitor,
private readonly _contributionProvider: MarkdownContributionProvider,
+ private readonly _engine: MarkdownEngine,
) {
super();
@@ -612,7 +618,12 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
}));
this._register(vscode.window.onDidChangeActiveTextEditor(editor => {
- if (editor && isMarkdownFile(editor.document) && !this._locked && !this._preview.isPreviewOf(editor.document.uri)) {
+ // Only allow previewing normal text editors which have a viewColumn: See #101514
+ if (typeof editor?.viewColumn === 'undefined') {
+ return;
+ }
+
+ if (isMarkdownFile(editor.document) && !this._locked && !this._preview.isPreviewOf(editor.document.uri)) {
const line = getVisibleLine(editor);
this.update(editor.document.uri, line ? new StartingScrollLine(line) : undefined);
}
@@ -724,6 +735,7 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
this.update(link, fragment ? new StartingScrollFragment(fragment) : undefined);
}
},
+ this._engine,
this._contentProvider,
this._previewConfigurations,
this._logger,
diff --git a/extensions/markdown-language-features/src/features/previewManager.ts b/extensions/markdown-language-features/src/features/previewManager.ts
index c830d0ca12..77d8ef2bc4 100644
--- a/extensions/markdown-language-features/src/features/previewManager.ts
+++ b/extensions/markdown-language-features/src/features/previewManager.ts
@@ -5,10 +5,11 @@
import * as vscode from 'vscode';
import { Logger } from '../logger';
+import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
-import { disposeAll, Disposable } from '../util/dispose';
+import { Disposable, disposeAll } from '../util/dispose';
import { TopmostLineMonitor } from '../util/topmostLineMonitor';
-import { DynamicMarkdownPreview, StaticMarkdownPreview, ManagedMarkdownPreview } from './preview';
+import { DynamicMarkdownPreview, ManagedMarkdownPreview, StaticMarkdownPreview } from './preview';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider } from './previewContentProvider';
@@ -68,7 +69,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
public constructor(
private readonly _contentProvider: MarkdownContentProvider,
private readonly _logger: Logger,
- private readonly _contributions: MarkdownContributionProvider
+ private readonly _contributions: MarkdownContributionProvider,
+ private readonly _engine: MarkdownEngine,
) {
super();
this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this));
@@ -145,7 +147,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
this._previewConfigurations,
this._logger,
this._topmostLineMonitor,
- this._contributions);
+ this._contributions,
+ this._engine);
this.registerDynamicPreview(preview);
}
@@ -160,7 +163,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
this._contentProvider,
this._previewConfigurations,
this._logger,
- this._contributions);
+ this._contributions,
+ this._engine);
this.registerStaticPreview(preview);
}
@@ -179,7 +183,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
this._previewConfigurations,
this._logger,
this._topmostLineMonitor,
- this._contributions);
+ this._contributions,
+ this._engine);
this.setPreviewActiveContext(true);
this._activePreview = preview;
diff --git a/extensions/markdown-language-features/src/markdownExtensions.ts b/extensions/markdown-language-features/src/markdownExtensions.ts
index 073ca3e972..0b55d66793 100644
--- a/extensions/markdown-language-features/src/markdownExtensions.ts
+++ b/extensions/markdown-language-features/src/markdownExtensions.ts
@@ -70,7 +70,7 @@ export namespace MarkdownContributions {
const previewStyles = getContributedStyles(contributions, extension);
const previewScripts = getContributedScripts(contributions, extension);
- const previewResourceRoots = previewStyles.length || previewScripts.length ? [vscode.Uri.file(extension.extensionPath)] : [];
+ const previewResourceRoots = previewStyles.length || previewScripts.length ? [extension.extensionUri] : [];
const markdownItPlugins = getContributedMarkdownItPlugins(contributions, extension);
return {
diff --git a/extensions/markdown-language-features/src/test/documentLink.test.ts b/extensions/markdown-language-features/src/test/documentLink.test.ts
new file mode 100644
index 0000000000..e86b93cb74
--- /dev/null
+++ b/extensions/markdown-language-features/src/test/documentLink.test.ts
@@ -0,0 +1,145 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as assert from 'assert';
+import 'mocha';
+import * as vscode from 'vscode';
+import { joinLines } from './util';
+
+const testFileA = workspaceFile('a.md');
+
+function workspaceFile(...segments: string[]) {
+ return vscode.Uri.joinPath(vscode.workspace.workspaceFolders![0].uri, ...segments);
+}
+
+async function getLinksForFile(file: vscode.Uri): Promise {
+ return (await vscode.commands.executeCommand('vscode.executeLinkProvider', file))!;
+}
+
+suite('Markdown Document links', () => {
+
+ teardown(async () => {
+ await vscode.commands.executeCommand('workbench.action.closeAllEditors');
+ });
+
+ test('Should navigate to markdown file', async () => {
+ await withFileContents(testFileA, '[b](b.md)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('b.md'));
+ });
+
+ test('Should navigate to markdown file with leading ./', async () => {
+ await withFileContents(testFileA, '[b](./b.md)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('b.md'));
+ });
+
+ test('Should navigate to markdown file with leading /', async () => {
+ await withFileContents(testFileA, '[b](./b.md)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('b.md'));
+ });
+
+ test('Should navigate to markdown file without file extension', async () => {
+ await withFileContents(testFileA, '[b](b)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('b.md'));
+ });
+
+ test('Should navigate to markdown file in directory', async () => {
+ await withFileContents(testFileA, '[b](sub/c)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('sub', 'c.md'));
+ });
+
+ test('Should navigate to fragment by title in file', async () => {
+ await withFileContents(testFileA, '[b](sub/c#second)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('sub', 'c.md'));
+ assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
+ });
+
+ test('Should navigate to fragment by line', async () => {
+ await withFileContents(testFileA, '[b](sub/c#L2)');
+
+ const [link] = await getLinksForFile(testFileA);
+ await executeLink(link);
+
+ assertActiveDocumentUri(workspaceFile('sub', 'c.md'));
+ assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
+ });
+
+ test('Should navigate to fragment within current file', async () => {
+ await withFileContents(testFileA, joinLines(
+ '[](a#header)',
+ '[](#header)',
+ '# Header'));
+
+ const links = await getLinksForFile(testFileA);
+ {
+ await executeLink(links[0]);
+ assertActiveDocumentUri(workspaceFile('a.md'));
+ assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 2);
+ }
+ {
+ await executeLink(links[1]);
+ assertActiveDocumentUri(workspaceFile('a.md'));
+ assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 2);
+ }
+ });
+
+ test('Should navigate to fragment within current untitled file', async () => {
+ const testFile = workspaceFile('x.md').with({ scheme: 'untitled' });
+ await withFileContents(testFile, joinLines(
+ '[](#second)',
+ '# Second'));
+
+ const [link] = await getLinksForFile(testFile);
+ await executeLink(link);
+
+ assertActiveDocumentUri(testFile);
+ assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
+ });
+});
+
+
+function assertActiveDocumentUri(expectedUri: vscode.Uri) {
+ assert.strictEqual(
+ vscode.window.activeTextEditor!.document.uri.fsPath,
+ expectedUri.fsPath
+ );
+}
+
+async function withFileContents(file: vscode.Uri, contents: string): Promise {
+ const document = await vscode.workspace.openTextDocument(file);
+ const editor = await vscode.window.showTextDocument(document);
+ await editor.edit(edit => {
+ edit.replace(new vscode.Range(0, 0, 1000, 0), contents);
+ });
+}
+
+async function executeLink(link: vscode.DocumentLink) {
+ const args = JSON.parse(decodeURIComponent(link.target!.query));
+ await vscode.commands.executeCommand(link.target!.path, args);
+}
+
diff --git a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts
index d1dec19917..c97c8fbeae 100644
--- a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts
+++ b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts
@@ -10,7 +10,7 @@ import LinkProvider from '../features/documentLinkProvider';
import { InMemoryDocument } from './inMemoryDocument';
-const testFileName = vscode.Uri.file('test.md');
+const testFile = vscode.Uri.joinPath(vscode.workspace.workspaceFolders![0].uri, 'x.md');
const noopToken = new class implements vscode.CancellationToken {
private _onCancellationRequestedEmitter = new vscode.EventEmitter();
@@ -20,7 +20,7 @@ const noopToken = new class implements vscode.CancellationToken {
};
function getLinksForFile(fileContents: string) {
- const doc = new InMemoryDocument(testFileName, fileContents);
+ const doc = new InMemoryDocument(testFile, fileContents);
const provider = new LinkProvider();
return provider.provideDocumentLinks(doc, noopToken);
}
@@ -118,24 +118,24 @@ suite('markdown.DocumentLinkProvider', () => {
const links = getLinksForFile('[](https://example.com)');
assert.strictEqual(links.length, 2);
const [link1, link2] = links;
- assertRangeEqual(link1.range, new vscode.Range(0,13,0,22));
- assertRangeEqual(link2.range, new vscode.Range(0,25,0,44));
+ assertRangeEqual(link1.range, new vscode.Range(0, 13, 0, 22));
+ assertRangeEqual(link2.range, new vscode.Range(0, 25, 0, 44));
}
{
const links = getLinksForFile('[]( https://whitespace.com )');
assert.strictEqual(links.length, 2);
const [link1, link2] = links;
- assertRangeEqual(link1.range, new vscode.Range(0,7,0,21));
- assertRangeEqual(link2.range, new vscode.Range(0,26,0,48));
+ assertRangeEqual(link1.range, new vscode.Range(0, 7, 0, 21));
+ assertRangeEqual(link2.range, new vscode.Range(0, 26, 0, 48));
}
{
const links = getLinksForFile('[](file1.txt) text [](file2.txt)');
assert.strictEqual(links.length, 4);
const [link1, link2, link3, link4] = links;
- assertRangeEqual(link1.range, new vscode.Range(0,6,0,14));
- assertRangeEqual(link2.range, new vscode.Range(0,17,0,26));
- assertRangeEqual(link3.range, new vscode.Range(0,39,0,47));
- assertRangeEqual(link4.range, new vscode.Range(0,50,0,59));
+ assertRangeEqual(link1.range, new vscode.Range(0, 6, 0, 14));
+ assertRangeEqual(link2.range, new vscode.Range(0, 17, 0, 26));
+ assertRangeEqual(link3.range, new vscode.Range(0, 39, 0, 47));
+ assertRangeEqual(link4.range, new vscode.Range(0, 50, 0, 59));
}
});
});
diff --git a/extensions/markdown-language-features/src/test/test-fixtures/marker.txt b/extensions/markdown-language-features/src/test/test-fixtures/marker.txt
deleted file mode 100644
index a4c9ad4073..0000000000
--- a/extensions/markdown-language-features/src/test/test-fixtures/marker.txt
+++ /dev/null
@@ -1 +0,0 @@
-DO NOT DELETE, USED BY INTEGRATION TESTS
diff --git a/extensions/markdown-language-features/src/test/util.ts b/extensions/markdown-language-features/src/test/util.ts
new file mode 100644
index 0000000000..5fb48ed01f
--- /dev/null
+++ b/extensions/markdown-language-features/src/test/util.ts
@@ -0,0 +1,8 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+import * as os from 'os';
+
+export const joinLines = (...args: string[]) =>
+ args.join(os.platform() === 'win32' ? '\r\n' : '\n');
diff --git a/extensions/markdown-language-features/src/util/links.ts b/extensions/markdown-language-features/src/util/links.ts
index 8cce8221e8..1f74343119 100644
--- a/extensions/markdown-language-features/src/util/links.ts
+++ b/extensions/markdown-language-features/src/util/links.ts
@@ -9,6 +9,7 @@ export const Schemes = {
http: 'http:',
https: 'https:',
file: 'file:',
+ untitled: 'untitled',
mailto: 'mailto:',
data: 'data:',
vscode: 'vscode:',
diff --git a/extensions/markdown-language-features/test-workspace/a.md b/extensions/markdown-language-features/test-workspace/a.md
new file mode 100644
index 0000000000..9d70918067
--- /dev/null
+++ b/extensions/markdown-language-features/test-workspace/a.md
@@ -0,0 +1,4 @@
+[b](b)
+[b](b.md)
+[b](./b.md)
+[b](/b.md)
diff --git a/extensions/markdown-language-features/test-workspace/b.md b/extensions/markdown-language-features/test-workspace/b.md
new file mode 100644
index 0000000000..730f53ee6c
--- /dev/null
+++ b/extensions/markdown-language-features/test-workspace/b.md
@@ -0,0 +1,3 @@
+# b
+
+[](./a)
\ No newline at end of file
diff --git a/extensions/markdown-language-features/test-workspace/sub/c.md b/extensions/markdown-language-features/test-workspace/sub/c.md
new file mode 100644
index 0000000000..f5c9bec43a
--- /dev/null
+++ b/extensions/markdown-language-features/test-workspace/sub/c.md
@@ -0,0 +1,6 @@
+# First
+# Second
+
+[b](/b.md)
+[b](../b.md)
+[b](./../b.md)
diff --git a/extensions/markdown-language-features/test-workspace/sub/d.md b/extensions/markdown-language-features/test-workspace/sub/d.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts
index 6fc1013a21..230e720db6 100644
--- a/extensions/microsoft-authentication/src/AADHelper.ts
+++ b/extensions/microsoft-authentication/src/AADHelper.ts
@@ -26,7 +26,7 @@ interface IToken {
refreshToken: string;
account: {
- displayName: string;
+ label: string;
id: string;
};
scope: string;
@@ -48,7 +48,8 @@ interface IStoredSession {
refreshToken: string;
scope: string; // Scopes are alphabetized and joined with a space
account: {
- displayName: string,
+ label?: string;
+ displayName?: string,
id: string
}
}
@@ -101,7 +102,7 @@ export class AzureActiveDirectoryService {
accessToken: undefined,
refreshToken: session.refreshToken,
account: {
- displayName: session.account.displayName,
+ label: session.account.label ?? session.account.displayName!,
id: session.account.id
},
scope: session.scope,
@@ -437,7 +438,7 @@ export class AzureActiveDirectoryService {
scope,
sessionId: existingId || `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}/${uuid()}`,
account: {
- displayName: claims.email || claims.unique_name || 'user@example.com',
+ label: claims.email || claims.unique_name || 'user@example.com',
id: `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}`
}
};
diff --git a/extensions/microsoft-authentication/src/extension.ts b/extensions/microsoft-authentication/src/extension.ts
index 874640c78c..4089548e6f 100644
--- a/extensions/microsoft-authentication/src/extension.ts
+++ b/extensions/microsoft-authentication/src/extension.ts
@@ -19,27 +19,42 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.authentication.registerAuthenticationProvider({
id: 'microsoft',
- displayName: 'Microsoft',
+ label: 'Microsoft',
supportsMultipleAccounts: true,
onDidChangeSessions: onDidChangeSessions.event,
getSessions: () => Promise.resolve(loginService.sessions),
login: async (scopes: string[]) => {
try {
+ /* __GDPR__
+ "login" : { }
+ */
telemetryReporter.sendTelemetryEvent('login');
+
const session = await loginService.login(scopes.sort().join(' '));
onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] });
return session;
} catch (e) {
+ /* __GDPR__
+ "loginFailed" : { }
+ */
telemetryReporter.sendTelemetryEvent('loginFailed');
+
throw e;
}
},
logout: async (id: string) => {
try {
+ /* __GDPR__
+ "logout" : { }
+ */
telemetryReporter.sendTelemetryEvent('logout');
+
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
} catch (e) {
+ /* __GDPR__
+ "logoutFailed" : { }
+ */
telemetryReporter.sendTelemetryEvent('logoutFailed');
}
}
diff --git a/extensions/notebook/src/test/model/completionItemProvider.test.ts b/extensions/notebook/src/test/model/completionItemProvider.test.ts
index f70a774ea7..daa2e7ba17 100644
--- a/extensions/notebook/src/test/model/completionItemProvider.test.ts
+++ b/extensions/notebook/src/test/model/completionItemProvider.test.ts
@@ -15,6 +15,7 @@ import { JupyterNotebookManager } from '../../jupyter/jupyterNotebookManager';
import { JupyterSessionManager, JupyterSession } from '../../jupyter/jupyterSessionManager';
import { LocalJupyterServerManager } from '../../jupyter/jupyterServerManager';
import { TestKernel } from '../common';
+import { sleep } from '../common/testUtils';
describe('Completion Item Provider', function () {
let completionItemProvider: NotebookCompletionItemProvider;
@@ -64,7 +65,7 @@ describe('Completion Item Provider', function () {
it('should not provide items when session does not exist in notebook provider', async () => {
let notebook = await notebookUtils.newNotebook();
await notebookUtils.addCell('code');
- let document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ let document = await tryFindTextDocument(notebook);
should(document).not.equal(undefined, 'Could not find text document that matched cell uri path');
let completionItems = await completionItemProvider.provideCompletionItems(document, undefined, undefined, undefined);
@@ -76,7 +77,7 @@ describe('Completion Item Provider', function () {
let notebook = await notebookUtils.newNotebook();
await notebookUtils.addCell('code');
- let document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ let document = await tryFindTextDocument(notebook);
let completionItems = await completionItemProvider.provideCompletionItems(document, undefined, undefined, undefined);
should(completionItems).deepEqual([]);
@@ -87,7 +88,7 @@ describe('Completion Item Provider', function () {
let notebook = await notebookUtils.newNotebook();
await notebookUtils.addCell('code');
- let document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ let document = await tryFindTextDocument(notebook);
mockJupyterSession.setup(s => s.path).returns(() => document.uri.path);
@@ -103,7 +104,7 @@ describe('Completion Item Provider', function () {
let notebook = await notebookUtils.newNotebook();
await notebookUtils.addCell('code');
- let document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ let document = await tryFindTextDocument(notebook);
mockJupyterSession.setup(s => s.path).returns(() => document.uri.path);
@@ -151,7 +152,7 @@ describe('Completion Item Provider', function () {
source: 'sample text'
});
});
- let document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ let document = await tryFindTextDocument(notebook);
let completionItems = await completionItemProvider.provideCompletionItems(document, new vscode.Position(1, 1), token, undefined);
should(completionItems).deepEqual([]);
@@ -192,7 +193,18 @@ describe('Completion Item Provider', function () {
} else {
await notebookUtils.addCell('code');
}
+ let document = await tryFindTextDocument(notebook);
+ return document;
+ }
+
+ async function tryFindTextDocument(notebook: azdata.nb.NotebookEditor): Promise {
let document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ let triesRemaining = 10;
+ while (!document && triesRemaining > 0) {
+ await sleep(500);
+ document = vscode.workspace.textDocuments.find(d => d.uri.path === notebook.document.cells[0].uri.path);
+ triesRemaining--;
+ }
return document;
}
});
diff --git a/extensions/package.json b/extensions/package.json
index e54ff1794b..7c668c9744 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.9.5"
+ "typescript": "3.9.6"
},
"scripts": {
"postinstall": "node ./postinstall"
diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json
index 73309c34b4..436dfa5291 100644
--- a/extensions/theme-defaults/themes/hc_black.json
+++ b/extensions/theme-defaults/themes/hc_black.json
@@ -122,5 +122,11 @@
"foreground": "#CBEDCB",
}
}
- ]
+ ],
+ "semanticTokenColors": {
+ "newOperator": "#FFFFFF",
+ "stringLiteral": "#ce9178",
+ "customLiteral": "#DCDCAA",
+ "numberLiteral": "#b5cea8",
+ }
}
diff --git a/extensions/theme-defaults/themes/light_defaults.json b/extensions/theme-defaults/themes/light_defaults.json
index a22dd21b4a..3fad0bc14f 100644
--- a/extensions/theme-defaults/themes/light_defaults.json
+++ b/extensions/theme-defaults/themes/light_defaults.json
@@ -20,10 +20,9 @@
"statusBarItem.remoteBackground": "#16825D",
"sideBarSectionHeader.background": "#0000",
"sideBarSectionHeader.border": "#61616130",
- "notebook.cellFocusBackground": "#c8ddf150",
+ "notebook.focusedCellBackground": "#c8ddf150",
"notebook.cellBorderColor": "#dae3e9",
- "notebook.outputContainerBackgroundColor": "#c8ddf150",
- "notebook.focusedCellShadow": "#00315040"
+ "notebook.outputContainerBackgroundColor": "#c8ddf150"
},
"semanticHighlighting": true
}
diff --git a/extensions/vscode-web-playground/src/exampleFiles.ts b/extensions/vscode-web-playground/src/exampleFiles.ts
index f382391bfc..5663067a36 100644
--- a/extensions/vscode-web-playground/src/exampleFiles.ts
+++ b/extensions/vscode-web-playground/src/exampleFiles.ts
@@ -282,7 +282,7 @@ Or discuss debug adapters on Gitter:
You can now 'step through' the 'readme.md' file, set and hit breakpoints, and run into exceptions (if the word exception appears in a line).
-
+
## Build and Run
@@ -302,3 +302,9 @@ export function getImageFile(): Uint8Array {
const data = atob(`/9j/4AAQSkZJRgABAQAASABIAAD/2wCEAA4ODg4ODhcODhchFxcXIS0hISEhLTktLS0tLTlFOTk5OTk5RUVFRUVFRUVSUlJSUlJgYGBgYGxsbGxsbGxsbGwBERISGxkbLxkZL3FMP0xxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcf/AABEIAFYAZAMBIgACEQEDEQH/xAB1AAACAwEBAQAAAAAAAAAAAAAABAMFBgIBBxAAAgIBAwMCBQQCAwAAAAAAAQIAAxEEBSESMUFRcRMiIzJhFIGRoQbBQlKxAQEBAQEAAAAAAAAAAAAAAAABAgADEQEBAQADAQEAAAAAAAAAAAAAARESITECQf/aAAwDAQACEQMRAD8A2LEZkLc/bKxbdYEHWoyfEze56zXpqRTTYUyPHiVrY2TVZyMzhFZMg8iYE6jcVXAusY98KMnj2lhRu+4aLoGuTNTYPV5APnyDNyPFp6EY3EsO3kxnVVLZVg8z2tw9YsXkGQpcbGIbxHQzep0vw8Jgc8n28CJJRY30lBwzf1iaa2ku/HmMV01VW/k/6hh0abTDTafpPcTytmckEewjeosAqJEj0yDo6yO/rFLzoGME5nIAXtGSM9uwnjLn8zFECw7QneITMWouR7gj9/Ep94061bjXa32WDGfzOGuCXKy9/wDc0FlFe5aX4OpHJHBHcSfT4w246bWJar6MsCwKnp9DOF0r6XRiu5snvg9hNK217vQeih0tXwzcED895R7voNfWoN9gOT2QH/2T3mHrda3Y+p9ppZuSV/qR0j6r+5ju2oun2ypOwCAASGikISzdySf5lxLsAdRPpIqw91xC/wDHvGbAAh88RnSVCjT9b8E/MYsguerTqWuYKo8k4ESTcttsPSmoQ+zCZPWPbvWqsvLE0IxCL4wPP7xEW7TXeKsvaGABOMdLef2ky7ejevX0tBWy5Qhh6jmS9IIxPm6XazbW69K56M/aeRibnSaqyytWtGCfE0+tazDhrHpCdixT5EJSWD1BPkcjsYxpN21FWEcdu0dG3hl8rIX0YqUgDqkSrq/0+6oyfOOZT7hqxqLMKMk8ARfS0fqGatAR04yCY+u3OpLt38e0rQl0tzsFrc8rxj0lqqDHMzujIXUMGPI4mjS1MTCvG8gRLddYE2811n5nHTJ9RaAsztzZ1AZhlX9fBi0VWgWzbSqahfpWfa/iSnatMuqOpVgVPIHGMzc6erS3aQVOoZSMFTK19i2pTwGA9Axx/E58b+K2M8lP6/Urp6BkA5Y+OPE112nrIFeOw8RMajQ7dWU0iAH8TyrVG0mw8EypMFuk7K9TS5RGJHiEYsuUtmEWO1KO2RGDRSVJzj1MiQhOQIx8QEYK5hGpUUJVc1lTgcDjEe1FPxqGQHBZSMiQqa8/Z38xgOoHB/aIfJNVZrdFqirsVbsfzLXT7+UQLYmcDHBlh/k+g+KP1dOCV+4efcTNbdtGq3CxQiMKyeX7CGqxqtDuK7lYK2BXnAz3JMuNZoPpDAyV5zHNt2bRbcA1S/Pjljyf7jerWxx0V4wQeZgynxrUXoUnIif629GJY595cptr1N9XJYjOfEi1G3LYMLgH1m04qxelrAtnj/qZYIvUPpMcHwYtTT8FzVaMN6+sslqVF6gcQ1sRivPccwjS314+bGYRBnqzws6FhUfL7CQ8gdI7+TDIHHgcSVGBYRznMXfUL2J5ngPUOYCpfM2tiq1tnUpVRnMe0DGtAKyQIw+mU4GJCKmrPy+I6V0lxYYIzxOCtdjZyVIMRqtPsYx8RT37+sdRhsFlHzcyC0J0kmcfqFX5cxC7VAk4OPUQtM+UVtYf7vH8iKP8SnKg5U9xHQwsGV7jxF9QnWACMEcgwlUjT4ZUE+YRRLGRehwciEpLRMAAT6SALlIQkF4kl7HEIQLwuQfac9RPeEJi5H3TruvvmEJo1QOcgGQuvVg+sITM8rDKeDHVItXkQhKgqM6esnJEIQlJf//Z`);
return Uint8Array.from([...data].map(x => x.charCodeAt(0)));
}
+
+// encoded from 'ĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐРХТУФмЌЧШЊЪЍЏĐЎЯайвгдоМСиКкНПнОпŃŃŃŃŃŃ
ŃŃŃŃŃŃŃŃŃŃ'
+export const windows1251File = Uint8Array.from([192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]);
+
+// encoded from 'ä¸ĺ˝abc'
+export const gbkFile = Uint8Array.from([214, 208, 185, 250, 97, 98, 99]);
diff --git a/extensions/vscode-web-playground/src/memfs.ts b/extensions/vscode-web-playground/src/memfs.ts
index f3a407443d..b3c4538f9e 100644
--- a/extensions/vscode-web-playground/src/memfs.ts
+++ b/extensions/vscode-web-playground/src/memfs.ts
@@ -29,7 +29,7 @@ import {
Uri,
workspace,
} from 'vscode';
-import { largeTSFile, getImageFile, debuggableFile } from './exampleFiles';
+import { largeTSFile, getImageFile, debuggableFile, windows1251File, gbkFile } from './exampleFiles';
export class File implements FileStat {
@@ -123,6 +123,19 @@ export class MemFS implements FileSystemProvider, FileSearchProvider, TextSearch
this.writeFile(Uri.parse(`memfs:/sample-folder/xyz/UPPER.txt`), textEncoder.encode('UPPER'), { create: true, overwrite: true });
this.writeFile(Uri.parse(`memfs:/sample-folder/xyz/upper.txt`), textEncoder.encode('upper'), { create: true, overwrite: true });
this.writeFile(Uri.parse(`memfs:/sample-folder/xyz/def/foo.md`), textEncoder.encode('*MemFS*'), { create: true, overwrite: true });
+
+ // some files in different encodings
+ this.createDirectory(Uri.parse(`memfs:/sample-folder/encodings/`));
+ this.writeFile(
+ Uri.parse(`memfs:/sample-folder/encodings/windows1251.txt`),
+ windows1251File,
+ { create: true, overwrite: true }
+ );
+ this.writeFile(
+ Uri.parse(`memfs:/sample-folder/encodings/gbk.txt`),
+ gbkFile,
+ { create: true, overwrite: true }
+ );
}
root = new Directory(Uri.parse('memfs:/'), '');
diff --git a/extensions/xml/package.json b/extensions/xml/package.json
index 77e36951b7..3e5042df70 100644
--- a/extensions/xml/package.json
+++ b/extensions/xml/package.json
@@ -23,8 +23,8 @@
".dita",
".ditamap",
".dtd",
- ".ent",
- ".mod",
+ ".ent",
+ ".mod",
".dtml",
".fsproj",
".fxml",
diff --git a/extensions/yarn.lock b/extensions/yarn.lock
index e0f5c7c4dd..d41a4ab48b 100644
--- a/extensions/yarn.lock
+++ b/extensions/yarn.lock
@@ -76,10 +76,10 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-typescript@3.9.5:
- version "3.9.5"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36"
- integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==
+typescript@3.9.6:
+ version "3.9.6"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a"
+ integrity sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==
wrappy@1:
version "1.0.2"
diff --git a/package.json b/package.json
index bfaf2f236a..7898c31bdf 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "azuredatastudio",
"version": "1.21.0",
- "distro": "0e27fd464a32a78a47a0aa815f408233820c59cc",
+ "distro": "e2e446ca4ccd7cad605bad3c8266fca3f8ee33c1",
"author": {
"name": "Microsoft Corporation"
},
@@ -14,7 +14,7 @@
"preinstall": "node build/npm/preinstall.js",
"postinstall": "node build/npm/postinstall.js",
"compile": "gulp compile --max_old_space_size=4095",
- "watch": "gulp watch --max_old_space_size=4095",
+ "watch": "concurrently \"npm:watch-client\" \"npm:watch-extensions\"",
"watchd": "deemon yarn watch",
"watch-webd": "deemon yarn watch-web",
"kill-watchd": "deemon --kill yarn watch",
@@ -22,6 +22,11 @@
"restart-watchd": "deemon --restart yarn watch",
"restart-watch-webd": "deemon --restart yarn watch-web",
"watch-client": "gulp watch-client --max_old_space_size=4095",
+ "watch-clientd": "deemon yarn watch-client",
+ "kill-watch-clientd": "deemon --kill yarn watch-client",
+ "watch-extensions": "gulp watch-extensions --max_old_space_size=4095",
+ "watch-extensionsd": "deemon yarn watch-extensions",
+ "kill-watch-extensionsd": "deemon --kill yarn watch-extensions",
"mocha": "mocha test/unit/node/all.js --delay",
"precommit": "node build/gulpfile.hygiene.js",
"gulp": "gulp --max_old_space_size=8192",
@@ -62,9 +67,9 @@
"html-query-plan": "git://github.com/anthonydresser/html-query-plan.git#2.6",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.3",
- "iconv-lite-umd": "0.6.5",
+ "iconv-lite-umd": "0.6.8",
"jquery": "3.5.0",
- "jschardet": "2.1.1",
+ "jschardet": "2.2.1",
"keytar": "^5.5.0",
"minimist": "^1.2.5",
"native-is-elevated": "0.4.1",
@@ -84,10 +89,10 @@
"vscode-nsfw": "1.2.8",
"vscode-oniguruma": "1.3.1",
"vscode-proxy-agent": "^0.5.2",
- "vscode-ripgrep": "^1.7.0",
+ "vscode-ripgrep": "^1.8.0",
"vscode-sqlite3": "4.0.10",
"vscode-textmate": "5.2.0",
- "xterm": "4.7.0-beta.3",
+ "xterm": "4.8.1",
"xterm-addon-search": "0.7.0",
"xterm-addon-unicode11": "0.2.0",
"xterm-addon-webgl": "0.7.0",
@@ -124,12 +129,13 @@
"ansi-colors": "^3.2.3",
"asar": "^0.14.0",
"chromium-pickle-js": "^0.2.0",
+ "concurrently": "^5.2.0",
"copy-webpack-plugin": "^4.5.2",
"cson-parser": "^1.3.3",
"css-loader": "^3.2.0",
"debounce": "^1.0.0",
"deemon": "^1.4.0",
- "electron": "7.3.2",
+ "electron": "8.3.3",
"eslint": "6.8.0",
"eslint-plugin-jsdoc": "^19.1.0",
"event-stream": "3.3.4",
@@ -157,7 +163,7 @@
"gulp-untar": "^0.0.7",
"gulp-vinyl-zip": "^2.1.2",
"husky": "^0.13.1",
- "innosetup": "5.6.1",
+ "innosetup": "6.0.5",
"is": "^3.1.0",
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-instrument": "^4.0.0",
diff --git a/remote/package.json b/remote/package.json
index 0892761f3b..363a97d80c 100644
--- a/remote/package.json
+++ b/remote/package.json
@@ -20,9 +20,9 @@
"html-query-plan": "git://github.com/anthonydresser/html-query-plan.git#2.6",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.3",
- "iconv-lite-umd": "0.6.5",
+ "iconv-lite-umd": "0.6.8",
"jquery": "3.5.0",
- "jschardet": "2.1.1",
+ "jschardet": "2.2.1",
"minimist": "^1.2.5",
"native-watchdog": "1.3.0",
"ng2-charts": "^1.6.0",
@@ -36,9 +36,9 @@
"vscode-nsfw": "1.2.8",
"vscode-oniguruma": "1.3.1",
"vscode-proxy-agent": "^0.5.2",
- "vscode-ripgrep": "^1.7.0",
+ "vscode-ripgrep": "^1.8.0",
"vscode-textmate": "5.2.0",
- "xterm": "4.7.0-beta.3",
+ "xterm": "4.8.1",
"xterm-addon-search": "0.7.0",
"xterm-addon-unicode11": "0.2.0",
"xterm-addon-webgl": "0.7.0",
diff --git a/remote/web/package.json b/remote/web/package.json
index 8de1ac76b2..cef07e7f5d 100644
--- a/remote/web/package.json
+++ b/remote/web/package.json
@@ -14,8 +14,8 @@
"ansi_up": "^3.0.0",
"chart.js": "^2.6.0",
"html-query-plan": "git://github.com/anthonydresser/html-query-plan.git#2.6",
- "iconv-lite-umd": "0.6.5",
- "jschardet": "2.1.1",
+ "iconv-lite-umd": "0.6.8",
+ "jschardet": "2.2.1",
"jquery": "3.5.0",
"ng2-charts": "^1.6.0",
"reflect-metadata": "^0.1.8",
@@ -25,7 +25,7 @@
"slickgrid": "github:anthonydresser/SlickGrid#2.3.33",
"vscode-oniguruma": "1.3.1",
"vscode-textmate": "5.2.0",
- "xterm": "4.7.0-beta.3",
+ "xterm": "4.8.1",
"xterm-addon-search": "0.7.0",
"xterm-addon-unicode11": "0.2.0",
"xterm-addon-webgl": "0.7.0",
diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock
index 6bc88bb10f..694113201c 100644
--- a/remote/web/yarn.lock
+++ b/remote/web/yarn.lock
@@ -182,10 +182,10 @@ htmlparser2@^3.10.0:
inherits "^2.0.1"
readable-stream "^3.1.1"
-iconv-lite-umd@0.6.5:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.5.tgz#6a1f621a3b4d125f72feff813a9839e1ebd6c722"
- integrity sha512-WDegH4al+e3n3jTOStRvm+jzDA3JMUQGgzdAsMxAgcgB0Oi72HjfdsoX08ieKsy3rKexXVjWZr41aOIUaCZnMg==
+iconv-lite-umd@0.6.8:
+ version "0.6.8"
+ resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
+ integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
inherits@^2.0.1, inherits@^2.0.3:
version "2.0.4"
@@ -197,10 +197,10 @@ jquery@3.5.0:
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9"
integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==
-jschardet@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184"
- integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q==
+jschardet@2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.2.1.tgz#03b0264669a90c7a5c436a68c5a7d4e4cb0c9823"
+ integrity sha512-Ks2JNuUJoc7PGaZ7bVFtSEvOcr0rBq6Q1J5/7+zKWLT+g+4zziL63O0jg7y2jxhzIa1LVsHUbPXrbaWmz9iwDw==
lodash.clonedeep@^4.5.0:
version "4.5.0"
@@ -378,10 +378,10 @@ xterm-addon-webgl@0.7.0:
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.7.0.tgz#a13732ac937170e53ce02ec91963da042c80614b"
integrity sha512-PMWLgccAF31GulCYkQxIA8qwMI4q4UbRi5O/zwMnSJWBozB0yy84lX31ZhJeJhcrlEn1Vpcd+OUGPE8Z1hBjnw==
-xterm@4.7.0-beta.3:
- version "4.7.0-beta.3"
- resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.7.0-beta.3.tgz#d8997f190430d750201717adf3857f6c8052f149"
- integrity sha512-mL9VCB7Ql7KSql2PJmRQYba77mMXlliK9lVKd3XCDqtOYYWjg+CKKeNtFljIrPoiI25nvoqlkrv5dFuuIAR5hA==
+xterm@4.8.1:
+ version "4.8.1"
+ resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.8.1.tgz#155a1729a43e1a89b406524e22c5634339e39ca1"
+ integrity sha512-ax91ny4tI5eklqIfH79OUSGE2PUX2rGbwONmB6DfqpyhSZO8/cf++sqiaMWEVCMjACyMfnISW7C3gGMoNvNolQ==
zone.js@^0.8.4:
version "0.8.29"
diff --git a/remote/yarn.lock b/remote/yarn.lock
index 98809ebf37..0ed3f67039 100644
--- a/remote/yarn.lock
+++ b/remote/yarn.lock
@@ -376,10 +376,10 @@ https-proxy-agent@^4.0.0:
agent-base "5"
debug "4"
-iconv-lite-umd@0.6.5:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.5.tgz#6a1f621a3b4d125f72feff813a9839e1ebd6c722"
- integrity sha512-WDegH4al+e3n3jTOStRvm+jzDA3JMUQGgzdAsMxAgcgB0Oi72HjfdsoX08ieKsy3rKexXVjWZr41aOIUaCZnMg==
+iconv-lite-umd@0.6.8:
+ version "0.6.8"
+ resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
+ integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
inherits@^2.0.1, inherits@^2.0.3:
version "2.0.4"
@@ -420,10 +420,10 @@ jquery@3.5.0:
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9"
integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==
-jschardet@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184"
- integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q==
+jschardet@2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.2.1.tgz#03b0264669a90c7a5c436a68c5a7d4e4cb0c9823"
+ integrity sha512-Ks2JNuUJoc7PGaZ7bVFtSEvOcr0rBq6Q1J5/7+zKWLT+g+4zziL63O0jg7y2jxhzIa1LVsHUbPXrbaWmz9iwDw==
jsonfile@^4.0.0:
version "4.0.0"
@@ -736,10 +736,10 @@ vscode-proxy-agent@^0.5.2:
https-proxy-agent "^2.2.3"
socks-proxy-agent "^4.0.1"
-vscode-ripgrep@^1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.7.0.tgz#ec912e04aa29f7d73bcef04b7576b792f12c9b38"
- integrity sha512-sQY/u0ymc9YMiPaSsMmdZSFQ6PTS2UxcGuiQkF7aoIezDxZcGE1sMarqftWEl9wYWYc9hElYm00WpoFgzj1oUg==
+vscode-ripgrep@^1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.8.0.tgz#dfe7c2ae2a2032df8a8108765c2feef73474888a"
+ integrity sha512-/Q5XtePkTLLi8yplr5ai24pVEymRF62xH9xXrtj35GTaDCJg3zq1s1/L1UqhVbfNDv4OcMBYjyIAt/quEi3d5w==
dependencies:
https-proxy-agent "^4.0.0"
proxy-from-env "^1.1.0"
@@ -781,10 +781,10 @@ xterm-addon-webgl@0.7.0:
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.7.0.tgz#a13732ac937170e53ce02ec91963da042c80614b"
integrity sha512-PMWLgccAF31GulCYkQxIA8qwMI4q4UbRi5O/zwMnSJWBozB0yy84lX31ZhJeJhcrlEn1Vpcd+OUGPE8Z1hBjnw==
-xterm@4.7.0-beta.3:
- version "4.7.0-beta.3"
- resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.7.0-beta.3.tgz#d8997f190430d750201717adf3857f6c8052f149"
- integrity sha512-mL9VCB7Ql7KSql2PJmRQYba77mMXlliK9lVKd3XCDqtOYYWjg+CKKeNtFljIrPoiI25nvoqlkrv5dFuuIAR5hA==
+xterm@4.8.1:
+ version "4.8.1"
+ resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.8.1.tgz#155a1729a43e1a89b406524e22c5634339e39ca1"
+ integrity sha512-ax91ny4tI5eklqIfH79OUSGE2PUX2rGbwONmB6DfqpyhSZO8/cf++sqiaMWEVCMjACyMfnISW7C3gGMoNvNolQ==
yauzl@^2.9.2:
version "2.10.0"
diff --git a/resources/serverless/code-web.js b/resources/serverless/code-web.js
index bee6ca5b71..998d88b884 100644
--- a/resources/serverless/code-web.js
+++ b/resources/serverless/code-web.js
@@ -20,32 +20,35 @@ const ansiColors = require('ansi-colors');
const extensions = require('../../build/lib/extensions');
const APP_ROOT = path.join(__dirname, '..', '..');
-const EXTENSIONS_ROOT = path.join(APP_ROOT, 'extensions');
+const BUILTIN_EXTENSIONS_ROOT = path.join(APP_ROOT, 'extensions');
+const BUILTIN_MARKETPLACE_EXTENSIONS_ROOT = path.join(APP_ROOT, '.build', 'builtInExtensions');
const WEB_MAIN = path.join(APP_ROOT, 'src', 'vs', 'code', 'browser', 'workbench', 'workbench-dev.html');
const args = minimist(process.argv, {
boolean: [
- 'watch',
'no-launch',
- 'help'
+ 'help',
+ 'verbose'
],
string: [
'scheme',
'host',
'port',
- 'local_port'
+ 'local_port',
+ 'extension'
],
});
if (args.help) {
console.log(
'yarn web [options]\n' +
- ' --watch Watch extensions that require browser specific builds\n' +
- ' --no-launch Do not open VSCode web in the browser\n' +
- ' --scheme Protocol (https or http)\n' +
- ' --host Remote host\n' +
- ' --port Remote/Local port\n' +
- ' --local_port Local port override\n' +
+ ' --no-launch Do not open VSCode web in the browser\n' +
+ ' --scheme Protocol (https or http)\n' +
+ ' --host Remote host\n' +
+ ' --port Remote/Local port\n' +
+ ' --local_port Local port override\n' +
+ ' --extension Path of an extension to include\n' +
+ ' --verbose Print out more information\n' +
' --help\n' +
'[Example]\n' +
' yarn web --scheme https --host example.com --port 8080 --local_port 30000'
@@ -61,76 +64,124 @@ const AUTHORITY = process.env.VSCODE_AUTHORITY || `${HOST}:${PORT}`;
const exists = (path) => util.promisify(fs.exists)(path);
const readFile = (path) => util.promisify(fs.readFile)(path);
+const readdir = (path) => util.promisify(fs.readdir)(path);
+const readdirWithFileTypes = (path) => util.promisify(fs.readdir)(path, { withFileTypes: true });
-let unbuiltExensions = [];
+async function getBuiltInExtensionInfos() {
+ const extensions = [];
+ /** @type {Object.} */
+ const locations = {};
-async function initialize() {
- const builtinExtensions = [];
-
- const children = await util.promisify(fs.readdir)(EXTENSIONS_ROOT, { withFileTypes: true });
- const folders = children.filter(c => !c.isFile());
- await Promise.all(folders.map(async folder => {
- const folderName = folder.name;
- const extensionPath = path.join(EXTENSIONS_ROOT, folderName);
-
- let children = [];
- try {
- children = await util.promisify(fs.readdir)(extensionPath);
- } catch (error) {
- console.log(error);
- return;
- }
-
- const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
- const readmePath = readme ? path.join(extensionPath, readme) : undefined;
- const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
- const changelogPath = changelog ? path.join(extensionPath, changelog) : undefined;
-
- const packageJSONPath = path.join(EXTENSIONS_ROOT, folderName, 'package.json');
- if (await exists(packageJSONPath)) {
- try {
- let packageJSON = JSON.parse((await readFile(packageJSONPath)).toString());
- if (packageJSON.main && !packageJSON.browser) {
- return; // unsupported
- }
-
- if (packageJSON.browser) {
- packageJSON.main = packageJSON.browser;
-
- let mainFilePath = path.join(EXTENSIONS_ROOT, folderName, packageJSON.browser);
- if (path.extname(mainFilePath) !== '.js') {
- mainFilePath += '.js';
- }
- if (!await exists(mainFilePath)) {
- unbuiltExensions.push(path.relative(EXTENSIONS_ROOT, mainFilePath));
+ for (const extensionsRoot of [BUILTIN_EXTENSIONS_ROOT, BUILTIN_MARKETPLACE_EXTENSIONS_ROOT]) {
+ if (await exists(extensionsRoot)) {
+ const children = await readdirWithFileTypes(extensionsRoot);
+ await Promise.all(children.map(async child => {
+ if (child.isDirectory()) {
+ const extensionPath = path.join(extensionsRoot, child.name);
+ const info = await getBuiltInExtensionInfo(extensionPath);
+ if (info) {
+ extensions.push(info);
+ locations[path.basename(extensionPath)] = extensionPath;
}
}
- packageJSON.extensionKind = ['web']; // enable for Web
-
- const packageNLSPath = path.join(folderName, 'package.nls.json');
- const packageNLSExists = await exists(path.join(EXTENSIONS_ROOT, packageNLSPath));
- if (packageNLSExists) {
- packageJSON = extensions.translatePackageJSON(packageJSON, path.join(EXTENSIONS_ROOT, packageNLSPath)); // temporary, until fixed in core
- }
- builtinExtensions.push({
- extensionPath: folderName,
- packageJSON,
- packageNLSPath: packageNLSExists ? packageNLSPath : undefined,
- readmePath,
- changelogPath
- });
- } catch (e) {
- console.log(e);
- }
+ }));
}
- }));
- if (unbuiltExensions.length) {
- fancyLog(`${ansiColors.yellow('Warning')}: Make sure to run ${ansiColors.cyan('yarn gulp watch-web')}\nCould not find the following browser main files: \n${unbuiltExensions.join('\n')}`);
}
- return builtinExtensions;
+ return { extensions, locations };
}
-const builtinExtensionsPromise = initialize();
+async function getBuiltInExtensionInfo(extensionPath) {
+ const packageJSON = await getExtensionPackageJSON(extensionPath);
+ if (!packageJSON) {
+ return undefined;
+ }
+ const builtInExtensionPath = path.basename(extensionPath);
+
+ let children = [];
+ try {
+ children = await readdir(extensionPath);
+ } catch (error) {
+ console.log(`Can not read extension folder ${extensionPath}: ${error}`);
+ return;
+ }
+ const readme = children.find(child => /^readme(\.txt|\.md|)$/i.test(child));
+ const changelog = children.find(child => /^changelog(\.txt|\.md|)$/i.test(child));
+ const packageJSONNLS = children.find(child => /^package.nls.json$/i.test(child));
+ return {
+ extensionPath: builtInExtensionPath,
+ packageJSON,
+ packageNLSPath: packageJSONNLS ? `${builtInExtensionPath}/${packageJSONNLS}` : undefined,
+ readmePath: readme ? `${builtInExtensionPath}/${readme}` : undefined,
+ changelogPath: changelog ? `${builtInExtensionPath}/${changelog}` : undefined
+ };
+}
+
+async function getDefaultExtensionInfos() {
+ const extensions = [];
+
+ /** @type {Object.} */
+ const locations = {};
+
+ let extensionArg = args['extension'];
+ if (!extensionArg) {
+ return { extensions, locations }
+ }
+
+ const extensionPaths = Array.isArray(extensionArg) ? extensionArg : [extensionArg];
+ await Promise.all(extensionPaths.map(async extensionPath => {
+ extensionPath = path.resolve(process.cwd(), extensionPath);
+ const packageJSON = await getExtensionPackageJSON(extensionPath);
+ if (packageJSON) {
+ const extensionId = `${packageJSON.publisher}.${packageJSON.name}`;
+ extensions.push({
+ packageJSON,
+ extensionLocation: { scheme: SCHEME, authority: AUTHORITY, path: `/extension/${extensionId}` }
+ });
+ locations[extensionId] = extensionPath;
+ }
+ }));
+ return { extensions, locations };
+}
+
+async function getExtensionPackageJSON(extensionPath) {
+
+ const packageJSONPath = path.join(extensionPath, 'package.json');
+ if (await exists(packageJSONPath)) {
+ try {
+ let packageJSON = JSON.parse((await readFile(packageJSONPath)).toString());
+ if (packageJSON.main && !packageJSON.browser) {
+ return; // unsupported
+ }
+
+ if (packageJSON.browser) {
+ packageJSON.main = packageJSON.browser;
+
+ let mainFilePath = path.join(extensionPath, packageJSON.browser);
+ if (path.extname(mainFilePath) !== '.js') {
+ mainFilePath += '.js';
+ }
+ if (!await exists(mainFilePath)) {
+ fancyLog(`${ansiColors.yellow('Warning')}: Could not find ${mainFilePath}. Use ${ansiColors.cyan('yarn gulp watch-web')} to build the built-in extensions.`);
+ }
+ }
+ packageJSON.extensionKind = ['web']; // enable for Web
+
+ const packageNLSPath = path.join(extensionPath, 'package.nls.json');
+ const packageNLSExists = await exists(packageNLSPath);
+ if (packageNLSExists) {
+ packageJSON = extensions.translatePackageJSON(packageJSON, packageNLSPath); // temporary, until fixed in core
+ }
+
+ return packageJSON;
+ } catch (e) {
+ console.log(e);
+ }
+ }
+ return undefined;
+}
+
+const builtInExtensionsPromise = getBuiltInExtensionInfos();
+const defaultExtensionsPromise = getDefaultExtensionInfos();
const mapCallbackUriToRequestId = new Map();
@@ -158,9 +209,13 @@ const server = http.createServer((req, res) => {
// static requests
return handleStatic(req, res, parsedUrl);
}
- if (/^\/static-extension\//.test(pathname)) {
- // static extension requests
- return handleStaticExtension(req, res, parsedUrl);
+ if (/^\/extension\//.test(pathname)) {
+ // default extension requests
+ return handleExtension(req, res, parsedUrl);
+ }
+ if (/^\/builtin-extension\//.test(pathname)) {
+ // built-in extension requests
+ return handleBuiltInExtension(req, res, parsedUrl);
}
if (pathname === '/') {
// main web
@@ -211,13 +266,28 @@ function handleStatic(req, res, parsedUrl) {
* @param {import('http').ServerResponse} res
* @param {import('url').UrlWithParsedQuery} parsedUrl
*/
-function handleStaticExtension(req, res, parsedUrl) {
-
- // Strip `/static-extension/` from the path
- const relativeFilePath = path.normalize(decodeURIComponent(parsedUrl.pathname.substr('/static-extension/'.length)));
-
- const filePath = path.join(EXTENSIONS_ROOT, relativeFilePath);
+async function handleExtension(req, res, parsedUrl) {
+ // Strip `/extension/` from the path
+ const relativePath = decodeURIComponent(parsedUrl.pathname.substr('/extension/'.length));
+ const filePath = getExtensionFilePath(relativePath, (await defaultExtensionsPromise).locations);
+ if (!filePath) {
+ return serveError(req, res, 400, `Bad request.`);
+ }
+ return serveFile(req, res, filePath);
+}
+/**
+ * @param {import('http').IncomingMessage} req
+ * @param {import('http').ServerResponse} res
+ * @param {import('url').UrlWithParsedQuery} parsedUrl
+ */
+async function handleBuiltInExtension(req, res, parsedUrl) {
+ // Strip `/builtin-extension/` from the path
+ const relativePath = decodeURIComponent(parsedUrl.pathname.substr('/builtin-extension/'.length));
+ const filePath = getExtensionFilePath(relativePath, (await builtInExtensionsPromise).locations);
+ if (!filePath) {
+ return serveError(req, res, 400, `Bad request.`);
+ }
return serveFile(req, res, filePath);
}
@@ -232,34 +302,44 @@ async function handleRoot(req, res) {
if (match) {
const qs = new URLSearchParams(match[1]);
- let ghPath = qs.get('gh');
- if (ghPath) {
- if (!ghPath.startsWith('/')) {
- ghPath = '/' + ghPath;
+ let gh = qs.get('gh');
+ if (gh) {
+ if (gh.startsWith('/')) {
+ gh = gh.substr(1);
}
- folderUri = { scheme: 'github', authority: 'HEAD', path: ghPath };
- } else {
- let csPath = qs.get('cs');
- if (csPath) {
- if (!csPath.startsWith('/')) {
- csPath = '/' + csPath;
+ const [owner, repo, ...branch] = gh.split('/', 3);
+ folderUri = { scheme: 'github', authority: branch.join('/') || 'HEAD', path: `/${owner}/${repo}` };
+ } else {
+ let cs = qs.get('cs');
+ if (cs) {
+ if (cs.startsWith('/')) {
+ cs = cs.substr(1);
}
- folderUri = { scheme: 'codespace', authority: 'HEAD', path: csPath };
+
+ const [owner, repo, ...branch] = cs.split('/');
+ folderUri = { scheme: 'codespace', authority: branch.join('/') || 'HEAD', path: `/${owner}/${repo}` };
}
}
}
- const builtinExtensions = await builtinExtensionsPromise;
+ const { extensions: builtInExtensions } = await builtInExtensionsPromise;
+ const { extensions: staticExtensions } = await defaultExtensionsPromise;
+
+ if (args.verbose) {
+ fancyLog(`${ansiColors.magenta('BuiltIn extensions')}: ${builtInExtensions.map(e => path.basename(e.extensionPath)).join(', ')}`);
+ fancyLog(`${ansiColors.magenta('Additional extensions')}: ${staticExtensions.map(e => path.basename(e.extensionLocation.path)).join(', ') || 'None'}`);
+ }
const webConfigJSON = escapeAttribute(JSON.stringify({
folderUri: folderUri,
- builtinExtensionsServiceUrl: `${SCHEME}://${AUTHORITY}/static-extension`
+ staticExtensions,
+ builtinExtensionsServiceUrl: `${SCHEME}://${AUTHORITY}/builtin-extension`
}));
- const data = (await util.promisify(fs.readFile)(WEB_MAIN)).toString()
+ const data = (await readFile(WEB_MAIN)).toString()
.replace('{{WORKBENCH_WEB_CONFIGURATION}}', () => webConfigJSON) // use a replace function to avoid that regexp replace patterns ($&, $0, ...) are applied
- .replace('{{WORKBENCH_BUILTIN_EXTENSIONS}}', () => escapeAttribute(JSON.stringify(builtinExtensions)))
+ .replace('{{WORKBENCH_BUILTIN_EXTENSIONS}}', () => escapeAttribute(JSON.stringify(builtInExtensions)))
.replace('{{WEBVIEW_ENDPOINT}}', '')
.replace('{{REMOTE_USER_DATA_URI}}', '');
@@ -368,6 +448,25 @@ function escapeAttribute(value) {
return value.replace(/"/g, '"');
}
+/**
+ * @param {string} relativePath
+ * @param {Object.} locations
+ * @returns {string | undefined}
+*/
+function getExtensionFilePath(relativePath, locations) {
+ const firstSlash = relativePath.indexOf('/');
+ if (firstSlash === -1) {
+ return undefined;
+ }
+ const extensionId = relativePath.substr(0, firstSlash);
+
+ const extensionPath = locations[extensionId];
+ if (!extensionPath) {
+ return undefined;
+ }
+ return path.join(extensionPath, relativePath.substr(firstSlash + 1));
+}
+
/**
* @param {import('http').IncomingMessage} req
* @param {import('http').ServerResponse} res
@@ -419,10 +518,6 @@ async function serveFile(req, res, filePath, responseHeaders = Object.create(nul
// Sanity checks
filePath = path.normalize(filePath); // ensure no "." and ".."
- if (filePath.indexOf(`${APP_ROOT}${path.sep}`) !== 0) {
- // invalid location outside of APP_ROOT
- return serveError(req, res, 400, `Bad request.`);
- }
const stat = await util.promisify(fs.stat)(filePath);
diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat
index 1dc84176fc..69566719f4 100755
--- a/scripts/test-integration.bat
+++ b/scripts/test-integration.bat
@@ -49,7 +49,10 @@ REM if %errorlevel% neq 0 exit /b %errorlevel%
REM call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR%
REM if %errorlevel% neq 0 exit /b %errorlevel%
-REM call "%INTEGRATION_TEST_ELECTRON_PATH%" $%~dp0\..\extensions\markdown-language-features\out\test\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\markdown-language-features --extensionTestsPath=%~dp0\..\extensions\markdown-language-features\out\test --disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% .
+REM call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\typescript-language-features\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\typescript-language-features --extensionTestsPath=%~dp0\..\extensions\typescript-language-features\out\test --disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR%
+REM if %errorlevel% neq 0 exit /b %errorlevel%
+
+REM call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\markdown-language-features\out\test\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\markdown-language-features --extensionTestsPath=%~dp0\..\extensions\markdown-language-features\out\test --disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR%
REM if %errorlevel% neq 0 exit /b %errorlevel%
REM call "%INTEGRATION_TEST_ELECTRON_PATH%" $%~dp0\..\extensions\emmet\out\test\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% .
diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh
index f92e3c44f1..f57534c448 100755
--- a/scripts/test-integration.sh
+++ b/scripts/test-integration.sh
@@ -46,8 +46,9 @@ fi
# "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
# "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
# "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/markdown-language-features/out/test/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
+# "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/typescript-language-features/test-workspace --extensionDevelopmentPath=$ROOT/extensions/typescript-language-features --extensionTestsPath=$ROOT/extensions/typescript-language-features/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
# "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/emmet/out/test/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
-"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.git --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHD
+"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.git --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/azurecore/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/azurecore --extensionTestsPath=$ROOT/extensions/azurecore/out/test --no-cached-data --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR
diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js
index 313a4f8be1..eb23b2f989 100644
--- a/src/bootstrap-window.js
+++ b/src/bootstrap-window.js
@@ -22,8 +22,6 @@
}
}(this, function () {
const path = require.__$__nodeRequire('path');
- const webFrame = require.__$__nodeRequire('electron').webFrame;
- const ipc = require.__$__nodeRequire('electron').ipcRenderer;
const bootstrap = globalThis.MonacoBootstrap;
/**
@@ -36,7 +34,6 @@
/**
* // configuration: INativeWindowConfiguration
* @type {{
- * zoomLevel?: number,
* extensionDevelopmentPath?: string[],
* extensionTestsPath?: string,
* userEnv?: { [key: string]: string | undefined },
@@ -45,12 +42,6 @@
* }} */
const configuration = JSON.parse(args['config'] || '{}') || {};
- // Apply zoom level early to avoid glitches
- const zoomLevel = configuration.zoomLevel;
- if (typeof zoomLevel === 'number' && zoomLevel !== 0) {
- webFrame.setZoomLevel(zoomLevel);
- }
-
// Error handler
process.on('uncaughtException', function (error) {
onUnexpectedError(error, enableDeveloperTools);
@@ -96,28 +87,9 @@
const loaderConfig = {
baseUrl: `${bootstrap.uriFromPath(configuration.appRoot)}/out`,
'vs/nls': nlsConfig,
- nodeModules: [/*BUILD->INSERT_NODE_MODULES*/]
+ amdModulesPattern: /^(vs|sql)\//, // {{SQL CARBON EDIT}} include sql in regex
};
- loaderConfig.nodeModules = loaderConfig.nodeModules.concat([
- '@angular/common',
- '@angular/core',
- '@angular/forms',
- '@angular/platform-browser',
- '@angular/platform-browser-dynamic',
- '@angular/router',
- 'rxjs/Observable',
- 'rxjs/add/observable/fromPromise',
- 'rxjs/Subject',
- 'rxjs/Observer',
- 'slickgrid/lib/jquery.event.drag-2.3.0',
- 'slickgrid/lib/jquery-ui-1.9.2',
- 'slickgrid/slick.core',
- 'slickgrid/slick.grid',
- 'slickgrid/slick.editors',
- 'slickgrid/slick.dataview'
- ]);
-
// cached data config
if (configuration.nodeCachedDataDir) {
loaderConfig.nodeCachedData = {
@@ -178,6 +150,8 @@
* @returns {() => void}
*/
function registerDeveloperKeybindings(disallowReloadKeybinding) {
+ const ipcRenderer = globals().ipcRenderer;
+
const extractKey = function (e) {
return [
e.ctrlKey ? 'ctrl-' : '',
@@ -196,9 +170,9 @@
let listener = function (e) {
const key = extractKey(e);
if (key === TOGGLE_DEV_TOOLS_KB || key === TOGGLE_DEV_TOOLS_KB_ALT) {
- ipc.send('vscode:toggleDevTools');
+ ipcRenderer.send('vscode:toggleDevTools');
} else if (key === RELOAD_KB && !disallowReloadKeybinding) {
- ipc.send('vscode:reloadWindow');
+ ipcRenderer.send('vscode:reloadWindow');
}
};
@@ -218,7 +192,8 @@
*/
function onUnexpectedError(error, enableDeveloperTools) {
if (enableDeveloperTools) {
- ipc.send('vscode:openDevTools');
+ const ipcRenderer = globals().ipcRenderer;
+ ipcRenderer.send('vscode:openDevTools');
}
console.error(`[uncaught exception]: ${error}`);
@@ -228,7 +203,16 @@
}
}
+ /**
+ * @return {typeof import('./vs/base/parts/sandbox/electron-sandbox/globals')}
+ */
+ function globals() {
+ // @ts-ignore (defined in globals.js)
+ return window.vscode;
+ }
+
return {
- load
+ load,
+ globals
};
}));
diff --git a/src/main.js b/src/main.js
index f6f59aceb0..183f9e072c 100644
--- a/src/main.js
+++ b/src/main.js
@@ -206,6 +206,8 @@ function configureCommandlineSwitchesSync(cliArgs) {
];
if (process.platform === 'linux') {
+
+ // Force enable screen readers on Linux via this flag
SUPPORTED_ELECTRON_SWITCHES.push('force-renderer-accessibility');
}
@@ -223,6 +225,7 @@ function configureCommandlineSwitchesSync(cliArgs) {
// Append Electron flags to Electron
if (SUPPORTED_ELECTRON_SWITCHES.indexOf(argvKey) !== -1) {
+
// Color profile
if (argvKey === 'force-color-profile') {
if (argvValue) {
diff --git a/src/sql/base/browser/ui/panel/panel.ts b/src/sql/base/browser/ui/panel/panel.ts
index b9ba9a6ab4..64ac8d94d5 100644
--- a/src/sql/base/browser/ui/panel/panel.ts
+++ b/src/sql/base/browser/ui/panel/panel.ts
@@ -14,7 +14,6 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { isUndefinedOrNull } from 'vs/base/common/types';
-import * as map from 'vs/base/common/map';
import { firstIndex } from 'vs/base/common/arrays';
export interface ITabbedPanelStyles {
@@ -285,7 +284,7 @@ export class TabbedPanel extends Disposable {
}
}
if (!this._shownTabId && this._tabMap.size > 0) {
- this.showTab(map.values(this._tabMap)[0].tab.identifier);
+ this.showTab(this._tabMap.values().next().value.tab.identifier);
}
}
diff --git a/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts b/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts
index 25f9237179..6384b6454a 100644
--- a/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts
+++ b/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts
@@ -31,7 +31,7 @@ import { TestCapabilitiesService } from 'sql/platform/capabilities/test/common/t
import { UNSAVED_GROUP_ID, mssqlProviderName } from 'sql/platform/connection/common/constants';
import { $ } from 'vs/base/browser/dom';
import { OEManageConnectionAction } from 'sql/workbench/contrib/dashboard/browser/dashboardActions';
-import { IViewsService, IView, ViewContainerLocation, ViewContainer } from 'vs/workbench/common/views';
+import { IViewsService, IView, ViewContainerLocation, ViewContainer, IViewPaneContainer } from 'vs/workbench/common/views';
import { ConsoleLogService } from 'vs/platform/log/common/log';
import { IProgressIndicator } from 'vs/platform/progress/common/progress';
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
@@ -111,6 +111,9 @@ suite('SQL Connection Tree Action tests', () => {
});
const viewsService = new class implements IViewsService {
+ getActiveViewPaneContainerWithId(viewContainerId: string): IViewPaneContainer {
+ throw new Error('Method not implemented.');
+ }
getViewProgressIndicator(id: string): IProgressIndicator {
throw new Error('Method not implemented.');
}
diff --git a/src/sql/workbench/services/accountManagement/browser/accountDialog.ts b/src/sql/workbench/services/accountManagement/browser/accountDialog.ts
index d99ecd278c..07ddf10d70 100644
--- a/src/sql/workbench/services/accountManagement/browser/accountDialog.ts
+++ b/src/sql/workbench/services/accountManagement/browser/accountDialog.ts
@@ -18,7 +18,6 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { SplitView, Sizing } from 'vs/base/browser/ui/splitview/splitview';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { values } from 'vs/base/common/map';
import * as azdata from 'azdata';
@@ -44,6 +43,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
+import { Iterable } from 'vs/base/common/iterator';
export const VIEWLET_ID = 'workbench.view.accountpanel';
@@ -219,7 +219,7 @@ export class AccountDialog extends Modal {
this._addAccountButton.label = localize('accountDialog.addConnection', "Add an account");
this._register(this._addAccountButton.onDidClick(async () => {
- const vals = values(this._providerViewsMap);
+ const vals = Iterable.consume(this._providerViewsMap.values())[0];
let pickedValue: string;
if (vals.length === 0) {
@@ -291,8 +291,8 @@ export class AccountDialog extends Modal {
private showSplitView() {
this._splitViewContainer.hidden = false;
this._noaccountViewContainer.hidden = true;
- if (values(this._providerViewsMap).length > 0) {
- const firstView = values(this._providerViewsMap)[0];
+ if (Iterable.consume(this._providerViewsMap.values()).length > 0) {
+ const firstView = this._providerViewsMap.values().next().value;
if (firstView instanceof AccountPanel) {
firstView.setSelection([0]);
firstView.focus();
@@ -301,7 +301,7 @@ export class AccountDialog extends Modal {
}
private isEmptyLinkedAccount(): boolean {
- for (const provider of values(this._providerViewsMap)) {
+ for (const provider of this._providerViewsMap.values()) {
const listView = provider.view;
if (listView && listView.length > 0) {
return false;
@@ -312,7 +312,7 @@ export class AccountDialog extends Modal {
public dispose(): void {
super.dispose();
- for (const provider of values(this._providerViewsMap)) {
+ for (const provider of this._providerViewsMap.values()) {
if (provider.addAccountAction) {
provider.addAccountAction.dispose();
}
diff --git a/src/sql/workbench/services/bootstrap/browser/bootstrapService.ts b/src/sql/workbench/services/bootstrap/browser/bootstrapService.ts
index 4b0b57038b..64248c51e5 100644
--- a/src/sql/workbench/services/bootstrap/browser/bootstrapService.ts
+++ b/src/sql/workbench/services/bootstrap/browser/bootstrapService.ts
@@ -8,7 +8,6 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { IInstantiationService, _util, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IEditorInput } from 'vs/workbench/common/editor';
import { Trace } from 'vs/platform/instantiation/common/instantiationService';
-import { values } from 'vs/base/common/map';
import { IModuleFactory, IBootstrapParams } from 'sql/workbench/services/bootstrap/common/bootstrapParams';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
@@ -16,7 +15,7 @@ import { ILogService } from 'vs/platform/log/common/log';
const selectorCounter = new Map();
export function providerIterator(service: IInstantiationService): Provider[] {
- return Array.from(values(_util.serviceIds)).map(v => {
+ return Array.from(_util.serviceIds.values()).map(v => {
let factory = () => {
return (service)._getOrCreateServiceInstance(v, Trace.traceCreation(v));
};
diff --git a/src/sql/workbench/services/notebook/browser/models/notebookModel.ts b/src/sql/workbench/services/notebook/browser/models/notebookModel.ts
index 58f678dc2a..fd30ac1e87 100644
--- a/src/sql/workbench/services/notebook/browser/models/notebookModel.ts
+++ b/src/sql/workbench/services/notebook/browser/models/notebookModel.ts
@@ -22,7 +22,6 @@ import { URI } from 'vs/base/common/uri';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { uriPrefixes } from 'sql/platform/connection/common/utils';
-import { keys } from 'vs/base/common/map';
import { ILogService } from 'vs/platform/log/common/log';
import { getErrorMessage } from 'vs/base/common/errors';
import { find, firstIndex } from 'vs/base/common/arrays';
@@ -213,7 +212,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
}
public standardKernelsDisplayName(): string[] {
- return Array.from(keys(this._kernelDisplayNameToNotebookProviderIds));
+ return Array.from(this._kernelDisplayNameToNotebookProviderIds.keys());
}
public get inErrorState(): boolean {
diff --git a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts
index fc2a570171..8264b27a9a 100644
--- a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts
+++ b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts
@@ -27,7 +27,6 @@ import { IQueryManagementService } from 'sql/workbench/services/query/common/que
import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { SqlNotebookProvider } from 'sql/workbench/services/notebook/browser/sql/sqlNotebookProvider';
-import { keys } from 'vs/base/common/map';
import { IFileService, IFileStatWithMetadata } from 'vs/platform/files/common/files';
import { Schemas } from 'vs/base/common/network';
import { ILogService } from 'vs/platform/log/common/log';
@@ -269,7 +268,7 @@ export class NotebookService extends Disposable implements INotebookService {
}
getSupportedFileExtensions(): string[] {
- return Array.from(keys(this._fileToProviders));
+ return Array.from(this._fileToProviders.keys());
}
getProvidersForFileType(fileType: string): string[] {
diff --git a/src/sql/workbench/services/query/common/gridDataProvider.ts b/src/sql/workbench/services/query/common/gridDataProvider.ts
index 8dda4b49a1..8984e48a23 100644
--- a/src/sql/workbench/services/query/common/gridDataProvider.ts
+++ b/src/sql/workbench/services/query/common/gridDataProvider.ts
@@ -102,7 +102,7 @@ export async function getResultsString(provider: IGridDataProvider, selection: S
let copyString = '';
if (includeHeaders) {
- copyString = [...headers.values()].join('\t').concat(eol);
+ copyString = Array.from(headers.values()).join('\t').concat(eol);
}
const rowKeys = [...headers.keys()];
diff --git a/src/sql/workbench/services/query/common/queryManagement.ts b/src/sql/workbench/services/query/common/queryManagement.ts
index 1a25b5d687..2d12ca42ab 100644
--- a/src/sql/workbench/services/query/common/queryManagement.ts
+++ b/src/sql/workbench/services/query/common/queryManagement.ts
@@ -10,7 +10,6 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import * as azdata from 'azdata';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { Event, Emitter } from 'vs/base/common/event';
-import { keys } from 'vs/base/common/map';
import { assign } from 'vs/base/common/objects';
import { IAdsTelemetryService, ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
import EditQueryRunner from 'sql/workbench/services/editData/common/editQueryRunner';
@@ -175,7 +174,7 @@ export class QueryManagementService implements IQueryManagementService {
}
public getRegisteredProviders(): string[] {
- return Array.from(keys(this._requestHandlers));
+ return Array.from(this._requestHandlers.keys());
}
private addTelemetry(eventName: string, ownerUri: string, runOptions?: ExecutionPlanOptions): void {
diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts
index c3909d78ac..7a7093aca6 100644
--- a/src/vs/base/browser/markdownRenderer.ts
+++ b/src/vs/base/browser/markdownRenderer.ts
@@ -221,10 +221,13 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
allowedSchemes.push(Schemas.command);
}
+ // values that are too long will freeze the UI
+ let value = markdown.value ?? '';
+ if (value.length > 100_000) {
+ value = `${value.substr(0, 100_000)}âŚ`;
+ }
const renderedMarkdown = marked.parse(
- markdown.supportThemeIcons
- ? markdownEscapeEscapedCodicons(markdown.value || '')
- : (markdown.value || ''),
+ markdown.supportThemeIcons ? markdownEscapeEscapedCodicons(value) : value,
markedOptions
);
diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts
index 98cca67642..73752865a0 100644
--- a/src/vs/base/browser/ui/actionbar/actionbar.ts
+++ b/src/vs/base/browser/ui/actionbar/actionbar.ts
@@ -406,6 +406,7 @@ export interface IActionBarOptions {
animated?: boolean;
triggerKeys?: ActionTrigger;
allowContextMenu?: boolean;
+ preventLoopNavigation?: boolean;
}
const defaultOptions: IActionBarOptions = {
@@ -509,9 +510,9 @@ export class ActionBar extends Disposable implements IActionRunner {
let eventHandled = true;
if (event.equals(previousKey)) {
- this.focusPrevious();
+ eventHandled = this.focusPrevious();
} else if (event.equals(nextKey)) {
- this.focusNext();
+ eventHandled = this.focusNext();
} else if (event.equals(KeyCode.Escape)) {
this._onDidCancel.fire();
} else if (this.isTriggerKeyEvent(event)) {
@@ -724,7 +725,7 @@ export class ActionBar extends Disposable implements IActionRunner {
if (selectFirst && typeof this.focusedItem === 'undefined') {
// Focus the first enabled item
- this.focusedItem = this.viewItems.length - 1;
+ this.focusedItem = -1;
this.focusNext();
} else {
if (index !== undefined) {
@@ -735,7 +736,7 @@ export class ActionBar extends Disposable implements IActionRunner {
}
}
- protected focusNext(): void {
+ protected focusNext(): boolean {
if (typeof this.focusedItem === 'undefined') {
this.focusedItem = this.viewItems.length - 1;
}
@@ -744,6 +745,11 @@ export class ActionBar extends Disposable implements IActionRunner {
let item: IActionViewItem;
do {
+ if (this.options.preventLoopNavigation && this.focusedItem + 1 >= this.viewItems.length) {
+ this.focusedItem = startIndex;
+ return false;
+ }
+
this.focusedItem = (this.focusedItem + 1) % this.viewItems.length;
item = this.viewItems[this.focusedItem];
} while (this.focusedItem !== startIndex && !item.isEnabled());
@@ -753,9 +759,10 @@ export class ActionBar extends Disposable implements IActionRunner {
}
this.updateFocus();
+ return true;
}
- protected focusPrevious(): void {
+ protected focusPrevious(): boolean {
if (typeof this.focusedItem === 'undefined') {
this.focusedItem = 0;
}
@@ -767,6 +774,11 @@ export class ActionBar extends Disposable implements IActionRunner {
this.focusedItem = this.focusedItem - 1;
if (this.focusedItem < 0) {
+ if (this.options.preventLoopNavigation) {
+ this.focusedItem = startIndex;
+ return false;
+ }
+
this.focusedItem = this.viewItems.length - 1;
}
@@ -778,6 +790,7 @@ export class ActionBar extends Disposable implements IActionRunner {
}
this.updateFocus(true);
+ return true;
}
protected updateFocus(fromRight?: boolean, preventScroll?: boolean): void {
diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf
index 691a9c3798..575a779d5d 100644
Binary files a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf and b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf differ
diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts
index f1f6e9c6ac..b09b736630 100644
--- a/src/vs/base/browser/ui/contextview/contextview.ts
+++ b/src/vs/base/browser/ui/contextview/contextview.ts
@@ -162,6 +162,7 @@ export class ContextView extends Disposable {
this.view.className = 'context-view';
this.view.style.top = '0px';
this.view.style.left = '0px';
+ this.view.style.position = this.useFixedPosition ? 'fixed' : 'absolute';
DOM.show(this.view);
// Render content
diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts
index f30baff33a..27cc471d62 100644
--- a/src/vs/base/browser/ui/inputbox/inputBox.ts
+++ b/src/vs/base/browser/ui/inputbox/inputBox.ts
@@ -175,8 +175,8 @@ export class InputBox extends Widget {
this.input.setAttribute('autocapitalize', 'off');
this.input.setAttribute('spellcheck', 'false');
- this.onfocus(this.input, () => dom.addClass(this.element, 'synthetic-focus'));
- this.onblur(this.input, () => dom.removeClass(this.element, 'synthetic-focus'));
+ this.onfocus(this.input, () => this.element.classList.add('synthetic-focus'));
+ this.onblur(this.input, () => this.element.classList.remove('synthetic-focus'));
if (this.options.flexibleHeight) {
this.maxHeight = typeof this.options.flexibleMaxHeight === 'number' ? this.options.flexibleMaxHeight : Number.POSITIVE_INFINITY;
@@ -392,11 +392,11 @@ export class InputBox extends Widget {
public showMessage(message: IMessage, force?: boolean): void {
this.message = message;
- dom.removeClass(this.element, 'idle');
- dom.removeClass(this.element, 'info');
- dom.removeClass(this.element, 'warning');
- dom.removeClass(this.element, 'error');
- dom.addClass(this.element, this.classForType(message.type));
+ this.element.classList.remove('idle');
+ this.element.classList.remove('info');
+ this.element.classList.remove('warning');
+ this.element.classList.remove('error');
+ this.element.classList.add(this.classForType(message.type));
const styles = this.stylesForType(this.message.type);
this.element.style.border = styles.border ? `1px solid ${styles.border}` : '';
@@ -409,10 +409,10 @@ export class InputBox extends Widget {
public hideMessage(): void {
this.message = null;
- dom.removeClass(this.element, 'info');
- dom.removeClass(this.element, 'warning');
- dom.removeClass(this.element, 'error');
- dom.addClass(this.element, 'idle');
+ this.element.classList.remove('info');
+ this.element.classList.remove('warning');
+ this.element.classList.remove('error');
+ this.element.classList.add('idle');
this._hideMessage();
this.applyStyles();
@@ -494,7 +494,7 @@ export class InputBox extends Widget {
const spanElement = (this.message.formatContent
? renderFormattedText(this.message.content, renderOptions)
: renderText(this.message.content, renderOptions));
- dom.addClass(spanElement, this.classForType(this.message.type));
+ spanElement.classList.add(this.classForType(this.message.type));
const styles = this.stylesForType(this.message.type);
spanElement.style.backgroundColor = styles.background ? styles.background.toString() : '';
@@ -543,7 +543,7 @@ export class InputBox extends Widget {
this.validate();
this.updateMirror();
- dom.toggleClass(this.input, 'empty', !this.value);
+ this.input.classList.toggle('empty', !this.value);
if (this.state === 'open' && this.contextViewProvider) {
this.contextViewProvider.layout();
diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts
index 7941364db9..c2bdc3ba11 100644
--- a/src/vs/base/browser/ui/list/listView.ts
+++ b/src/vs/base/browser/ui/list/listView.ts
@@ -411,7 +411,6 @@ export class ListView implements ISpliceable, IDisposable {
if (this.supportDynamicHeights) {
this._rerender(this.lastRenderTop, this.lastRenderHeight);
}
- return;
}
splice(start: number, deleteCount: number, elements: T[] = []): T[] {
@@ -790,8 +789,8 @@ export class ListView implements ISpliceable, IDisposable {
item.dragStartDisposable.dispose();
const renderer = this.renderers.get(item.templateId);
- if (renderer && renderer.disposeElement) {
- renderer.disposeElement(item.element, index, item.row!.templateData, item.size);
+ if (item.row && renderer && renderer.disposeElement) {
+ renderer.disposeElement(item.element, index, item.row.templateData, item.size);
}
this.cache.release(item.row!);
diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts
index b123935448..1374280514 100644
--- a/src/vs/base/browser/ui/list/listWidget.ts
+++ b/src/vs/base/browser/ui/list/listWidget.ts
@@ -854,6 +854,7 @@ export interface IListOptions {
readonly horizontalScrolling?: boolean;
readonly additionalScrollHeight?: number;
readonly transformOptimization?: boolean;
+ readonly smoothScrolling?: boolean;
}
export interface IListStyles {
diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts
index fcf6e34aab..aa54df4c43 100644
--- a/src/vs/base/browser/ui/menu/menu.ts
+++ b/src/vs/base/browser/ui/menu/menu.ts
@@ -395,10 +395,9 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
}
this._register(addDisposableListener(this.element, EventType.MOUSE_UP, e => {
- if (e.defaultPrevented) {
- return;
- }
-
+ // removed default prevention as it conflicts
+ // with BaseActionViewItem #101537
+ // add back if issues arise and link new issue
EventHelper.stop(e, true);
this.onClick(e);
}));
diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts
index b02c483889..bf14a48e8c 100644
--- a/src/vs/base/browser/ui/menu/menubar.ts
+++ b/src/vs/base/browser/ui/menu/menubar.ts
@@ -326,7 +326,15 @@ export class MenuBar extends Disposable {
let event = new StandardKeyboardEvent(e as KeyboardEvent);
let eventHandled = true;
- if ((event.equals(KeyCode.DownArrow) || event.equals(KeyCode.Enter) || (this.options.compactMode !== undefined && event.equals(KeyCode.Space))) && !this.isOpen) {
+ const triggerKeys = [KeyCode.Enter];
+ if (this.options.compactMode === undefined) {
+ triggerKeys.push(KeyCode.DownArrow);
+ } else {
+ triggerKeys.push(KeyCode.Space);
+ triggerKeys.push(this.options.compactMode === Direction.Right ? KeyCode.RightArrow : KeyCode.LeftArrow);
+ }
+
+ if ((triggerKeys.some(k => event.equals(k)) && !this.isOpen)) {
this.focusedMenu = { index: MenuBar.OVERFLOW_INDEX };
this.openedViaKeyboard = true;
this.focusState = MenubarState.OPEN;
diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts
index 88caef66f0..520db591f4 100644
--- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts
+++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts
@@ -17,6 +17,7 @@ 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';
+import { getZoomFactor } from 'vs/base/browser/browser';
const HIDE_TIMEOUT = 500;
const SCROLL_WHEEL_SENSITIVITY = 50;
@@ -130,13 +131,18 @@ export class MouseWheelClassifier {
// }
}
- if (Math.abs(item.deltaX - Math.round(item.deltaX)) > 0 || Math.abs(item.deltaY - Math.round(item.deltaY)) > 0) {
+ if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {
// non-integer deltas => indicator that this is not a physical mouse wheel
score += 0.25;
}
return Math.min(Math.max(score, 0), 1);
}
+
+ private _isAlmostInt(value: number): boolean {
+ const delta = Math.abs(Math.round(value) - value);
+ return (delta < 0.01);
+ }
}
export abstract class AbstractScrollableElement extends Widget {
@@ -343,10 +349,11 @@ export abstract class AbstractScrollableElement extends Widget {
const classifier = MouseWheelClassifier.INSTANCE;
if (SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED) {
- if (platform.isWindows) {
- // On Windows, the incoming delta events are multiplied with the device pixel ratio,
- // so to get a better classification, simply undo that.
- classifier.accept(Date.now(), e.deltaX / window.devicePixelRatio, e.deltaY / window.devicePixelRatio);
+ const osZoomFactor = window.devicePixelRatio / getZoomFactor();
+ if (platform.isWindows || platform.isLinux) {
+ // On Windows and Linux, the incoming delta events are multiplied with the OS zoom factor.
+ // The OS zoom factor can be reverse engineered by using the device pixel ratio and the configured zoom factor into account.
+ classifier.accept(Date.now(), e.deltaX / osZoomFactor, e.deltaY / osZoomFactor);
} else {
classifier.accept(Date.now(), e.deltaX, e.deltaY);
}
diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts
index 13b707c2fd..d46b93ff42 100644
--- a/src/vs/base/browser/ui/tree/abstractTree.ts
+++ b/src/vs/base/browser/ui/tree/abstractTree.ts
@@ -951,6 +951,7 @@ export interface IAbstractTreeOptionsUpdate extends ITreeRendererOptions {
readonly filterOnType?: boolean;
readonly smoothScrolling?: boolean;
readonly horizontalScrolling?: boolean;
+ readonly expandOnlyOnDoubleClick?: boolean;
}
export interface IAbstractTreeOptions extends IAbstractTreeOptionsUpdate, IListOptions {
@@ -1094,7 +1095,10 @@ class TreeNodeListMouseController extends MouseController<
return super.onViewPointer(e);
}
- const onTwistie = hasClass(e.browserEvent.target as HTMLElement, 'monaco-tl-twistie');
+ const target = e.browserEvent.target as HTMLElement;
+ const onTwistie = hasClass(target, 'monaco-tl-twistie')
+ || (hasClass(target, 'monaco-icon-label') && hasClass(target, 'folder-icon') && e.browserEvent.offsetX < 16);
+
let expandOnlyOnTwistieClick = false;
if (typeof this.tree.expandOnlyOnTwistieClick === 'function') {
@@ -1107,6 +1111,10 @@ class TreeNodeListMouseController extends MouseController<
return super.onViewPointer(e);
}
+ if (this.tree.expandOnlyOnDoubleClick && e.browserEvent.detail !== 2 && !onTwistie) {
+ return super.onViewPointer(e);
+ }
+
if (node.collapsible) {
const model = ((this.tree as any).model as ITreeModel); // internal
const location = model.getNodeLocation(node);
@@ -1244,6 +1252,7 @@ export abstract class AbstractTree implements IDisposable
get filterOnType(): boolean { return !!this._options.filterOnType; }
get onDidChangeTypeFilterPattern(): Event { return this.typeFilterController ? this.typeFilterController.onDidChangePattern : Event.None; }
+ get expandOnlyOnDoubleClick(): boolean { return this._options.expandOnlyOnDoubleClick ?? false; }
get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { return typeof this._options.expandOnlyOnTwistieClick === 'undefined' ? false : this._options.expandOnlyOnTwistieClick; }
private readonly _onDidUpdateOptions = new Emitter>();
diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts
index 9a7e2d4762..772bd0b824 100644
--- a/src/vs/base/common/arrays.ts
+++ b/src/vs/base/common/arrays.ts
@@ -591,6 +591,14 @@ export function asArray(x: T | T[]): T[] {
return Array.isArray(x) ? x : [x];
}
+export function toArray(iterable: IterableIterator): T[] {
+ const result: T[] = [];
+ for (let element of iterable) {
+ result.push(element);
+ }
+ return result;
+}
+
export function getRandomElement(arr: T[]): T | undefined {
return arr[Math.floor(Math.random() * arr.length)];
}
diff --git a/src/vs/base/common/codicons.ts b/src/vs/base/common/codicons.ts
index af7c151f0c..496875b922 100644
--- a/src/vs/base/common/codicons.ts
+++ b/src/vs/base/common/codicons.ts
@@ -52,6 +52,8 @@ export class Codicon {
_registry.add(this);
}
public get classNames() { return 'codicon codicon-' + this.id; }
+ // classNamesArray is useful for migrating to ES6 classlist
+ public get classNamesArray() { return ['codicon', 'codicon-' + this.id]; }
public get cssSelector() { return '.codicon.codicon-' + this.id; }
}
@@ -472,6 +474,8 @@ export namespace Codicon {
export const stopCircle = new Codicon('stop-circle', { character: '\\eba5' });
export const playCircle = new Codicon('play-circle', { character: '\\eba6' });
export const record = new Codicon('record', { character: '\\eba7' });
+ export const debugAltSmall = new Codicon('debug-alt-small', { character: '\\eba8' });
+ export const vmConnect = new Codicon('vm-connect', { character: '\\eba9' });
}
diff --git a/src/vs/base/common/errors.ts b/src/vs/base/common/errors.ts
index 792526cdec..ba5434f2c1 100644
--- a/src/vs/base/common/errors.ts
+++ b/src/vs/base/common/errors.ts
@@ -203,3 +203,12 @@ export class NotImplementedError extends Error {
}
}
}
+
+export class NotSupportedError extends Error {
+ constructor(message?: string) {
+ super('NotSupported');
+ if (message) {
+ this.message = message;
+ }
+ }
+}
diff --git a/src/vs/base/common/fuzzyScorer.ts b/src/vs/base/common/fuzzyScorer.ts
index d2c8abd615..a0b41f5901 100644
--- a/src/vs/base/common/fuzzyScorer.ts
+++ b/src/vs/base/common/fuzzyScorer.ts
@@ -42,8 +42,7 @@ export function scoreFuzzy(target: string, query: string, queryLower: string, fu
// When not searching fuzzy, we require the query to be contained fully
// in the target string contiguously.
if (!fuzzy) {
- const indexOfQueryInTarget = targetLower.indexOf(queryLower);
- if (indexOfQueryInTarget === -1) {
+ if (!targetLower.includes(queryLower)) {
// if (DEBUG) {
// console.log(`Characters not matching consecutively ${queryLower} within ${targetLower}`);
// }
diff --git a/src/vs/base/common/htmlContent.ts b/src/vs/base/common/htmlContent.ts
index b479cd4fb3..5bc4fc6bf4 100644
--- a/src/vs/base/common/htmlContent.ts
+++ b/src/vs/base/common/htmlContent.ts
@@ -6,6 +6,7 @@
import { equals } from 'vs/base/common/arrays';
import { UriComponents } from 'vs/base/common/uri';
import { escapeCodicons } from 'vs/base/common/codicons';
+import { illegalArgument } from 'vs/base/common/errors';
export interface IMarkdownString {
readonly value: string;
@@ -22,6 +23,10 @@ export class MarkdownString implements IMarkdownString {
private _value: string = '',
isTrustedOrOptions: boolean | { isTrusted?: boolean, supportThemeIcons?: boolean } = false,
) {
+ if (typeof this._value !== 'string') {
+ throw illegalArgument('value');
+ }
+
if (typeof isTrustedOrOptions === 'boolean') {
this._isTrusted = isTrustedOrOptions;
this._supportThemeIcons = false;
@@ -30,7 +35,6 @@ export class MarkdownString implements IMarkdownString {
this._isTrusted = isTrustedOrOptions.isTrusted ?? false;
this._supportThemeIcons = isTrustedOrOptions.supportThemeIcons ?? false;
}
-
}
get value() { return this._value; }
diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts
index 328cfffe57..80ecca6cd4 100644
--- a/src/vs/base/common/map.ts
+++ b/src/vs/base/common/map.ts
@@ -9,27 +9,6 @@ import { compareSubstringIgnoreCase, compare, compareSubstring } from 'vs/base/c
import { Schemas } from 'vs/base/common/network';
import { isLinux } from 'vs/base/common/platform';
-/**
- * @deprecated ES6: use `[...SetOrMap.values()]`
- */
-export function values(set: Set): V[];
-export function values(map: Map): V[];
-export function values(forEachable: { forEach(callback: (value: V, ...more: any[]) => any): void }): V[] {
- const result: V[] = [];
- forEachable.forEach(value => result.push(value));
- return result;
-}
-
-/**
- * @deprecated ES6: use `[...map.keys()]`
- */
-export function keys(map: Map): K[] {
- const result: K[] = [];
- map.forEach((_value, key) => result.push(key));
-
- return result;
-}
-
export function getOrSet(map: Map, key: K, value: V): V {
let result = map.get(key);
if (result === undefined) {
diff --git a/src/vs/base/common/mime.ts b/src/vs/base/common/mime.ts
index 03f3019ac9..54df373e1c 100644
--- a/src/vs/base/common/mime.ts
+++ b/src/vs/base/common/mime.ts
@@ -5,7 +5,6 @@
import { basename, posix, extname } from 'vs/base/common/path';
import { startsWithUTF8BOM } from 'vs/base/common/strings';
-import { coalesce } from 'vs/base/common/arrays';
import { match } from 'vs/base/common/glob';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
@@ -247,34 +246,6 @@ export function isUnspecific(mime: string[] | string): boolean {
return mime.length === 1 && isUnspecific(mime[0]);
}
-/**
- * Returns a suggestion for the filename by the following logic:
- * 1. If a relevant extension exists and is an actual filename extension (starting with a dot), suggest the prefix appended by the first one.
- * 2. Otherwise, if there are other extensions, suggest the first one.
- * 3. Otherwise, suggest the prefix.
- */
-export function suggestFilename(mode: string | undefined, prefix: string): string {
- const extensions = registeredAssociations
- .filter(assoc => !assoc.userConfigured && assoc.extension && assoc.id === mode)
- .map(assoc => assoc.extension);
-
- const extensionsWithDotFirst = coalesce(extensions)
- .filter(assoc => assoc.startsWith('.'));
-
- if (extensionsWithDotFirst.length > 0) {
- const candidateExtension = extensionsWithDotFirst[0];
- if (prefix.endsWith(candidateExtension)) {
- // do not add the prefix if it already exists
- // https://github.com/microsoft/vscode/issues/83603
- return prefix;
- }
-
- return prefix + candidateExtension;
- }
-
- return extensions[0] || prefix;
-}
-
interface MapExtToMediaMimes {
[index: string]: string;
}
diff --git a/src/vs/base/common/performance.js b/src/vs/base/common/performance.js
index c3891415b0..e1387b65d5 100644
--- a/src/vs/base/common/performance.js
+++ b/src/vs/base/common/performance.js
@@ -9,22 +9,22 @@
function _factory(sharedObj) {
- sharedObj._performanceEntries = sharedObj._performanceEntries || [];
+ sharedObj.MonacoPerformanceMarks = sharedObj.MonacoPerformanceMarks || [];
const _dataLen = 2;
const _timeStamp = typeof console.timeStamp === 'function' ? console.timeStamp.bind(console) : () => { };
function importEntries(entries) {
- sharedObj._performanceEntries.splice(0, 0, ...entries);
+ sharedObj.MonacoPerformanceMarks.splice(0, 0, ...entries);
}
function exportEntries() {
- return sharedObj._performanceEntries.slice(0);
+ return sharedObj.MonacoPerformanceMarks.slice(0);
}
function getEntries() {
const result = [];
- const entries = sharedObj._performanceEntries;
+ const entries = sharedObj.MonacoPerformanceMarks;
for (let i = 0; i < entries.length; i += _dataLen) {
result.push({
name: entries[i],
@@ -35,7 +35,7 @@ function _factory(sharedObj) {
}
function getDuration(from, to) {
- const entries = sharedObj._performanceEntries;
+ const entries = sharedObj.MonacoPerformanceMarks;
let target = to;
let endIndex = 0;
for (let i = entries.length - _dataLen; i >= 0; i -= _dataLen) {
@@ -54,7 +54,7 @@ function _factory(sharedObj) {
}
function mark(name) {
- sharedObj._performanceEntries.push(name, Date.now());
+ sharedObj.MonacoPerformanceMarks.push(name, Date.now());
_timeStamp(name);
}
@@ -73,7 +73,8 @@ function _factory(sharedObj) {
// Because we want both instances to use the same perf-data
// we store them globally
-let sharedObj;
+// eslint-disable-next-line no-var
+var sharedObj;
if (typeof global === 'object') {
// nodejs
sharedObj = global;
@@ -91,5 +92,5 @@ if (typeof define === 'function') {
// commonjs
module.exports = _factory(sharedObj);
} else {
- // invalid context...
+ sharedObj.perf = _factory(sharedObj);
}
diff --git a/src/vs/base/common/stream.ts b/src/vs/base/common/stream.ts
index 331abf973a..d9a90ef5d9 100644
--- a/src/vs/base/common/stream.ts
+++ b/src/vs/base/common/stream.ts
@@ -474,7 +474,7 @@ export function peekReadable(readable: Readable, reducer: IReducer, max
/**
* Helper to fully read a T stream into a T.
*/
-export function consumeStream(stream: ReadableStream, reducer: IReducer): Promise {
+export function consumeStream(stream: ReadableStreamEvents, reducer: IReducer): Promise {
return new Promise((resolve, reject) => {
const chunks: T[] = [];
diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts
index 9d6681764e..acd21d9eea 100644
--- a/src/vs/base/common/types.ts
+++ b/src/vs/base/common/types.ts
@@ -8,7 +8,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
/**
* @returns whether the provided parameter is a JavaScript Array or not.
*/
-export function isArray(array: any): array is any[] {
+export function isArray(array: T | {}): array is T extends readonly any[] ? (unknown extends T ? never : readonly any[]) : any[] {
return Array.isArray(array);
}
@@ -171,7 +171,7 @@ export function validateConstraint(arg: any, constraint: TypeConstraint | undefi
if (arg instanceof constraint) {
return;
}
- } catch{
+ } catch {
// ignore
}
if (!isUndefinedOrNull(arg) && arg.constructor === constraint) {
diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts
index 447e47d9ac..3a04006795 100644
--- a/src/vs/base/common/uri.ts
+++ b/src/vs/base/common/uri.ts
@@ -252,7 +252,7 @@ export class URI implements UriComponents {
return this;
}
- return new _URI(scheme, authority, path, query, fragment);
+ return new CachingURI(scheme, authority, path, query, fragment);
}
// ---- parse & validate ------------------------
@@ -266,9 +266,9 @@ export class URI implements UriComponents {
static parse(value: string, _strict: boolean = false): URI {
const match = _regexp.exec(value);
if (!match) {
- return new _URI(_empty, _empty, _empty, _empty, _empty);
+ return new CachingURI(_empty, _empty, _empty, _empty, _empty);
}
- return new _URI(
+ return new CachingURI(
match[2] || _empty,
percentDecode(match[4] || _empty),
percentDecode(match[5] || _empty),
@@ -323,11 +323,11 @@ export class URI implements UriComponents {
}
}
- return new _URI('file', authority, path, _empty, _empty);
+ return new CachingURI('file', authority, path, _empty, _empty);
}
static from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string }): URI {
- return new _URI(
+ return new CachingURI(
components.scheme,
components.authority,
components.path,
@@ -388,7 +388,7 @@ export class URI implements UriComponents {
} else if (data instanceof URI) {
return data;
} else {
- const result = new _URI(data);
+ const result = new CachingURI(data);
result._formatted = (data).external;
result._fsPath = (data)._sep === _pathSepMarker ? (data).fsPath : null;
return result;
@@ -413,8 +413,8 @@ interface UriState extends UriComponents {
const _pathSepMarker = isWindows ? 1 : undefined;
-// eslint-disable-next-line @typescript-eslint/naming-convention
-class _URI extends URI {
+// This class exists so that URI is compatibile with vscode.Uri (API).
+class CachingURI extends URI {
_formatted: string | null = null;
_fsPath: string | null = null;
diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts
index 5fc3ef43f1..16e3721f0c 100644
--- a/src/vs/base/node/processes.ts
+++ b/src/vs/base/node/processes.ts
@@ -457,7 +457,7 @@ export namespace win32 {
async function fileExists(path: string): Promise {
if (await promisify(fs.exists)(path)) {
- return !((await promisify(fs.stat)(path)).isDirectory);
+ return !((await promisify(fs.stat)(path)).isDirectory());
}
return false;
}
diff --git a/src/vs/base/parts/contextmenu/common/contextmenu.ts b/src/vs/base/parts/contextmenu/common/contextmenu.ts
index ce3f446359..a5aaa61441 100644
--- a/src/vs/base/parts/contextmenu/common/contextmenu.ts
+++ b/src/vs/base/parts/contextmenu/common/contextmenu.ts
@@ -36,8 +36,7 @@ export interface IPopupOptions {
x?: number;
y?: number;
positioningItem?: number;
- onHide?: () => void;
}
export const CONTEXT_MENU_CHANNEL = 'vscode:contextmenu';
-export const CONTEXT_MENU_CLOSE_CHANNEL = 'vscode:onCloseContextMenu';
\ No newline at end of file
+export const CONTEXT_MENU_CLOSE_CHANNEL = 'vscode:onCloseContextMenu';
diff --git a/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts b/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
index 6d7fc4c11c..a679309536 100644
--- a/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
+++ b/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
@@ -9,9 +9,10 @@ import { ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_
export function registerContextMenuListener(): void {
ipcMain.on(CONTEXT_MENU_CHANNEL, (event: IpcMainEvent, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
const menu = createMenu(event, onClickChannel, items);
+ const window = BrowserWindow.fromWebContents(event.sender);
menu.popup({
- window: BrowserWindow.fromWebContents(event.sender),
+ window: window ? window : undefined,
x: options ? options.x : undefined,
y: options ? options.y : undefined,
positioningItem: options ? options.positioningItem : undefined,
diff --git a/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts b/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts
index ab14d788a6..0379ab0925 100644
--- a/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts
+++ b/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts
@@ -8,7 +8,7 @@ import { IContextMenuItem, ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHAN
let contextMenuIdPool = 0;
-export function popup(items: IContextMenuItem[], options?: IPopupOptions): void {
+export function popup(items: IContextMenuItem[], options?: IPopupOptions, onHide?: () => void): void {
const processedItems: IContextMenuItem[] = [];
const contextMenuId = contextMenuIdPool++;
@@ -28,8 +28,8 @@ export function popup(items: IContextMenuItem[], options?: IPopupOptions): void
ipcRenderer.removeListener(onClickChannel, onClickChannelHandler);
- if (options?.onHide) {
- options.onHide();
+ if (onHide) {
+ onHide();
}
});
diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts
index 361b82f816..a1775a9ac9 100644
--- a/src/vs/base/parts/quickinput/browser/quickInput.ts
+++ b/src/vs/base/parts/quickinput/browser/quickInput.ts
@@ -1230,10 +1230,10 @@ export class QuickInputController extends Disposable {
this.previousFocusElement = e.relatedTarget instanceof HTMLElement ? e.relatedTarget : undefined;
}, true));
this._register(focusTracker.onDidBlur(() => {
- this.previousFocusElement = undefined;
if (!this.getUI().ignoreFocusOut && !this.options.ignoreFocusOut()) {
- this.hide(true);
+ this.hide();
}
+ this.previousFocusElement = undefined;
}));
this._register(dom.addDisposableListener(container, dom.EventType.FOCUS, (e: FocusEvent) => {
inputBox.setFocus();
@@ -1574,13 +1574,14 @@ export class QuickInputController extends Disposable {
}
}
- hide(focusLost?: boolean) {
+ hide() {
const controller = this.controller;
if (controller) {
+ const focusChanged = !this.ui?.container.contains(document.activeElement);
this.controller = null;
this.onHideEmitter.fire();
this.getUI().container.style.display = 'none';
- if (!focusLost) {
+ if (!focusChanged) {
if (this.previousFocusElement && this.previousFocusElement.offsetParent) {
this.previousFocusElement.focus();
this.previousFocusElement = undefined;
diff --git a/src/vs/base/parts/sandbox/electron-browser/preload.js b/src/vs/base/parts/sandbox/electron-browser/preload.js
index 47abbf0d02..bb4cec959a 100644
--- a/src/vs/base/parts/sandbox/electron-browser/preload.js
+++ b/src/vs/base/parts/sandbox/electron-browser/preload.js
@@ -68,14 +68,6 @@
*/
webFrame: {
- getZoomFactor() {
- return webFrame.getZoomFactor();
- },
-
- getZoomLevel() {
- return webFrame.getZoomLevel();
- },
-
/**
* @param {number} level
*/
diff --git a/src/vs/base/parts/sandbox/electron-sandbox/globals.ts b/src/vs/base/parts/sandbox/electron-sandbox/globals.ts
index 812e97e3a1..5449340452 100644
--- a/src/vs/base/parts/sandbox/electron-sandbox/globals.ts
+++ b/src/vs/base/parts/sandbox/electron-sandbox/globals.ts
@@ -43,16 +43,6 @@ export const ipcRenderer = (window as any).vscode.ipcRenderer as {
export const webFrame = (window as any).vscode.webFrame as {
- /**
- * The current zoom factor.
- */
- getZoomFactor(): number;
-
- /**
- * The current zoom level.
- */
- getZoomLevel(): number;
-
/**
* Changes the zoom level to the specified level. The original size is 0 and each
* increment above or below represents zooming 20% larger or smaller to default
diff --git a/src/vs/base/test/common/mime.test.ts b/src/vs/base/test/common/mime.test.ts
index e7788ae2eb..2a9d335be4 100644
--- a/src/vs/base/test/common/mime.test.ts
+++ b/src/vs/base/test/common/mime.test.ts
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
-import { guessMimeTypes, registerTextMime, suggestFilename } from 'vs/base/common/mime';
+import { guessMimeTypes, registerTextMime } from 'vs/base/common/mime';
import { URI } from 'vs/base/common/uri';
suite('Mime', () => {
@@ -126,53 +126,4 @@ suite('Mime', () => {
assert.deepEqual(guessMimeTypes(URI.parse(`data:;label:something.data;description:data,`)), ['text/data', 'text/plain']);
});
-
- test('Filename Suggestion - Suggest prefix only when there are no relevant extensions', () => {
- const id = 'plumbus0';
- const mime = `text/${id}`;
- for (let extension of ['one', 'two']) {
- registerTextMime({ id, mime, extension });
- }
-
- let suggested = suggestFilename('shleem', 'Untitled-1');
- assert.equal(suggested, 'Untitled-1');
- });
-
- test('Filename Suggestion - Suggest prefix with first extension that begins with a dot', () => {
- const id = 'plumbus1';
- const mime = `text/${id}`;
- for (let extension of ['plumbus', '.shleem', '.gazorpazorp']) {
- registerTextMime({ id, mime, extension });
- }
-
- let suggested = suggestFilename('plumbus1', 'Untitled-1');
- assert.equal(suggested, 'Untitled-1.shleem');
- });
-
- test('Filename Suggestion - Suggest first relevant extension when there are none that begin with a dot', () => {
- const id = 'plumbus2';
- const mime = `text/${id}`;
- for (let extension of ['plumbus', 'shleem', 'gazorpazorp']) {
- registerTextMime({ id, mime, extension });
- }
-
- let suggested = suggestFilename('plumbus2', 'Untitled-1');
- assert.equal(suggested, 'plumbus');
- });
-
- test('Filename Suggestion - Should ignore user-configured associations', () => {
- registerTextMime({ id: 'plumbus3', mime: 'text/plumbus3', extension: 'plumbus', userConfigured: true });
- registerTextMime({ id: 'plumbus3', mime: 'text/plumbus3', extension: '.shleem', userConfigured: true });
- registerTextMime({ id: 'plumbus3', mime: 'text/plumbus3', extension: '.gazorpazorp', userConfigured: false });
-
- let suggested = suggestFilename('plumbus3', 'Untitled-1');
- assert.equal(suggested, 'Untitled-1.gazorpazorp');
-
- registerTextMime({ id: 'plumbus4', mime: 'text/plumbus4', extension: 'plumbus', userConfigured: true });
- registerTextMime({ id: 'plumbus4', mime: 'text/plumbus4', extension: '.shleem', userConfigured: true });
- registerTextMime({ id: 'plumbus4', mime: 'text/plumbus4', extension: '.gazorpazorp', userConfigured: true });
-
- suggested = suggestFilename('plumbus4', 'Untitled-1');
- assert.equal(suggested, 'Untitled-1');
- });
});
diff --git a/src/vs/code/browser/workbench/workbench-dev.html b/src/vs/code/browser/workbench/workbench-dev.html
index 02a8fd68ad..2619d72ac3 100644
--- a/src/vs/code/browser/workbench/workbench-dev.html
+++ b/src/vs/code/browser/workbench/workbench-dev.html
@@ -2,6 +2,10 @@
+
@@ -29,6 +33,7 @@
// NOTE: Changes to inline scripts require update of content security policy
self.require = {
baseUrl: `${window.location.origin}/static/out`,
+ recordStats: true,
paths: {
'vscode-textmate': `${window.location.origin}/static/remote/web/node_modules/vscode-textmate/release/main`,
'vscode-oniguruma': `${window.location.origin}/static/remote/web/node_modules/vscode-oniguruma/release/main`,
@@ -90,7 +95,11 @@
+
+
@@ -30,6 +34,7 @@
// NOTE: Changes to inline scripts require update of content security policy
self.require = {
baseUrl: `${window.location.origin}/static/out`,
+ recordStats: true,
paths: {
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
'vscode-oniguruma': `${window.location.origin}/static/node_modules/vscode-oniguruma/release/main`,
@@ -79,6 +84,9 @@
+
diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts
index d414140029..adfeed1c32 100644
--- a/src/vs/code/browser/workbench/workbench.ts
+++ b/src/vs/code/browser/workbench/workbench.ts
@@ -12,6 +12,7 @@ import { request } from 'vs/base/parts/request/browser/request';
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/windows';
import { isEqual } from 'vs/base/common/resources';
import { isStandalone } from 'vs/base/browser/browser';
+import { mark } from 'vs/base/common/performance';
interface ICredential {
service: string;
@@ -277,6 +278,10 @@ class WorkspaceProvider implements IWorkspaceProvider {
(function () {
+ // Mark start of workbench
+ mark('didLoadWorkbenchMain');
+ performance.mark('workbench-start');
+
// Find config by checking for DOM
const configElement = document.getElementById('vscode-workbench-web-configuration');
const configElementAttribute = configElement ? configElement.getAttribute('data-settings') : undefined;
diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts
index c86fe478c8..184a195841 100644
--- a/src/vs/code/electron-browser/issue/issueReporterMain.ts
+++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts
@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/issueReporter';
-import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
-import { ipcRenderer, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
+import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
import * as os from 'os';
-import * as browser from 'vs/base/browser/browser';
+import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
+import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
+import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
import { $, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
import { Button } from 'vs/base/browser/ui/button/button';
-import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
import * as collections from 'vs/base/common/collections';
import { debounce } from 'vs/base/common/decorators';
@@ -152,7 +152,7 @@ export class IssueReporter extends Disposable {
this.setUpTypes();
this.setEventHandlers();
- this.applyZoom(configuration.data.zoomLevel);
+ applyZoom(configuration.data.zoomLevel);
this.applyStyles(configuration.data.styles);
this.handleExtensionData(configuration.data.enabledExtensions);
@@ -180,15 +180,6 @@ export class IssueReporter extends Disposable {
}
}
- private applyZoom(zoomLevel: number) {
- webFrame.setZoomLevel(zoomLevel);
- browser.setZoomFactor(webFrame.getZoomFactor());
- // See https://github.com/Microsoft/vscode/issues/26151
- // Cannot be trusted because the webFrame might take some time
- // until it really applies the new zoom level
- browser.setZoomLevel(webFrame.getZoomLevel(), /*isTrusted*/false);
- }
-
private applyStyles(styles: IssueReporterStyles) {
const styleTag = document.createElement('style');
const content: string[] = [];
@@ -505,12 +496,12 @@ export class IssueReporter extends Disposable {
// Cmd/Ctrl + zooms in
if (cmdOrCtrlKey && e.keyCode === 187) {
- this.applyZoom(webFrame.getZoomLevel() + 1);
+ zoomIn();
}
// Cmd/Ctrl - zooms out
if (cmdOrCtrlKey && e.keyCode === 189) {
- this.applyZoom(webFrame.getZoomLevel() - 1);
+ zoomOut();
}
// With latest electron upgrade, cmd+a is no longer propagating correctly for inputs in this window on mac
diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts
index 6a4eb290e6..77643c5f7c 100644
--- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts
+++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts
@@ -5,13 +5,12 @@
import 'vs/css!./media/processExplorer';
import { clipboard } from 'electron';
-import { webFrame, ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
-import { repeat } from 'vs/base/common/strings';
import { totalmem } from 'os';
+import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import product from 'vs/platform/product/common/product';
import { localize } from 'vs/nls';
import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/common/issue';
-import * as browser from 'vs/base/browser/browser';
+import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
import * as platform from 'vs/base/common/platform';
import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu';
import { popup } from 'vs/base/parts/contextmenu/electron-sandbox/contextmenu';
@@ -20,13 +19,8 @@ import { addDisposableListener, addClass } from 'vs/base/browser/dom';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
-let mapPidToWindowTitle = new Map();
-
const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/;
const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/;
-const listeners = new DisposableStore();
-const collapsedStateCache: Map = new Map();
-let lastRequestTime: number;
interface FormattedProcessItem {
cpu: number;
@@ -37,391 +31,400 @@ interface FormattedProcessItem {
cmd: string;
}
-function getProcessList(rootProcess: ProcessItem, isLocal: boolean): FormattedProcessItem[] {
- const processes: FormattedProcessItem[] = [];
+class ProcessExplorer {
+ private lastRequestTime: number;
- if (rootProcess) {
- getProcessItem(processes, rootProcess, 0, isLocal);
+ private collapsedStateCache: Map = new Map();
+
+ private mapPidToWindowTitle = new Map();
+
+ private listeners = new DisposableStore();
+
+ constructor(data: ProcessExplorerData) {
+ this.applyStyles(data.styles);
+
+ // Map window process pids to titles, annotate process names with this when rendering to distinguish between them
+ ipcRenderer.on('vscode:windowsInfoResponse', (event: unknown, windows: any[]) => {
+ this.mapPidToWindowTitle = new Map();
+ windows.forEach(window => this.mapPidToWindowTitle.set(window.pid, window.title));
+ });
+
+ ipcRenderer.on('vscode:listProcessesResponse', (event: unknown, processRoots: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]) => {
+ this.updateProcessInfo(processRoots);
+ this.requestProcessList(0);
+ });
+
+ this.lastRequestTime = Date.now();
+ ipcRenderer.send('vscode:windowsInfoRequest');
+ ipcRenderer.send('vscode:listProcesses');
}
- return processes;
-}
+ private getProcessList(rootProcess: ProcessItem, isLocal: boolean): FormattedProcessItem[] {
+ const processes: FormattedProcessItem[] = [];
-function getProcessItem(processes: FormattedProcessItem[], item: ProcessItem, indent: number, isLocal: boolean): void {
- const isRoot = (indent === 0);
+ if (rootProcess) {
+ this.getProcessItem(processes, rootProcess, 0, isLocal);
+ }
- const MB = 1024 * 1024;
-
- let name = item.name;
- if (isRoot) {
- name = isLocal ? `${product.applicationName} main` : 'remote agent';
+ return processes;
}
- if (name === 'window') {
- const windowTitle = mapPidToWindowTitle.get(item.pid);
- name = windowTitle !== undefined ? `${name} (${mapPidToWindowTitle.get(item.pid)})` : name;
+ private getProcessItem(processes: FormattedProcessItem[], item: ProcessItem, indent: number, isLocal: boolean): void {
+ const isRoot = (indent === 0);
+
+ const MB = 1024 * 1024;
+
+ let name = item.name;
+ if (isRoot) {
+ name = isLocal ? `${product.applicationName} main` : 'remote agent';
+ }
+
+ if (name === 'window') {
+ const windowTitle = this.mapPidToWindowTitle.get(item.pid);
+ name = windowTitle !== undefined ? `${name} (${this.mapPidToWindowTitle.get(item.pid)})` : name;
+ }
+
+ // Format name with indent
+ const formattedName = isRoot ? name : `${' '.repeat(indent)} ${name}`;
+ const memory = process.platform === 'win32' ? item.mem : (totalmem() * (item.mem / 100));
+ processes.push({
+ cpu: item.load,
+ memory: (memory / MB),
+ pid: item.pid.toFixed(0),
+ name,
+ formattedName,
+ cmd: item.cmd
+ });
+
+ // Recurse into children if any
+ if (Array.isArray(item.children)) {
+ item.children.forEach(child => {
+ if (child) {
+ this.getProcessItem(processes, child, indent + 1, isLocal);
+ }
+ });
+ }
}
- // Format name with indent
- const formattedName = isRoot ? name : `${repeat(' ', indent)} ${name}`;
- const memory = process.platform === 'win32' ? item.mem : (totalmem() * (item.mem / 100));
- processes.push({
- cpu: item.load,
- memory: (memory / MB),
- pid: item.pid.toFixed(0),
- name,
- formattedName,
- cmd: item.cmd
- });
+ private isDebuggable(cmd: string): boolean {
+ const matches = DEBUG_FLAGS_PATTERN.exec(cmd);
+ return (matches && matches.length >= 2) || cmd.indexOf('node ') >= 0 || cmd.indexOf('node.exe') >= 0;
+ }
- // Recurse into children if any
- if (Array.isArray(item.children)) {
- item.children.forEach(child => {
- if (child) {
- getProcessItem(processes, child, indent + 1, isLocal);
+ private attachTo(item: FormattedProcessItem) {
+ const config: any = {
+ type: 'node',
+ request: 'attach',
+ name: `process ${item.pid}`
+ };
+
+ let matches = DEBUG_FLAGS_PATTERN.exec(item.cmd);
+ if (matches && matches.length >= 2) {
+ // attach via port
+ if (matches.length === 4 && matches[3]) {
+ config.port = parseInt(matches[3]);
+ }
+ config.protocol = matches[1] === 'debug' ? 'legacy' : 'inspector';
+ } else {
+ // no port -> try to attach via pid (send SIGUSR1)
+ config.processId = String(item.pid);
+ }
+
+ // a debug-port=n or inspect-port=n overrides the port
+ matches = DEBUG_PORT_PATTERN.exec(item.cmd);
+ if (matches && matches.length === 3) {
+ // override port
+ config.port = parseInt(matches[2]);
+ }
+
+ ipcRenderer.send('vscode:workbenchCommand', { id: 'debug.startFromConfig', from: 'processExplorer', args: [config] });
+ }
+
+ private getProcessIdWithHighestProperty(processList: any[], propertyName: string) {
+ let max = 0;
+ let maxProcessId;
+ processList.forEach(process => {
+ if (process[propertyName] > max) {
+ max = process[propertyName];
+ maxProcessId = process.pid;
}
});
+
+ return maxProcessId;
}
-}
-function isDebuggable(cmd: string): boolean {
- const matches = DEBUG_FLAGS_PATTERN.exec(cmd);
- return (matches && matches.length >= 2) || cmd.indexOf('node ') >= 0 || cmd.indexOf('node.exe') >= 0;
-}
-
-function attachTo(item: FormattedProcessItem) {
- const config: any = {
- type: 'node',
- request: 'attach',
- name: `process ${item.pid}`
- };
-
- let matches = DEBUG_FLAGS_PATTERN.exec(item.cmd);
- if (matches && matches.length >= 2) {
- // attach via port
- if (matches.length === 4 && matches[3]) {
- config.port = parseInt(matches[3]);
+ private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: HTMLImageElement, sectionName: string) {
+ if (shouldExpand) {
+ body.classList.remove('hidden');
+ this.collapsedStateCache.set(sectionName, false);
+ twistie.src = './media/expanded.svg';
+ } else {
+ body.classList.add('hidden');
+ this.collapsedStateCache.set(sectionName, true);
+ twistie.src = './media/collapsed.svg';
}
- config.protocol = matches[1] === 'debug' ? 'legacy' : 'inspector';
- } else {
- // no port -> try to attach via pid (send SIGUSR1)
- config.processId = String(item.pid);
}
- // a debug-port=n or inspect-port=n overrides the port
- matches = DEBUG_PORT_PATTERN.exec(item.cmd);
- if (matches && matches.length === 3) {
- // override port
- config.port = parseInt(matches[2]);
- }
-
- ipcRenderer.send('vscode:workbenchCommand', { id: 'debug.startFromConfig', from: 'processExplorer', args: [config] });
-}
-
-function getProcessIdWithHighestProperty(processList: any[], propertyName: string) {
- let max = 0;
- let maxProcessId;
- processList.forEach(process => {
- if (process[propertyName] > max) {
- max = process[propertyName];
- maxProcessId = process.pid;
+ private renderProcessFetchError(sectionName: string, errorMessage: string) {
+ const container = document.getElementById('process-list');
+ if (!container) {
+ return;
}
- });
- return maxProcessId;
-}
+ const body = document.createElement('tbody');
-function updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: HTMLImageElement, sectionName: string) {
- if (shouldExpand) {
- body.classList.remove('hidden');
- collapsedStateCache.set(sectionName, false);
- twistie.src = './media/expanded.svg';
- } else {
- body.classList.add('hidden');
- collapsedStateCache.set(sectionName, true);
- twistie.src = './media/collapsed.svg';
- }
-}
+ this.renderProcessGroupHeader(sectionName, body, container);
-function renderProcessFetchError(sectionName: string, errorMessage: string) {
- const container = document.getElementById('process-list');
- if (!container) {
- return;
+ const errorRow = document.createElement('tr');
+ const data = document.createElement('td');
+ data.textContent = errorMessage;
+ data.className = 'error';
+ data.colSpan = 4;
+ errorRow.appendChild(data);
+
+ body.appendChild(errorRow);
+ container.appendChild(body);
}
- const body = document.createElement('tbody');
+ private renderProcessGroupHeader(sectionName: string, body: HTMLElement, container: HTMLElement) {
+ const headerRow = document.createElement('tr');
+ const data = document.createElement('td');
+ data.textContent = sectionName;
+ data.colSpan = 4;
+ headerRow.appendChild(data);
- renderProcessGroupHeader(sectionName, body, container);
+ const twistie = document.createElement('img');
+ this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistie, sectionName);
+ data.prepend(twistie);
- const errorRow = document.createElement('tr');
- const data = document.createElement('td');
- data.textContent = errorMessage;
- data.className = 'error';
- data.colSpan = 4;
- errorRow.appendChild(data);
-
- body.appendChild(errorRow);
- container.appendChild(body);
-}
-
-function renderProcessGroupHeader(sectionName: string, body: HTMLElement, container: HTMLElement) {
- const headerRow = document.createElement('tr');
- const data = document.createElement('td');
- data.textContent = sectionName;
- data.colSpan = 4;
- headerRow.appendChild(data);
-
- const twistie = document.createElement('img');
- updateSectionCollapsedState(!collapsedStateCache.get(sectionName), body, twistie, sectionName);
- data.prepend(twistie);
-
- listeners.add(addDisposableListener(data, 'click', (e) => {
- const isHidden = body.classList.contains('hidden');
- updateSectionCollapsedState(isHidden, body, twistie, sectionName);
- }));
-
- container.appendChild(headerRow);
-}
-
-function renderTableSection(sectionName: string, processList: FormattedProcessItem[], renderManySections: boolean, sectionIsLocal: boolean): void {
- const container = document.getElementById('process-list');
- if (!container) {
- return;
- }
-
- const highestCPUProcess = getProcessIdWithHighestProperty(processList, 'cpu');
- const highestMemoryProcess = getProcessIdWithHighestProperty(processList, 'memory');
-
- const body = document.createElement('tbody');
-
- if (renderManySections) {
- renderProcessGroupHeader(sectionName, body, container);
- }
-
- processList.forEach(p => {
- const row = document.createElement('tr');
- row.id = p.pid.toString();
-
- const cpu = document.createElement('td');
- p.pid === highestCPUProcess
- ? cpu.classList.add('centered', 'highest')
- : cpu.classList.add('centered');
- cpu.textContent = p.cpu.toFixed(0);
-
- const memory = document.createElement('td');
- p.pid === highestMemoryProcess
- ? memory.classList.add('centered', 'highest')
- : memory.classList.add('centered');
- memory.textContent = p.memory.toFixed(0);
-
- const pid = document.createElement('td');
- pid.classList.add('centered');
- pid.textContent = p.pid;
-
- const name = document.createElement('th');
- name.scope = 'row';
- name.classList.add('data');
- name.title = p.cmd;
- name.textContent = p.formattedName;
-
- row.append(cpu, memory, pid, name);
-
- listeners.add(addDisposableListener(row, 'contextmenu', (e) => {
- showContextMenu(e, p, sectionIsLocal);
+ this.listeners.add(addDisposableListener(data, 'click', (e) => {
+ const isHidden = body.classList.contains('hidden');
+ this.updateSectionCollapsedState(isHidden, body, twistie, sectionName);
}));
- body.appendChild(row);
- });
-
- container.appendChild(body);
-}
-
-function updateProcessInfo(processLists: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]): void {
- const container = document.getElementById('process-list');
- if (!container) {
- return;
+ container.appendChild(headerRow);
}
- container.innerHTML = '';
- listeners.clear();
-
- const tableHead = document.createElement('thead');
- tableHead.innerHTML = `
- | ${localize('cpu', "CPU %")} |
- ${localize('memory', "Memory (MB)")} |
- ${localize('pid', "pid")} |
- ${localize('name', "Name")} |
-
`;
-
- container.append(tableHead);
-
- const hasMultipleMachines = Object.keys(processLists).length > 1;
- processLists.forEach((remote, i) => {
- const isLocal = i === 0;
- if (isRemoteDiagnosticError(remote.rootProcess)) {
- renderProcessFetchError(remote.name, remote.rootProcess.errorMessage);
- } else {
- renderTableSection(remote.name, getProcessList(remote.rootProcess, isLocal), hasMultipleMachines, isLocal);
+ private renderTableSection(sectionName: string, processList: FormattedProcessItem[], renderManySections: boolean, sectionIsLocal: boolean): void {
+ const container = document.getElementById('process-list');
+ if (!container) {
+ return;
}
- });
-}
-function applyStyles(styles: ProcessExplorerStyles): void {
- const styleTag = document.createElement('style');
- const content: string[] = [];
+ const highestCPUProcess = this.getProcessIdWithHighestProperty(processList, 'cpu');
+ const highestMemoryProcess = this.getProcessIdWithHighestProperty(processList, 'memory');
- if (styles.hoverBackground) {
- content.push(`tbody > tr:hover, table > tr:hover { background-color: ${styles.hoverBackground}; }`);
+ const body = document.createElement('tbody');
+
+ if (renderManySections) {
+ this.renderProcessGroupHeader(sectionName, body, container);
+ }
+
+ processList.forEach(p => {
+ const row = document.createElement('tr');
+ row.id = p.pid.toString();
+
+ const cpu = document.createElement('td');
+ p.pid === highestCPUProcess
+ ? cpu.classList.add('centered', 'highest')
+ : cpu.classList.add('centered');
+ cpu.textContent = p.cpu.toFixed(0);
+
+ const memory = document.createElement('td');
+ p.pid === highestMemoryProcess
+ ? memory.classList.add('centered', 'highest')
+ : memory.classList.add('centered');
+ memory.textContent = p.memory.toFixed(0);
+
+ const pid = document.createElement('td');
+ pid.classList.add('centered');
+ pid.textContent = p.pid;
+
+ const name = document.createElement('th');
+ name.scope = 'row';
+ name.classList.add('data');
+ name.title = p.cmd;
+ name.textContent = p.formattedName;
+
+ row.append(cpu, memory, pid, name);
+
+ this.listeners.add(addDisposableListener(row, 'contextmenu', (e) => {
+ this.showContextMenu(e, p, sectionIsLocal);
+ }));
+
+ body.appendChild(row);
+ });
+
+ container.appendChild(body);
}
- if (styles.hoverForeground) {
- content.push(`tbody > tr:hover, table > tr:hover { color: ${styles.hoverForeground}; }`);
+ private updateProcessInfo(processLists: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]): void {
+ const container = document.getElementById('process-list');
+ if (!container) {
+ return;
+ }
+
+ container.innerHTML = '';
+ this.listeners.clear();
+
+ const tableHead = document.createElement('thead');
+ tableHead.innerHTML = `
+ | ${localize('cpu', "CPU %")} |
+ ${localize('memory', "Memory (MB)")} |
+ ${localize('pid', "pid")} |
+ ${localize('name', "Name")} |
+
`;
+
+ container.append(tableHead);
+
+ const hasMultipleMachines = Object.keys(processLists).length > 1;
+ processLists.forEach((remote, i) => {
+ const isLocal = i === 0;
+ if (isRemoteDiagnosticError(remote.rootProcess)) {
+ this.renderProcessFetchError(remote.name, remote.rootProcess.errorMessage);
+ } else {
+ this.renderTableSection(remote.name, this.getProcessList(remote.rootProcess, isLocal), hasMultipleMachines, isLocal);
+ }
+ });
}
- if (styles.highlightForeground) {
- content.push(`.highest { color: ${styles.highlightForeground}; }`);
+ private applyStyles(styles: ProcessExplorerStyles): void {
+ const styleTag = document.createElement('style');
+ const content: string[] = [];
+
+ if (styles.hoverBackground) {
+ content.push(`tbody > tr:hover, table > tr:hover { background-color: ${styles.hoverBackground}; }`);
+ }
+
+ if (styles.hoverForeground) {
+ content.push(`tbody > tr:hover, table > tr:hover { color: ${styles.hoverForeground}; }`);
+ }
+
+ if (styles.highlightForeground) {
+ content.push(`.highest { color: ${styles.highlightForeground}; }`);
+ }
+
+ styleTag.innerHTML = content.join('\n');
+ if (document.head) {
+ document.head.appendChild(styleTag);
+ }
+ if (styles.color) {
+ document.body.style.color = styles.color;
+ }
}
- styleTag.innerHTML = content.join('\n');
- if (document.head) {
- document.head.appendChild(styleTag);
- }
- if (styles.color) {
- document.body.style.color = styles.color;
- }
-}
+ private showContextMenu(e: MouseEvent, item: FormattedProcessItem, isLocal: boolean) {
+ e.preventDefault();
-function applyZoom(zoomLevel: number): void {
- webFrame.setZoomLevel(zoomLevel);
- browser.setZoomFactor(webFrame.getZoomFactor());
- // See https://github.com/Microsoft/vscode/issues/26151
- // Cannot be trusted because the webFrame might take some time
- // until it really applies the new zoom level
- browser.setZoomLevel(webFrame.getZoomLevel(), /*isTrusted*/false);
-}
+ const items: IContextMenuItem[] = [];
+ const pid = Number(item.pid);
-function showContextMenu(e: MouseEvent, item: FormattedProcessItem, isLocal: boolean) {
- e.preventDefault();
+ if (isLocal) {
+ items.push({
+ label: localize('killProcess', "Kill Process"),
+ click() {
+ process.kill(pid, 'SIGTERM');
+ }
+ });
- const items: IContextMenuItem[] = [];
- const pid = Number(item.pid);
+ items.push({
+ label: localize('forceKillProcess', "Force Kill Process"),
+ click() {
+ process.kill(pid, 'SIGKILL');
+ }
+ });
+
+ items.push({
+ type: 'separator'
+ });
+ }
- if (isLocal) {
items.push({
- label: localize('killProcess', "Kill Process"),
+ label: localize('copy', "Copy"),
click() {
- process.kill(pid, 'SIGTERM');
+ const row = document.getElementById(pid.toString());
+ if (row) {
+ clipboard.writeText(row.innerText);
+ }
}
});
items.push({
- label: localize('forceKillProcess', "Force Kill Process"),
+ label: localize('copyAll', "Copy All"),
click() {
- process.kill(pid, 'SIGKILL');
+ const processList = document.getElementById('process-list');
+ if (processList) {
+ clipboard.writeText(processList.innerText);
+ }
}
});
- items.push({
- type: 'separator'
- });
+ if (item && isLocal && this.isDebuggable(item.cmd)) {
+ items.push({
+ type: 'separator'
+ });
+
+ items.push({
+ label: localize('debug', "Debug"),
+ click: () => {
+ this.attachTo(item);
+ }
+ });
+ }
+
+ popup(items);
}
- items.push({
- label: localize('copy', "Copy"),
- click() {
- const row = document.getElementById(pid.toString());
- if (row) {
- clipboard.writeText(row.innerText);
- }
- }
- });
+ private requestProcessList(totalWaitTime: number): void {
+ setTimeout(() => {
+ const nextRequestTime = Date.now();
+ const waited = totalWaitTime + nextRequestTime - this.lastRequestTime;
+ this.lastRequestTime = nextRequestTime;
- items.push({
- label: localize('copyAll', "Copy All"),
- click() {
- const processList = document.getElementById('process-list');
- if (processList) {
- clipboard.writeText(processList.innerText);
+ // Wait at least a second between requests.
+ if (waited > 1000) {
+ ipcRenderer.send('vscode:windowsInfoRequest');
+ ipcRenderer.send('vscode:listProcesses');
+ } else {
+ this.requestProcessList(waited);
}
- }
- });
-
- if (item && isLocal && isDebuggable(item.cmd)) {
- items.push({
- type: 'separator'
- });
-
- items.push({
- label: localize('debug', "Debug"),
- click() {
- attachTo(item);
- }
- });
+ }, 200);
}
- popup(items);
+ public dispose() {
+ this.listeners.dispose();
+ }
}
-function requestProcessList(totalWaitTime: number): void {
- setTimeout(() => {
- const nextRequestTime = Date.now();
- const waited = totalWaitTime + nextRequestTime - lastRequestTime;
- lastRequestTime = nextRequestTime;
- // Wait at least a second between requests.
- if (waited > 1000) {
- ipcRenderer.send('vscode:windowsInfoRequest');
- ipcRenderer.send('vscode:listProcesses');
- } else {
- requestProcessList(waited);
- }
- }, 200);
-}
-
-function createCloseListener(): void {
- // Cmd/Ctrl + w closes process explorer
- window.addEventListener('keydown', e => {
- const cmdOrCtrlKey = platform.isMacintosh ? e.metaKey : e.ctrlKey;
- if (cmdOrCtrlKey && e.keyCode === 87) {
- ipcRenderer.send('vscode:closeProcessExplorer');
- }
- });
-}
export function startup(data: ProcessExplorerData): void {
const platformClass = platform.isWindows ? 'windows' : platform.isLinux ? 'linux' : 'mac';
addClass(document.body, platformClass); // used by our fonts
-
- applyStyles(data.styles);
applyZoom(data.zoomLevel);
- createCloseListener();
- // Map window process pids to titles, annotate process names with this when rendering to distinguish between them
- ipcRenderer.on('vscode:windowsInfoResponse', (event: unknown, windows: any[]) => {
- mapPidToWindowTitle = new Map();
- windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title));
- });
-
- ipcRenderer.on('vscode:listProcessesResponse', (event: unknown, processRoots: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]) => {
- updateProcessInfo(processRoots);
- requestProcessList(0);
- });
-
- lastRequestTime = Date.now();
- ipcRenderer.send('vscode:windowsInfoRequest');
- ipcRenderer.send('vscode:listProcesses');
+ const processExplorer = new ProcessExplorer(data);
document.onkeydown = (e: KeyboardEvent) => {
const cmdOrCtrlKey = platform.isMacintosh ? e.metaKey : e.ctrlKey;
// Cmd/Ctrl + zooms in
if (cmdOrCtrlKey && e.keyCode === 187) {
- applyZoom(webFrame.getZoomLevel() + 1);
+ zoomIn();
}
// Cmd/Ctrl - zooms out
if (cmdOrCtrlKey && e.keyCode === 189) {
- applyZoom(webFrame.getZoomLevel() - 1);
+ zoomOut();
}
};
+
+ // Cmd/Ctrl + w closes process explorer
+ window.addEventListener('keydown', e => {
+ const cmdOrCtrlKey = platform.isMacintosh ? e.metaKey : e.ctrlKey;
+ if (cmdOrCtrlKey && e.keyCode === 87) {
+ processExplorer.dispose();
+ ipcRenderer.send('vscode:closeProcessExplorer');
+ }
+ });
}
diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts
index 79b973aef5..f15410f935 100644
--- a/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts
+++ b/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts
@@ -35,7 +35,7 @@ export class StorageDataCleaner extends Disposable {
const emptyWorkspaces = workspaces.emptyWorkspaceInfos.map(info => info.backupFolder);
// Read all workspace storage folders that exist
- return readdir(this.environmentService.workspaceStorageHome).then(storageFolders => {
+ return readdir(this.environmentService.workspaceStorageHome.fsPath).then(storageFolders => {
const deletes: Promise[] = [];
storageFolders.forEach(storageFolder => {
@@ -44,7 +44,7 @@ export class StorageDataCleaner extends Disposable {
}
if (emptyWorkspaces.indexOf(storageFolder) === -1) {
- deletes.push(rimraf(join(this.environmentService.workspaceStorageHome, storageFolder)));
+ deletes.push(rimraf(join(this.environmentService.workspaceStorageHome.fsPath, storageFolder)));
}
});
diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
index cda53693a9..a661bb2782 100644
--- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
+++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
@@ -238,7 +238,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
server.registerChannel('userDataSyncAccount', authTokenChannel);
const userDataSyncService = accessor.get(IUserDataSyncService);
- const userDataSyncChannel = new UserDataSyncChannel(userDataSyncService, logService);
+ const userDataSyncChannel = new UserDataSyncChannel(server, userDataSyncService, logService);
server.registerChannel('userDataSync', userDataSyncChannel);
const userDataAutoSync = instantiationService2.createInstance(UserDataAutoSyncService);
diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js
index 51e7290dbe..1a190b1046 100644
--- a/src/vs/code/electron-browser/workbench/workbench.js
+++ b/src/vs/code/electron-browser/workbench/workbench.js
@@ -9,41 +9,33 @@
'use strict';
const perf = (function () {
- let sharedObj;
- if (typeof global === 'object') {
- // nodejs
- sharedObj = global;
- } else if (typeof self === 'object') {
- // browser
- sharedObj = self;
- } else {
- sharedObj = {};
- }
- // @ts-ignore
- sharedObj._performanceEntries = sharedObj._performanceEntries || [];
+ globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || [];
return {
/**
* @param {string} name
*/
mark(name) {
- sharedObj._performanceEntries.push(name, Date.now());
+ globalThis.MonacoPerformanceMarks.push(name, Date.now());
}
};
})();
perf.mark('renderer/started');
-// Setup shell environment
-process['lazyEnv'] = getLazyEnv();
-
/**
- * @type {{ load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown }}
+ * @type {{
+ * load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown,
+ * globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals')
+ * }}
*/
const bootstrapWindow = (() => {
// @ts-ignore (defined in bootstrap-window.js)
return window.MonacoBootstrapWindow;
})();
+// Setup shell environment
+process['lazyEnv'] = getLazyEnv();
+
// Load workbench main JS, CSS and NLS all in parallel. This is an
// optimization to prevent a waterfall of loading to happen, because
// we know for a fact that workbench.desktop.main will depend on
@@ -55,6 +47,8 @@ bootstrapWindow.load([
'vs/css!vs/workbench/workbench.desktop.main'
],
function (workbench, configuration) {
+
+ // Mark start of workbench
perf.mark('didLoadWorkbenchMain');
performance.mark('workbench-start');
@@ -183,8 +177,7 @@ function showPartsSplash(configuration) {
* @returns {Promise}
*/
function getLazyEnv() {
-
- const ipc = require.__$__nodeRequire('electron').ipcRenderer;
+ const ipcRenderer = bootstrapWindow.globals().ipcRenderer;
return new Promise(function (resolve) {
const handle = setTimeout(function () {
@@ -192,13 +185,13 @@ function getLazyEnv() {
console.warn('renderer did not receive lazyEnv in time');
}, 10000);
- ipc.once('vscode:acceptShellEnv', function (event, shellEnv) {
+ ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnv) {
clearTimeout(handle);
Object.assign(process.env, shellEnv);
// @ts-ignore
resolve(process.env);
});
- ipc.send('vscode:fetchShellEnv');
+ ipcRenderer.send('vscode:fetchShellEnv');
});
}
diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts
index aaa7fb61bf..95048b0269 100644
--- a/src/vs/code/electron-main/auth.ts
+++ b/src/vs/code/electron-main/auth.ts
@@ -6,6 +6,7 @@
import { localize } from 'vs/nls';
import { Disposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
+import { URI } from 'vs/base/common/uri';
import { BrowserWindow, BrowserWindowConstructorOptions, app, AuthInfo, WebContents, Event as ElectronEvent } from 'electron';
type LoginEvent = {
@@ -58,10 +59,12 @@ export class ProxyAuthHandler extends Disposable {
show: true,
title: 'VS Code',
webPreferences: {
- nodeIntegration: true,
+ preload: URI.parse(require.toUrl('vs/base/parts/sandbox/electron-browser/preload.js')).fsPath,
enableWebSQL: false,
+ sandbox: true,
+ devTools: false,
enableRemoteModule: false,
- nativeWindowOpen: true
+ v8CacheOptions: 'bypassHeatCheck'
}
};
@@ -72,24 +75,27 @@ export class ProxyAuthHandler extends Disposable {
}
const win = new BrowserWindow(opts);
- const config = {};
- const baseUrl = require.toUrl('vs/code/electron-browser/proxy/auth.html');
- const url = `${baseUrl}?config=${encodeURIComponent(JSON.stringify(config))}`;
+ const url = require.toUrl('vs/code/electron-sandbox/proxy/auth.html');
const proxyUrl = `${authInfo.host}:${authInfo.port}`;
const title = localize('authRequire', "Proxy Authentication Required");
const message = localize('proxyauth', "The proxy {0} requires authentication.", proxyUrl);
- const data = { title, message };
- const javascript = 'promptForCredentials(' + JSON.stringify(data) + ')';
const onWindowClose = () => cb('', '');
win.on('close', onWindowClose);
win.setMenu(null);
- win.loadURL(url);
- win.webContents.executeJavaScript(javascript, true).then(({ username, password }: Credentials) => {
- cb(username, password);
+ win.webContents.on('did-finish-load', () => {
+ const data = { title, message };
+ win.webContents.send('vscode:openProxyAuthDialog', data);
+ });
+ win.webContents.on('ipc-message', (event, channel, credentials: Credentials) => {
+ if (channel === 'vscode:proxyAuthResponse') {
+ const { username, password } = credentials;
+ cb(username, password);
+ }
win.removeListener('close', onWindowClose);
win.close();
});
+ win.loadURL(url);
}
}
diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts
index 415107bb19..9a9e1c6376 100644
--- a/src/vs/code/electron-main/main.ts
+++ b/src/vs/code/electron-main/main.ts
@@ -178,8 +178,8 @@ class CodeMain {
environmentService.extensionsPath,
environmentService.nodeCachedDataDir,
environmentService.logsPath,
- environmentService.globalStorageHome,
- environmentService.workspaceStorageHome,
+ environmentService.globalStorageHome.fsPath,
+ environmentService.workspaceStorageHome.fsPath,
environmentService.backupHome.fsPath
].map((path): undefined | Promise => path ? mkdirp(path) : undefined));
diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts
index 45d7886ecf..4ab39785c0 100644
--- a/src/vs/code/electron-main/window.ts
+++ b/src/vs/code/electron-main/window.ts
@@ -15,7 +15,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { parseArgs, OPTIONS, ParsedArgs } from 'vs/platform/environment/node/argv';
import product from 'vs/platform/product/common/product';
-import { IWindowSettings, MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility } from 'vs/platform/windows/common/windows';
+import { IWindowSettings, MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { ICodeWindow, IWindowState, WindowMode } from 'vs/platform/windows/electron-main/windows';
@@ -153,6 +153,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// in case we are maximized or fullscreen, only show later after the call to maximize/fullscreen (see below)
const isFullscreenOrMaximized = (this.windowState.mode === WindowMode.Maximized || this.windowState.mode === WindowMode.Fullscreen);
+ const windowConfig = this.configurationService.getValue('window');
+
const options: BrowserWindowConstructorOptions = {
width: this.windowState.width,
height: this.windowState.height,
@@ -169,7 +171,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
webviewTag: true,
enableWebSQL: false,
enableRemoteModule: false,
- nativeWindowOpen: true
+ nativeWindowOpen: true,
+ zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel)
}
};
@@ -182,8 +185,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
options.icon = path.join(this.environmentService.appRoot, 'resources/win32/code_150x150.png');
}
- const windowConfig = this.configurationService.getValue('window');
-
if (isMacintosh && !this.useNativeFullScreen()) {
options.fullscreenable = false; // enables simple fullscreen mode
}
@@ -214,6 +215,11 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this._win = new BrowserWindow(options);
this._id = this._win.id;
+ // Open devtools if instructed from command line args
+ if (this.environmentService.args['open-devtools'] === true) {
+ this._win.webContents.openDevTools();
+ }
+
if (isMacintosh && useCustomTitleStyle) {
this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any
}
diff --git a/src/vs/code/electron-browser/proxy/auth.html b/src/vs/code/electron-sandbox/proxy/auth.html
similarity index 58%
rename from src/vs/code/electron-browser/proxy/auth.html
rename to src/vs/code/electron-sandbox/proxy/auth.html
index e5cc351b14..788b68fce7 100644
--- a/src/vs/code/electron-browser/proxy/auth.html
+++ b/src/vs/code/electron-sandbox/proxy/auth.html
@@ -5,7 +5,7 @@
+ content="default-src 'none'; img-src 'self' https: data:; media-src 'none'; child-src 'self'; object-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https:;">