|
|
/******/ (function() { // webpackBootstrap
|
|
|
/******/ var __webpack_modules__ = ({
|
|
|
|
|
|
/***/ 671:
|
|
|
/*!**********************************************************!*\
|
|
|
!*** ./node_modules/_process@0.11.10@process/browser.js ***!
|
|
|
\**********************************************************/
|
|
|
/***/ (function(module) {
|
|
|
|
|
|
// shim for using process in browser
|
|
|
var process = module.exports = {};
|
|
|
|
|
|
// cached from whatever global is present so that test runners that stub it
|
|
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
|
// function because try/catches deoptimize in certain engines.
|
|
|
|
|
|
var cachedSetTimeout;
|
|
|
var cachedClearTimeout;
|
|
|
|
|
|
function defaultSetTimout() {
|
|
|
throw new Error('setTimeout has not been defined');
|
|
|
}
|
|
|
function defaultClearTimeout () {
|
|
|
throw new Error('clearTimeout has not been defined');
|
|
|
}
|
|
|
(function () {
|
|
|
try {
|
|
|
if (typeof setTimeout === 'function') {
|
|
|
cachedSetTimeout = setTimeout;
|
|
|
} else {
|
|
|
cachedSetTimeout = defaultSetTimout;
|
|
|
}
|
|
|
} catch (e) {
|
|
|
cachedSetTimeout = defaultSetTimout;
|
|
|
}
|
|
|
try {
|
|
|
if (typeof clearTimeout === 'function') {
|
|
|
cachedClearTimeout = clearTimeout;
|
|
|
} else {
|
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
|
}
|
|
|
} catch (e) {
|
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
|
}
|
|
|
} ())
|
|
|
function runTimeout(fun) {
|
|
|
if (cachedSetTimeout === setTimeout) {
|
|
|
//normal enviroments in sane situations
|
|
|
return setTimeout(fun, 0);
|
|
|
}
|
|
|
// if setTimeout wasn't available but was latter defined
|
|
|
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
|
cachedSetTimeout = setTimeout;
|
|
|
return setTimeout(fun, 0);
|
|
|
}
|
|
|
try {
|
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
|
return cachedSetTimeout(fun, 0);
|
|
|
} catch(e){
|
|
|
try {
|
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
|
return cachedSetTimeout.call(null, fun, 0);
|
|
|
} catch(e){
|
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|
|
return cachedSetTimeout.call(this, fun, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
function runClearTimeout(marker) {
|
|
|
if (cachedClearTimeout === clearTimeout) {
|
|
|
//normal enviroments in sane situations
|
|
|
return clearTimeout(marker);
|
|
|
}
|
|
|
// if clearTimeout wasn't available but was latter defined
|
|
|
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
|
cachedClearTimeout = clearTimeout;
|
|
|
return clearTimeout(marker);
|
|
|
}
|
|
|
try {
|
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
|
return cachedClearTimeout(marker);
|
|
|
} catch (e){
|
|
|
try {
|
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
|
return cachedClearTimeout.call(null, marker);
|
|
|
} catch (e){
|
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
|
return cachedClearTimeout.call(this, marker);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
var queue = [];
|
|
|
var draining = false;
|
|
|
var currentQueue;
|
|
|
var queueIndex = -1;
|
|
|
|
|
|
function cleanUpNextTick() {
|
|
|
if (!draining || !currentQueue) {
|
|
|
return;
|
|
|
}
|
|
|
draining = false;
|
|
|
if (currentQueue.length) {
|
|
|
queue = currentQueue.concat(queue);
|
|
|
} else {
|
|
|
queueIndex = -1;
|
|
|
}
|
|
|
if (queue.length) {
|
|
|
drainQueue();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function drainQueue() {
|
|
|
if (draining) {
|
|
|
return;
|
|
|
}
|
|
|
var timeout = runTimeout(cleanUpNextTick);
|
|
|
draining = true;
|
|
|
|
|
|
var len = queue.length;
|
|
|
while(len) {
|
|
|
currentQueue = queue;
|
|
|
queue = [];
|
|
|
while (++queueIndex < len) {
|
|
|
if (currentQueue) {
|
|
|
currentQueue[queueIndex].run();
|
|
|
}
|
|
|
}
|
|
|
queueIndex = -1;
|
|
|
len = queue.length;
|
|
|
}
|
|
|
currentQueue = null;
|
|
|
draining = false;
|
|
|
runClearTimeout(timeout);
|
|
|
}
|
|
|
|
|
|
process.nextTick = function (fun) {
|
|
|
var args = new Array(arguments.length - 1);
|
|
|
if (arguments.length > 1) {
|
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
|
args[i - 1] = arguments[i];
|
|
|
}
|
|
|
}
|
|
|
queue.push(new Item(fun, args));
|
|
|
if (queue.length === 1 && !draining) {
|
|
|
runTimeout(drainQueue);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// v8 likes predictible objects
|
|
|
function Item(fun, array) {
|
|
|
this.fun = fun;
|
|
|
this.array = array;
|
|
|
}
|
|
|
Item.prototype.run = function () {
|
|
|
this.fun.apply(null, this.array);
|
|
|
};
|
|
|
process.title = 'browser';
|
|
|
process.browser = true;
|
|
|
process.env = {};
|
|
|
process.argv = [];
|
|
|
process.version = ''; // empty string to avoid regexp issues
|
|
|
process.versions = {};
|
|
|
|
|
|
function noop() {}
|
|
|
|
|
|
process.on = noop;
|
|
|
process.addListener = noop;
|
|
|
process.once = noop;
|
|
|
process.off = noop;
|
|
|
process.removeListener = noop;
|
|
|
process.removeAllListeners = noop;
|
|
|
process.emit = noop;
|
|
|
process.prependListener = noop;
|
|
|
process.prependOnceListener = noop;
|
|
|
|
|
|
process.listeners = function (name) { return [] }
|
|
|
|
|
|
process.binding = function (name) {
|
|
|
throw new Error('process.binding is not supported');
|
|
|
};
|
|
|
|
|
|
process.cwd = function () { return '/' };
|
|
|
process.chdir = function (dir) {
|
|
|
throw new Error('process.chdir is not supported');
|
|
|
};
|
|
|
process.umask = function() { return 0; };
|
|
|
|
|
|
|
|
|
/***/ })
|
|
|
|
|
|
/******/ });
|
|
|
/************************************************************************/
|
|
|
/******/ // The module cache
|
|
|
/******/ var __webpack_module_cache__ = {};
|
|
|
/******/
|
|
|
/******/ // The require function
|
|
|
/******/ function __webpack_require__(moduleId) {
|
|
|
/******/ // Check if module is in cache
|
|
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
|
/******/ if (cachedModule !== undefined) {
|
|
|
/******/ return cachedModule.exports;
|
|
|
/******/ }
|
|
|
/******/ // Create a new module (and put it into the cache)
|
|
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
|
/******/ // no module.id needed
|
|
|
/******/ // no module.loaded needed
|
|
|
/******/ exports: {}
|
|
|
/******/ };
|
|
|
/******/
|
|
|
/******/ // Execute the module function
|
|
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
|
/******/
|
|
|
/******/ // Return the exports of the module
|
|
|
/******/ return module.exports;
|
|
|
/******/ }
|
|
|
/******/
|
|
|
/************************************************************************/
|
|
|
/******/ /* webpack/runtime/global */
|
|
|
/******/ !function() {
|
|
|
/******/ __webpack_require__.g = (function() {
|
|
|
/******/ if (typeof globalThis === 'object') return globalThis;
|
|
|
/******/ try {
|
|
|
/******/ return this || new Function('return this')();
|
|
|
/******/ } catch (e) {
|
|
|
/******/ if (typeof window === 'object') return window;
|
|
|
/******/ }
|
|
|
/******/ })();
|
|
|
/******/ }();
|
|
|
/******/
|
|
|
/************************************************************************/
|
|
|
var __webpack_exports__ = {};
|
|
|
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
|
|
|
!function() {
|
|
|
"use strict";
|
|
|
/*!******************************************************************************************************!*\
|
|
|
!*** ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/editor.worker.js + 34 modules ***!
|
|
|
\******************************************************************************************************/
|
|
|
|
|
|
// UNUSED EXPORTS: initialize
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/errors.js
|
|
|
// Avoid circular dependency on EventEmitter by implementing a subset of the interface.
|
|
|
class ErrorHandler {
|
|
|
constructor() {
|
|
|
this.listeners = [];
|
|
|
this.unexpectedErrorHandler = function (e) {
|
|
|
setTimeout(() => {
|
|
|
if (e.stack) {
|
|
|
throw new Error(e.message + '\n\n' + e.stack);
|
|
|
}
|
|
|
throw e;
|
|
|
}, 0);
|
|
|
};
|
|
|
}
|
|
|
emit(e) {
|
|
|
this.listeners.forEach((listener) => {
|
|
|
listener(e);
|
|
|
});
|
|
|
}
|
|
|
onUnexpectedError(e) {
|
|
|
this.unexpectedErrorHandler(e);
|
|
|
this.emit(e);
|
|
|
}
|
|
|
// For external errors, we don't want the listeners to be called
|
|
|
onUnexpectedExternalError(e) {
|
|
|
this.unexpectedErrorHandler(e);
|
|
|
}
|
|
|
}
|
|
|
const errorHandler = new ErrorHandler();
|
|
|
function onUnexpectedError(e) {
|
|
|
// ignore errors from cancelled promises
|
|
|
if (!isPromiseCanceledError(e)) {
|
|
|
errorHandler.onUnexpectedError(e);
|
|
|
}
|
|
|
return undefined;
|
|
|
}
|
|
|
function onUnexpectedExternalError(e) {
|
|
|
// ignore errors from cancelled promises
|
|
|
if (!isPromiseCanceledError(e)) {
|
|
|
errorHandler.onUnexpectedExternalError(e);
|
|
|
}
|
|
|
return undefined;
|
|
|
}
|
|
|
function transformErrorForSerialization(error) {
|
|
|
if (error instanceof Error) {
|
|
|
let { name, message } = error;
|
|
|
const stack = error.stacktrace || error.stack;
|
|
|
return {
|
|
|
$isError: true,
|
|
|
name,
|
|
|
message,
|
|
|
stack
|
|
|
};
|
|
|
}
|
|
|
// return as is
|
|
|
return error;
|
|
|
}
|
|
|
const canceledName = 'Canceled';
|
|
|
/**
|
|
|
* Checks if the given error is a promise in canceled state
|
|
|
*/
|
|
|
function isPromiseCanceledError(error) {
|
|
|
return error instanceof Error && error.name === canceledName && error.message === canceledName;
|
|
|
}
|
|
|
/**
|
|
|
* Returns an error that signals cancellation.
|
|
|
*/
|
|
|
function canceled() {
|
|
|
const error = new Error(canceledName);
|
|
|
error.name = error.message;
|
|
|
return error;
|
|
|
}
|
|
|
function illegalArgument(name) {
|
|
|
if (name) {
|
|
|
return new Error(`Illegal argument: ${name}`);
|
|
|
}
|
|
|
else {
|
|
|
return new Error('Illegal argument');
|
|
|
}
|
|
|
}
|
|
|
function illegalState(name) {
|
|
|
if (name) {
|
|
|
return new Error(`Illegal state: ${name}`);
|
|
|
}
|
|
|
else {
|
|
|
return new Error('Illegal state');
|
|
|
}
|
|
|
}
|
|
|
class NotSupportedError extends (/* unused pure expression or super */ null && (Error)) {
|
|
|
constructor(message) {
|
|
|
super('NotSupported');
|
|
|
if (message) {
|
|
|
this.message = message;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/functional.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
function once(fn) {
|
|
|
const _this = this;
|
|
|
let didCall = false;
|
|
|
let result;
|
|
|
return function () {
|
|
|
if (didCall) {
|
|
|
return result;
|
|
|
}
|
|
|
didCall = true;
|
|
|
result = fn.apply(_this, arguments);
|
|
|
return result;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/iterator.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
var Iterable;
|
|
|
(function (Iterable) {
|
|
|
function is(thing) {
|
|
|
return thing && typeof thing === 'object' && typeof thing[Symbol.iterator] === 'function';
|
|
|
}
|
|
|
Iterable.is = is;
|
|
|
const _empty = Object.freeze([]);
|
|
|
function empty() {
|
|
|
return _empty;
|
|
|
}
|
|
|
Iterable.empty = empty;
|
|
|
function* single(element) {
|
|
|
yield element;
|
|
|
}
|
|
|
Iterable.single = single;
|
|
|
function from(iterable) {
|
|
|
return iterable || _empty;
|
|
|
}
|
|
|
Iterable.from = from;
|
|
|
function isEmpty(iterable) {
|
|
|
return !iterable || iterable[Symbol.iterator]().next().done === true;
|
|
|
}
|
|
|
Iterable.isEmpty = isEmpty;
|
|
|
function first(iterable) {
|
|
|
return iterable[Symbol.iterator]().next().value;
|
|
|
}
|
|
|
Iterable.first = first;
|
|
|
function some(iterable, predicate) {
|
|
|
for (const element of iterable) {
|
|
|
if (predicate(element)) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
Iterable.some = some;
|
|
|
function find(iterable, predicate) {
|
|
|
for (const element of iterable) {
|
|
|
if (predicate(element)) {
|
|
|
return element;
|
|
|
}
|
|
|
}
|
|
|
return undefined;
|
|
|
}
|
|
|
Iterable.find = find;
|
|
|
function* filter(iterable, predicate) {
|
|
|
for (const element of iterable) {
|
|
|
if (predicate(element)) {
|
|
|
yield element;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Iterable.filter = filter;
|
|
|
function* map(iterable, fn) {
|
|
|
let index = 0;
|
|
|
for (const element of iterable) {
|
|
|
yield fn(element, index++);
|
|
|
}
|
|
|
}
|
|
|
Iterable.map = map;
|
|
|
function* concat(...iterables) {
|
|
|
for (const iterable of iterables) {
|
|
|
for (const element of iterable) {
|
|
|
yield element;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Iterable.concat = concat;
|
|
|
function* concatNested(iterables) {
|
|
|
for (const iterable of iterables) {
|
|
|
for (const element of iterable) {
|
|
|
yield element;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Iterable.concatNested = concatNested;
|
|
|
function reduce(iterable, reducer, initialValue) {
|
|
|
let value = initialValue;
|
|
|
for (const element of iterable) {
|
|
|
value = reducer(value, element);
|
|
|
}
|
|
|
return value;
|
|
|
}
|
|
|
Iterable.reduce = reduce;
|
|
|
/**
|
|
|
* Returns an iterable slice of the array, with the same semantics as `array.slice()`.
|
|
|
*/
|
|
|
function* slice(arr, from, to = arr.length) {
|
|
|
if (from < 0) {
|
|
|
from += arr.length;
|
|
|
}
|
|
|
if (to < 0) {
|
|
|
to += arr.length;
|
|
|
}
|
|
|
else if (to > arr.length) {
|
|
|
to = arr.length;
|
|
|
}
|
|
|
for (; from < to; from++) {
|
|
|
yield arr[from];
|
|
|
}
|
|
|
}
|
|
|
Iterable.slice = slice;
|
|
|
/**
|
|
|
* Consumes `atMost` elements from iterable and returns the consumed elements,
|
|
|
* and an iterable for the rest of the elements.
|
|
|
*/
|
|
|
function consume(iterable, atMost = Number.POSITIVE_INFINITY) {
|
|
|
const consumed = [];
|
|
|
if (atMost === 0) {
|
|
|
return [consumed, iterable];
|
|
|
}
|
|
|
const iterator = iterable[Symbol.iterator]();
|
|
|
for (let i = 0; i < atMost; i++) {
|
|
|
const next = iterator.next();
|
|
|
if (next.done) {
|
|
|
return [consumed, Iterable.empty()];
|
|
|
}
|
|
|
consumed.push(next.value);
|
|
|
}
|
|
|
return [consumed, { [Symbol.iterator]() { return iterator; } }];
|
|
|
}
|
|
|
Iterable.consume = consume;
|
|
|
/**
|
|
|
* Returns whether the iterables are the same length and all items are
|
|
|
* equal using the comparator function.
|
|
|
*/
|
|
|
function equals(a, b, comparator = (at, bt) => at === bt) {
|
|
|
const ai = a[Symbol.iterator]();
|
|
|
const bi = b[Symbol.iterator]();
|
|
|
while (true) {
|
|
|
const an = ai.next();
|
|
|
const bn = bi.next();
|
|
|
if (an.done !== bn.done) {
|
|
|
return false;
|
|
|
}
|
|
|
else if (an.done) {
|
|
|
return true;
|
|
|
}
|
|
|
else if (!comparator(an.value, bn.value)) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Iterable.equals = equals;
|
|
|
})(Iterable || (Iterable = {}));
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/lifecycle.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Enables logging of potentially leaked disposables.
|
|
|
*
|
|
|
* A disposable is considered leaked if it is not disposed or not registered as the child of
|
|
|
* another disposable. This tracking is very simple an only works for classes that either
|
|
|
* extend Disposable or use a DisposableStore. This means there are a lot of false positives.
|
|
|
*/
|
|
|
const TRACK_DISPOSABLES = false;
|
|
|
let disposableTracker = null;
|
|
|
function setDisposableTracker(tracker) {
|
|
|
disposableTracker = tracker;
|
|
|
}
|
|
|
if (TRACK_DISPOSABLES) {
|
|
|
const __is_disposable_tracked__ = '__is_disposable_tracked__';
|
|
|
setDisposableTracker(new class {
|
|
|
trackDisposable(x) {
|
|
|
const stack = new Error('Potentially leaked disposable').stack;
|
|
|
setTimeout(() => {
|
|
|
if (!x[__is_disposable_tracked__]) {
|
|
|
console.log(stack);
|
|
|
}
|
|
|
}, 3000);
|
|
|
}
|
|
|
setParent(child, parent) {
|
|
|
if (child && child !== lifecycle_Disposable.None) {
|
|
|
try {
|
|
|
child[__is_disposable_tracked__] = true;
|
|
|
}
|
|
|
catch (_a) {
|
|
|
// noop
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
markAsDisposed(disposable) {
|
|
|
if (disposable && disposable !== lifecycle_Disposable.None) {
|
|
|
try {
|
|
|
disposable[__is_disposable_tracked__] = true;
|
|
|
}
|
|
|
catch (_a) {
|
|
|
// noop
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
markAsSingleton(disposable) { }
|
|
|
});
|
|
|
}
|
|
|
function trackDisposable(x) {
|
|
|
disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.trackDisposable(x);
|
|
|
return x;
|
|
|
}
|
|
|
function markAsDisposed(disposable) {
|
|
|
disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.markAsDisposed(disposable);
|
|
|
}
|
|
|
function setParentOfDisposable(child, parent) {
|
|
|
disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.setParent(child, parent);
|
|
|
}
|
|
|
function setParentOfDisposables(children, parent) {
|
|
|
if (!disposableTracker) {
|
|
|
return;
|
|
|
}
|
|
|
for (const child of children) {
|
|
|
disposableTracker.setParent(child, parent);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Indicates that the given object is a singleton which does not need to be disposed.
|
|
|
*/
|
|
|
function markAsSingleton(singleton) {
|
|
|
disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.markAsSingleton(singleton);
|
|
|
return singleton;
|
|
|
}
|
|
|
class MultiDisposeError extends Error {
|
|
|
constructor(errors) {
|
|
|
super(`Encountered errors while disposing of store. Errors: [${errors.join(', ')}]`);
|
|
|
this.errors = errors;
|
|
|
}
|
|
|
}
|
|
|
function isDisposable(thing) {
|
|
|
return typeof thing.dispose === 'function' && thing.dispose.length === 0;
|
|
|
}
|
|
|
function dispose(arg) {
|
|
|
if (Iterable.is(arg)) {
|
|
|
let errors = [];
|
|
|
for (const d of arg) {
|
|
|
if (d) {
|
|
|
try {
|
|
|
d.dispose();
|
|
|
}
|
|
|
catch (e) {
|
|
|
errors.push(e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (errors.length === 1) {
|
|
|
throw errors[0];
|
|
|
}
|
|
|
else if (errors.length > 1) {
|
|
|
throw new MultiDisposeError(errors);
|
|
|
}
|
|
|
return Array.isArray(arg) ? [] : arg;
|
|
|
}
|
|
|
else if (arg) {
|
|
|
arg.dispose();
|
|
|
return arg;
|
|
|
}
|
|
|
}
|
|
|
function combinedDisposable(...disposables) {
|
|
|
const parent = toDisposable(() => dispose(disposables));
|
|
|
setParentOfDisposables(disposables, parent);
|
|
|
return parent;
|
|
|
}
|
|
|
function toDisposable(fn) {
|
|
|
const self = trackDisposable({
|
|
|
dispose: once(() => {
|
|
|
markAsDisposed(self);
|
|
|
fn();
|
|
|
})
|
|
|
});
|
|
|
return self;
|
|
|
}
|
|
|
class DisposableStore {
|
|
|
constructor() {
|
|
|
this._toDispose = new Set();
|
|
|
this._isDisposed = false;
|
|
|
trackDisposable(this);
|
|
|
}
|
|
|
/**
|
|
|
* Dispose of all registered disposables and mark this object as disposed.
|
|
|
*
|
|
|
* Any future disposables added to this object will be disposed of on `add`.
|
|
|
*/
|
|
|
dispose() {
|
|
|
if (this._isDisposed) {
|
|
|
return;
|
|
|
}
|
|
|
markAsDisposed(this);
|
|
|
this._isDisposed = true;
|
|
|
this.clear();
|
|
|
}
|
|
|
/**
|
|
|
* Dispose of all registered disposables but do not mark this object as disposed.
|
|
|
*/
|
|
|
clear() {
|
|
|
try {
|
|
|
dispose(this._toDispose.values());
|
|
|
}
|
|
|
finally {
|
|
|
this._toDispose.clear();
|
|
|
}
|
|
|
}
|
|
|
add(o) {
|
|
|
if (!o) {
|
|
|
return o;
|
|
|
}
|
|
|
if (o === this) {
|
|
|
throw new Error('Cannot register a disposable on itself!');
|
|
|
}
|
|
|
setParentOfDisposable(o, this);
|
|
|
if (this._isDisposed) {
|
|
|
if (!DisposableStore.DISABLE_DISPOSED_WARNING) {
|
|
|
console.warn(new Error('Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!').stack);
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
this._toDispose.add(o);
|
|
|
}
|
|
|
return o;
|
|
|
}
|
|
|
}
|
|
|
DisposableStore.DISABLE_DISPOSED_WARNING = false;
|
|
|
class lifecycle_Disposable {
|
|
|
constructor() {
|
|
|
this._store = new DisposableStore();
|
|
|
trackDisposable(this);
|
|
|
setParentOfDisposable(this._store, this);
|
|
|
}
|
|
|
dispose() {
|
|
|
markAsDisposed(this);
|
|
|
this._store.dispose();
|
|
|
}
|
|
|
_register(o) {
|
|
|
if (o === this) {
|
|
|
throw new Error('Cannot register a disposable on itself!');
|
|
|
}
|
|
|
return this._store.add(o);
|
|
|
}
|
|
|
}
|
|
|
lifecycle_Disposable.None = Object.freeze({ dispose() { } });
|
|
|
/**
|
|
|
* Manages the lifecycle of a disposable value that may be changed.
|
|
|
*
|
|
|
* This ensures that when the disposable value is changed, the previously held disposable is disposed of. You can
|
|
|
* also register a `MutableDisposable` on a `Disposable` to ensure it is automatically cleaned up.
|
|
|
*/
|
|
|
class MutableDisposable {
|
|
|
constructor() {
|
|
|
this._isDisposed = false;
|
|
|
trackDisposable(this);
|
|
|
}
|
|
|
get value() {
|
|
|
return this._isDisposed ? undefined : this._value;
|
|
|
}
|
|
|
set value(value) {
|
|
|
var _a;
|
|
|
if (this._isDisposed || value === this._value) {
|
|
|
return;
|
|
|
}
|
|
|
(_a = this._value) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
|
if (value) {
|
|
|
setParentOfDisposable(value, this);
|
|
|
}
|
|
|
this._value = value;
|
|
|
}
|
|
|
clear() {
|
|
|
this.value = undefined;
|
|
|
}
|
|
|
dispose() {
|
|
|
var _a;
|
|
|
this._isDisposed = true;
|
|
|
markAsDisposed(this);
|
|
|
(_a = this._value) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
|
this._value = undefined;
|
|
|
}
|
|
|
/**
|
|
|
* Clears the value, but does not dispose it.
|
|
|
* The old value is returned.
|
|
|
*/
|
|
|
clearAndLeak() {
|
|
|
const oldValue = this._value;
|
|
|
this._value = undefined;
|
|
|
if (oldValue) {
|
|
|
setParentOfDisposable(oldValue, null);
|
|
|
}
|
|
|
return oldValue;
|
|
|
}
|
|
|
}
|
|
|
class ImmortalReference {
|
|
|
constructor(object) {
|
|
|
this.object = object;
|
|
|
}
|
|
|
dispose() { }
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/linkedList.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
class Node {
|
|
|
constructor(element) {
|
|
|
this.element = element;
|
|
|
this.next = Node.Undefined;
|
|
|
this.prev = Node.Undefined;
|
|
|
}
|
|
|
}
|
|
|
Node.Undefined = new Node(undefined);
|
|
|
class linkedList_LinkedList {
|
|
|
constructor() {
|
|
|
this._first = Node.Undefined;
|
|
|
this._last = Node.Undefined;
|
|
|
this._size = 0;
|
|
|
}
|
|
|
get size() {
|
|
|
return this._size;
|
|
|
}
|
|
|
isEmpty() {
|
|
|
return this._first === Node.Undefined;
|
|
|
}
|
|
|
clear() {
|
|
|
let node = this._first;
|
|
|
while (node !== Node.Undefined) {
|
|
|
const next = node.next;
|
|
|
node.prev = Node.Undefined;
|
|
|
node.next = Node.Undefined;
|
|
|
node = next;
|
|
|
}
|
|
|
this._first = Node.Undefined;
|
|
|
this._last = Node.Undefined;
|
|
|
this._size = 0;
|
|
|
}
|
|
|
unshift(element) {
|
|
|
return this._insert(element, false);
|
|
|
}
|
|
|
push(element) {
|
|
|
return this._insert(element, true);
|
|
|
}
|
|
|
_insert(element, atTheEnd) {
|
|
|
const newNode = new Node(element);
|
|
|
if (this._first === Node.Undefined) {
|
|
|
this._first = newNode;
|
|
|
this._last = newNode;
|
|
|
}
|
|
|
else if (atTheEnd) {
|
|
|
// push
|
|
|
const oldLast = this._last;
|
|
|
this._last = newNode;
|
|
|
newNode.prev = oldLast;
|
|
|
oldLast.next = newNode;
|
|
|
}
|
|
|
else {
|
|
|
// unshift
|
|
|
const oldFirst = this._first;
|
|
|
this._first = newNode;
|
|
|
newNode.next = oldFirst;
|
|
|
oldFirst.prev = newNode;
|
|
|
}
|
|
|
this._size += 1;
|
|
|
let didRemove = false;
|
|
|
return () => {
|
|
|
if (!didRemove) {
|
|
|
didRemove = true;
|
|
|
this._remove(newNode);
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
shift() {
|
|
|
if (this._first === Node.Undefined) {
|
|
|
return undefined;
|
|
|
}
|
|
|
else {
|
|
|
const res = this._first.element;
|
|
|
this._remove(this._first);
|
|
|
return res;
|
|
|
}
|
|
|
}
|
|
|
pop() {
|
|
|
if (this._last === Node.Undefined) {
|
|
|
return undefined;
|
|
|
}
|
|
|
else {
|
|
|
const res = this._last.element;
|
|
|
this._remove(this._last);
|
|
|
return res;
|
|
|
}
|
|
|
}
|
|
|
_remove(node) {
|
|
|
if (node.prev !== Node.Undefined && node.next !== Node.Undefined) {
|
|
|
// middle
|
|
|
const anchor = node.prev;
|
|
|
anchor.next = node.next;
|
|
|
node.next.prev = anchor;
|
|
|
}
|
|
|
else if (node.prev === Node.Undefined && node.next === Node.Undefined) {
|
|
|
// only node
|
|
|
this._first = Node.Undefined;
|
|
|
this._last = Node.Undefined;
|
|
|
}
|
|
|
else if (node.next === Node.Undefined) {
|
|
|
// last
|
|
|
this._last = this._last.prev;
|
|
|
this._last.next = Node.Undefined;
|
|
|
}
|
|
|
else if (node.prev === Node.Undefined) {
|
|
|
// first
|
|
|
this._first = this._first.next;
|
|
|
this._first.prev = Node.Undefined;
|
|
|
}
|
|
|
// done
|
|
|
this._size -= 1;
|
|
|
}
|
|
|
*[Symbol.iterator]() {
|
|
|
let node = this._first;
|
|
|
while (node !== Node.Undefined) {
|
|
|
yield node.element;
|
|
|
node = node.next;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/platform.js
|
|
|
/* provided dependency */ var process = __webpack_require__(/*! ./node_modules/_process@0.11.10@process/browser.js */ 671);
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
var _a;
|
|
|
const LANGUAGE_DEFAULT = 'en';
|
|
|
let _isWindows = false;
|
|
|
let _isMacintosh = false;
|
|
|
let _isLinux = false;
|
|
|
let _isLinuxSnap = false;
|
|
|
let _isNative = false;
|
|
|
let _isWeb = false;
|
|
|
let _isIOS = false;
|
|
|
let _locale = undefined;
|
|
|
let _language = (/* unused pure expression or super */ null && (LANGUAGE_DEFAULT));
|
|
|
let _translationsConfigFile = (/* unused pure expression or super */ null && (undefined));
|
|
|
let _userAgent = undefined;
|
|
|
const platform_globals = (typeof self === 'object' ? self : typeof __webpack_require__.g === 'object' ? __webpack_require__.g : {});
|
|
|
let nodeProcess = undefined;
|
|
|
if (typeof platform_globals.vscode !== 'undefined' && typeof platform_globals.vscode.process !== 'undefined') {
|
|
|
// Native environment (sandboxed)
|
|
|
nodeProcess = platform_globals.vscode.process;
|
|
|
}
|
|
|
else if (typeof process !== 'undefined') {
|
|
|
// Native environment (non-sandboxed)
|
|
|
nodeProcess = process;
|
|
|
}
|
|
|
const isElectronRenderer = typeof ((_a = nodeProcess === null || nodeProcess === void 0 ? void 0 : nodeProcess.versions) === null || _a === void 0 ? void 0 : _a.electron) === 'string' && nodeProcess.type === 'renderer';
|
|
|
// Web environment
|
|
|
if (typeof navigator === 'object' && !isElectronRenderer) {
|
|
|
_userAgent = navigator.userAgent;
|
|
|
_isWindows = _userAgent.indexOf('Windows') >= 0;
|
|
|
_isMacintosh = _userAgent.indexOf('Macintosh') >= 0;
|
|
|
_isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0;
|
|
|
_isLinux = _userAgent.indexOf('Linux') >= 0;
|
|
|
_isWeb = true;
|
|
|
_locale = navigator.language;
|
|
|
_language = _locale;
|
|
|
}
|
|
|
// Native environment
|
|
|
else if (typeof nodeProcess === 'object') {
|
|
|
_isWindows = (nodeProcess.platform === 'win32');
|
|
|
_isMacintosh = (nodeProcess.platform === 'darwin');
|
|
|
_isLinux = (nodeProcess.platform === 'linux');
|
|
|
_isLinuxSnap = _isLinux && !!nodeProcess.env['SNAP'] && !!nodeProcess.env['SNAP_REVISION'];
|
|
|
_locale = LANGUAGE_DEFAULT;
|
|
|
_language = LANGUAGE_DEFAULT;
|
|
|
const rawNlsConfig = nodeProcess.env['VSCODE_NLS_CONFIG'];
|
|
|
if (rawNlsConfig) {
|
|
|
try {
|
|
|
const nlsConfig = JSON.parse(rawNlsConfig);
|
|
|
const resolved = nlsConfig.availableLanguages['*'];
|
|
|
_locale = nlsConfig.locale;
|
|
|
// VSCode's default language is 'en'
|
|
|
_language = resolved ? resolved : LANGUAGE_DEFAULT;
|
|
|
_translationsConfigFile = nlsConfig._translationsConfigFile;
|
|
|
}
|
|
|
catch (e) {
|
|
|
}
|
|
|
}
|
|
|
_isNative = true;
|
|
|
}
|
|
|
// Unknown environment
|
|
|
else {
|
|
|
console.error('Unable to resolve platform.');
|
|
|
}
|
|
|
let _platform = 0 /* Web */;
|
|
|
if (_isMacintosh) {
|
|
|
_platform = 1 /* Mac */;
|
|
|
}
|
|
|
else if (_isWindows) {
|
|
|
_platform = 3 /* Windows */;
|
|
|
}
|
|
|
else if (_isLinux) {
|
|
|
_platform = 2 /* Linux */;
|
|
|
}
|
|
|
const isWindows = _isWindows;
|
|
|
const isMacintosh = _isMacintosh;
|
|
|
const isLinux = (/* unused pure expression or super */ null && (_isLinux));
|
|
|
const isNative = (/* unused pure expression or super */ null && (_isNative));
|
|
|
const platform_isWeb = (/* unused pure expression or super */ null && (_isWeb));
|
|
|
const isIOS = (/* unused pure expression or super */ null && (_isIOS));
|
|
|
const userAgent = (/* unused pure expression or super */ null && (_userAgent));
|
|
|
const setImmediate = (function defineSetImmediate() {
|
|
|
if (platform_globals.setImmediate) {
|
|
|
return platform_globals.setImmediate.bind(platform_globals);
|
|
|
}
|
|
|
if (typeof platform_globals.postMessage === 'function' && !platform_globals.importScripts) {
|
|
|
let pending = [];
|
|
|
platform_globals.addEventListener('message', (e) => {
|
|
|
if (e.data && e.data.vscodeSetImmediateId) {
|
|
|
for (let i = 0, len = pending.length; i < len; i++) {
|
|
|
const candidate = pending[i];
|
|
|
if (candidate.id === e.data.vscodeSetImmediateId) {
|
|
|
pending.splice(i, 1);
|
|
|
candidate.callback();
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
let lastId = 0;
|
|
|
return (callback) => {
|
|
|
const myId = ++lastId;
|
|
|
pending.push({
|
|
|
id: myId,
|
|
|
callback: callback
|
|
|
});
|
|
|
platform_globals.postMessage({ vscodeSetImmediateId: myId }, '*');
|
|
|
};
|
|
|
}
|
|
|
if (typeof (nodeProcess === null || nodeProcess === void 0 ? void 0 : nodeProcess.nextTick) === 'function') {
|
|
|
return nodeProcess.nextTick.bind(nodeProcess);
|
|
|
}
|
|
|
const _promise = Promise.resolve();
|
|
|
return (callback) => _promise.then(callback);
|
|
|
})();
|
|
|
const OS = ((/* unused pure expression or super */ null && (_isMacintosh || _isIOS ? 2 /* Macintosh */ : (_isWindows ? 1 /* Windows */ : 3 /* Linux */))));
|
|
|
let _isLittleEndian = true;
|
|
|
let _isLittleEndianComputed = false;
|
|
|
function isLittleEndian() {
|
|
|
if (!_isLittleEndianComputed) {
|
|
|
_isLittleEndianComputed = true;
|
|
|
const test = new Uint8Array(2);
|
|
|
test[0] = 1;
|
|
|
test[1] = 2;
|
|
|
const view = new Uint16Array(test.buffer);
|
|
|
_isLittleEndian = (view[0] === (2 << 8) + 1);
|
|
|
}
|
|
|
return _isLittleEndian;
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/stopwatch.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
const hasPerformanceNow = (platform_globals.performance && typeof platform_globals.performance.now === 'function');
|
|
|
class StopWatch {
|
|
|
constructor(highResolution) {
|
|
|
this._highResolution = hasPerformanceNow && highResolution;
|
|
|
this._startTime = this._now();
|
|
|
this._stopTime = -1;
|
|
|
}
|
|
|
static create(highResolution = true) {
|
|
|
return new StopWatch(highResolution);
|
|
|
}
|
|
|
stop() {
|
|
|
this._stopTime = this._now();
|
|
|
}
|
|
|
elapsed() {
|
|
|
if (this._stopTime !== -1) {
|
|
|
return this._stopTime - this._startTime;
|
|
|
}
|
|
|
return this._now() - this._startTime;
|
|
|
}
|
|
|
_now() {
|
|
|
return this._highResolution ? platform_globals.performance.now() : Date.now();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/event.js
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var Event;
|
|
|
(function (Event) {
|
|
|
Event.None = () => lifecycle_Disposable.None;
|
|
|
/**
|
|
|
* Given an event, returns another event which only fires once.
|
|
|
*/
|
|
|
function once(event) {
|
|
|
return (listener, thisArgs = null, disposables) => {
|
|
|
// we need this, in case the event fires during the listener call
|
|
|
let didFire = false;
|
|
|
let result;
|
|
|
result = event(e => {
|
|
|
if (didFire) {
|
|
|
return;
|
|
|
}
|
|
|
else if (result) {
|
|
|
result.dispose();
|
|
|
}
|
|
|
else {
|
|
|
didFire = true;
|
|
|
}
|
|
|
return listener.call(thisArgs, e);
|
|
|
}, null, disposables);
|
|
|
if (didFire) {
|
|
|
result.dispose();
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
}
|
|
|
Event.once = once;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function map(event, map) {
|
|
|
return snapshot((listener, thisArgs = null, disposables) => event(i => listener.call(thisArgs, map(i)), null, disposables));
|
|
|
}
|
|
|
Event.map = map;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function forEach(event, each) {
|
|
|
return snapshot((listener, thisArgs = null, disposables) => event(i => { each(i); listener.call(thisArgs, i); }, null, disposables));
|
|
|
}
|
|
|
Event.forEach = forEach;
|
|
|
function filter(event, filter) {
|
|
|
return snapshot((listener, thisArgs = null, disposables) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables));
|
|
|
}
|
|
|
Event.filter = filter;
|
|
|
/**
|
|
|
* Given an event, returns the same event but typed as `Event<void>`.
|
|
|
*/
|
|
|
function signal(event) {
|
|
|
return event;
|
|
|
}
|
|
|
Event.signal = signal;
|
|
|
function any(...events) {
|
|
|
return (listener, thisArgs = null, disposables) => combinedDisposable(...events.map(event => event(e => listener.call(thisArgs, e), null, disposables)));
|
|
|
}
|
|
|
Event.any = any;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function reduce(event, merge, initial) {
|
|
|
let output = initial;
|
|
|
return map(event, e => {
|
|
|
output = merge(output, e);
|
|
|
return output;
|
|
|
});
|
|
|
}
|
|
|
Event.reduce = reduce;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function snapshot(event) {
|
|
|
let listener;
|
|
|
const emitter = new Emitter({
|
|
|
onFirstListenerAdd() {
|
|
|
listener = event(emitter.fire, emitter);
|
|
|
},
|
|
|
onLastListenerRemove() {
|
|
|
listener.dispose();
|
|
|
}
|
|
|
});
|
|
|
return emitter.event;
|
|
|
}
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function debounce(event, merge, delay = 100, leading = false, leakWarningThreshold) {
|
|
|
let subscription;
|
|
|
let output = undefined;
|
|
|
let handle = undefined;
|
|
|
let numDebouncedCalls = 0;
|
|
|
const emitter = new Emitter({
|
|
|
leakWarningThreshold,
|
|
|
onFirstListenerAdd() {
|
|
|
subscription = event(cur => {
|
|
|
numDebouncedCalls++;
|
|
|
output = merge(output, cur);
|
|
|
if (leading && !handle) {
|
|
|
emitter.fire(output);
|
|
|
output = undefined;
|
|
|
}
|
|
|
clearTimeout(handle);
|
|
|
handle = setTimeout(() => {
|
|
|
const _output = output;
|
|
|
output = undefined;
|
|
|
handle = undefined;
|
|
|
if (!leading || numDebouncedCalls > 1) {
|
|
|
emitter.fire(_output);
|
|
|
}
|
|
|
numDebouncedCalls = 0;
|
|
|
}, delay);
|
|
|
});
|
|
|
},
|
|
|
onLastListenerRemove() {
|
|
|
subscription.dispose();
|
|
|
}
|
|
|
});
|
|
|
return emitter.event;
|
|
|
}
|
|
|
Event.debounce = debounce;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function latch(event, equals = (a, b) => a === b) {
|
|
|
let firstCall = true;
|
|
|
let cache;
|
|
|
return filter(event, value => {
|
|
|
const shouldEmit = firstCall || !equals(value, cache);
|
|
|
firstCall = false;
|
|
|
cache = value;
|
|
|
return shouldEmit;
|
|
|
});
|
|
|
}
|
|
|
Event.latch = latch;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function split(event, isT) {
|
|
|
return [
|
|
|
Event.filter(event, isT),
|
|
|
Event.filter(event, e => !isT(e)),
|
|
|
];
|
|
|
}
|
|
|
Event.split = split;
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function buffer(event, nextTick = false, _buffer = []) {
|
|
|
let buffer = _buffer.slice();
|
|
|
let listener = event(e => {
|
|
|
if (buffer) {
|
|
|
buffer.push(e);
|
|
|
}
|
|
|
else {
|
|
|
emitter.fire(e);
|
|
|
}
|
|
|
});
|
|
|
const flush = () => {
|
|
|
if (buffer) {
|
|
|
buffer.forEach(e => emitter.fire(e));
|
|
|
}
|
|
|
buffer = null;
|
|
|
};
|
|
|
const emitter = new Emitter({
|
|
|
onFirstListenerAdd() {
|
|
|
if (!listener) {
|
|
|
listener = event(e => emitter.fire(e));
|
|
|
}
|
|
|
},
|
|
|
onFirstListenerDidAdd() {
|
|
|
if (buffer) {
|
|
|
if (nextTick) {
|
|
|
setTimeout(flush);
|
|
|
}
|
|
|
else {
|
|
|
flush();
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
onLastListenerRemove() {
|
|
|
if (listener) {
|
|
|
listener.dispose();
|
|
|
}
|
|
|
listener = null;
|
|
|
}
|
|
|
});
|
|
|
return emitter.event;
|
|
|
}
|
|
|
Event.buffer = buffer;
|
|
|
class ChainableEvent {
|
|
|
constructor(event) {
|
|
|
this.event = event;
|
|
|
}
|
|
|
map(fn) {
|
|
|
return new ChainableEvent(map(this.event, fn));
|
|
|
}
|
|
|
forEach(fn) {
|
|
|
return new ChainableEvent(forEach(this.event, fn));
|
|
|
}
|
|
|
filter(fn) {
|
|
|
return new ChainableEvent(filter(this.event, fn));
|
|
|
}
|
|
|
reduce(merge, initial) {
|
|
|
return new ChainableEvent(reduce(this.event, merge, initial));
|
|
|
}
|
|
|
latch() {
|
|
|
return new ChainableEvent(latch(this.event));
|
|
|
}
|
|
|
debounce(merge, delay = 100, leading = false, leakWarningThreshold) {
|
|
|
return new ChainableEvent(debounce(this.event, merge, delay, leading, leakWarningThreshold));
|
|
|
}
|
|
|
on(listener, thisArgs, disposables) {
|
|
|
return this.event(listener, thisArgs, disposables);
|
|
|
}
|
|
|
once(listener, thisArgs, disposables) {
|
|
|
return once(this.event)(listener, thisArgs, disposables);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* @deprecated DO NOT use, this leaks memory
|
|
|
*/
|
|
|
function chain(event) {
|
|
|
return new ChainableEvent(event);
|
|
|
}
|
|
|
Event.chain = chain;
|
|
|
function fromNodeEventEmitter(emitter, eventName, map = id => id) {
|
|
|
const fn = (...args) => result.fire(map(...args));
|
|
|
const onFirstListenerAdd = () => emitter.on(eventName, fn);
|
|
|
const onLastListenerRemove = () => emitter.removeListener(eventName, fn);
|
|
|
const result = new Emitter({ onFirstListenerAdd, onLastListenerRemove });
|
|
|
return result.event;
|
|
|
}
|
|
|
Event.fromNodeEventEmitter = fromNodeEventEmitter;
|
|
|
function fromDOMEventEmitter(emitter, eventName, map = id => id) {
|
|
|
const fn = (...args) => result.fire(map(...args));
|
|
|
const onFirstListenerAdd = () => emitter.addEventListener(eventName, fn);
|
|
|
const onLastListenerRemove = () => emitter.removeEventListener(eventName, fn);
|
|
|
const result = new Emitter({ onFirstListenerAdd, onLastListenerRemove });
|
|
|
return result.event;
|
|
|
}
|
|
|
Event.fromDOMEventEmitter = fromDOMEventEmitter;
|
|
|
function toPromise(event) {
|
|
|
return new Promise(resolve => once(event)(resolve));
|
|
|
}
|
|
|
Event.toPromise = toPromise;
|
|
|
})(Event || (Event = {}));
|
|
|
class EventProfiling {
|
|
|
constructor(name) {
|
|
|
this._listenerCount = 0;
|
|
|
this._invocationCount = 0;
|
|
|
this._elapsedOverall = 0;
|
|
|
this._name = `${name}_${EventProfiling._idPool++}`;
|
|
|
}
|
|
|
start(listenerCount) {
|
|
|
this._stopWatch = new StopWatch(true);
|
|
|
this._listenerCount = listenerCount;
|
|
|
}
|
|
|
stop() {
|
|
|
if (this._stopWatch) {
|
|
|
const elapsed = this._stopWatch.elapsed();
|
|
|
this._elapsedOverall += elapsed;
|
|
|
this._invocationCount += 1;
|
|
|
console.info(`did FIRE ${this._name}: elapsed_ms: ${elapsed.toFixed(5)}, listener: ${this._listenerCount} (elapsed_overall: ${this._elapsedOverall.toFixed(2)}, invocations: ${this._invocationCount})`);
|
|
|
this._stopWatch = undefined;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
EventProfiling._idPool = 0;
|
|
|
let _globalLeakWarningThreshold = -1;
|
|
|
class LeakageMonitor {
|
|
|
constructor(customThreshold, name = Math.random().toString(18).slice(2, 5)) {
|
|
|
this.customThreshold = customThreshold;
|
|
|
this.name = name;
|
|
|
this._warnCountdown = 0;
|
|
|
}
|
|
|
dispose() {
|
|
|
if (this._stacks) {
|
|
|
this._stacks.clear();
|
|
|
}
|
|
|
}
|
|
|
check(listenerCount) {
|
|
|
let threshold = _globalLeakWarningThreshold;
|
|
|
if (typeof this.customThreshold === 'number') {
|
|
|
threshold = this.customThreshold;
|
|
|
}
|
|
|
if (threshold <= 0 || listenerCount < threshold) {
|
|
|
return undefined;
|
|
|
}
|
|
|
if (!this._stacks) {
|
|
|
this._stacks = new Map();
|
|
|
}
|
|
|
const stack = new Error().stack.split('\n').slice(3).join('\n');
|
|
|
const count = (this._stacks.get(stack) || 0);
|
|
|
this._stacks.set(stack, count + 1);
|
|
|
this._warnCountdown -= 1;
|
|
|
if (this._warnCountdown <= 0) {
|
|
|
// only warn on first exceed and then every time the limit
|
|
|
// is exceeded by 50% again
|
|
|
this._warnCountdown = threshold * 0.5;
|
|
|
// find most frequent listener and print warning
|
|
|
let topStack;
|
|
|
let topCount = 0;
|
|
|
for (const [stack, count] of this._stacks) {
|
|
|
if (!topStack || topCount < count) {
|
|
|
topStack = stack;
|
|
|
topCount = count;
|
|
|
}
|
|
|
}
|
|
|
console.warn(`[${this.name}] potential listener LEAK detected, having ${listenerCount} listeners already. MOST frequent listener (${topCount}):`);
|
|
|
console.warn(topStack);
|
|
|
}
|
|
|
return () => {
|
|
|
const count = (this._stacks.get(stack) || 0);
|
|
|
this._stacks.set(stack, count - 1);
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* The Emitter can be used to expose an Event to the public
|
|
|
* to fire it from the insides.
|
|
|
* Sample:
|
|
|
class Document {
|
|
|
|
|
|
private readonly _onDidChange = new Emitter<(value:string)=>any>();
|
|
|
|
|
|
public onDidChange = this._onDidChange.event;
|
|
|
|
|
|
// getter-style
|
|
|
// get onDidChange(): Event<(value:string)=>any> {
|
|
|
// return this._onDidChange.event;
|
|
|
// }
|
|
|
|
|
|
private _doIt() {
|
|
|
//...
|
|
|
this._onDidChange.fire(value);
|
|
|
}
|
|
|
}
|
|
|
*/
|
|
|
class Emitter {
|
|
|
constructor(options) {
|
|
|
var _a;
|
|
|
this._disposed = false;
|
|
|
this._options = options;
|
|
|
this._leakageMon = _globalLeakWarningThreshold > 0 ? new LeakageMonitor(this._options && this._options.leakWarningThreshold) : undefined;
|
|
|
this._perfMon = ((_a = this._options) === null || _a === void 0 ? void 0 : _a._profName) ? new EventProfiling(this._options._profName) : undefined;
|
|
|
}
|
|
|
/**
|
|
|
* For the public to allow to subscribe
|
|
|
* to events from this Emitter
|
|
|
*/
|
|
|
get event() {
|
|
|
if (!this._event) {
|
|
|
this._event = (listener, thisArgs, disposables) => {
|
|
|
var _a;
|
|
|
if (!this._listeners) {
|
|
|
this._listeners = new linkedList_LinkedList();
|
|
|
}
|
|
|
const firstListener = this._listeners.isEmpty();
|
|
|
if (firstListener && this._options && this._options.onFirstListenerAdd) {
|
|
|
this._options.onFirstListenerAdd(this);
|
|
|
}
|
|
|
const remove = this._listeners.push(!thisArgs ? listener : [listener, thisArgs]);
|
|
|
if (firstListener && this._options && this._options.onFirstListenerDidAdd) {
|
|
|
this._options.onFirstListenerDidAdd(this);
|
|
|
}
|
|
|
if (this._options && this._options.onListenerDidAdd) {
|
|
|
this._options.onListenerDidAdd(this, listener, thisArgs);
|
|
|
}
|
|
|
// check and record this emitter for potential leakage
|
|
|
const removeMonitor = (_a = this._leakageMon) === null || _a === void 0 ? void 0 : _a.check(this._listeners.size);
|
|
|
const result = toDisposable(() => {
|
|
|
if (removeMonitor) {
|
|
|
removeMonitor();
|
|
|
}
|
|
|
if (!this._disposed) {
|
|
|
remove();
|
|
|
if (this._options && this._options.onLastListenerRemove) {
|
|
|
const hasListeners = (this._listeners && !this._listeners.isEmpty());
|
|
|
if (!hasListeners) {
|
|
|
this._options.onLastListenerRemove(this);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
if (disposables instanceof DisposableStore) {
|
|
|
disposables.add(result);
|
|
|
}
|
|
|
else if (Array.isArray(disposables)) {
|
|
|
disposables.push(result);
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
}
|
|
|
return this._event;
|
|
|
}
|
|
|
/**
|
|
|
* To be kept private to fire an event to
|
|
|
* subscribers
|
|
|
*/
|
|
|
fire(event) {
|
|
|
var _a, _b;
|
|
|
if (this._listeners) {
|
|
|
// put all [listener,event]-pairs into delivery queue
|
|
|
// then emit all event. an inner/nested event might be
|
|
|
// the driver of this
|
|
|
if (!this._deliveryQueue) {
|
|
|
this._deliveryQueue = new linkedList_LinkedList();
|
|
|
}
|
|
|
for (let listener of this._listeners) {
|
|
|
this._deliveryQueue.push([listener, event]);
|
|
|
}
|
|
|
// start/stop performance insight collection
|
|
|
(_a = this._perfMon) === null || _a === void 0 ? void 0 : _a.start(this._deliveryQueue.size);
|
|
|
while (this._deliveryQueue.size > 0) {
|
|
|
const [listener, event] = this._deliveryQueue.shift();
|
|
|
try {
|
|
|
if (typeof listener === 'function') {
|
|
|
listener.call(undefined, event);
|
|
|
}
|
|
|
else {
|
|
|
listener[0].call(listener[1], event);
|
|
|
}
|
|
|
}
|
|
|
catch (e) {
|
|
|
onUnexpectedError(e);
|
|
|
}
|
|
|
}
|
|
|
(_b = this._perfMon) === null || _b === void 0 ? void 0 : _b.stop();
|
|
|
}
|
|
|
}
|
|
|
dispose() {
|
|
|
var _a, _b, _c, _d, _e;
|
|
|
if (!this._disposed) {
|
|
|
this._disposed = true;
|
|
|
(_a = this._listeners) === null || _a === void 0 ? void 0 : _a.clear();
|
|
|
(_b = this._deliveryQueue) === null || _b === void 0 ? void 0 : _b.clear();
|
|
|
(_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.onLastListenerRemove) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
|
(_e = this._leakageMon) === null || _e === void 0 ? void 0 : _e.dispose();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
class PauseableEmitter extends (/* unused pure expression or super */ null && (Emitter)) {
|
|
|
constructor(options) {
|
|
|
super(options);
|
|
|
this._isPaused = 0;
|
|
|
this._eventQueue = new LinkedList();
|
|
|
this._mergeFn = options === null || options === void 0 ? void 0 : options.merge;
|
|
|
}
|
|
|
pause() {
|
|
|
this._isPaused++;
|
|
|
}
|
|
|
resume() {
|
|
|
if (this._isPaused !== 0 && --this._isPaused === 0) {
|
|
|
if (this._mergeFn) {
|
|
|
// use the merge function to create a single composite
|
|
|
// event. make a copy in case firing pauses this emitter
|
|
|
const events = Array.from(this._eventQueue);
|
|
|
this._eventQueue.clear();
|
|
|
super.fire(this._mergeFn(events));
|
|
|
}
|
|
|
else {
|
|
|
// no merging, fire each event individually and test
|
|
|
// that this emitter isn't paused halfway through
|
|
|
while (!this._isPaused && this._eventQueue.size !== 0) {
|
|
|
super.fire(this._eventQueue.shift());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
fire(event) {
|
|
|
if (this._listeners) {
|
|
|
if (this._isPaused !== 0) {
|
|
|
this._eventQueue.push(event);
|
|
|
}
|
|
|
else {
|
|
|
super.fire(event);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
class DebounceEmitter extends (/* unused pure expression or super */ null && (PauseableEmitter)) {
|
|
|
constructor(options) {
|
|
|
var _a;
|
|
|
super(options);
|
|
|
this._delay = (_a = options.delay) !== null && _a !== void 0 ? _a : 100;
|
|
|
}
|
|
|
fire(event) {
|
|
|
if (!this._handle) {
|
|
|
this.pause();
|
|
|
this._handle = setTimeout(() => {
|
|
|
this._handle = undefined;
|
|
|
this.resume();
|
|
|
}, this._delay);
|
|
|
}
|
|
|
super.fire(event);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* The EventBufferer is useful in situations in which you want
|
|
|
* to delay firing your events during some code.
|
|
|
* You can wrap that code and be sure that the event will not
|
|
|
* be fired during that wrap.
|
|
|
*
|
|
|
* ```
|
|
|
* const emitter: Emitter;
|
|
|
* const delayer = new EventDelayer();
|
|
|
* const delayedEvent = delayer.wrapEvent(emitter.event);
|
|
|
*
|
|
|
* delayedEvent(console.log);
|
|
|
*
|
|
|
* delayer.bufferEvents(() => {
|
|
|
* emitter.fire(); // event will not be fired yet
|
|
|
* });
|
|
|
*
|
|
|
* // event will only be fired at this point
|
|
|
* ```
|
|
|
*/
|
|
|
class EventBufferer {
|
|
|
constructor() {
|
|
|
this.buffers = [];
|
|
|
}
|
|
|
wrapEvent(event) {
|
|
|
return (listener, thisArgs, disposables) => {
|
|
|
return event(i => {
|
|
|
const buffer = this.buffers[this.buffers.length - 1];
|
|
|
if (buffer) {
|
|
|
buffer.push(() => listener.call(thisArgs, i));
|
|
|
}
|
|
|
else {
|
|
|
listener.call(thisArgs, i);
|
|
|
}
|
|
|
}, undefined, disposables);
|
|
|
};
|
|
|
}
|
|
|
bufferEvents(fn) {
|
|
|
const buffer = [];
|
|
|
this.buffers.push(buffer);
|
|
|
const r = fn();
|
|
|
this.buffers.pop();
|
|
|
buffer.forEach(flush => flush());
|
|
|
return r;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* A Relay is an event forwarder which functions as a replugabble event pipe.
|
|
|
* Once created, you can connect an input event to it and it will simply forward
|
|
|
* events from that input event through its own `event` property. The `input`
|
|
|
* can be changed at any point in time.
|
|
|
*/
|
|
|
class Relay {
|
|
|
constructor() {
|
|
|
this.listening = false;
|
|
|
this.inputEvent = Event.None;
|
|
|
this.inputEventListener = Disposable.None;
|
|
|
this.emitter = new Emitter({
|
|
|
onFirstListenerDidAdd: () => {
|
|
|
this.listening = true;
|
|
|
this.inputEventListener = this.inputEvent(this.emitter.fire, this.emitter);
|
|
|
},
|
|
|
onLastListenerRemove: () => {
|
|
|
this.listening = false;
|
|
|
this.inputEventListener.dispose();
|
|
|
}
|
|
|
});
|
|
|
this.event = this.emitter.event;
|
|
|
}
|
|
|
set input(event) {
|
|
|
this.inputEvent = event;
|
|
|
if (this.listening) {
|
|
|
this.inputEventListener.dispose();
|
|
|
this.inputEventListener = event(this.emitter.fire, this.emitter);
|
|
|
}
|
|
|
}
|
|
|
dispose() {
|
|
|
this.inputEventListener.dispose();
|
|
|
this.emitter.dispose();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/types.js
|
|
|
/**
|
|
|
* @returns whether the provided parameter is a JavaScript Array or not.
|
|
|
*/
|
|
|
function isArray(array) {
|
|
|
return Array.isArray(array);
|
|
|
}
|
|
|
/**
|
|
|
* @returns whether the provided parameter is a JavaScript String or not.
|
|
|
*/
|
|
|
function isString(str) {
|
|
|
return (typeof str === 'string');
|
|
|
}
|
|
|
/**
|
|
|
*
|
|
|
* @returns whether the provided parameter is of type `object` but **not**
|
|
|
* `null`, an `array`, a `regexp`, nor a `date`.
|
|
|
*/
|
|
|
function isObject(obj) {
|
|
|
// The method can't do a type cast since there are type (like strings) which
|
|
|
// are subclasses of any put not positvely matched by the function. Hence type
|
|
|
// narrowing results in wrong results.
|
|
|
return typeof obj === 'object'
|
|
|
&& obj !== null
|
|
|
&& !Array.isArray(obj)
|
|
|
&& !(obj instanceof RegExp)
|
|
|
&& !(obj instanceof Date);
|
|
|
}
|
|
|
/**
|
|
|
* In **contrast** to just checking `typeof` this will return `false` for `NaN`.
|
|
|
* @returns whether the provided parameter is a JavaScript Number or not.
|
|
|
*/
|
|
|
function isNumber(obj) {
|
|
|
return (typeof obj === 'number' && !isNaN(obj));
|
|
|
}
|
|
|
/**
|
|
|
* @returns whether the provided parameter is a JavaScript Boolean or not.
|
|
|
*/
|
|
|
function isBoolean(obj) {
|
|
|
return (obj === true || obj === false);
|
|
|
}
|
|
|
/**
|
|
|
* @returns whether the provided parameter is undefined.
|
|
|
*/
|
|
|
function isUndefined(obj) {
|
|
|
return (typeof obj === 'undefined');
|
|
|
}
|
|
|
/**
|
|
|
* @returns whether the provided parameter is defined.
|
|
|
*/
|
|
|
function isDefined(arg) {
|
|
|
return !isUndefinedOrNull(arg);
|
|
|
}
|
|
|
/**
|
|
|
* @returns whether the provided parameter is undefined or null.
|
|
|
*/
|
|
|
function isUndefinedOrNull(obj) {
|
|
|
return (isUndefined(obj) || obj === null);
|
|
|
}
|
|
|
function assertType(condition, type) {
|
|
|
if (!condition) {
|
|
|
throw new Error(type ? `Unexpected type, expected '${type}'` : 'Unexpected type');
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Asserts that the argument passed in is neither undefined nor null.
|
|
|
*/
|
|
|
function assertIsDefined(arg) {
|
|
|
if (isUndefinedOrNull(arg)) {
|
|
|
throw new Error('Assertion Failed: argument is undefined or null');
|
|
|
}
|
|
|
return arg;
|
|
|
}
|
|
|
/**
|
|
|
* @returns whether the provided parameter is a JavaScript Function or not.
|
|
|
*/
|
|
|
function isFunction(obj) {
|
|
|
return (typeof obj === 'function');
|
|
|
}
|
|
|
function validateConstraints(args, constraints) {
|
|
|
const len = Math.min(args.length, constraints.length);
|
|
|
for (let i = 0; i < len; i++) {
|
|
|
validateConstraint(args[i], constraints[i]);
|
|
|
}
|
|
|
}
|
|
|
function validateConstraint(arg, constraint) {
|
|
|
if (isString(constraint)) {
|
|
|
if (typeof arg !== constraint) {
|
|
|
throw new Error(`argument does not match constraint: typeof ${constraint}`);
|
|
|
}
|
|
|
}
|
|
|
else if (isFunction(constraint)) {
|
|
|
try {
|
|
|
if (arg instanceof constraint) {
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
catch (_a) {
|
|
|
// ignore
|
|
|
}
|
|
|
if (!isUndefinedOrNull(arg) && arg.constructor === constraint) {
|
|
|
return;
|
|
|
}
|
|
|
if (constraint.length === 1 && constraint.call(undefined, arg) === true) {
|
|
|
return;
|
|
|
}
|
|
|
throw new Error(`argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true`);
|
|
|
}
|
|
|
}
|
|
|
function getAllPropertyNames(obj) {
|
|
|
let res = [];
|
|
|
let proto = Object.getPrototypeOf(obj);
|
|
|
while (Object.prototype !== proto) {
|
|
|
res = res.concat(Object.getOwnPropertyNames(proto));
|
|
|
proto = Object.getPrototypeOf(proto);
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
function getAllMethodNames(obj) {
|
|
|
const methods = [];
|
|
|
for (const prop of getAllPropertyNames(obj)) {
|
|
|
if (typeof obj[prop] === 'function') {
|
|
|
methods.push(prop);
|
|
|
}
|
|
|
}
|
|
|
return methods;
|
|
|
}
|
|
|
function createProxyObject(methodNames, invoke) {
|
|
|
const createProxyMethod = (method) => {
|
|
|
return function () {
|
|
|
const args = Array.prototype.slice.call(arguments, 0);
|
|
|
return invoke(method, args);
|
|
|
};
|
|
|
};
|
|
|
let result = {};
|
|
|
for (const methodName of methodNames) {
|
|
|
result[methodName] = createProxyMethod(methodName);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
/**
|
|
|
* Converts null to undefined, passes all other values through.
|
|
|
*/
|
|
|
function withNullAsUndefined(x) {
|
|
|
return x === null ? undefined : x;
|
|
|
}
|
|
|
function assertNever(value, message = 'Unreachable') {
|
|
|
throw new Error(message);
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/strings.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
function isFalsyOrWhitespace(str) {
|
|
|
if (!str || typeof str !== 'string') {
|
|
|
return true;
|
|
|
}
|
|
|
return str.trim().length === 0;
|
|
|
}
|
|
|
const _formatRegexp = /{(\d+)}/g;
|
|
|
/**
|
|
|
* Helper to produce a string with a variable number of arguments. Insert variable segments
|
|
|
* into the string using the {n} notation where N is the index of the argument following the string.
|
|
|
* @param value string to which formatting is applied
|
|
|
* @param args replacements for {n}-entries
|
|
|
*/
|
|
|
function format(value, ...args) {
|
|
|
if (args.length === 0) {
|
|
|
return value;
|
|
|
}
|
|
|
return value.replace(_formatRegexp, function (match, group) {
|
|
|
const idx = parseInt(group, 10);
|
|
|
return isNaN(idx) || idx < 0 || idx >= args.length ?
|
|
|
match :
|
|
|
args[idx];
|
|
|
});
|
|
|
}
|
|
|
/**
|
|
|
* Converts HTML characters inside the string to use entities instead. Makes the string safe from
|
|
|
* being used e.g. in HTMLElement.innerHTML.
|
|
|
*/
|
|
|
function strings_escape(html) {
|
|
|
return html.replace(/[<>&]/g, function (match) {
|
|
|
switch (match) {
|
|
|
case '<': return '<';
|
|
|
case '>': return '>';
|
|
|
case '&': return '&';
|
|
|
default: return match;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
/**
|
|
|
* Escapes regular expression characters in a given string
|
|
|
*/
|
|
|
function escapeRegExpCharacters(value) {
|
|
|
return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&');
|
|
|
}
|
|
|
/**
|
|
|
* Removes all occurrences of needle from the beginning and end of haystack.
|
|
|
* @param haystack string to trim
|
|
|
* @param needle the thing to trim (default is a blank)
|
|
|
*/
|
|
|
function trim(haystack, needle = ' ') {
|
|
|
const trimmed = ltrim(haystack, needle);
|
|
|
return rtrim(trimmed, needle);
|
|
|
}
|
|
|
/**
|
|
|
* Removes all occurrences of needle from the beginning of haystack.
|
|
|
* @param haystack string to trim
|
|
|
* @param needle the thing to trim
|
|
|
*/
|
|
|
function ltrim(haystack, needle) {
|
|
|
if (!haystack || !needle) {
|
|
|
return haystack;
|
|
|
}
|
|
|
const needleLen = needle.length;
|
|
|
if (needleLen === 0 || haystack.length === 0) {
|
|
|
return haystack;
|
|
|
}
|
|
|
let offset = 0;
|
|
|
while (haystack.indexOf(needle, offset) === offset) {
|
|
|
offset = offset + needleLen;
|
|
|
}
|
|
|
return haystack.substring(offset);
|
|
|
}
|
|
|
/**
|
|
|
* Removes all occurrences of needle from the end of haystack.
|
|
|
* @param haystack string to trim
|
|
|
* @param needle the thing to trim
|
|
|
*/
|
|
|
function rtrim(haystack, needle) {
|
|
|
if (!haystack || !needle) {
|
|
|
return haystack;
|
|
|
}
|
|
|
const needleLen = needle.length, haystackLen = haystack.length;
|
|
|
if (needleLen === 0 || haystackLen === 0) {
|
|
|
return haystack;
|
|
|
}
|
|
|
let offset = haystackLen, idx = -1;
|
|
|
while (true) {
|
|
|
idx = haystack.lastIndexOf(needle, offset - 1);
|
|
|
if (idx === -1 || idx + needleLen !== offset) {
|
|
|
break;
|
|
|
}
|
|
|
if (idx === 0) {
|
|
|
return '';
|
|
|
}
|
|
|
offset = idx;
|
|
|
}
|
|
|
return haystack.substring(0, offset);
|
|
|
}
|
|
|
function convertSimple2RegExpPattern(pattern) {
|
|
|
return pattern.replace(/[\-\\\{\}\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&').replace(/[\*]/g, '.*');
|
|
|
}
|
|
|
function stripWildcards(pattern) {
|
|
|
return pattern.replace(/\*/g, '');
|
|
|
}
|
|
|
function createRegExp(searchString, isRegex, options = {}) {
|
|
|
if (!searchString) {
|
|
|
throw new Error('Cannot create regex from empty string');
|
|
|
}
|
|
|
if (!isRegex) {
|
|
|
searchString = escapeRegExpCharacters(searchString);
|
|
|
}
|
|
|
if (options.wholeWord) {
|
|
|
if (!/\B/.test(searchString.charAt(0))) {
|
|
|
searchString = '\\b' + searchString;
|
|
|
}
|
|
|
if (!/\B/.test(searchString.charAt(searchString.length - 1))) {
|
|
|
searchString = searchString + '\\b';
|
|
|
}
|
|
|
}
|
|
|
let modifiers = '';
|
|
|
if (options.global) {
|
|
|
modifiers += 'g';
|
|
|
}
|
|
|
if (!options.matchCase) {
|
|
|
modifiers += 'i';
|
|
|
}
|
|
|
if (options.multiline) {
|
|
|
modifiers += 'm';
|
|
|
}
|
|
|
if (options.unicode) {
|
|
|
modifiers += 'u';
|
|
|
}
|
|
|
return new RegExp(searchString, modifiers);
|
|
|
}
|
|
|
function regExpLeadsToEndlessLoop(regexp) {
|
|
|
// Exit early if it's one of these special cases which are meant to match
|
|
|
// against an empty string
|
|
|
if (regexp.source === '^' || regexp.source === '^$' || regexp.source === '$' || regexp.source === '^\\s*$') {
|
|
|
return false;
|
|
|
}
|
|
|
// We check against an empty string. If the regular expression doesn't advance
|
|
|
// (e.g. ends in an endless loop) it will match an empty string.
|
|
|
const match = regexp.exec('');
|
|
|
return !!(match && regexp.lastIndex === 0);
|
|
|
}
|
|
|
function regExpFlags(regexp) {
|
|
|
return (regexp.global ? 'g' : '')
|
|
|
+ (regexp.ignoreCase ? 'i' : '')
|
|
|
+ (regexp.multiline ? 'm' : '')
|
|
|
+ (regexp /* standalone editor compilation */.unicode ? 'u' : '');
|
|
|
}
|
|
|
function splitLines(str) {
|
|
|
return str.split(/\r\n|\r|\n/);
|
|
|
}
|
|
|
/**
|
|
|
* Returns first index of the string that is not whitespace.
|
|
|
* If string is empty or contains only whitespaces, returns -1
|
|
|
*/
|
|
|
function firstNonWhitespaceIndex(str) {
|
|
|
for (let i = 0, len = str.length; i < len; i++) {
|
|
|
const chCode = str.charCodeAt(i);
|
|
|
if (chCode !== 32 /* Space */ && chCode !== 9 /* Tab */) {
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
return -1;
|
|
|
}
|
|
|
/**
|
|
|
* Returns the leading whitespace of the string.
|
|
|
* If the string contains only whitespaces, returns entire string
|
|
|
*/
|
|
|
function getLeadingWhitespace(str, start = 0, end = str.length) {
|
|
|
for (let i = start; i < end; i++) {
|
|
|
const chCode = str.charCodeAt(i);
|
|
|
if (chCode !== 32 /* Space */ && chCode !== 9 /* Tab */) {
|
|
|
return str.substring(start, i);
|
|
|
}
|
|
|
}
|
|
|
return str.substring(start, end);
|
|
|
}
|
|
|
/**
|
|
|
* Returns last index of the string that is not whitespace.
|
|
|
* If string is empty or contains only whitespaces, returns -1
|
|
|
*/
|
|
|
function lastNonWhitespaceIndex(str, startIndex = str.length - 1) {
|
|
|
for (let i = startIndex; i >= 0; i--) {
|
|
|
const chCode = str.charCodeAt(i);
|
|
|
if (chCode !== 32 /* Space */ && chCode !== 9 /* Tab */) {
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
return -1;
|
|
|
}
|
|
|
function compare(a, b) {
|
|
|
if (a < b) {
|
|
|
return -1;
|
|
|
}
|
|
|
else if (a > b) {
|
|
|
return 1;
|
|
|
}
|
|
|
else {
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
function compareSubstring(a, b, aStart = 0, aEnd = a.length, bStart = 0, bEnd = b.length) {
|
|
|
for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) {
|
|
|
let codeA = a.charCodeAt(aStart);
|
|
|
let codeB = b.charCodeAt(bStart);
|
|
|
if (codeA < codeB) {
|
|
|
return -1;
|
|
|
}
|
|
|
else if (codeA > codeB) {
|
|
|
return 1;
|
|
|
}
|
|
|
}
|
|
|
const aLen = aEnd - aStart;
|
|
|
const bLen = bEnd - bStart;
|
|
|
if (aLen < bLen) {
|
|
|
return -1;
|
|
|
}
|
|
|
else if (aLen > bLen) {
|
|
|
return 1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
function compareIgnoreCase(a, b) {
|
|
|
return compareSubstringIgnoreCase(a, b, 0, a.length, 0, b.length);
|
|
|
}
|
|
|
function compareSubstringIgnoreCase(a, b, aStart = 0, aEnd = a.length, bStart = 0, bEnd = b.length) {
|
|
|
for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) {
|
|
|
let codeA = a.charCodeAt(aStart);
|
|
|
let codeB = b.charCodeAt(bStart);
|
|
|
if (codeA === codeB) {
|
|
|
// equal
|
|
|
continue;
|
|
|
}
|
|
|
if (codeA >= 128 || codeB >= 128) {
|
|
|
// not ASCII letters -> fallback to lower-casing strings
|
|
|
return compareSubstring(a.toLowerCase(), b.toLowerCase(), aStart, aEnd, bStart, bEnd);
|
|
|
}
|
|
|
// mapper lower-case ascii letter onto upper-case varinats
|
|
|
// [97-122] (lower ascii) --> [65-90] (upper ascii)
|
|
|
if (isLowerAsciiLetter(codeA)) {
|
|
|
codeA -= 32;
|
|
|
}
|
|
|
if (isLowerAsciiLetter(codeB)) {
|
|
|
codeB -= 32;
|
|
|
}
|
|
|
// compare both code points
|
|
|
const diff = codeA - codeB;
|
|
|
if (diff === 0) {
|
|
|
continue;
|
|
|
}
|
|
|
return diff;
|
|
|
}
|
|
|
const aLen = aEnd - aStart;
|
|
|
const bLen = bEnd - bStart;
|
|
|
if (aLen < bLen) {
|
|
|
return -1;
|
|
|
}
|
|
|
else if (aLen > bLen) {
|
|
|
return 1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
function isLowerAsciiLetter(code) {
|
|
|
return code >= 97 /* a */ && code <= 122 /* z */;
|
|
|
}
|
|
|
function isUpperAsciiLetter(code) {
|
|
|
return code >= 65 /* A */ && code <= 90 /* Z */;
|
|
|
}
|
|
|
function equalsIgnoreCase(a, b) {
|
|
|
return a.length === b.length && compareSubstringIgnoreCase(a, b) === 0;
|
|
|
}
|
|
|
function startsWithIgnoreCase(str, candidate) {
|
|
|
const candidateLength = candidate.length;
|
|
|
if (candidate.length > str.length) {
|
|
|
return false;
|
|
|
}
|
|
|
return compareSubstringIgnoreCase(str, candidate, 0, candidateLength) === 0;
|
|
|
}
|
|
|
/**
|
|
|
* @returns the length of the common prefix of the two strings.
|
|
|
*/
|
|
|
function commonPrefixLength(a, b) {
|
|
|
let i, len = Math.min(a.length, b.length);
|
|
|
for (i = 0; i < len; i++) {
|
|
|
if (a.charCodeAt(i) !== b.charCodeAt(i)) {
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
return len;
|
|
|
}
|
|
|
/**
|
|
|
* @returns the length of the common suffix of the two strings.
|
|
|
*/
|
|
|
function commonSuffixLength(a, b) {
|
|
|
let i, len = Math.min(a.length, b.length);
|
|
|
const aLastIndex = a.length - 1;
|
|
|
const bLastIndex = b.length - 1;
|
|
|
for (i = 0; i < len; i++) {
|
|
|
if (a.charCodeAt(aLastIndex - i) !== b.charCodeAt(bLastIndex - i)) {
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
return len;
|
|
|
}
|
|
|
/**
|
|
|
* See http://en.wikipedia.org/wiki/Surrogate_pair
|
|
|
*/
|
|
|
function isHighSurrogate(charCode) {
|
|
|
return (0xD800 <= charCode && charCode <= 0xDBFF);
|
|
|
}
|
|
|
/**
|
|
|
* See http://en.wikipedia.org/wiki/Surrogate_pair
|
|
|
*/
|
|
|
function isLowSurrogate(charCode) {
|
|
|
return (0xDC00 <= charCode && charCode <= 0xDFFF);
|
|
|
}
|
|
|
/**
|
|
|
* See http://en.wikipedia.org/wiki/Surrogate_pair
|
|
|
*/
|
|
|
function computeCodePoint(highSurrogate, lowSurrogate) {
|
|
|
return ((highSurrogate - 0xD800) << 10) + (lowSurrogate - 0xDC00) + 0x10000;
|
|
|
}
|
|
|
/**
|
|
|
* get the code point that begins at offset `offset`
|
|
|
*/
|
|
|
function getNextCodePoint(str, len, offset) {
|
|
|
const charCode = str.charCodeAt(offset);
|
|
|
if (isHighSurrogate(charCode) && offset + 1 < len) {
|
|
|
const nextCharCode = str.charCodeAt(offset + 1);
|
|
|
if (isLowSurrogate(nextCharCode)) {
|
|
|
return computeCodePoint(charCode, nextCharCode);
|
|
|
}
|
|
|
}
|
|
|
return charCode;
|
|
|
}
|
|
|
/**
|
|
|
* get the code point that ends right before offset `offset`
|
|
|
*/
|
|
|
function getPrevCodePoint(str, offset) {
|
|
|
const charCode = str.charCodeAt(offset - 1);
|
|
|
if (isLowSurrogate(charCode) && offset > 1) {
|
|
|
const prevCharCode = str.charCodeAt(offset - 2);
|
|
|
if (isHighSurrogate(prevCharCode)) {
|
|
|
return computeCodePoint(prevCharCode, charCode);
|
|
|
}
|
|
|
}
|
|
|
return charCode;
|
|
|
}
|
|
|
function nextCharLength(str, offset) {
|
|
|
const graphemeBreakTree = GraphemeBreakTree.getInstance();
|
|
|
const initialOffset = offset;
|
|
|
const len = str.length;
|
|
|
const initialCodePoint = getNextCodePoint(str, len, offset);
|
|
|
offset += (initialCodePoint >= 65536 /* UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1);
|
|
|
let graphemeBreakType = graphemeBreakTree.getGraphemeBreakType(initialCodePoint);
|
|
|
while (offset < len) {
|
|
|
const nextCodePoint = getNextCodePoint(str, len, offset);
|
|
|
const nextGraphemeBreakType = graphemeBreakTree.getGraphemeBreakType(nextCodePoint);
|
|
|
if (breakBetweenGraphemeBreakType(graphemeBreakType, nextGraphemeBreakType)) {
|
|
|
break;
|
|
|
}
|
|
|
offset += (nextCodePoint >= 65536 /* UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1);
|
|
|
graphemeBreakType = nextGraphemeBreakType;
|
|
|
}
|
|
|
return (offset - initialOffset);
|
|
|
}
|
|
|
function prevCharLength(str, offset) {
|
|
|
const graphemeBreakTree = GraphemeBreakTree.getInstance();
|
|
|
const initialOffset = offset;
|
|
|
const initialCodePoint = getPrevCodePoint(str, offset);
|
|
|
offset -= (initialCodePoint >= 65536 /* UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1);
|
|
|
let graphemeBreakType = graphemeBreakTree.getGraphemeBreakType(initialCodePoint);
|
|
|
while (offset > 0) {
|
|
|
const prevCodePoint = getPrevCodePoint(str, offset);
|
|
|
const prevGraphemeBreakType = graphemeBreakTree.getGraphemeBreakType(prevCodePoint);
|
|
|
if (breakBetweenGraphemeBreakType(prevGraphemeBreakType, graphemeBreakType)) {
|
|
|
break;
|
|
|
}
|
|
|
offset -= (prevCodePoint >= 65536 /* UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1);
|
|
|
graphemeBreakType = prevGraphemeBreakType;
|
|
|
}
|
|
|
return (initialOffset - offset);
|
|
|
}
|
|
|
/**
|
|
|
* Generated using https://github.com/alexdima/unicode-utils/blob/master/generate-rtl-test.js
|
|
|
*/
|
|
|
const CONTAINS_RTL = /(?:[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05F4\u0608\u060B\u060D\u061B-\u064A\u066D-\u066F\u0671-\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u0710\u0712-\u072F\u074D-\u07A5\u07B1-\u07EA\u07F4\u07F5\u07FA-\u0815\u081A\u0824\u0828\u0830-\u0858\u085E-\u08BD\u200F\uFB1D\uFB1F-\uFB28\uFB2A-\uFD3D\uFD50-\uFDFC\uFE70-\uFEFC]|\uD802[\uDC00-\uDD1B\uDD20-\uDE00\uDE10-\uDE33\uDE40-\uDEE4\uDEEB-\uDF35\uDF40-\uDFFF]|\uD803[\uDC00-\uDCFF]|\uD83A[\uDC00-\uDCCF\uDD00-\uDD43\uDD50-\uDFFF]|\uD83B[\uDC00-\uDEBB])/;
|
|
|
/**
|
|
|
* Returns true if `str` contains any Unicode character that is classified as "R" or "AL".
|
|
|
*/
|
|
|
function containsRTL(str) {
|
|
|
return CONTAINS_RTL.test(str);
|
|
|
}
|
|
|
/**
|
|
|
* Generated using https://github.com/alexdima/unicode-utils/blob/master/generate-emoji-test.js
|
|
|
*/
|
|
|
const CONTAINS_EMOJI = /(?:[\u231A\u231B\u23F0\u23F3\u2600-\u27BF\u2B50\u2B55]|\uD83C[\uDDE6-\uDDFF\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F\uDE80-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD00-\uDDFF\uDE70-\uDED6])/;
|
|
|
function containsEmoji(str) {
|
|
|
return CONTAINS_EMOJI.test(str);
|
|
|
}
|
|
|
const IS_BASIC_ASCII = /^[\t\n\r\x20-\x7E]*$/;
|
|
|
/**
|
|
|
* Returns true if `str` contains only basic ASCII characters in the range 32 - 126 (including 32 and 126) or \n, \r, \t
|
|
|
*/
|
|
|
function isBasicASCII(str) {
|
|
|
return IS_BASIC_ASCII.test(str);
|
|
|
}
|
|
|
const UNUSUAL_LINE_TERMINATORS = /[\u2028\u2029]/; // LINE SEPARATOR (LS) or PARAGRAPH SEPARATOR (PS)
|
|
|
/**
|
|
|
* Returns true if `str` contains unusual line terminators, like LS or PS
|
|
|
*/
|
|
|
function containsUnusualLineTerminators(str) {
|
|
|
return UNUSUAL_LINE_TERMINATORS.test(str);
|
|
|
}
|
|
|
function containsFullWidthCharacter(str) {
|
|
|
for (let i = 0, len = str.length; i < len; i++) {
|
|
|
if (isFullWidthCharacter(str.charCodeAt(i))) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
function isFullWidthCharacter(charCode) {
|
|
|
// Do a cheap trick to better support wrapping of wide characters, treat them as 2 columns
|
|
|
// http://jrgraphix.net/research/unicode_blocks.php
|
|
|
// 2E80 — 2EFF CJK Radicals Supplement
|
|
|
// 2F00 — 2FDF Kangxi Radicals
|
|
|
// 2FF0 — 2FFF Ideographic Description Characters
|
|
|
// 3000 — 303F CJK Symbols and Punctuation
|
|
|
// 3040 — 309F Hiragana
|
|
|
// 30A0 — 30FF Katakana
|
|
|
// 3100 — 312F Bopomofo
|
|
|
// 3130 — 318F Hangul Compatibility Jamo
|
|
|
// 3190 — 319F Kanbun
|
|
|
// 31A0 — 31BF Bopomofo Extended
|
|
|
// 31F0 — 31FF Katakana Phonetic Extensions
|
|
|
// 3200 — 32FF Enclosed CJK Letters and Months
|
|
|
// 3300 — 33FF CJK Compatibility
|
|
|
// 3400 — 4DBF CJK Unified Ideographs Extension A
|
|
|
// 4DC0 — 4DFF Yijing Hexagram Symbols
|
|
|
// 4E00 — 9FFF CJK Unified Ideographs
|
|
|
// A000 — A48F Yi Syllables
|
|
|
// A490 — A4CF Yi Radicals
|
|
|
// AC00 — D7AF Hangul Syllables
|
|
|
// [IGNORE] D800 — DB7F High Surrogates
|
|
|
// [IGNORE] DB80 — DBFF High Private Use Surrogates
|
|
|
// [IGNORE] DC00 — DFFF Low Surrogates
|
|
|
// [IGNORE] E000 — F8FF Private Use Area
|
|
|
// F900 — FAFF CJK Compatibility Ideographs
|
|
|
// [IGNORE] FB00 — FB4F Alphabetic Presentation Forms
|
|
|
// [IGNORE] FB50 — FDFF Arabic Presentation Forms-A
|
|
|
// [IGNORE] FE00 — FE0F Variation Selectors
|
|
|
// [IGNORE] FE20 — FE2F Combining Half Marks
|
|
|
// [IGNORE] FE30 — FE4F CJK Compatibility Forms
|
|
|
// [IGNORE] FE50 — FE6F Small Form Variants
|
|
|
// [IGNORE] FE70 — FEFF Arabic Presentation Forms-B
|
|
|
// FF00 — FFEF Halfwidth and Fullwidth Forms
|
|
|
// [https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms]
|
|
|
// of which FF01 - FF5E fullwidth ASCII of 21 to 7E
|
|
|
// [IGNORE] and FF65 - FFDC halfwidth of Katakana and Hangul
|
|
|
// [IGNORE] FFF0 — FFFF Specials
|
|
|
charCode = +charCode; // @perf
|
|
|
return ((charCode >= 0x2E80 && charCode <= 0xD7AF)
|
|
|
|| (charCode >= 0xF900 && charCode <= 0xFAFF)
|
|
|
|| (charCode >= 0xFF01 && charCode <= 0xFF5E));
|
|
|
}
|
|
|
/**
|
|
|
* A fast function (therefore imprecise) to check if code points are emojis.
|
|
|
* Generated using https://github.com/alexdima/unicode-utils/blob/master/generate-emoji-test.js
|
|
|
*/
|
|
|
function isEmojiImprecise(x) {
|
|
|
return ((x >= 0x1F1E6 && x <= 0x1F1FF) || (x === 8986) || (x === 8987) || (x === 9200)
|
|
|
|| (x === 9203) || (x >= 9728 && x <= 10175) || (x === 11088) || (x === 11093)
|
|
|
|| (x >= 127744 && x <= 128591) || (x >= 128640 && x <= 128764)
|
|
|
|| (x >= 128992 && x <= 129003) || (x >= 129280 && x <= 129535)
|
|
|
|| (x >= 129648 && x <= 129750));
|
|
|
}
|
|
|
// -- UTF-8 BOM
|
|
|
const UTF8_BOM_CHARACTER = String.fromCharCode(65279 /* UTF8_BOM */);
|
|
|
function startsWithUTF8BOM(str) {
|
|
|
return !!(str && str.length > 0 && str.charCodeAt(0) === 65279 /* UTF8_BOM */);
|
|
|
}
|
|
|
function containsUppercaseCharacter(target, ignoreEscapedChars = false) {
|
|
|
if (!target) {
|
|
|
return false;
|
|
|
}
|
|
|
if (ignoreEscapedChars) {
|
|
|
target = target.replace(/\\./g, '');
|
|
|
}
|
|
|
return target.toLowerCase() !== target;
|
|
|
}
|
|
|
/**
|
|
|
* Produces 'a'-'z', followed by 'A'-'Z'... followed by 'a'-'z', etc.
|
|
|
*/
|
|
|
function singleLetterHash(n) {
|
|
|
const LETTERS_CNT = (90 /* Z */ - 65 /* A */ + 1);
|
|
|
n = n % (2 * LETTERS_CNT);
|
|
|
if (n < LETTERS_CNT) {
|
|
|
return String.fromCharCode(97 /* a */ + n);
|
|
|
}
|
|
|
return String.fromCharCode(65 /* A */ + n - LETTERS_CNT);
|
|
|
}
|
|
|
//#region Unicode Grapheme Break
|
|
|
function getGraphemeBreakType(codePoint) {
|
|
|
const graphemeBreakTree = GraphemeBreakTree.getInstance();
|
|
|
return graphemeBreakTree.getGraphemeBreakType(codePoint);
|
|
|
}
|
|
|
function breakBetweenGraphemeBreakType(breakTypeA, breakTypeB) {
|
|
|
// http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
|
|
|
// !!! Let's make the common case a bit faster
|
|
|
if (breakTypeA === 0 /* Other */) {
|
|
|
// see https://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakTest-13.0.0d10.html#table
|
|
|
return (breakTypeB !== 5 /* Extend */ && breakTypeB !== 7 /* SpacingMark */);
|
|
|
}
|
|
|
// Do not break between a CR and LF. Otherwise, break before and after controls.
|
|
|
// GB3 CR × LF
|
|
|
// GB4 (Control | CR | LF) ÷
|
|
|
// GB5 ÷ (Control | CR | LF)
|
|
|
if (breakTypeA === 2 /* CR */) {
|
|
|
if (breakTypeB === 3 /* LF */) {
|
|
|
return false; // GB3
|
|
|
}
|
|
|
}
|
|
|
if (breakTypeA === 4 /* Control */ || breakTypeA === 2 /* CR */ || breakTypeA === 3 /* LF */) {
|
|
|
return true; // GB4
|
|
|
}
|
|
|
if (breakTypeB === 4 /* Control */ || breakTypeB === 2 /* CR */ || breakTypeB === 3 /* LF */) {
|
|
|
return true; // GB5
|
|
|
}
|
|
|
// Do not break Hangul syllable sequences.
|
|
|
// GB6 L × (L | V | LV | LVT)
|
|
|
// GB7 (LV | V) × (V | T)
|
|
|
// GB8 (LVT | T) × T
|
|
|
if (breakTypeA === 8 /* L */) {
|
|
|
if (breakTypeB === 8 /* L */ || breakTypeB === 9 /* V */ || breakTypeB === 11 /* LV */ || breakTypeB === 12 /* LVT */) {
|
|
|
return false; // GB6
|
|
|
}
|
|
|
}
|
|
|
if (breakTypeA === 11 /* LV */ || breakTypeA === 9 /* V */) {
|
|
|
if (breakTypeB === 9 /* V */ || breakTypeB === 10 /* T */) {
|
|
|
return false; // GB7
|
|
|
}
|
|
|
}
|
|
|
if (breakTypeA === 12 /* LVT */ || breakTypeA === 10 /* T */) {
|
|
|
if (breakTypeB === 10 /* T */) {
|
|
|
return false; // GB8
|
|
|
}
|
|
|
}
|
|
|
// Do not break before extending characters or ZWJ.
|
|
|
// GB9 × (Extend | ZWJ)
|
|
|
if (breakTypeB === 5 /* Extend */ || breakTypeB === 13 /* ZWJ */) {
|
|
|
return false; // GB9
|
|
|
}
|
|
|
// The GB9a and GB9b rules only apply to extended grapheme clusters:
|
|
|
// Do not break before SpacingMarks, or after Prepend characters.
|
|
|
// GB9a × SpacingMark
|
|
|
// GB9b Prepend ×
|
|
|
if (breakTypeB === 7 /* SpacingMark */) {
|
|
|
return false; // GB9a
|
|
|
}
|
|
|
if (breakTypeA === 1 /* Prepend */) {
|
|
|
return false; // GB9b
|
|
|
}
|
|
|
// Do not break within emoji modifier sequences or emoji zwj sequences.
|
|
|
// GB11 \p{Extended_Pictographic} Extend* ZWJ × \p{Extended_Pictographic}
|
|
|
if (breakTypeA === 13 /* ZWJ */ && breakTypeB === 14 /* Extended_Pictographic */) {
|
|
|
// Note: we are not implementing the rule entirely here to avoid introducing states
|
|
|
return false; // GB11
|
|
|
}
|
|
|
// GB12 sot (RI RI)* RI × RI
|
|
|
// GB13 [^RI] (RI RI)* RI × RI
|
|
|
if (breakTypeA === 6 /* Regional_Indicator */ && breakTypeB === 6 /* Regional_Indicator */) {
|
|
|
// Note: we are not implementing the rule entirely here to avoid introducing states
|
|
|
return false; // GB12 & GB13
|
|
|
}
|
|
|
// GB999 Any ÷ Any
|
|
|
return true;
|
|
|
}
|
|
|
class GraphemeBreakTree {
|
|
|
constructor() {
|
|
|
this._data = getGraphemeBreakRawData();
|
|
|
}
|
|
|
static getInstance() {
|
|
|
if (!GraphemeBreakTree._INSTANCE) {
|
|
|
GraphemeBreakTree._INSTANCE = new GraphemeBreakTree();
|
|
|
}
|
|
|
return GraphemeBreakTree._INSTANCE;
|
|
|
}
|
|
|
getGraphemeBreakType(codePoint) {
|
|
|
// !!! Let's make 7bit ASCII a bit faster: 0..31
|
|
|
if (codePoint < 32) {
|
|
|
if (codePoint === 10 /* LineFeed */) {
|
|
|
return 3 /* LF */;
|
|
|
}
|
|
|
if (codePoint === 13 /* CarriageReturn */) {
|
|
|
return 2 /* CR */;
|
|
|
}
|
|
|
return 4 /* Control */;
|
|
|
}
|
|
|
// !!! Let's make 7bit ASCII a bit faster: 32..126
|
|
|
if (codePoint < 127) {
|
|
|
return 0 /* Other */;
|
|
|
}
|
|
|
const data = this._data;
|
|
|
const nodeCount = data.length / 3;
|
|
|
let nodeIndex = 1;
|
|
|
while (nodeIndex <= nodeCount) {
|
|
|
if (codePoint < data[3 * nodeIndex]) {
|
|
|
// go left
|
|
|
nodeIndex = 2 * nodeIndex;
|
|
|
}
|
|
|
else if (codePoint > data[3 * nodeIndex + 1]) {
|
|
|
// go right
|
|
|
nodeIndex = 2 * nodeIndex + 1;
|
|
|
}
|
|
|
else {
|
|
|
// hit
|
|
|
return data[3 * nodeIndex + 2];
|
|
|
}
|
|
|
}
|
|
|
return 0 /* Other */;
|
|
|
}
|
|
|
}
|
|
|
GraphemeBreakTree._INSTANCE = null;
|
|
|
function getGraphemeBreakRawData() {
|
|
|
// generated using https://github.com/alexdima/unicode-utils/blob/master/generate-grapheme-break.js
|
|
|
return JSON.parse('[0,0,0,51592,51592,11,44424,44424,11,72251,72254,5,7150,7150,7,48008,48008,11,55176,55176,11,128420,128420,14,3276,3277,5,9979,9980,14,46216,46216,11,49800,49800,11,53384,53384,11,70726,70726,5,122915,122916,5,129320,129327,14,2558,2558,5,5906,5908,5,9762,9763,14,43360,43388,8,45320,45320,11,47112,47112,11,48904,48904,11,50696,50696,11,52488,52488,11,54280,54280,11,70082,70083,1,71350,71350,7,73111,73111,5,127892,127893,14,128726,128727,14,129473,129474,14,2027,2035,5,2901,2902,5,3784,3789,5,6754,6754,5,8418,8420,5,9877,9877,14,11088,11088,14,44008,44008,5,44872,44872,11,45768,45768,11,46664,46664,11,47560,47560,11,48456,48456,11,49352,49352,11,50248,50248,11,51144,51144,11,52040,52040,11,52936,52936,11,53832,53832,11,54728,54728,11,69811,69814,5,70459,70460,5,71096,71099,7,71998,71998,5,72874,72880,5,119149,119149,7,127374,127374,14,128335,128335,14,128482,128482,14,128765,128767,14,129399,129400,14,129680,129685,14,1476,1477,5,2377,2380,7,2759,2760,5,3137,3140,7,3458,3459,7,4153,4154,5,6432,6434,5,6978,6978,5,7675,7679,5,9723,9726,14,9823,9823,14,9919,9923,14,10035,10036,14,42736,42737,5,43596,43596,5,44200,44200,11,44648,44648,11,45096,45096,11,45544,45544,11,45992,45992,11,46440,46440,11,46888,46888,11,47336,47336,11,47784,47784,11,48232,48232,11,48680,48680,11,49128,49128,11,49576,49576,11,50024,50024,11,50472,50472,11,50920,50920,11,51368,51368,11,51816,51816,11,52264,52264,11,52712,52712,11,53160,53160,11,53608,53608,11,54056,54056,11,54504,54504,11,54952,54952,11,68108,68111,5,69933,69940,5,70197,70197,7,70498,70499,7,70845,70845,5,71229,71229,5,71727,71735,5,72154,72155,5,72344,72345,5,73023,73029,5,94095,94098,5,121403,121452,5,126981,127182,14,127538,127546,14,127990,127990,14,128391,128391,14,128445,128449,14,128500,128505,14,128752,128752,14,129160,129167,14,129356,129356,14,129432,129442,14,129648,129651,14,129751,131069,14,173,173,4,1757,1757,1,2274,2274,1,2494,2494,5,2641,2641,5,2876,2876,5,3014,3016,7,3262,3262,7,3393,3396,5,3570,3571,7,3968,3972,5,4228,4228,7,6086,6086,5,6679,6680,5,6912,6915,5,7080,7081,5,7380,7392,5,8252,8252,14,9096,9096,14,9748,9749,14,9784,9786,14,9833,9850,14,9890,9894,14,9938,9938,14,9999,9999,14,10085,10087,14,12349,12349,14,43136,43137,7,43454,43456,7,43755,43755,7,44088,44088,11,44312,44312,11,44536,44536,11,44760,44760,11,44984,44984,11,45208,45208,11,45432,45432,11,45656,45656,11,45880,45880,11,46104,46104,11,46328,46328,11,46552,46552,11,46776,46776,11,47000,47000,11,47224,47224,11,47448,47448,11,47672,47672,11,47896,47896,11,48120,48120,11,48344,48344,11,48568,48568,11,48792,48792,11,49016,49016,11,49240,49240,11,49464,49464,11,49688,49688,11,49912,49912,11,50136,50136,11,50360,50360,11,50584,50584,11,50808,50808,11,51032,51032,11,51256,51256,11,51480,51480,11,51704,51704,11,51928,51928,11,52152,52152,11,52376,52376,11,52600,52600,11,52824,52824,11,53048,53048,11,53272,53272,11,53496,53496,11,53720,53720,11,53944,53944,11,54168,54168,11,54392,54392,11,54616,54616,11,54840,54840,11,55064,55064,11,65438,65439,5,69633,69633,5,69837,69837,1,70018,70018,7,70188,70190,7,70368,70370,7,70465,70468,7,70712,70719,5,70835,70840,5,70850,70851,5,71132,71133,5,71340,71340,7,71458,71461,5,71985,71989,7,72002,72002,7,72193,72202,5,72281,72283,5,72766,72766,7,72885,72886,5,73104,73105,5,92912,92916,5,113824,113827,4,119173,119179,5,121505,121519,5,125136,125142,5,127279,127279,14,127489,127490,14,127570,127743,14,127900,127901,14,128254,128254,14,128369,128370,14,128400,128400,14,128425,128432,14,128468,128475,14,128489,128494,14,128715,128720,14,128745,128745,14,128759,128760,14,129004,129023,14,129296,129304,14,129340,129342,14,129388,129392,14,129404,129407,14,129454,129455,14,129485,129487,14,129659,129663,14,129719,129727,14,917536,917631,5,13,13,2,1160,1161,5,1564,1564,4,1807,1807,1,2085,2087,5,2363,2363,7,2402,2403,5,2507,2508,7,2622,2624,7,2691,2691,7,2786,2787,5,2881,2884,5,3006,3006,5,3072,3072,5,3170,3171,5,3267,3268,7,3330,3331,7,3406,3406,1,3538,3540,5,3655,3662,5,3897,3897,5,4038,4038,5,4184,4185,5,4352,4447,8,6068,6069,5,6155,6157,5,6448,6449,7,6742,6742,5,6783,6783,5,6966,6970,5,7042,7042,7,7143,7143,7,7212,7219,5,7412,7412,5,8206,8207,4,8294,8303,4,8596,8601,14,9410,9410,14,9742,9742,14,9757,9757,14,9770,9770,14,9794,9794,14,9828,9828,14,9855,9855,14,9882,9882,14,9900,9903,14,9929,9933,14,9963,9967,14,9987,9988,14,10006,10006,14,10062,10062,14,10175,10175,14,11744,11775,5,42607,42607,5,43043,43044,7,43263,43263,5,43444,43445,7,43569,43570,5,43698,43700,5,43766,43766,5,44032,44032,11,44144,44144,11,44256,44256,11,44368,44368,11,44480,44480,11,44592,44592,11,44704,44704,11,44816,44816,11,44928,44928,11,45040,45040,11,45152,45152,11,45264,45264,11,45376,45376,11,45488,45488,11,45600,45600,11,45712,45712,11,45824,45824,11,45936,45936,11,46048,46048,11,46160,46160,11,46272,46272,11,46384,46384,11,46496,46496,11,46608,46608,11,46720,46720,11,46832,46832,11,46944,46944,11,47056,47056,11,47168,47168,11,47280,47280,11,47392,47392,11,47504,47504,11,47616,47616,11,47728,47728,11,47840,47840,11,47952,47952,11,48064,48064,11,48176,48176,11,48288,48288,11,48400,48400,11,48512,48512,11,48624,48624,11,48736,48736,11,48848,48848,11,48960,48960,11,49072,49072,11,49184,49184,11,49296,49296,11,49408,49408,11,49520,49520,11,49632,49632,11,49744,49744,11,49856,49856,11,49968,49968,11,50080,50080,11,50192,50192,11,50304,50304,11,50416,50416,11,50528,50528,11,50640,50640,11,50752,50752,11,50864,50864,11,50976,50976,11,51088,51088,11,51200,51200,11,51312,51312,11,51424,51424,11,51536,51536,11,51648,51648,11,51760,51760,11,51872,51872,11,51984,51984,11,52096,52096,11,52208,52208,11,52320,52320,11,52432,52432,11,52544,52544,11,52656,52656,11,52768,52768,11,52880,52880,11,52992,52992,11,53104,53104,11,53216,53216,11,53328,53328,11,53440,53440,11,53552,53552,11,53664,53664,11,53776,53776,11,53888,53888,11,54000,54000,11,54112,54112,11,54224,54224,11,54336,54336,11,54448,54448,11,54560,54560,11,54672,54672,11,54784,54784,11,54896,54896,11,55008,55008,11,55120,55120,11,64286,64286,5,66272,66272,5,68900,68903,5,69762,69762,7,69817,69818,5,69927,69931,5,70003,70003,5,70070,70078,5,70094,70094,7,70194,70195,7,70206,70206,5,70400,70401,5,70463,70463,7,70475,70477,7,70512,70516,5,70722,70724,5,70832,70832,5,70842,70842,5,70847,70848,5,71088,71089,7,71102,71102,7,71219,71226,5,71231,71232,5,71342,71343,7,71453,71455,5,71463,71467,5,71737,71738,5,71995,71996,5,72000,72000,7,72145,72147,7,72160,72160,5,72249,72249,7,72273,72278,5,72330,72342,5,72752,72758,5,72850,72871,5,72882,72883,5,73018,73018,5,73031,73031,5,73109,73109,5,73461,73462,7,94031,94031,5,94192,94193,7,119142,119142,7,119155,119162,4,119362,119364,5,121476,121476,5,122888,122904,5,123184,123190,5,126976,126979,14,127184,127231,14,127344,127345,14,127405,127461,14,127514,127514,14,127561,127567,14,127778,127779,14,127896,127896,14,127985,127986,14,127995,127999,5,128326,128328,14,128360,128366,14,128378,128378,14,128394,128397,14,128405,128406,14,128422,128423,14,128435,128443,14,128453,128464,14,128479,128480,14,128484,128487,14,128496,128498,14,128640,128709,14,128723,128724,14,128736,128741,14,128747,128748,14,128755,128755,14,128762,128762,14,128981,128991,14,129096,129103,14,129292,129292,14,129311,129311,14,129329,129330,14,129344,129349,14,129360,129374,14,129394,129394,14,129402,129402,14,129413,129425,14,129445,129450,14,129466,129471,14,129483,129483,14,129511,129535,14,129653,129655,14,129667,129670,14,129705,129711,14,129731,129743,14,917505,917505,4,917760,917999,5,10,10,3,127,159,4,768,879,5,1471,1471,5,1536,1541,1,1648,1648,5,1767,1768,5,1840,1866,5,2070,2073,5,2137,2139,5,2307,2307,7,2366,2368,7,2382,2383,7,2434,2435,7,2497,2500,5,2519,2519,5,2563,2563,7,2631,2632,5,2677,2677,5,2750,2752,7,2763,2764,7,2817,2817,5,2879,2879,5,2891,2892,7,2914,2915,5,3008,3008,5,3021,3021,5,3076,3076,5,3146,3149,5,3202,3203,7,3264,3265,7,3271,3272,7,3298,3299,5,3390,3390,5,3402,3404,7,3426,3427,5,3535,3535,5,3544,3550,7,3635,3635,7,3763,3763,7,3893,3893,5,3953,3966,5,3981,3991,5,4145,4145,7,4157,4158,5,4209,4212,5,4237,4237,5,4520,4607,10,5970,5971,5,6071,6077,5,6089,6099,5,6277,6278,5,6439,6440,5,6451,6456,7,6683,6683,5,6744,6750,5,6765,6770,7,6846,6846,5,6964,6964,5,6972,6972,5,7019,7027,5,7074,7077,5,7083,7085,5,7146,7148,7,7154,7155,7,7222,7223,5,7394,7400,5,7416,7417,5,8204,8204,5,8233,8233,4,8288,8292,4,8413,8416,5,8482,8482,14,8986,8987,14,9193,9203,14,9654,9654,14,9733,9733,14,9745,9745,14,9752,9752,14,9760,9760,14,9766,9766,14,9774,9775,14,9792,9792,14,9800,9811,14,9825,9826,14,9831,9831,14,9852,9853,14,9872,9873,14,9880,9880,14,9885,9887,14,9896,9897,14,9906,9916,14,9926,9927,14,9936,9936,14,9941,9960,14,9974,9974,14,9982,9985,14,9992,9997,14,10002,10002,14,10017,10017,14,10055,10055,14,10071,10071,14,10145,10145,14,11013,11015,14,11503,11505,5,12334,12335,5,12951,12951,14,42612,42621,5,43014,43014,5,43047,43047,7,43204,43205,5,43335,43345,5,43395,43395,7,43450,43451,7,43561,43566,5,43573,43574,5,43644,43644,5,43710,43711,5,43758,43759,7,44005,44005,5,44012,44012,7,44060,44060,11,44116,44116,11,44172,44172,11,44228,44228,11,44284,44284,11,44340,44340,11,44396,44396,11,44452,44452,11,44508,44508,11,44564,44564,11,44620,44620,11,44676,44676,11,44732,44732,11,44788,44788,11,44844,44844,11,44900,44900,11,44956,44956,11,45012,45012,11,45068,45068,11,45124,45124,11,45180,45180,11,45236,45236,11,45292,45292,11,45348,45348,11,45404,45404,11,45460,45460,11,45516,45516,11,45572,45572,11,45628,45628,11,45684,45684,11,45740,45740,11,45796,45796,11,45852,45852,11,45908,45908,11,45964,45964,11,46020,46020,11,46076,46076,11,46132,46132,11,46188,46188,11,46244,46244,11,46300,46300,11,46356,46356,11,46412,46412,11,46468,46468,11,46524,46524,11,46580,46580,11,46636,46636,11,46692,46692,11,46748,46748,11,46804,46804,11,46860,46860,11,46916,46916,11,46972,46972,11,47028,47028,11,47084,47084,11,47140,47140,11,47196,47196,11,47252,47252,11,47308,47308,11,47364,47364,11,47420,47420,11,47476,47476,11,47532,47532,11,47588,47588,11,47644,47644,11,47700,47700,11,47756,47756,11,47812,47812,11,47868,47868,11,47924,47924,11,47980,47980,11,48036,48036,11,48092,48092,11,48148,48148,11,48204,48204,11,48260,48260,11,48316,48316,11,48372,48372,11,48428,48428,11,48484,48484,11,48540,48540,11,48596,48596,11,48652,48652,11,48708,48708,11,48764,48764,11,48820,48820,11,48876,48876,11,48932,48932,11,48988,48988,11,49044,49044,11,49100,49100,11,49156,49156,11,49212,49212,11,49268,49268,11,49324,49324,11,49380,49380,11,49436,49436,11,49492,49492,11,49548,49548,11,49604,49604,11,49660,49660,11,49716,49716,11,49772,49772,11,49828,49828,11,49884,49884,11,49940,49940,11,49996,49996,11,50052,50052,11,50108,50108,11,50164,50164,11,50220,50220,11,50276,50276,11,50332,50332,11,50388,50388,11,50444,50444,11,50500,50500,11,50556,50556,11,50612,50612,11,50668,50668,11,50724,50724,11,50780,50780,11,50836,50836,11,50892,50892,11,50948,50948,11,51004,51004,11,51060,51060,11,51116,51116,11,51172,51172,11,51228,51228,11,51284,51284,11,51340,51340,11,51396,51396,11,51452,51452,11,51508,51508,11,51564,51564,11,51620,51620,11,51676,51676,11,51732,51732,11,51788,51788,11,51844,51844,11,51900,51900,11,51956,51956,11,52012,52012,11,52068,52068,11,52124,52124,11,52180,52180,11,52236,52236,11,52292,52292,11,52348,52348,11,52404,52404,11,52460,52460,11,52516,52516,11,52572,52572,11,52628,52628,11,52684,52684,11,52740,52740,11,52796,52796,11,52852,52852,11,52908,52908,11,52964,52964,11,53020,53020,11,53076,53076,11,53132,53132,11,53188,53188,11,53244,53244,11,53300,53300,11,53356,53356,11,53412,53412,11,53468,53468,11,53524,53524,11,53580,53580,11,53636,53636,11,53692,53692,11,53748,53748,11,53804,53804,11,53860,53860,11,53916,53916,11,53972,53972,11,54028,54028,11,54084,54084,11,54140,54140,11,54196,54196,11,54252,54252,11,54308,54308,11,54364,54364,11,54420,54420,11,54476,54476,11,54532,54532,11,54588,54588,11,54644,54644,11,54700,54700,11,54756,54756,11,54812,54812,11,54868,54868,11,54924,54924,11,54980,54980,11,55036,55036,11,55092,55092,11,55148,55148,11,55216,55238,9,65056,65071,5,65529,65531,4,68097,68099,5,68159,68159,5,69446,69456,5,69688,69702,5,69808,69810,7,69815,69816,7,69821,69821,1,69888,69890,5,69932,69932,7,69957,69958,7,70016,70017,5,70067,70069,7,70079,70080,7,70089,70092,5,70095,70095,5,70191,70193,5,70196,70196,5,70198,70199,5,70367,70367,5,70371,70378,5,70402,70403,7,70462,70462,5,70464,70464,5,70471,70472,7,70487,70487,5,70502,70508,5,70709,70711,7,70720,70721,7,70725,70725,7,70750,70750,5,70833,70834,7,70841,70841,7,70843,70844,7,70846,70846,7,70849,70849,7,71087,71087,5,71090,71093,5,71100,71101,5,71103,71104,5,71216,71218,7,71227,71228,7,71230,71230,7,71339,71339,5,71341,71341,5,71344,71349,5,71351,71351,5,71456,71457,7,71462,71462,7,71724,71726,7,71736,71736,7,71984,71984,5,71991,71992,7,71997,71997,7,71999,71999,1,72001,72001,1,72003,72003,5,72148,72151,5,72156,72159,7,72164,72164,7,72243,72248,5,72250,72250,1,72263,72263,5,72279,72280,7,72324,72329,1,72343,72343,7,72751,72751,7,72760,72765,5,72767,72767,5,72873,72873,7,72881,72881,7,72884,72884,7,73009,73014,5,73020,73021,5,73030,73030,1,73098,73102,7,73107,73108,7,73110,73110,7,73459,73460,5,78896,78904,4,92976,92982,5,94033,94087,7,94180,94180,5,113821,113822,5,119141,119141,5,119143,119145,5,119150,119154,5,119163,119170,5,119210,119213,5,121344,121398,5,121461,121461,5,121499,121503,5,122880,122886,5,122907,122913,5,122918,122922,5,123628,123631,5,125252,125258,5,126980,126980,14,127183,127183,14,127245,127247,14,127340,127343,14,127358,127359,14,127377,127386,14,127462,127487,6,127491,127503,14,127535,127535,14,127548,127551,14,127568,127569,14,127744,127777,14,127780,127891,14,127894,127895,14,127897,127899,14,127902,127984,14,127987,127989,14,127991,127994,14,128000,128253,14,128255,128317,14,128329,128334,14,128336,128359,14,128367,128368,14,128371,128377,14,128379,128390,14,128392,128393,14,128398,128399,14,128401,128404,14,128407,128419,14,128421,128421,14,128424,128424,14,128433,128434,14,128444,128444,14,128450,128452,14,128465,128467,14,128476,128478,14,128481,128481,14,128483,128483,14,128488,128488,14,128495,128495,14,128499,128499,14,128506,128591,14,128710,128714,14,128721,128722,14,128725,128725,14,128728,128735,14,128742,128744,14,128746,128746,14,128749,128751,14,128753,128754,14,128756,128758,14,128761,128761,14,128763,128764,14,128884,128895,14,128992,129003,14,129036,129039,14,129114,129119,14,129198,129279,14,129293,129295,14,129305,129310,14,129312,129319,14,129328,129328,14,129331,129338,14,129343,129343,14,129351,129355,14,129357,129359,14,129375,129387,14,129393,129393,14,129395,129398,14,129401,129401,14,129403,129403,14,129408,129412,14,129426,129431,14,129443,129444,14,129451,129453,14,129456,129465,14,129472,129472,14,129475,129482,14,129484,129484,14,129488,129510,14,129536,129647,14,129652,129652,14,129656,129658,14,129664,129666,14,129671,129679,14,129686,129704,14,129712,129718,14,129728,129730,14,129744,129750,14,917504,917504,4,917506,917535,4,917632,917759,4,918000,921599,4,0,9,4,11,12,4,14,31,4,169,169,14,174,174,14,1155,1159,5,1425,1469,5,1473,1474,5,1479,1479,5,1552,1562,5,1611,1631,5,1750,1756,5,1759,1764,5,1770,1773,5,1809,1809,5,1958,1968,5,2045,2045,5,2075,2083,5,2089,2093,5,2259,2273,5,2275,2306,5,2362,2362,5,2364,2364,5,2369,2376,5,2381,2381,5,2385,2391,5,2433,2433,5,2492,2492,5,2495,2496,7,2503,2504,7,2509,2509,5,2530,2531,5,2561,2562,5,2620,2620,5,2625,2626,5,2635,2637,5,2672,2673,5,2689,2690,5,2748,2748,5,2753,2757,5,2761,2761,7,2765,2765,5,2810,2815,5,2818,2819,7,2878,2878,5,2880,2880,7,2887,2888,7,2893,2893,5,2903,2903,5,2946,2946,5,3007,3007,7,3009,3010,7,3018,3020,7,3031,3031,5,3073,3075,7,3134,3136,5,3142,3144,5,3157,3158,5,3201,3201,5,3260,3260,5,3263,3263,5,3266,3266,5,3270,3270,5,3274,3275,7,3285,3286,5,3328,3329,5,3387,3388,5,3391,3392,7,3398,3400,7,3405,3405,5,3415,3415,5,3457,3457,5,3530,3530,5,3536,3537,7,3542,3542,5,3551,3551,5,3633,3633,5,3636,3642,5,3761,3761,5,3764,3772,5,3864,3865,5,3895,3895,5,3902,3903,7,3967,3967,7,3974,3975,5,3993,4028,5,4141,4144,5,4146,4151,5,4155,4156,7,4182,4183,7,4190,4192,5,4226,4226,5,4229,4230,5,4253,4253,5,4448,4519,9,4957,4959,5,5938,5940,5,6002,6003,5,6070,6070,7,6078,6085,7,6087,6088,7,6109,6109,5,6158,6158,4,6313,6313,5,6435,6438,7,6441,6443,7,6450,6450,5,6457,6459,5,6681,6682,7,6741,6741,7,6743,6743,7,6752,6752,5,6757,6764,5,6771,6780,5,6832,6845,5,6847,6848,5,6916,6916,7,6965,6965,5,6971,6971,7,6973,6977,7,6979,6980,7,7040,7041,5,7073,7073,7,7078,7079,7,7082,7082,7,7142,7142,5,7144,7145,5,7149,7149,5,7151,7153,5,7204,7211,7,7220,7221,7,7376,7378,5,7393,7393,7,7405,7405,5,7415,7415,7,7616,7673,5,8203,8203,4,8205,8205,13,8232,8232,4,8234,8238,4,8265,8265,14,8293,8293,4,8400,8412,5,8417,8417,5,8421,8432,5,8505,8505,14,8617,8618,14,9000,9000,14,9167,9167,14,9208,9210,14,9642,9643,14,9664,9664,14,9728,9732,14,9735,9741,14,9743,9744,14,9746,9746,14,9750,9751,14,9753,9756,14,9758,9759,14,9761,9761,14,9764,9765,14,9767,9769,14,9771,9773,14,9776,9783,14,9787,9791,14,9793,9793,14,9795,9799,14,9812,9822,14,9824,9824,14,9827,9827,14,9829,9830,14,9832,9832,14,9851,9851,14,9854,9854,14,9856,9861,14,9874,9876,14,9878,9879,14,9881,9881,14,9883,9884,14,9888,9889,14,9895,9895,14,9898,9899,14,9904,9905,14,9917,9918,14,9924,9925,14,9928,9928,14,9934,9935,14,9937,9937,14,9939,9940,14,9961,9962,14,9968,9973,14,9975,9978,14,9981,9981,14,9986,9986,14,9989,9989,14,9998,9998,14,10000,10001,14,10004,10004,14,10013,10013,14,10024,10024,14,10052,10052,14,10060,10060,14,10067,10069,14,10083,10084,14,10133,10135,14,10160,10160,14,10548,10549,14,11035,11036,14,11093,11093,14,11647,11647,5,12330,12333,5,12336,12336,14,12441,12442,5,12953,12953,14,42608,42610,5,42654,42655,5,43010,43010,5,43019,43019,5,43045,43046,5,43052,43052,5,43188,43203,7,43232,43249,5,43302,43309,5,43346,43347,7,43392,43394,5,43443,43443,5,43446,43449,5,43452,43453,5,43493,43493,5,43567,43568,7,43571,43572,7,43587,43587,5,43597,43597,7,43696,43696,5,43703,43704,5,43713,43713,5,43756,43757,5,43765,43765,7,44003,44004,7,44006,44007,7,44009,44010,7,44013,44013,5,44033,44059,12,44061,44087,12,44089,44115,12,44117,44143,12,44145,44171,12,44173,44199,12,44201,44227,12,44229,44255,12,44257,44283,12,44285,44311,12,44313,44339,12,44341,44367,12,44369,44395,12,44397,44423,12,44425,44451,12,44453,44479,12,44481,44507,12,44509,44535,12,44537,44563,12,44565,44591,12,44593,44619,12,44621,44647,12,44649,44675,12,44677,44703,12,44705,44731,12,44733,44759,12,44761,44787,12,44789,44815,12,44817,44843,12,44845,44871,12,44873,44899,12,44901,44927,12,44929,44955,12,44957,44983,12,44985,45011,12,45013,45039,12,45041,45067,12,45069,45095,12,45097,45123,12,45125,45151,12,45153,45179,12,45181,45207,12,45209,45235,12,45237,45263,12,45265,45291,12,45293,45319,12,45321,45347,12,45349,45375,12,45377,45403,12,45405,45431,12,45433,45459,12,45461,45487,12,45489,45515,12,45517,45543,12,45545,45571,12,45573,45599,12,45601,45627,12,45629,45655,12,45657,45683,12,45685,45711,12,45713,45739,12,45741,45767,12,45769,45795,12,45797,45823,12,45825,45851,12,45853,45879,12,45881,45907,12,45909,45935,12,45937,45963,12,45965,45991,12,45993,46019,12,46021,46047,12,46049,46075,12,46077,46103,12,46105,46131,12,46133,46159,12,46161,46187,12,46189,46215,12,46217,46243,12,46245,46271,12,46273,46299,12,46301,46327,12,46329,46355,12,46357,46383,12,46385,46411,12,46413,46439,12,46441,46467,12,46469,46495,12,46497,46523,12,46525,46551,12,46553,46579,12,46581,46607,12,46609,46635,12,46637,46663,12,46665,46691,12,46693,46719,12,46721,46747,12,46749,46775,12,46777,46803,12,46805,46831,12,46833,46859,12,46861,46887,12,46889,46915,12,46917,46943,12,46945,46971,12,46973,46999,12,47001,47027,12,47029,47055,12,47057,47083,12,47085,47111,12,47113,47139,12,47141,47167,12,47169,47195,12,47197,47223,12,47225,47251,12,47253,47279,12,47281,47307,12,47309,47335,12,47337,47363,12,47365,47391,12,47393,47419,12,47421,47447,12,47449,47475,12,47477,47503,12,47505,47531,12,47533,47559,12,47561,47587,12,47589,47615,12,47617,47643,12,47645,47671,12,47673,47699,12,47701,47727,12,47729,47755,12,47757,47783,12,47785,47811,12,47813,47839,12,47841,47867,12,47869,47895,12,47897,47923,12,47925,47951,12,47953,47979,12,47981,48007,12,48009,48035,12,48037,48063,12,48065,48091,12,48093,48119,12,48121,48147,12,48149,48175,12,48177,48203,12,48205,48231,12,48233,48259,12,48261,48287,12,48289,48315,12,48317,48343,12,48345,48371,12,48373,48399,12,48401,48427,12,48429,48455,12,48457,48483,12,48485,48511,12,48513,48539,12,48541,48567,12,48569,48595,12,48597,48623,12,48625,48651,12,48653,48679,12,48681,48707,12,48709,48735,12,48737,48763,12,48765,48791,12,48793,48819,12,48821,48847,12,48849,48875,12,48877,48903,12,48905,48931,12,48933,48959,12,48961,48987,12,48989,49015,12,49017,49043,12,49045,49071,12,49073,49099,12,49101,49127,12,49129,49155,12,49157,49183,12,49185,49211,12,49213,49239,12,49241,49267,12,49269,49295,12,49297,49323,12,49325,49351,12,49353,49379,12,49381,49407,12,49409,49435,12,49437,49463,12,49465,49491,12,49493,49519,12,49521,49547,12,49549,49575,12,49577,49603,12,49605,49631,12,49633,49659,12,49661,49687,12,49689,49715,12,49717,49743,12,49745,49771,12,49773,49799,12,49801,49827,12,49829,49855,12,49857,49883,12,49885,49911,12,49913,49939,12,49941,49967,12,49969,49995,12,49997,50023,12,50025,50051,12,50053,50079,12,50081,50107,12,50109,50135,12,50137,50163,12,50165,50191,12,50193,50219,12,50221,50247,12,50249,50275,12,50277,50303,12,50305,50331,12,50333,50359,12,50361,50387,12,50389,50415,12,50417,50443,12,50445,50471,12,50473,50499,12,50501,50527,12,50529,50555,12,50557,50583,12,50585,50611,12,50613,50639,12,50641,50667,12,50669,50695,12,50697,50723,12,50725,50751,12,50753,50779,12,50781,50807,12,50809,50835,12,50837,50863,12,50865,50891,12,50893,50919,12,50921,50947,12,50949,50975,12,50977,51003,12,51005,51031,12,51033,51059,12,51061,51087,12,51089,51115,12,51117,51143,12,51145,51171,12,51173,51199,12,51201,51227,12,51229,51255,12,51257,51283,12,51285,51311,12,51313,51339,12,51341,51367,12,51369,51395,12,51397,51423,12,51425,51451,12,51453,51479,12,51481,51507,12,51509,51535,12,51537,51563,12,51565,51591,12,51593,51619,12,51621,51647,12,51649,51675,12,51677,51703,12,51705,51731,12,51733,51759,12,51761,51787,12,51789,51815,12,51817,51843,12,51845,51871,12,51873,51899,12,51901,51927,12,51929,51955,12,51957,51983,12,51985,52011,12,52013,52039,12,52041,52067,12,52069,52095,12,52097,52123,12,52125,52151,12,52153,52179,12,52181,52207,12,52209,52235,12,52237,52263,12,52265,52291,12,52293,52319,12,52321,52347,12,52349,52375,12,52377,52403,12,52405,52431,12,52433,52459,12,52461,52487,12,52489,52515,12,52517,52543,12,52545,52571,12,52573,52599,12,52601,52627,12,52629,52655,12,52657,52683,12,52685,52711,12,52713,52739,12,52741,52767,12,52769,52795,12,52797,52823,12,52825,52851,12,52853,52879,12,52881,52907,12,52909,52935,12,52937,52963,12,52965,52991,12,52993,53019,12,53021,53047,12,53049,53075,12,53077,53103,12,53105,53131,12,53133,53159,12,53161,53187,12,53189,53215,12,53217,53243,12,53245,53271,12,53273,53299,12,53301,53327,12,53329,53355,12,53357,53383,12,53385,53411,12,53413,53439,12,53441,53467,12,53469,53495,12,53497,53523,12,53525,53551,12,53553,53579,12,53581,53607,12,53609,53635,12,53637,53663,12,53665,53691,12,53693,53719,12,53721,53747,12,53749,53775,12,53777,53803,12,53805,53831,12,53833,53859,12,53861,53887,12,53889,53915,12,53917,53943,12,53945,53971,12,53973,53999,12,54001,54027,12,54029,54055,12,54057,54083,12,54085,54111,12,54113,54139,12,54141,54167,12,54169,54195,12,54197,54223,12,54225,54251,12,54253,54279,12,54281,54307,12,54309,54335,12,54337,54363,12,54365,54391,12,54393,54419,12,54421,54447,12,54449,54475,12,54477,54503,12,54505,54531,12,54533,54559,12,54561,54587,12,54589,54615,12,54617,54643,12,54645,54671,12,54673,54699,12,54701,54727,12,54729,54755,12,54757,54783,12,54785,54811,12,54813,54839,12,54841,54867,12,54869,54895,12,54897,54923,12,54925,54951,12,54953,54979,12,54981,55007,12,55009,55035,12,55037,55063,12,55065,55091,12,55093,55119,12,55121,55147,12,55149,55175,12,55177,55203,12,55243,55291,10,65024,65039,5,65279,65279,4,65520,65528,4,66045,66045,5,66422,66426,5,68101,68102,5,68152,68154,5,68325,68326,5,69291,69292,5,69632,69632,7,69634,69634,7,69759,69761,5]');
|
|
|
}
|
|
|
//#endregion
|
|
|
/**
|
|
|
* Computes the offset after performing a left delete on the given string,
|
|
|
* while considering unicode grapheme/emoji rules.
|
|
|
*/
|
|
|
function getLeftDeleteOffset(offset, str) {
|
|
|
if (offset === 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
// Try to delete emoji part.
|
|
|
const emojiOffset = getOffsetBeforeLastEmojiComponent(offset, str);
|
|
|
if (emojiOffset !== undefined) {
|
|
|
return emojiOffset;
|
|
|
}
|
|
|
// Otherwise, just skip a single code point.
|
|
|
const codePoint = getPrevCodePoint(str, offset);
|
|
|
offset -= getUTF16Length(codePoint);
|
|
|
return offset;
|
|
|
}
|
|
|
function getOffsetBeforeLastEmojiComponent(offset, str) {
|
|
|
// See https://www.unicode.org/reports/tr51/tr51-14.html#EBNF_and_Regex for the
|
|
|
// structure of emojis.
|
|
|
let codePoint = getPrevCodePoint(str, offset);
|
|
|
offset -= getUTF16Length(codePoint);
|
|
|
// Skip modifiers
|
|
|
while ((isEmojiModifier(codePoint) || codePoint === 65039 /* emojiVariantSelector */ || codePoint === 8419 /* enclosingKeyCap */)) {
|
|
|
if (offset === 0) {
|
|
|
// Cannot skip modifier, no preceding emoji base.
|
|
|
return undefined;
|
|
|
}
|
|
|
codePoint = getPrevCodePoint(str, offset);
|
|
|
offset -= getUTF16Length(codePoint);
|
|
|
}
|
|
|
// Expect base emoji
|
|
|
if (!isEmojiImprecise(codePoint)) {
|
|
|
// Unexpected code point, not a valid emoji.
|
|
|
return undefined;
|
|
|
}
|
|
|
if (offset >= 0) {
|
|
|
// Skip optional ZWJ code points that combine multiple emojis.
|
|
|
// In theory, we should check if that ZWJ actually combines multiple emojis
|
|
|
// to prevent deleting ZWJs in situations we didn't account for.
|
|
|
const optionalZwjCodePoint = getPrevCodePoint(str, offset);
|
|
|
if (optionalZwjCodePoint === 8205 /* zwj */) {
|
|
|
offset -= getUTF16Length(optionalZwjCodePoint);
|
|
|
}
|
|
|
}
|
|
|
return offset;
|
|
|
}
|
|
|
function getUTF16Length(codePoint) {
|
|
|
return codePoint >= 65536 /* UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1;
|
|
|
}
|
|
|
function isEmojiModifier(codePoint) {
|
|
|
return 0x1F3FB <= codePoint && codePoint <= 0x1F3FF;
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/worker/simpleWorker.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const INITIALIZE = '$initialize';
|
|
|
let webWorkerWarningLogged = false;
|
|
|
function logOnceWebWorkerWarning(err) {
|
|
|
if (!isWeb) {
|
|
|
// running tests
|
|
|
return;
|
|
|
}
|
|
|
if (!webWorkerWarningLogged) {
|
|
|
webWorkerWarningLogged = true;
|
|
|
console.warn('Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/microsoft/monaco-editor#faq');
|
|
|
}
|
|
|
console.warn(err.message);
|
|
|
}
|
|
|
class RequestMessage {
|
|
|
constructor(vsWorker, req, method, args) {
|
|
|
this.vsWorker = vsWorker;
|
|
|
this.req = req;
|
|
|
this.method = method;
|
|
|
this.args = args;
|
|
|
this.type = 0 /* Request */;
|
|
|
}
|
|
|
}
|
|
|
class ReplyMessage {
|
|
|
constructor(vsWorker, seq, res, err) {
|
|
|
this.vsWorker = vsWorker;
|
|
|
this.seq = seq;
|
|
|
this.res = res;
|
|
|
this.err = err;
|
|
|
this.type = 1 /* Reply */;
|
|
|
}
|
|
|
}
|
|
|
class SubscribeEventMessage {
|
|
|
constructor(vsWorker, req, eventName, arg) {
|
|
|
this.vsWorker = vsWorker;
|
|
|
this.req = req;
|
|
|
this.eventName = eventName;
|
|
|
this.arg = arg;
|
|
|
this.type = 2 /* SubscribeEvent */;
|
|
|
}
|
|
|
}
|
|
|
class EventMessage {
|
|
|
constructor(vsWorker, req, event) {
|
|
|
this.vsWorker = vsWorker;
|
|
|
this.req = req;
|
|
|
this.event = event;
|
|
|
this.type = 3 /* Event */;
|
|
|
}
|
|
|
}
|
|
|
class UnsubscribeEventMessage {
|
|
|
constructor(vsWorker, req) {
|
|
|
this.vsWorker = vsWorker;
|
|
|
this.req = req;
|
|
|
this.type = 4 /* UnsubscribeEvent */;
|
|
|
}
|
|
|
}
|
|
|
class SimpleWorkerProtocol {
|
|
|
constructor(handler) {
|
|
|
this._workerId = -1;
|
|
|
this._handler = handler;
|
|
|
this._lastSentReq = 0;
|
|
|
this._pendingReplies = Object.create(null);
|
|
|
this._pendingEmitters = new Map();
|
|
|
this._pendingEvents = new Map();
|
|
|
}
|
|
|
setWorkerId(workerId) {
|
|
|
this._workerId = workerId;
|
|
|
}
|
|
|
sendMessage(method, args) {
|
|
|
const req = String(++this._lastSentReq);
|
|
|
return new Promise((resolve, reject) => {
|
|
|
this._pendingReplies[req] = {
|
|
|
resolve: resolve,
|
|
|
reject: reject
|
|
|
};
|
|
|
this._send(new RequestMessage(this._workerId, req, method, args));
|
|
|
});
|
|
|
}
|
|
|
listen(eventName, arg) {
|
|
|
let req = null;
|
|
|
const emitter = new Emitter({
|
|
|
onFirstListenerAdd: () => {
|
|
|
req = String(++this._lastSentReq);
|
|
|
this._pendingEmitters.set(req, emitter);
|
|
|
this._send(new SubscribeEventMessage(this._workerId, req, eventName, arg));
|
|
|
},
|
|
|
onLastListenerRemove: () => {
|
|
|
this._pendingEmitters.delete(req);
|
|
|
this._send(new UnsubscribeEventMessage(this._workerId, req));
|
|
|
req = null;
|
|
|
}
|
|
|
});
|
|
|
return emitter.event;
|
|
|
}
|
|
|
handleMessage(message) {
|
|
|
if (!message || !message.vsWorker) {
|
|
|
return;
|
|
|
}
|
|
|
if (this._workerId !== -1 && message.vsWorker !== this._workerId) {
|
|
|
return;
|
|
|
}
|
|
|
this._handleMessage(message);
|
|
|
}
|
|
|
_handleMessage(msg) {
|
|
|
switch (msg.type) {
|
|
|
case 1 /* Reply */:
|
|
|
return this._handleReplyMessage(msg);
|
|
|
case 0 /* Request */:
|
|
|
return this._handleRequestMessage(msg);
|
|
|
case 2 /* SubscribeEvent */:
|
|
|
return this._handleSubscribeEventMessage(msg);
|
|
|
case 3 /* Event */:
|
|
|
return this._handleEventMessage(msg);
|
|
|
case 4 /* UnsubscribeEvent */:
|
|
|
return this._handleUnsubscribeEventMessage(msg);
|
|
|
}
|
|
|
}
|
|
|
_handleReplyMessage(replyMessage) {
|
|
|
if (!this._pendingReplies[replyMessage.seq]) {
|
|
|
console.warn('Got reply to unknown seq');
|
|
|
return;
|
|
|
}
|
|
|
let reply = this._pendingReplies[replyMessage.seq];
|
|
|
delete this._pendingReplies[replyMessage.seq];
|
|
|
if (replyMessage.err) {
|
|
|
let err = replyMessage.err;
|
|
|
if (replyMessage.err.$isError) {
|
|
|
err = new Error();
|
|
|
err.name = replyMessage.err.name;
|
|
|
err.message = replyMessage.err.message;
|
|
|
err.stack = replyMessage.err.stack;
|
|
|
}
|
|
|
reply.reject(err);
|
|
|
return;
|
|
|
}
|
|
|
reply.resolve(replyMessage.res);
|
|
|
}
|
|
|
_handleRequestMessage(requestMessage) {
|
|
|
let req = requestMessage.req;
|
|
|
let result = this._handler.handleMessage(requestMessage.method, requestMessage.args);
|
|
|
result.then((r) => {
|
|
|
this._send(new ReplyMessage(this._workerId, req, r, undefined));
|
|
|
}, (e) => {
|
|
|
if (e.detail instanceof Error) {
|
|
|
// Loading errors have a detail property that points to the actual error
|
|
|
e.detail = transformErrorForSerialization(e.detail);
|
|
|
}
|
|
|
this._send(new ReplyMessage(this._workerId, req, undefined, transformErrorForSerialization(e)));
|
|
|
});
|
|
|
}
|
|
|
_handleSubscribeEventMessage(msg) {
|
|
|
const req = msg.req;
|
|
|
const disposable = this._handler.handleEvent(msg.eventName, msg.arg)((event) => {
|
|
|
this._send(new EventMessage(this._workerId, req, event));
|
|
|
});
|
|
|
this._pendingEvents.set(req, disposable);
|
|
|
}
|
|
|
_handleEventMessage(msg) {
|
|
|
if (!this._pendingEmitters.has(msg.req)) {
|
|
|
console.warn('Got event for unknown req');
|
|
|
return;
|
|
|
}
|
|
|
this._pendingEmitters.get(msg.req).fire(msg.event);
|
|
|
}
|
|
|
_handleUnsubscribeEventMessage(msg) {
|
|
|
if (!this._pendingEvents.has(msg.req)) {
|
|
|
console.warn('Got unsubscribe for unknown req');
|
|
|
return;
|
|
|
}
|
|
|
this._pendingEvents.get(msg.req).dispose();
|
|
|
this._pendingEvents.delete(msg.req);
|
|
|
}
|
|
|
_send(msg) {
|
|
|
let transfer = [];
|
|
|
if (msg.type === 0 /* Request */) {
|
|
|
for (let i = 0; i < msg.args.length; i++) {
|
|
|
if (msg.args[i] instanceof ArrayBuffer) {
|
|
|
transfer.push(msg.args[i]);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (msg.type === 1 /* Reply */) {
|
|
|
if (msg.res instanceof ArrayBuffer) {
|
|
|
transfer.push(msg.res);
|
|
|
}
|
|
|
}
|
|
|
this._handler.sendMessage(msg, transfer);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Main thread side
|
|
|
*/
|
|
|
class SimpleWorkerClient extends (/* unused pure expression or super */ null && (Disposable)) {
|
|
|
constructor(workerFactory, moduleId, host) {
|
|
|
super();
|
|
|
let lazyProxyReject = null;
|
|
|
this._worker = this._register(workerFactory.create('vs/base/common/worker/simpleWorker', (msg) => {
|
|
|
this._protocol.handleMessage(msg);
|
|
|
}, (err) => {
|
|
|
// in Firefox, web workers fail lazily :(
|
|
|
// we will reject the proxy
|
|
|
if (lazyProxyReject) {
|
|
|
lazyProxyReject(err);
|
|
|
}
|
|
|
}));
|
|
|
this._protocol = new SimpleWorkerProtocol({
|
|
|
sendMessage: (msg, transfer) => {
|
|
|
this._worker.postMessage(msg, transfer);
|
|
|
},
|
|
|
handleMessage: (method, args) => {
|
|
|
if (typeof host[method] !== 'function') {
|
|
|
return Promise.reject(new Error('Missing method ' + method + ' on main thread host.'));
|
|
|
}
|
|
|
try {
|
|
|
return Promise.resolve(host[method].apply(host, args));
|
|
|
}
|
|
|
catch (e) {
|
|
|
return Promise.reject(e);
|
|
|
}
|
|
|
},
|
|
|
handleEvent: (eventName, arg) => {
|
|
|
if (propertyIsDynamicEvent(eventName)) {
|
|
|
const event = host[eventName].call(host, arg);
|
|
|
if (typeof event !== 'function') {
|
|
|
throw new Error(`Missing dynamic event ${eventName} on main thread host.`);
|
|
|
}
|
|
|
return event;
|
|
|
}
|
|
|
if (propertyIsEvent(eventName)) {
|
|
|
const event = host[eventName];
|
|
|
if (typeof event !== 'function') {
|
|
|
throw new Error(`Missing event ${eventName} on main thread host.`);
|
|
|
}
|
|
|
return event;
|
|
|
}
|
|
|
throw new Error(`Malformed event name ${eventName}`);
|
|
|
}
|
|
|
});
|
|
|
this._protocol.setWorkerId(this._worker.getId());
|
|
|
// Gather loader configuration
|
|
|
let loaderConfiguration = null;
|
|
|
if (typeof globals.require !== 'undefined' && typeof globals.require.getConfig === 'function') {
|
|
|
// Get the configuration from the Monaco AMD Loader
|
|
|
loaderConfiguration = globals.require.getConfig();
|
|
|
}
|
|
|
else if (typeof globals.requirejs !== 'undefined') {
|
|
|
// Get the configuration from requirejs
|
|
|
loaderConfiguration = globals.requirejs.s.contexts._.config;
|
|
|
}
|
|
|
const hostMethods = types.getAllMethodNames(host);
|
|
|
// Send initialize message
|
|
|
this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [
|
|
|
this._worker.getId(),
|
|
|
JSON.parse(JSON.stringify(loaderConfiguration)),
|
|
|
moduleId,
|
|
|
hostMethods,
|
|
|
]);
|
|
|
// Create proxy to loaded code
|
|
|
const proxyMethodRequest = (method, args) => {
|
|
|
return this._request(method, args);
|
|
|
};
|
|
|
const proxyListen = (eventName, arg) => {
|
|
|
return this._protocol.listen(eventName, arg);
|
|
|
};
|
|
|
this._lazyProxy = new Promise((resolve, reject) => {
|
|
|
lazyProxyReject = reject;
|
|
|
this._onModuleLoaded.then((availableMethods) => {
|
|
|
resolve(simpleWorker_createProxyObject(availableMethods, proxyMethodRequest, proxyListen));
|
|
|
}, (e) => {
|
|
|
reject(e);
|
|
|
this._onError('Worker failed to load ' + moduleId, e);
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
getProxyObject() {
|
|
|
return this._lazyProxy;
|
|
|
}
|
|
|
_request(method, args) {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
this._onModuleLoaded.then(() => {
|
|
|
this._protocol.sendMessage(method, args).then(resolve, reject);
|
|
|
}, reject);
|
|
|
});
|
|
|
}
|
|
|
_onError(message, error) {
|
|
|
console.error(message);
|
|
|
console.info(error);
|
|
|
}
|
|
|
}
|
|
|
function propertyIsEvent(name) {
|
|
|
// Assume a property is an event if it has a form of "onSomething"
|
|
|
return name[0] === 'o' && name[1] === 'n' && isUpperAsciiLetter(name.charCodeAt(2));
|
|
|
}
|
|
|
function propertyIsDynamicEvent(name) {
|
|
|
// Assume a property is a dynamic event (a method that returns an event) if it has a form of "onDynamicSomething"
|
|
|
return /^onDynamic/.test(name) && isUpperAsciiLetter(name.charCodeAt(9));
|
|
|
}
|
|
|
function simpleWorker_createProxyObject(methodNames, invoke, proxyListen) {
|
|
|
const createProxyMethod = (method) => {
|
|
|
return function () {
|
|
|
const args = Array.prototype.slice.call(arguments, 0);
|
|
|
return invoke(method, args);
|
|
|
};
|
|
|
};
|
|
|
const createProxyDynamicEvent = (eventName) => {
|
|
|
return function (arg) {
|
|
|
return proxyListen(eventName, arg);
|
|
|
};
|
|
|
};
|
|
|
let result = {};
|
|
|
for (const methodName of methodNames) {
|
|
|
if (propertyIsDynamicEvent(methodName)) {
|
|
|
result[methodName] = createProxyDynamicEvent(methodName);
|
|
|
continue;
|
|
|
}
|
|
|
if (propertyIsEvent(methodName)) {
|
|
|
result[methodName] = proxyListen(methodName, undefined);
|
|
|
continue;
|
|
|
}
|
|
|
result[methodName] = createProxyMethod(methodName);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
/**
|
|
|
* Worker side
|
|
|
*/
|
|
|
class SimpleWorkerServer {
|
|
|
constructor(postMessage, requestHandlerFactory) {
|
|
|
this._requestHandlerFactory = requestHandlerFactory;
|
|
|
this._requestHandler = null;
|
|
|
this._protocol = new SimpleWorkerProtocol({
|
|
|
sendMessage: (msg, transfer) => {
|
|
|
postMessage(msg, transfer);
|
|
|
},
|
|
|
handleMessage: (method, args) => this._handleMessage(method, args),
|
|
|
handleEvent: (eventName, arg) => this._handleEvent(eventName, arg)
|
|
|
});
|
|
|
}
|
|
|
onmessage(msg) {
|
|
|
this._protocol.handleMessage(msg);
|
|
|
}
|
|
|
_handleMessage(method, args) {
|
|
|
if (method === INITIALIZE) {
|
|
|
return this.initialize(args[0], args[1], args[2], args[3]);
|
|
|
}
|
|
|
if (!this._requestHandler || typeof this._requestHandler[method] !== 'function') {
|
|
|
return Promise.reject(new Error('Missing requestHandler or method: ' + method));
|
|
|
}
|
|
|
try {
|
|
|
return Promise.resolve(this._requestHandler[method].apply(this._requestHandler, args));
|
|
|
}
|
|
|
catch (e) {
|
|
|
return Promise.reject(e);
|
|
|
}
|
|
|
}
|
|
|
_handleEvent(eventName, arg) {
|
|
|
if (!this._requestHandler) {
|
|
|
throw new Error(`Missing requestHandler`);
|
|
|
}
|
|
|
if (propertyIsDynamicEvent(eventName)) {
|
|
|
const event = this._requestHandler[eventName].call(this._requestHandler, arg);
|
|
|
if (typeof event !== 'function') {
|
|
|
throw new Error(`Missing dynamic event ${eventName} on request handler.`);
|
|
|
}
|
|
|
return event;
|
|
|
}
|
|
|
if (propertyIsEvent(eventName)) {
|
|
|
const event = this._requestHandler[eventName];
|
|
|
if (typeof event !== 'function') {
|
|
|
throw new Error(`Missing event ${eventName} on request handler.`);
|
|
|
}
|
|
|
return event;
|
|
|
}
|
|
|
throw new Error(`Malformed event name ${eventName}`);
|
|
|
}
|
|
|
initialize(workerId, loaderConfig, moduleId, hostMethods) {
|
|
|
this._protocol.setWorkerId(workerId);
|
|
|
const proxyMethodRequest = (method, args) => {
|
|
|
return this._protocol.sendMessage(method, args);
|
|
|
};
|
|
|
const proxyListen = (eventName, arg) => {
|
|
|
return this._protocol.listen(eventName, arg);
|
|
|
};
|
|
|
const hostProxy = simpleWorker_createProxyObject(hostMethods, proxyMethodRequest, proxyListen);
|
|
|
if (this._requestHandlerFactory) {
|
|
|
// static request handler
|
|
|
this._requestHandler = this._requestHandlerFactory(hostProxy);
|
|
|
return Promise.resolve(getAllMethodNames(this._requestHandler));
|
|
|
}
|
|
|
if (loaderConfig) {
|
|
|
// Remove 'baseUrl', handling it is beyond scope for now
|
|
|
if (typeof loaderConfig.baseUrl !== 'undefined') {
|
|
|
delete loaderConfig['baseUrl'];
|
|
|
}
|
|
|
if (typeof loaderConfig.paths !== 'undefined') {
|
|
|
if (typeof loaderConfig.paths.vs !== 'undefined') {
|
|
|
delete loaderConfig.paths['vs'];
|
|
|
}
|
|
|
}
|
|
|
if (typeof loaderConfig.trustedTypesPolicy !== undefined) {
|
|
|
// don't use, it has been destroyed during serialize
|
|
|
delete loaderConfig['trustedTypesPolicy'];
|
|
|
}
|
|
|
// Since this is in a web worker, enable catching errors
|
|
|
loaderConfig.catchError = true;
|
|
|
platform_globals.require.config(loaderConfig);
|
|
|
}
|
|
|
return new Promise((resolve, reject) => {
|
|
|
// Use the global require to be sure to get the global config
|
|
|
// ESM-comment-begin
|
|
|
// const req = (globals.require || require);
|
|
|
// ESM-comment-end
|
|
|
// ESM-uncomment-begin
|
|
|
const req = platform_globals.require;
|
|
|
// ESM-uncomment-end
|
|
|
req([moduleId], (module) => {
|
|
|
this._requestHandler = module.create(hostProxy);
|
|
|
if (!this._requestHandler) {
|
|
|
reject(new Error(`No RequestHandler!`));
|
|
|
return;
|
|
|
}
|
|
|
resolve(getAllMethodNames(this._requestHandler));
|
|
|
}, reject);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Called on the worker side
|
|
|
*/
|
|
|
function create(postMessage) {
|
|
|
return new SimpleWorkerServer(postMessage, null);
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/diff/diffChange.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
/**
|
|
|
* Represents information about a specific difference between two sequences.
|
|
|
*/
|
|
|
class DiffChange {
|
|
|
/**
|
|
|
* Constructs a new DiffChange with the given sequence information
|
|
|
* and content.
|
|
|
*/
|
|
|
constructor(originalStart, originalLength, modifiedStart, modifiedLength) {
|
|
|
//Debug.Assert(originalLength > 0 || modifiedLength > 0, "originalLength and modifiedLength cannot both be <= 0");
|
|
|
this.originalStart = originalStart;
|
|
|
this.originalLength = originalLength;
|
|
|
this.modifiedStart = modifiedStart;
|
|
|
this.modifiedLength = modifiedLength;
|
|
|
}
|
|
|
/**
|
|
|
* The end point (exclusive) of the change in the original sequence.
|
|
|
*/
|
|
|
getOriginalEnd() {
|
|
|
return this.originalStart + this.originalLength;
|
|
|
}
|
|
|
/**
|
|
|
* The end point (exclusive) of the change in the modified sequence.
|
|
|
*/
|
|
|
getModifiedEnd() {
|
|
|
return this.modifiedStart + this.modifiedLength;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/hash.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
/**
|
|
|
* Return a hash value for an object.
|
|
|
*/
|
|
|
function hash(obj) {
|
|
|
return doHash(obj, 0);
|
|
|
}
|
|
|
function doHash(obj, hashVal) {
|
|
|
switch (typeof obj) {
|
|
|
case 'object':
|
|
|
if (obj === null) {
|
|
|
return numberHash(349, hashVal);
|
|
|
}
|
|
|
else if (Array.isArray(obj)) {
|
|
|
return arrayHash(obj, hashVal);
|
|
|
}
|
|
|
return objectHash(obj, hashVal);
|
|
|
case 'string':
|
|
|
return stringHash(obj, hashVal);
|
|
|
case 'boolean':
|
|
|
return booleanHash(obj, hashVal);
|
|
|
case 'number':
|
|
|
return numberHash(obj, hashVal);
|
|
|
case 'undefined':
|
|
|
return numberHash(937, hashVal);
|
|
|
default:
|
|
|
return numberHash(617, hashVal);
|
|
|
}
|
|
|
}
|
|
|
function numberHash(val, initialHashVal) {
|
|
|
return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32
|
|
|
}
|
|
|
function booleanHash(b, initialHashVal) {
|
|
|
return numberHash(b ? 433 : 863, initialHashVal);
|
|
|
}
|
|
|
function stringHash(s, hashVal) {
|
|
|
hashVal = numberHash(149417, hashVal);
|
|
|
for (let i = 0, length = s.length; i < length; i++) {
|
|
|
hashVal = numberHash(s.charCodeAt(i), hashVal);
|
|
|
}
|
|
|
return hashVal;
|
|
|
}
|
|
|
function arrayHash(arr, initialHashVal) {
|
|
|
initialHashVal = numberHash(104579, initialHashVal);
|
|
|
return arr.reduce((hashVal, item) => doHash(item, hashVal), initialHashVal);
|
|
|
}
|
|
|
function objectHash(obj, initialHashVal) {
|
|
|
initialHashVal = numberHash(181387, initialHashVal);
|
|
|
return Object.keys(obj).sort().reduce((hashVal, key) => {
|
|
|
hashVal = stringHash(key, hashVal);
|
|
|
return doHash(obj[key], hashVal);
|
|
|
}, initialHashVal);
|
|
|
}
|
|
|
function leftRotate(value, bits, totalBits = 32) {
|
|
|
// delta + bits = totalBits
|
|
|
const delta = totalBits - bits;
|
|
|
// All ones, expect `delta` zeros aligned to the right
|
|
|
const mask = ~((1 << delta) - 1);
|
|
|
// Join (value left-shifted `bits` bits) with (masked value right-shifted `delta` bits)
|
|
|
return ((value << bits) | ((mask & value) >>> delta)) >>> 0;
|
|
|
}
|
|
|
function fill(dest, index = 0, count = dest.byteLength, value = 0) {
|
|
|
for (let i = 0; i < count; i++) {
|
|
|
dest[index + i] = value;
|
|
|
}
|
|
|
}
|
|
|
function leftPad(value, length, char = '0') {
|
|
|
while (value.length < length) {
|
|
|
value = char + value;
|
|
|
}
|
|
|
return value;
|
|
|
}
|
|
|
function toHexString(bufferOrValue, bitsize = 32) {
|
|
|
if (bufferOrValue instanceof ArrayBuffer) {
|
|
|
return Array.from(new Uint8Array(bufferOrValue)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
|
}
|
|
|
return leftPad((bufferOrValue >>> 0).toString(16), bitsize / 4);
|
|
|
}
|
|
|
/**
|
|
|
* A SHA1 implementation that works with strings and does not allocate.
|
|
|
*/
|
|
|
class StringSHA1 {
|
|
|
constructor() {
|
|
|
this._h0 = 0x67452301;
|
|
|
this._h1 = 0xEFCDAB89;
|
|
|
this._h2 = 0x98BADCFE;
|
|
|
this._h3 = 0x10325476;
|
|
|
this._h4 = 0xC3D2E1F0;
|
|
|
this._buff = new Uint8Array(64 /* BLOCK_SIZE */ + 3 /* to fit any utf-8 */);
|
|
|
this._buffDV = new DataView(this._buff.buffer);
|
|
|
this._buffLen = 0;
|
|
|
this._totalLen = 0;
|
|
|
this._leftoverHighSurrogate = 0;
|
|
|
this._finished = false;
|
|
|
}
|
|
|
update(str) {
|
|
|
const strLen = str.length;
|
|
|
if (strLen === 0) {
|
|
|
return;
|
|
|
}
|
|
|
const buff = this._buff;
|
|
|
let buffLen = this._buffLen;
|
|
|
let leftoverHighSurrogate = this._leftoverHighSurrogate;
|
|
|
let charCode;
|
|
|
let offset;
|
|
|
if (leftoverHighSurrogate !== 0) {
|
|
|
charCode = leftoverHighSurrogate;
|
|
|
offset = -1;
|
|
|
leftoverHighSurrogate = 0;
|
|
|
}
|
|
|
else {
|
|
|
charCode = str.charCodeAt(0);
|
|
|
offset = 0;
|
|
|
}
|
|
|
while (true) {
|
|
|
let codePoint = charCode;
|
|
|
if (isHighSurrogate(charCode)) {
|
|
|
if (offset + 1 < strLen) {
|
|
|
const nextCharCode = str.charCodeAt(offset + 1);
|
|
|
if (isLowSurrogate(nextCharCode)) {
|
|
|
offset++;
|
|
|
codePoint = computeCodePoint(charCode, nextCharCode);
|
|
|
}
|
|
|
else {
|
|
|
// illegal => unicode replacement character
|
|
|
codePoint = 65533 /* UNICODE_REPLACEMENT */;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// last character is a surrogate pair
|
|
|
leftoverHighSurrogate = charCode;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else if (isLowSurrogate(charCode)) {
|
|
|
// illegal => unicode replacement character
|
|
|
codePoint = 65533 /* UNICODE_REPLACEMENT */;
|
|
|
}
|
|
|
buffLen = this._push(buff, buffLen, codePoint);
|
|
|
offset++;
|
|
|
if (offset < strLen) {
|
|
|
charCode = str.charCodeAt(offset);
|
|
|
}
|
|
|
else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
this._buffLen = buffLen;
|
|
|
this._leftoverHighSurrogate = leftoverHighSurrogate;
|
|
|
}
|
|
|
_push(buff, buffLen, codePoint) {
|
|
|
if (codePoint < 0x0080) {
|
|
|
buff[buffLen++] = codePoint;
|
|
|
}
|
|
|
else if (codePoint < 0x0800) {
|
|
|
buff[buffLen++] = 0b11000000 | ((codePoint & 0b00000000000000000000011111000000) >>> 6);
|
|
|
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);
|
|
|
}
|
|
|
else if (codePoint < 0x10000) {
|
|
|
buff[buffLen++] = 0b11100000 | ((codePoint & 0b00000000000000001111000000000000) >>> 12);
|
|
|
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000111111000000) >>> 6);
|
|
|
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);
|
|
|
}
|
|
|
else {
|
|
|
buff[buffLen++] = 0b11110000 | ((codePoint & 0b00000000000111000000000000000000) >>> 18);
|
|
|
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000111111000000000000) >>> 12);
|
|
|
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000111111000000) >>> 6);
|
|
|
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);
|
|
|
}
|
|
|
if (buffLen >= 64 /* BLOCK_SIZE */) {
|
|
|
this._step();
|
|
|
buffLen -= 64 /* BLOCK_SIZE */;
|
|
|
this._totalLen += 64 /* BLOCK_SIZE */;
|
|
|
// take last 3 in case of UTF8 overflow
|
|
|
buff[0] = buff[64 /* BLOCK_SIZE */ + 0];
|
|
|
buff[1] = buff[64 /* BLOCK_SIZE */ + 1];
|
|
|
buff[2] = buff[64 /* BLOCK_SIZE */ + 2];
|
|
|
}
|
|
|
return buffLen;
|
|
|
}
|
|
|
digest() {
|
|
|
if (!this._finished) {
|
|
|
this._finished = true;
|
|
|
if (this._leftoverHighSurrogate) {
|
|
|
// illegal => unicode replacement character
|
|
|
this._leftoverHighSurrogate = 0;
|
|
|
this._buffLen = this._push(this._buff, this._buffLen, 65533 /* UNICODE_REPLACEMENT */);
|
|
|
}
|
|
|
this._totalLen += this._buffLen;
|
|
|
this._wrapUp();
|
|
|
}
|
|
|
return toHexString(this._h0) + toHexString(this._h1) + toHexString(this._h2) + toHexString(this._h3) + toHexString(this._h4);
|
|
|
}
|
|
|
_wrapUp() {
|
|
|
this._buff[this._buffLen++] = 0x80;
|
|
|
fill(this._buff, this._buffLen);
|
|
|
if (this._buffLen > 56) {
|
|
|
this._step();
|
|
|
fill(this._buff);
|
|
|
}
|
|
|
// this will fit because the mantissa can cover up to 52 bits
|
|
|
const ml = 8 * this._totalLen;
|
|
|
this._buffDV.setUint32(56, Math.floor(ml / 4294967296), false);
|
|
|
this._buffDV.setUint32(60, ml % 4294967296, false);
|
|
|
this._step();
|
|
|
}
|
|
|
_step() {
|
|
|
const bigBlock32 = StringSHA1._bigBlock32;
|
|
|
const data = this._buffDV;
|
|
|
for (let j = 0; j < 64 /* 16*4 */; j += 4) {
|
|
|
bigBlock32.setUint32(j, data.getUint32(j, false), false);
|
|
|
}
|
|
|
for (let j = 64; j < 320 /* 80*4 */; j += 4) {
|
|
|
bigBlock32.setUint32(j, leftRotate((bigBlock32.getUint32(j - 12, false) ^ bigBlock32.getUint32(j - 32, false) ^ bigBlock32.getUint32(j - 56, false) ^ bigBlock32.getUint32(j - 64, false)), 1), false);
|
|
|
}
|
|
|
let a = this._h0;
|
|
|
let b = this._h1;
|
|
|
let c = this._h2;
|
|
|
let d = this._h3;
|
|
|
let e = this._h4;
|
|
|
let f, k;
|
|
|
let temp;
|
|
|
for (let j = 0; j < 80; j++) {
|
|
|
if (j < 20) {
|
|
|
f = (b & c) | ((~b) & d);
|
|
|
k = 0x5A827999;
|
|
|
}
|
|
|
else if (j < 40) {
|
|
|
f = b ^ c ^ d;
|
|
|
k = 0x6ED9EBA1;
|
|
|
}
|
|
|
else if (j < 60) {
|
|
|
f = (b & c) | (b & d) | (c & d);
|
|
|
k = 0x8F1BBCDC;
|
|
|
}
|
|
|
else {
|
|
|
f = b ^ c ^ d;
|
|
|
k = 0xCA62C1D6;
|
|
|
}
|
|
|
temp = (leftRotate(a, 5) + f + e + k + bigBlock32.getUint32(j * 4, false)) & 0xffffffff;
|
|
|
e = d;
|
|
|
d = c;
|
|
|
c = leftRotate(b, 30);
|
|
|
b = a;
|
|
|
a = temp;
|
|
|
}
|
|
|
this._h0 = (this._h0 + a) & 0xffffffff;
|
|
|
this._h1 = (this._h1 + b) & 0xffffffff;
|
|
|
this._h2 = (this._h2 + c) & 0xffffffff;
|
|
|
this._h3 = (this._h3 + d) & 0xffffffff;
|
|
|
this._h4 = (this._h4 + e) & 0xffffffff;
|
|
|
}
|
|
|
}
|
|
|
StringSHA1._bigBlock32 = new DataView(new ArrayBuffer(320)); // 80 * 4 = 320
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/diff/diff.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
class StringDiffSequence {
|
|
|
constructor(source) {
|
|
|
this.source = source;
|
|
|
}
|
|
|
getElements() {
|
|
|
const source = this.source;
|
|
|
const characters = new Int32Array(source.length);
|
|
|
for (let i = 0, len = source.length; i < len; i++) {
|
|
|
characters[i] = source.charCodeAt(i);
|
|
|
}
|
|
|
return characters;
|
|
|
}
|
|
|
}
|
|
|
function stringDiff(original, modified, pretty) {
|
|
|
return new LcsDiff(new StringDiffSequence(original), new StringDiffSequence(modified)).ComputeDiff(pretty).changes;
|
|
|
}
|
|
|
//
|
|
|
// The code below has been ported from a C# implementation in VS
|
|
|
//
|
|
|
class Debug {
|
|
|
static Assert(condition, message) {
|
|
|
if (!condition) {
|
|
|
throw new Error(message);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
class MyArray {
|
|
|
/**
|
|
|
* Copies a range of elements from an Array starting at the specified source index and pastes
|
|
|
* them to another Array starting at the specified destination index. The length and the indexes
|
|
|
* are specified as 64-bit integers.
|
|
|
* sourceArray:
|
|
|
* The Array that contains the data to copy.
|
|
|
* sourceIndex:
|
|
|
* A 64-bit integer that represents the index in the sourceArray at which copying begins.
|
|
|
* destinationArray:
|
|
|
* The Array that receives the data.
|
|
|
* destinationIndex:
|
|
|
* A 64-bit integer that represents the index in the destinationArray at which storing begins.
|
|
|
* length:
|
|
|
* A 64-bit integer that represents the number of elements to copy.
|
|
|
*/
|
|
|
static Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];
|
|
|
}
|
|
|
}
|
|
|
static Copy2(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* A utility class which helps to create the set of DiffChanges from
|
|
|
* a difference operation. This class accepts original DiffElements and
|
|
|
* modified DiffElements that are involved in a particular change. The
|
|
|
* MarkNextChange() method can be called to mark the separation between
|
|
|
* distinct changes. At the end, the Changes property can be called to retrieve
|
|
|
* the constructed changes.
|
|
|
*/
|
|
|
class DiffChangeHelper {
|
|
|
/**
|
|
|
* Constructs a new DiffChangeHelper for the given DiffSequences.
|
|
|
*/
|
|
|
constructor() {
|
|
|
this.m_changes = [];
|
|
|
this.m_originalStart = 1073741824 /* MAX_SAFE_SMALL_INTEGER */;
|
|
|
this.m_modifiedStart = 1073741824 /* MAX_SAFE_SMALL_INTEGER */;
|
|
|
this.m_originalCount = 0;
|
|
|
this.m_modifiedCount = 0;
|
|
|
}
|
|
|
/**
|
|
|
* Marks the beginning of the next change in the set of differences.
|
|
|
*/
|
|
|
MarkNextChange() {
|
|
|
// Only add to the list if there is something to add
|
|
|
if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {
|
|
|
// Add the new change to our list
|
|
|
this.m_changes.push(new DiffChange(this.m_originalStart, this.m_originalCount, this.m_modifiedStart, this.m_modifiedCount));
|
|
|
}
|
|
|
// Reset for the next change
|
|
|
this.m_originalCount = 0;
|
|
|
this.m_modifiedCount = 0;
|
|
|
this.m_originalStart = 1073741824 /* MAX_SAFE_SMALL_INTEGER */;
|
|
|
this.m_modifiedStart = 1073741824 /* MAX_SAFE_SMALL_INTEGER */;
|
|
|
}
|
|
|
/**
|
|
|
* Adds the original element at the given position to the elements
|
|
|
* affected by the current change. The modified index gives context
|
|
|
* to the change position with respect to the original sequence.
|
|
|
* @param originalIndex The index of the original element to add.
|
|
|
* @param modifiedIndex The index of the modified element that provides corresponding position in the modified sequence.
|
|
|
*/
|
|
|
AddOriginalElement(originalIndex, modifiedIndex) {
|
|
|
// The 'true' start index is the smallest of the ones we've seen
|
|
|
this.m_originalStart = Math.min(this.m_originalStart, originalIndex);
|
|
|
this.m_modifiedStart = Math.min(this.m_modifiedStart, modifiedIndex);
|
|
|
this.m_originalCount++;
|
|
|
}
|
|
|
/**
|
|
|
* Adds the modified element at the given position to the elements
|
|
|
* affected by the current change. The original index gives context
|
|
|
* to the change position with respect to the modified sequence.
|
|
|
* @param originalIndex The index of the original element that provides corresponding position in the original sequence.
|
|
|
* @param modifiedIndex The index of the modified element to add.
|
|
|
*/
|
|
|
AddModifiedElement(originalIndex, modifiedIndex) {
|
|
|
// The 'true' start index is the smallest of the ones we've seen
|
|
|
this.m_originalStart = Math.min(this.m_originalStart, originalIndex);
|
|
|
this.m_modifiedStart = Math.min(this.m_modifiedStart, modifiedIndex);
|
|
|
this.m_modifiedCount++;
|
|
|
}
|
|
|
/**
|
|
|
* Retrieves all of the changes marked by the class.
|
|
|
*/
|
|
|
getChanges() {
|
|
|
if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {
|
|
|
// Finish up on whatever is left
|
|
|
this.MarkNextChange();
|
|
|
}
|
|
|
return this.m_changes;
|
|
|
}
|
|
|
/**
|
|
|
* Retrieves all of the changes marked by the class in the reverse order
|
|
|
*/
|
|
|
getReverseChanges() {
|
|
|
if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {
|
|
|
// Finish up on whatever is left
|
|
|
this.MarkNextChange();
|
|
|
}
|
|
|
this.m_changes.reverse();
|
|
|
return this.m_changes;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* An implementation of the difference algorithm described in
|
|
|
* "An O(ND) Difference Algorithm and its variations" by Eugene W. Myers
|
|
|
*/
|
|
|
class LcsDiff {
|
|
|
/**
|
|
|
* Constructs the DiffFinder
|
|
|
*/
|
|
|
constructor(originalSequence, modifiedSequence, continueProcessingPredicate = null) {
|
|
|
this.ContinueProcessingPredicate = continueProcessingPredicate;
|
|
|
this._originalSequence = originalSequence;
|
|
|
this._modifiedSequence = modifiedSequence;
|
|
|
const [originalStringElements, originalElementsOrHash, originalHasStrings] = LcsDiff._getElements(originalSequence);
|
|
|
const [modifiedStringElements, modifiedElementsOrHash, modifiedHasStrings] = LcsDiff._getElements(modifiedSequence);
|
|
|
this._hasStrings = (originalHasStrings && modifiedHasStrings);
|
|
|
this._originalStringElements = originalStringElements;
|
|
|
this._originalElementsOrHash = originalElementsOrHash;
|
|
|
this._modifiedStringElements = modifiedStringElements;
|
|
|
this._modifiedElementsOrHash = modifiedElementsOrHash;
|
|
|
this.m_forwardHistory = [];
|
|
|
this.m_reverseHistory = [];
|
|
|
}
|
|
|
static _isStringArray(arr) {
|
|
|
return (arr.length > 0 && typeof arr[0] === 'string');
|
|
|
}
|
|
|
static _getElements(sequence) {
|
|
|
const elements = sequence.getElements();
|
|
|
if (LcsDiff._isStringArray(elements)) {
|
|
|
const hashes = new Int32Array(elements.length);
|
|
|
for (let i = 0, len = elements.length; i < len; i++) {
|
|
|
hashes[i] = stringHash(elements[i], 0);
|
|
|
}
|
|
|
return [elements, hashes, true];
|
|
|
}
|
|
|
if (elements instanceof Int32Array) {
|
|
|
return [[], elements, false];
|
|
|
}
|
|
|
return [[], new Int32Array(elements), false];
|
|
|
}
|
|
|
ElementsAreEqual(originalIndex, newIndex) {
|
|
|
if (this._originalElementsOrHash[originalIndex] !== this._modifiedElementsOrHash[newIndex]) {
|
|
|
return false;
|
|
|
}
|
|
|
return (this._hasStrings ? this._originalStringElements[originalIndex] === this._modifiedStringElements[newIndex] : true);
|
|
|
}
|
|
|
ElementsAreStrictEqual(originalIndex, newIndex) {
|
|
|
if (!this.ElementsAreEqual(originalIndex, newIndex)) {
|
|
|
return false;
|
|
|
}
|
|
|
const originalElement = LcsDiff._getStrictElement(this._originalSequence, originalIndex);
|
|
|
const modifiedElement = LcsDiff._getStrictElement(this._modifiedSequence, newIndex);
|
|
|
return (originalElement === modifiedElement);
|
|
|
}
|
|
|
static _getStrictElement(sequence, index) {
|
|
|
if (typeof sequence.getStrictElement === 'function') {
|
|
|
return sequence.getStrictElement(index);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
OriginalElementsAreEqual(index1, index2) {
|
|
|
if (this._originalElementsOrHash[index1] !== this._originalElementsOrHash[index2]) {
|
|
|
return false;
|
|
|
}
|
|
|
return (this._hasStrings ? this._originalStringElements[index1] === this._originalStringElements[index2] : true);
|
|
|
}
|
|
|
ModifiedElementsAreEqual(index1, index2) {
|
|
|
if (this._modifiedElementsOrHash[index1] !== this._modifiedElementsOrHash[index2]) {
|
|
|
return false;
|
|
|
}
|
|
|
return (this._hasStrings ? this._modifiedStringElements[index1] === this._modifiedStringElements[index2] : true);
|
|
|
}
|
|
|
ComputeDiff(pretty) {
|
|
|
return this._ComputeDiff(0, this._originalElementsOrHash.length - 1, 0, this._modifiedElementsOrHash.length - 1, pretty);
|
|
|
}
|
|
|
/**
|
|
|
* Computes the differences between the original and modified input
|
|
|
* sequences on the bounded range.
|
|
|
* @returns An array of the differences between the two input sequences.
|
|
|
*/
|
|
|
_ComputeDiff(originalStart, originalEnd, modifiedStart, modifiedEnd, pretty) {
|
|
|
const quitEarlyArr = [false];
|
|
|
let changes = this.ComputeDiffRecursive(originalStart, originalEnd, modifiedStart, modifiedEnd, quitEarlyArr);
|
|
|
if (pretty) {
|
|
|
// We have to clean up the computed diff to be more intuitive
|
|
|
// but it turns out this cannot be done correctly until the entire set
|
|
|
// of diffs have been computed
|
|
|
changes = this.PrettifyChanges(changes);
|
|
|
}
|
|
|
return {
|
|
|
quitEarly: quitEarlyArr[0],
|
|
|
changes: changes
|
|
|
};
|
|
|
}
|
|
|
/**
|
|
|
* Private helper method which computes the differences on the bounded range
|
|
|
* recursively.
|
|
|
* @returns An array of the differences between the two input sequences.
|
|
|
*/
|
|
|
ComputeDiffRecursive(originalStart, originalEnd, modifiedStart, modifiedEnd, quitEarlyArr) {
|
|
|
quitEarlyArr[0] = false;
|
|
|
// Find the start of the differences
|
|
|
while (originalStart <= originalEnd && modifiedStart <= modifiedEnd && this.ElementsAreEqual(originalStart, modifiedStart)) {
|
|
|
originalStart++;
|
|
|
modifiedStart++;
|
|
|
}
|
|
|
// Find the end of the differences
|
|
|
while (originalEnd >= originalStart && modifiedEnd >= modifiedStart && this.ElementsAreEqual(originalEnd, modifiedEnd)) {
|
|
|
originalEnd--;
|
|
|
modifiedEnd--;
|
|
|
}
|
|
|
// In the special case where we either have all insertions or all deletions or the sequences are identical
|
|
|
if (originalStart > originalEnd || modifiedStart > modifiedEnd) {
|
|
|
let changes;
|
|
|
if (modifiedStart <= modifiedEnd) {
|
|
|
Debug.Assert(originalStart === originalEnd + 1, 'originalStart should only be one more than originalEnd');
|
|
|
// All insertions
|
|
|
changes = [
|
|
|
new DiffChange(originalStart, 0, modifiedStart, modifiedEnd - modifiedStart + 1)
|
|
|
];
|
|
|
}
|
|
|
else if (originalStart <= originalEnd) {
|
|
|
Debug.Assert(modifiedStart === modifiedEnd + 1, 'modifiedStart should only be one more than modifiedEnd');
|
|
|
// All deletions
|
|
|
changes = [
|
|
|
new DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, 0)
|
|
|
];
|
|
|
}
|
|
|
else {
|
|
|
Debug.Assert(originalStart === originalEnd + 1, 'originalStart should only be one more than originalEnd');
|
|
|
Debug.Assert(modifiedStart === modifiedEnd + 1, 'modifiedStart should only be one more than modifiedEnd');
|
|
|
// Identical sequences - No differences
|
|
|
changes = [];
|
|
|
}
|
|
|
return changes;
|
|
|
}
|
|
|
// This problem can be solved using the Divide-And-Conquer technique.
|
|
|
const midOriginalArr = [0];
|
|
|
const midModifiedArr = [0];
|
|
|
const result = this.ComputeRecursionPoint(originalStart, originalEnd, modifiedStart, modifiedEnd, midOriginalArr, midModifiedArr, quitEarlyArr);
|
|
|
const midOriginal = midOriginalArr[0];
|
|
|
const midModified = midModifiedArr[0];
|
|
|
if (result !== null) {
|
|
|
// Result is not-null when there was enough memory to compute the changes while
|
|
|
// searching for the recursion point
|
|
|
return result;
|
|
|
}
|
|
|
else if (!quitEarlyArr[0]) {
|
|
|
// We can break the problem down recursively by finding the changes in the
|
|
|
// First Half: (originalStart, modifiedStart) to (midOriginal, midModified)
|
|
|
// Second Half: (midOriginal + 1, minModified + 1) to (originalEnd, modifiedEnd)
|
|
|
// NOTE: ComputeDiff() is inclusive, therefore the second range starts on the next point
|
|
|
const leftChanges = this.ComputeDiffRecursive(originalStart, midOriginal, modifiedStart, midModified, quitEarlyArr);
|
|
|
let rightChanges = [];
|
|
|
if (!quitEarlyArr[0]) {
|
|
|
rightChanges = this.ComputeDiffRecursive(midOriginal + 1, originalEnd, midModified + 1, modifiedEnd, quitEarlyArr);
|
|
|
}
|
|
|
else {
|
|
|
// We didn't have time to finish the first half, so we don't have time to compute this half.
|
|
|
// Consider the entire rest of the sequence different.
|
|
|
rightChanges = [
|
|
|
new DiffChange(midOriginal + 1, originalEnd - (midOriginal + 1) + 1, midModified + 1, modifiedEnd - (midModified + 1) + 1)
|
|
|
];
|
|
|
}
|
|
|
return this.ConcatenateChanges(leftChanges, rightChanges);
|
|
|
}
|
|
|
// If we hit here, we quit early, and so can't return anything meaningful
|
|
|
return [
|
|
|
new DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, modifiedEnd - modifiedStart + 1)
|
|
|
];
|
|
|
}
|
|
|
WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr) {
|
|
|
let forwardChanges = null;
|
|
|
let reverseChanges = null;
|
|
|
// First, walk backward through the forward diagonals history
|
|
|
let changeHelper = new DiffChangeHelper();
|
|
|
let diagonalMin = diagonalForwardStart;
|
|
|
let diagonalMax = diagonalForwardEnd;
|
|
|
let diagonalRelative = (midOriginalArr[0] - midModifiedArr[0]) - diagonalForwardOffset;
|
|
|
let lastOriginalIndex = -1073741824 /* MIN_SAFE_SMALL_INTEGER */;
|
|
|
let historyIndex = this.m_forwardHistory.length - 1;
|
|
|
do {
|
|
|
// Get the diagonal index from the relative diagonal number
|
|
|
const diagonal = diagonalRelative + diagonalForwardBase;
|
|
|
// Figure out where we came from
|
|
|
if (diagonal === diagonalMin || (diagonal < diagonalMax && forwardPoints[diagonal - 1] < forwardPoints[diagonal + 1])) {
|
|
|
// Vertical line (the element is an insert)
|
|
|
originalIndex = forwardPoints[diagonal + 1];
|
|
|
modifiedIndex = originalIndex - diagonalRelative - diagonalForwardOffset;
|
|
|
if (originalIndex < lastOriginalIndex) {
|
|
|
changeHelper.MarkNextChange();
|
|
|
}
|
|
|
lastOriginalIndex = originalIndex;
|
|
|
changeHelper.AddModifiedElement(originalIndex + 1, modifiedIndex);
|
|
|
diagonalRelative = (diagonal + 1) - diagonalForwardBase; //Setup for the next iteration
|
|
|
}
|
|
|
else {
|
|
|
// Horizontal line (the element is a deletion)
|
|
|
originalIndex = forwardPoints[diagonal - 1] + 1;
|
|
|
modifiedIndex = originalIndex - diagonalRelative - diagonalForwardOffset;
|
|
|
if (originalIndex < lastOriginalIndex) {
|
|
|
changeHelper.MarkNextChange();
|
|
|
}
|
|
|
lastOriginalIndex = originalIndex - 1;
|
|
|
changeHelper.AddOriginalElement(originalIndex, modifiedIndex + 1);
|
|
|
diagonalRelative = (diagonal - 1) - diagonalForwardBase; //Setup for the next iteration
|
|
|
}
|
|
|
if (historyIndex >= 0) {
|
|
|
forwardPoints = this.m_forwardHistory[historyIndex];
|
|
|
diagonalForwardBase = forwardPoints[0]; //We stored this in the first spot
|
|
|
diagonalMin = 1;
|
|
|
diagonalMax = forwardPoints.length - 1;
|
|
|
}
|
|
|
} while (--historyIndex >= -1);
|
|
|
// Ironically, we get the forward changes as the reverse of the
|
|
|
// order we added them since we technically added them backwards
|
|
|
forwardChanges = changeHelper.getReverseChanges();
|
|
|
if (quitEarlyArr[0]) {
|
|
|
// TODO: Calculate a partial from the reverse diagonals.
|
|
|
// For now, just assume everything after the midOriginal/midModified point is a diff
|
|
|
let originalStartPoint = midOriginalArr[0] + 1;
|
|
|
let modifiedStartPoint = midModifiedArr[0] + 1;
|
|
|
if (forwardChanges !== null && forwardChanges.length > 0) {
|
|
|
const lastForwardChange = forwardChanges[forwardChanges.length - 1];
|
|
|
originalStartPoint = Math.max(originalStartPoint, lastForwardChange.getOriginalEnd());
|
|
|
modifiedStartPoint = Math.max(modifiedStartPoint, lastForwardChange.getModifiedEnd());
|
|
|
}
|
|
|
reverseChanges = [
|
|
|
new DiffChange(originalStartPoint, originalEnd - originalStartPoint + 1, modifiedStartPoint, modifiedEnd - modifiedStartPoint + 1)
|
|
|
];
|
|
|
}
|
|
|
else {
|
|
|
// Now walk backward through the reverse diagonals history
|
|
|
changeHelper = new DiffChangeHelper();
|
|
|
diagonalMin = diagonalReverseStart;
|
|
|
diagonalMax = diagonalReverseEnd;
|
|
|
diagonalRelative = (midOriginalArr[0] - midModifiedArr[0]) - diagonalReverseOffset;
|
|
|
lastOriginalIndex = 1073741824 /* MAX_SAFE_SMALL_INTEGER */;
|
|
|
historyIndex = (deltaIsEven) ? this.m_reverseHistory.length - 1 : this.m_reverseHistory.length - 2;
|
|
|
do {
|
|
|
// Get the diagonal index from the relative diagonal number
|
|
|
const diagonal = diagonalRelative + diagonalReverseBase;
|
|
|
// Figure out where we came from
|
|
|
if (diagonal === diagonalMin || (diagonal < diagonalMax && reversePoints[diagonal - 1] >= reversePoints[diagonal + 1])) {
|
|
|
// Horizontal line (the element is a deletion))
|
|
|
originalIndex = reversePoints[diagonal + 1] - 1;
|
|
|
modifiedIndex = originalIndex - diagonalRelative - diagonalReverseOffset;
|
|
|
if (originalIndex > lastOriginalIndex) {
|
|
|
changeHelper.MarkNextChange();
|
|
|
}
|
|
|
lastOriginalIndex = originalIndex + 1;
|
|
|
changeHelper.AddOriginalElement(originalIndex + 1, modifiedIndex + 1);
|
|
|
diagonalRelative = (diagonal + 1) - diagonalReverseBase; //Setup for the next iteration
|
|
|
}
|
|
|
else {
|
|
|
// Vertical line (the element is an insertion)
|
|
|
originalIndex = reversePoints[diagonal - 1];
|
|
|
modifiedIndex = originalIndex - diagonalRelative - diagonalReverseOffset;
|
|
|
if (originalIndex > lastOriginalIndex) {
|
|
|
changeHelper.MarkNextChange();
|
|
|
}
|
|
|
lastOriginalIndex = originalIndex;
|
|
|
changeHelper.AddModifiedElement(originalIndex + 1, modifiedIndex + 1);
|
|
|
diagonalRelative = (diagonal - 1) - diagonalReverseBase; //Setup for the next iteration
|
|
|
}
|
|
|
if (historyIndex >= 0) {
|
|
|
reversePoints = this.m_reverseHistory[historyIndex];
|
|
|
diagonalReverseBase = reversePoints[0]; //We stored this in the first spot
|
|
|
diagonalMin = 1;
|
|
|
diagonalMax = reversePoints.length - 1;
|
|
|
}
|
|
|
} while (--historyIndex >= -1);
|
|
|
// There are cases where the reverse history will find diffs that
|
|
|
// are correct, but not intuitive, so we need shift them.
|
|
|
reverseChanges = changeHelper.getChanges();
|
|
|
}
|
|
|
return this.ConcatenateChanges(forwardChanges, reverseChanges);
|
|
|
}
|
|
|
/**
|
|
|
* Given the range to compute the diff on, this method finds the point:
|
|
|
* (midOriginal, midModified)
|
|
|
* that exists in the middle of the LCS of the two sequences and
|
|
|
* is the point at which the LCS problem may be broken down recursively.
|
|
|
* This method will try to keep the LCS trace in memory. If the LCS recursion
|
|
|
* point is calculated and the full trace is available in memory, then this method
|
|
|
* will return the change list.
|
|
|
* @param originalStart The start bound of the original sequence range
|
|
|
* @param originalEnd The end bound of the original sequence range
|
|
|
* @param modifiedStart The start bound of the modified sequence range
|
|
|
* @param modifiedEnd The end bound of the modified sequence range
|
|
|
* @param midOriginal The middle point of the original sequence range
|
|
|
* @param midModified The middle point of the modified sequence range
|
|
|
* @returns The diff changes, if available, otherwise null
|
|
|
*/
|
|
|
ComputeRecursionPoint(originalStart, originalEnd, modifiedStart, modifiedEnd, midOriginalArr, midModifiedArr, quitEarlyArr) {
|
|
|
let originalIndex = 0, modifiedIndex = 0;
|
|
|
let diagonalForwardStart = 0, diagonalForwardEnd = 0;
|
|
|
let diagonalReverseStart = 0, diagonalReverseEnd = 0;
|
|
|
// To traverse the edit graph and produce the proper LCS, our actual
|
|
|
// start position is just outside the given boundary
|
|
|
originalStart--;
|
|
|
modifiedStart--;
|
|
|
// We set these up to make the compiler happy, but they will
|
|
|
// be replaced before we return with the actual recursion point
|
|
|
midOriginalArr[0] = 0;
|
|
|
midModifiedArr[0] = 0;
|
|
|
// Clear out the history
|
|
|
this.m_forwardHistory = [];
|
|
|
this.m_reverseHistory = [];
|
|
|
// Each cell in the two arrays corresponds to a diagonal in the edit graph.
|
|
|
// The integer value in the cell represents the originalIndex of the furthest
|
|
|
// reaching point found so far that ends in that diagonal.
|
|
|
// The modifiedIndex can be computed mathematically from the originalIndex and the diagonal number.
|
|
|
const maxDifferences = (originalEnd - originalStart) + (modifiedEnd - modifiedStart);
|
|
|
const numDiagonals = maxDifferences + 1;
|
|
|
const forwardPoints = new Int32Array(numDiagonals);
|
|
|
const reversePoints = new Int32Array(numDiagonals);
|
|
|
// diagonalForwardBase: Index into forwardPoints of the diagonal which passes through (originalStart, modifiedStart)
|
|
|
// diagonalReverseBase: Index into reversePoints of the diagonal which passes through (originalEnd, modifiedEnd)
|
|
|
const diagonalForwardBase = (modifiedEnd - modifiedStart);
|
|
|
const diagonalReverseBase = (originalEnd - originalStart);
|
|
|
// diagonalForwardOffset: Geometric offset which allows modifiedIndex to be computed from originalIndex and the
|
|
|
// diagonal number (relative to diagonalForwardBase)
|
|
|
// diagonalReverseOffset: Geometric offset which allows modifiedIndex to be computed from originalIndex and the
|
|
|
// diagonal number (relative to diagonalReverseBase)
|
|
|
const diagonalForwardOffset = (originalStart - modifiedStart);
|
|
|
const diagonalReverseOffset = (originalEnd - modifiedEnd);
|
|
|
// delta: The difference between the end diagonal and the start diagonal. This is used to relate diagonal numbers
|
|
|
// relative to the start diagonal with diagonal numbers relative to the end diagonal.
|
|
|
// The Even/Oddn-ness of this delta is important for determining when we should check for overlap
|
|
|
const delta = diagonalReverseBase - diagonalForwardBase;
|
|
|
const deltaIsEven = (delta % 2 === 0);
|
|
|
// Here we set up the start and end points as the furthest points found so far
|
|
|
// in both the forward and reverse directions, respectively
|
|
|
forwardPoints[diagonalForwardBase] = originalStart;
|
|
|
reversePoints[diagonalReverseBase] = originalEnd;
|
|
|
// Remember if we quit early, and thus need to do a best-effort result instead of a real result.
|
|
|
quitEarlyArr[0] = false;
|
|
|
// A couple of points:
|
|
|
// --With this method, we iterate on the number of differences between the two sequences.
|
|
|
// The more differences there actually are, the longer this will take.
|
|
|
// --Also, as the number of differences increases, we have to search on diagonals further
|
|
|
// away from the reference diagonal (which is diagonalForwardBase for forward, diagonalReverseBase for reverse).
|
|
|
// --We extend on even diagonals (relative to the reference diagonal) only when numDifferences
|
|
|
// is even and odd diagonals only when numDifferences is odd.
|
|
|
for (let numDifferences = 1; numDifferences <= (maxDifferences / 2) + 1; numDifferences++) {
|
|
|
let furthestOriginalIndex = 0;
|
|
|
let furthestModifiedIndex = 0;
|
|
|
// Run the algorithm in the forward direction
|
|
|
diagonalForwardStart = this.ClipDiagonalBound(diagonalForwardBase - numDifferences, numDifferences, diagonalForwardBase, numDiagonals);
|
|
|
diagonalForwardEnd = this.ClipDiagonalBound(diagonalForwardBase + numDifferences, numDifferences, diagonalForwardBase, numDiagonals);
|
|
|
for (let diagonal = diagonalForwardStart; diagonal <= diagonalForwardEnd; diagonal += 2) {
|
|
|
// STEP 1: We extend the furthest reaching point in the present diagonal
|
|
|
// by looking at the diagonals above and below and picking the one whose point
|
|
|
// is further away from the start point (originalStart, modifiedStart)
|
|
|
if (diagonal === diagonalForwardStart || (diagonal < diagonalForwardEnd && forwardPoints[diagonal - 1] < forwardPoints[diagonal + 1])) {
|
|
|
originalIndex = forwardPoints[diagonal + 1];
|
|
|
}
|
|
|
else {
|
|
|
originalIndex = forwardPoints[diagonal - 1] + 1;
|
|
|
}
|
|
|
modifiedIndex = originalIndex - (diagonal - diagonalForwardBase) - diagonalForwardOffset;
|
|
|
// Save the current originalIndex so we can test for false overlap in step 3
|
|
|
const tempOriginalIndex = originalIndex;
|
|
|
// STEP 2: We can continue to extend the furthest reaching point in the present diagonal
|
|
|
// so long as the elements are equal.
|
|
|
while (originalIndex < originalEnd && modifiedIndex < modifiedEnd && this.ElementsAreEqual(originalIndex + 1, modifiedIndex + 1)) {
|
|
|
originalIndex++;
|
|
|
modifiedIndex++;
|
|
|
}
|
|
|
forwardPoints[diagonal] = originalIndex;
|
|
|
if (originalIndex + modifiedIndex > furthestOriginalIndex + furthestModifiedIndex) {
|
|
|
furthestOriginalIndex = originalIndex;
|
|
|
furthestModifiedIndex = modifiedIndex;
|
|
|
}
|
|
|
// STEP 3: If delta is odd (overlap first happens on forward when delta is odd)
|
|
|
// and diagonal is in the range of reverse diagonals computed for numDifferences-1
|
|
|
// (the previous iteration; we haven't computed reverse diagonals for numDifferences yet)
|
|
|
// then check for overlap.
|
|
|
if (!deltaIsEven && Math.abs(diagonal - diagonalReverseBase) <= (numDifferences - 1)) {
|
|
|
if (originalIndex >= reversePoints[diagonal]) {
|
|
|
midOriginalArr[0] = originalIndex;
|
|
|
midModifiedArr[0] = modifiedIndex;
|
|
|
if (tempOriginalIndex <= reversePoints[diagonal] && 1447 /* MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* MaxDifferencesHistory */ + 1)) {
|
|
|
// BINGO! We overlapped, and we have the full trace in memory!
|
|
|
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
|
}
|
|
|
else {
|
|
|
// Either false overlap, or we didn't have enough memory for the full trace
|
|
|
// Just return the recursion point
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// Check to see if we should be quitting early, before moving on to the next iteration.
|
|
|
const matchLengthOfLongest = ((furthestOriginalIndex - originalStart) + (furthestModifiedIndex - modifiedStart) - numDifferences) / 2;
|
|
|
if (this.ContinueProcessingPredicate !== null && !this.ContinueProcessingPredicate(furthestOriginalIndex, matchLengthOfLongest)) {
|
|
|
// We can't finish, so skip ahead to generating a result from what we have.
|
|
|
quitEarlyArr[0] = true;
|
|
|
// Use the furthest distance we got in the forward direction.
|
|
|
midOriginalArr[0] = furthestOriginalIndex;
|
|
|
midModifiedArr[0] = furthestModifiedIndex;
|
|
|
if (matchLengthOfLongest > 0 && 1447 /* MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* MaxDifferencesHistory */ + 1)) {
|
|
|
// Enough of the history is in memory to walk it backwards
|
|
|
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
|
}
|
|
|
else {
|
|
|
// We didn't actually remember enough of the history.
|
|
|
//Since we are quitting the diff early, we need to shift back the originalStart and modified start
|
|
|
//back into the boundary limits since we decremented their value above beyond the boundary limit.
|
|
|
originalStart++;
|
|
|
modifiedStart++;
|
|
|
return [
|
|
|
new DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, modifiedEnd - modifiedStart + 1)
|
|
|
];
|
|
|
}
|
|
|
}
|
|
|
// Run the algorithm in the reverse direction
|
|
|
diagonalReverseStart = this.ClipDiagonalBound(diagonalReverseBase - numDifferences, numDifferences, diagonalReverseBase, numDiagonals);
|
|
|
diagonalReverseEnd = this.ClipDiagonalBound(diagonalReverseBase + numDifferences, numDifferences, diagonalReverseBase, numDiagonals);
|
|
|
for (let diagonal = diagonalReverseStart; diagonal <= diagonalReverseEnd; diagonal += 2) {
|
|
|
// STEP 1: We extend the furthest reaching point in the present diagonal
|
|
|
// by looking at the diagonals above and below and picking the one whose point
|
|
|
// is further away from the start point (originalEnd, modifiedEnd)
|
|
|
if (diagonal === diagonalReverseStart || (diagonal < diagonalReverseEnd && reversePoints[diagonal - 1] >= reversePoints[diagonal + 1])) {
|
|
|
originalIndex = reversePoints[diagonal + 1] - 1;
|
|
|
}
|
|
|
else {
|
|
|
originalIndex = reversePoints[diagonal - 1];
|
|
|
}
|
|
|
modifiedIndex = originalIndex - (diagonal - diagonalReverseBase) - diagonalReverseOffset;
|
|
|
// Save the current originalIndex so we can test for false overlap
|
|
|
const tempOriginalIndex = originalIndex;
|
|
|
// STEP 2: We can continue to extend the furthest reaching point in the present diagonal
|
|
|
// as long as the elements are equal.
|
|
|
while (originalIndex > originalStart && modifiedIndex > modifiedStart && this.ElementsAreEqual(originalIndex, modifiedIndex)) {
|
|
|
originalIndex--;
|
|
|
modifiedIndex--;
|
|
|
}
|
|
|
reversePoints[diagonal] = originalIndex;
|
|
|
// STEP 4: If delta is even (overlap first happens on reverse when delta is even)
|
|
|
// and diagonal is in the range of forward diagonals computed for numDifferences
|
|
|
// then check for overlap.
|
|
|
if (deltaIsEven && Math.abs(diagonal - diagonalForwardBase) <= numDifferences) {
|
|
|
if (originalIndex <= forwardPoints[diagonal]) {
|
|
|
midOriginalArr[0] = originalIndex;
|
|
|
midModifiedArr[0] = modifiedIndex;
|
|
|
if (tempOriginalIndex >= forwardPoints[diagonal] && 1447 /* MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* MaxDifferencesHistory */ + 1)) {
|
|
|
// BINGO! We overlapped, and we have the full trace in memory!
|
|
|
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
|
}
|
|
|
else {
|
|
|
// Either false overlap, or we didn't have enough memory for the full trace
|
|
|
// Just return the recursion point
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// Save current vectors to history before the next iteration
|
|
|
if (numDifferences <= 1447 /* MaxDifferencesHistory */) {
|
|
|
// We are allocating space for one extra int, which we fill with
|
|
|
// the index of the diagonal base index
|
|
|
let temp = new Int32Array(diagonalForwardEnd - diagonalForwardStart + 2);
|
|
|
temp[0] = diagonalForwardBase - diagonalForwardStart + 1;
|
|
|
MyArray.Copy2(forwardPoints, diagonalForwardStart, temp, 1, diagonalForwardEnd - diagonalForwardStart + 1);
|
|
|
this.m_forwardHistory.push(temp);
|
|
|
temp = new Int32Array(diagonalReverseEnd - diagonalReverseStart + 2);
|
|
|
temp[0] = diagonalReverseBase - diagonalReverseStart + 1;
|
|
|
MyArray.Copy2(reversePoints, diagonalReverseStart, temp, 1, diagonalReverseEnd - diagonalReverseStart + 1);
|
|
|
this.m_reverseHistory.push(temp);
|
|
|
}
|
|
|
}
|
|
|
// If we got here, then we have the full trace in history. We just have to convert it to a change list
|
|
|
// NOTE: This part is a bit messy
|
|
|
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
|
}
|
|
|
/**
|
|
|
* Shifts the given changes to provide a more intuitive diff.
|
|
|
* While the first element in a diff matches the first element after the diff,
|
|
|
* we shift the diff down.
|
|
|
*
|
|
|
* @param changes The list of changes to shift
|
|
|
* @returns The shifted changes
|
|
|
*/
|
|
|
PrettifyChanges(changes) {
|
|
|
// Shift all the changes down first
|
|
|
for (let i = 0; i < changes.length; i++) {
|
|
|
const change = changes[i];
|
|
|
const originalStop = (i < changes.length - 1) ? changes[i + 1].originalStart : this._originalElementsOrHash.length;
|
|
|
const modifiedStop = (i < changes.length - 1) ? changes[i + 1].modifiedStart : this._modifiedElementsOrHash.length;
|
|
|
const checkOriginal = change.originalLength > 0;
|
|
|
const checkModified = change.modifiedLength > 0;
|
|
|
while (change.originalStart + change.originalLength < originalStop
|
|
|
&& change.modifiedStart + change.modifiedLength < modifiedStop
|
|
|
&& (!checkOriginal || this.OriginalElementsAreEqual(change.originalStart, change.originalStart + change.originalLength))
|
|
|
&& (!checkModified || this.ModifiedElementsAreEqual(change.modifiedStart, change.modifiedStart + change.modifiedLength))) {
|
|
|
const startStrictEqual = this.ElementsAreStrictEqual(change.originalStart, change.modifiedStart);
|
|
|
const endStrictEqual = this.ElementsAreStrictEqual(change.originalStart + change.originalLength, change.modifiedStart + change.modifiedLength);
|
|
|
if (endStrictEqual && !startStrictEqual) {
|
|
|
// moving the change down would create an equal change, but the elements are not strict equal
|
|
|
break;
|
|
|
}
|
|
|
change.originalStart++;
|
|
|
change.modifiedStart++;
|
|
|
}
|
|
|
let mergedChangeArr = [null];
|
|
|
if (i < changes.length - 1 && this.ChangesOverlap(changes[i], changes[i + 1], mergedChangeArr)) {
|
|
|
changes[i] = mergedChangeArr[0];
|
|
|
changes.splice(i + 1, 1);
|
|
|
i--;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
// Shift changes back up until we hit empty or whitespace-only lines
|
|
|
for (let i = changes.length - 1; i >= 0; i--) {
|
|
|
const change = changes[i];
|
|
|
let originalStop = 0;
|
|
|
let modifiedStop = 0;
|
|
|
if (i > 0) {
|
|
|
const prevChange = changes[i - 1];
|
|
|
originalStop = prevChange.originalStart + prevChange.originalLength;
|
|
|
modifiedStop = prevChange.modifiedStart + prevChange.modifiedLength;
|
|
|
}
|
|
|
const checkOriginal = change.originalLength > 0;
|
|
|
const checkModified = change.modifiedLength > 0;
|
|
|
let bestDelta = 0;
|
|
|
let bestScore = this._boundaryScore(change.originalStart, change.originalLength, change.modifiedStart, change.modifiedLength);
|
|
|
for (let delta = 1;; delta++) {
|
|
|
const originalStart = change.originalStart - delta;
|
|
|
const modifiedStart = change.modifiedStart - delta;
|
|
|
if (originalStart < originalStop || modifiedStart < modifiedStop) {
|
|
|
break;
|
|
|
}
|
|
|
if (checkOriginal && !this.OriginalElementsAreEqual(originalStart, originalStart + change.originalLength)) {
|
|
|
break;
|
|
|
}
|
|
|
if (checkModified && !this.ModifiedElementsAreEqual(modifiedStart, modifiedStart + change.modifiedLength)) {
|
|
|
break;
|
|
|
}
|
|
|
const touchingPreviousChange = (originalStart === originalStop && modifiedStart === modifiedStop);
|
|
|
const score = ((touchingPreviousChange ? 5 : 0)
|
|
|
+ this._boundaryScore(originalStart, change.originalLength, modifiedStart, change.modifiedLength));
|
|
|
if (score > bestScore) {
|
|
|
bestScore = score;
|
|
|
bestDelta = delta;
|
|
|
}
|
|
|
}
|
|
|
change.originalStart -= bestDelta;
|
|
|
change.modifiedStart -= bestDelta;
|
|
|
const mergedChangeArr = [null];
|
|
|
if (i > 0 && this.ChangesOverlap(changes[i - 1], changes[i], mergedChangeArr)) {
|
|
|
changes[i - 1] = mergedChangeArr[0];
|
|
|
changes.splice(i, 1);
|
|
|
i++;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
// There could be multiple longest common substrings.
|
|
|
// Give preference to the ones containing longer lines
|
|
|
if (this._hasStrings) {
|
|
|
for (let i = 1, len = changes.length; i < len; i++) {
|
|
|
const aChange = changes[i - 1];
|
|
|
const bChange = changes[i];
|
|
|
const matchedLength = bChange.originalStart - aChange.originalStart - aChange.originalLength;
|
|
|
const aOriginalStart = aChange.originalStart;
|
|
|
const bOriginalEnd = bChange.originalStart + bChange.originalLength;
|
|
|
const abOriginalLength = bOriginalEnd - aOriginalStart;
|
|
|
const aModifiedStart = aChange.modifiedStart;
|
|
|
const bModifiedEnd = bChange.modifiedStart + bChange.modifiedLength;
|
|
|
const abModifiedLength = bModifiedEnd - aModifiedStart;
|
|
|
// Avoid wasting a lot of time with these searches
|
|
|
if (matchedLength < 5 && abOriginalLength < 20 && abModifiedLength < 20) {
|
|
|
const t = this._findBetterContiguousSequence(aOriginalStart, abOriginalLength, aModifiedStart, abModifiedLength, matchedLength);
|
|
|
if (t) {
|
|
|
const [originalMatchStart, modifiedMatchStart] = t;
|
|
|
if (originalMatchStart !== aChange.originalStart + aChange.originalLength || modifiedMatchStart !== aChange.modifiedStart + aChange.modifiedLength) {
|
|
|
// switch to another sequence that has a better score
|
|
|
aChange.originalLength = originalMatchStart - aChange.originalStart;
|
|
|
aChange.modifiedLength = modifiedMatchStart - aChange.modifiedStart;
|
|
|
bChange.originalStart = originalMatchStart + matchedLength;
|
|
|
bChange.modifiedStart = modifiedMatchStart + matchedLength;
|
|
|
bChange.originalLength = bOriginalEnd - bChange.originalStart;
|
|
|
bChange.modifiedLength = bModifiedEnd - bChange.modifiedStart;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return changes;
|
|
|
}
|
|
|
_findBetterContiguousSequence(originalStart, originalLength, modifiedStart, modifiedLength, desiredLength) {
|
|
|
if (originalLength < desiredLength || modifiedLength < desiredLength) {
|
|
|
return null;
|
|
|
}
|
|
|
const originalMax = originalStart + originalLength - desiredLength + 1;
|
|
|
const modifiedMax = modifiedStart + modifiedLength - desiredLength + 1;
|
|
|
let bestScore = 0;
|
|
|
let bestOriginalStart = 0;
|
|
|
let bestModifiedStart = 0;
|
|
|
for (let i = originalStart; i < originalMax; i++) {
|
|
|
for (let j = modifiedStart; j < modifiedMax; j++) {
|
|
|
const score = this._contiguousSequenceScore(i, j, desiredLength);
|
|
|
if (score > 0 && score > bestScore) {
|
|
|
bestScore = score;
|
|
|
bestOriginalStart = i;
|
|
|
bestModifiedStart = j;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (bestScore > 0) {
|
|
|
return [bestOriginalStart, bestModifiedStart];
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
_contiguousSequenceScore(originalStart, modifiedStart, length) {
|
|
|
let score = 0;
|
|
|
for (let l = 0; l < length; l++) {
|
|
|
if (!this.ElementsAreEqual(originalStart + l, modifiedStart + l)) {
|
|
|
return 0;
|
|
|
}
|
|
|
score += this._originalStringElements[originalStart + l].length;
|
|
|
}
|
|
|
return score;
|
|
|
}
|
|
|
_OriginalIsBoundary(index) {
|
|
|
if (index <= 0 || index >= this._originalElementsOrHash.length - 1) {
|
|
|
return true;
|
|
|
}
|
|
|
return (this._hasStrings && /^\s*$/.test(this._originalStringElements[index]));
|
|
|
}
|
|
|
_OriginalRegionIsBoundary(originalStart, originalLength) {
|
|
|
if (this._OriginalIsBoundary(originalStart) || this._OriginalIsBoundary(originalStart - 1)) {
|
|
|
return true;
|
|
|
}
|
|
|
if (originalLength > 0) {
|
|
|
const originalEnd = originalStart + originalLength;
|
|
|
if (this._OriginalIsBoundary(originalEnd - 1) || this._OriginalIsBoundary(originalEnd)) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
_ModifiedIsBoundary(index) {
|
|
|
if (index <= 0 || index >= this._modifiedElementsOrHash.length - 1) {
|
|
|
return true;
|
|
|
}
|
|
|
return (this._hasStrings && /^\s*$/.test(this._modifiedStringElements[index]));
|
|
|
}
|
|
|
_ModifiedRegionIsBoundary(modifiedStart, modifiedLength) {
|
|
|
if (this._ModifiedIsBoundary(modifiedStart) || this._ModifiedIsBoundary(modifiedStart - 1)) {
|
|
|
return true;
|
|
|
}
|
|
|
if (modifiedLength > 0) {
|
|
|
const modifiedEnd = modifiedStart + modifiedLength;
|
|
|
if (this._ModifiedIsBoundary(modifiedEnd - 1) || this._ModifiedIsBoundary(modifiedEnd)) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
_boundaryScore(originalStart, originalLength, modifiedStart, modifiedLength) {
|
|
|
const originalScore = (this._OriginalRegionIsBoundary(originalStart, originalLength) ? 1 : 0);
|
|
|
const modifiedScore = (this._ModifiedRegionIsBoundary(modifiedStart, modifiedLength) ? 1 : 0);
|
|
|
return (originalScore + modifiedScore);
|
|
|
}
|
|
|
/**
|
|
|
* Concatenates the two input DiffChange lists and returns the resulting
|
|
|
* list.
|
|
|
* @param The left changes
|
|
|
* @param The right changes
|
|
|
* @returns The concatenated list
|
|
|
*/
|
|
|
ConcatenateChanges(left, right) {
|
|
|
let mergedChangeArr = [];
|
|
|
if (left.length === 0 || right.length === 0) {
|
|
|
return (right.length > 0) ? right : left;
|
|
|
}
|
|
|
else if (this.ChangesOverlap(left[left.length - 1], right[0], mergedChangeArr)) {
|
|
|
// Since we break the problem down recursively, it is possible that we
|
|
|
// might recurse in the middle of a change thereby splitting it into
|
|
|
// two changes. Here in the combining stage, we detect and fuse those
|
|
|
// changes back together
|
|
|
const result = new Array(left.length + right.length - 1);
|
|
|
MyArray.Copy(left, 0, result, 0, left.length - 1);
|
|
|
result[left.length - 1] = mergedChangeArr[0];
|
|
|
MyArray.Copy(right, 1, result, left.length, right.length - 1);
|
|
|
return result;
|
|
|
}
|
|
|
else {
|
|
|
const result = new Array(left.length + right.length);
|
|
|
MyArray.Copy(left, 0, result, 0, left.length);
|
|
|
MyArray.Copy(right, 0, result, left.length, right.length);
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Returns true if the two changes overlap and can be merged into a single
|
|
|
* change
|
|
|
* @param left The left change
|
|
|
* @param right The right change
|
|
|
* @param mergedChange The merged change if the two overlap, null otherwise
|
|
|
* @returns True if the two changes overlap
|
|
|
*/
|
|
|
ChangesOverlap(left, right, mergedChangeArr) {
|
|
|
Debug.Assert(left.originalStart <= right.originalStart, 'Left change is not less than or equal to right change');
|
|
|
Debug.Assert(left.modifiedStart <= right.modifiedStart, 'Left change is not less than or equal to right change');
|
|
|
if (left.originalStart + left.originalLength >= right.originalStart || left.modifiedStart + left.modifiedLength >= right.modifiedStart) {
|
|
|
const originalStart = left.originalStart;
|
|
|
let originalLength = left.originalLength;
|
|
|
const modifiedStart = left.modifiedStart;
|
|
|
let modifiedLength = left.modifiedLength;
|
|
|
if (left.originalStart + left.originalLength >= right.originalStart) {
|
|
|
originalLength = right.originalStart + right.originalLength - left.originalStart;
|
|
|
}
|
|
|
if (left.modifiedStart + left.modifiedLength >= right.modifiedStart) {
|
|
|
modifiedLength = right.modifiedStart + right.modifiedLength - left.modifiedStart;
|
|
|
}
|
|
|
mergedChangeArr[0] = new DiffChange(originalStart, originalLength, modifiedStart, modifiedLength);
|
|
|
return true;
|
|
|
}
|
|
|
else {
|
|
|
mergedChangeArr[0] = null;
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Helper method used to clip a diagonal index to the range of valid
|
|
|
* diagonals. This also decides whether or not the diagonal index,
|
|
|
* if it exceeds the boundary, should be clipped to the boundary or clipped
|
|
|
* one inside the boundary depending on the Even/Odd status of the boundary
|
|
|
* and numDifferences.
|
|
|
* @param diagonal The index of the diagonal to clip.
|
|
|
* @param numDifferences The current number of differences being iterated upon.
|
|
|
* @param diagonalBaseIndex The base reference diagonal.
|
|
|
* @param numDiagonals The total number of diagonals.
|
|
|
* @returns The clipped diagonal index.
|
|
|
*/
|
|
|
ClipDiagonalBound(diagonal, numDifferences, diagonalBaseIndex, numDiagonals) {
|
|
|
if (diagonal >= 0 && diagonal < numDiagonals) {
|
|
|
// Nothing to clip, its in range
|
|
|
return diagonal;
|
|
|
}
|
|
|
// diagonalsBelow: The number of diagonals below the reference diagonal
|
|
|
// diagonalsAbove: The number of diagonals above the reference diagonal
|
|
|
const diagonalsBelow = diagonalBaseIndex;
|
|
|
const diagonalsAbove = numDiagonals - diagonalBaseIndex - 1;
|
|
|
const diffEven = (numDifferences % 2 === 0);
|
|
|
if (diagonal < 0) {
|
|
|
const lowerBoundEven = (diagonalsBelow % 2 === 0);
|
|
|
return (diffEven === lowerBoundEven) ? 0 : 1;
|
|
|
}
|
|
|
else {
|
|
|
const upperBoundEven = (diagonalsAbove % 2 === 0);
|
|
|
return (diffEven === upperBoundEven) ? numDiagonals - 1 : numDiagonals - 2;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/process.js
|
|
|
/* provided dependency */ var process_process = __webpack_require__(/*! ./node_modules/_process@0.11.10@process/browser.js */ 671);
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
let safeProcess;
|
|
|
// Native sandbox environment
|
|
|
if (typeof platform_globals.vscode !== 'undefined' && typeof platform_globals.vscode.process !== 'undefined') {
|
|
|
const sandboxProcess = platform_globals.vscode.process;
|
|
|
safeProcess = {
|
|
|
get platform() { return sandboxProcess.platform; },
|
|
|
get arch() { return sandboxProcess.arch; },
|
|
|
get env() { return sandboxProcess.env; },
|
|
|
cwd() { return sandboxProcess.cwd(); },
|
|
|
nextTick(callback) { return setImmediate(callback); }
|
|
|
};
|
|
|
}
|
|
|
// Native node.js environment
|
|
|
else if (typeof process_process !== 'undefined') {
|
|
|
safeProcess = {
|
|
|
get platform() { return process_process.platform; },
|
|
|
get arch() { return process_process.arch; },
|
|
|
get env() { return ({"NODE_ENV":"production","PUBLIC_PATH":"/react/build/"}); },
|
|
|
cwd() { return ({"NODE_ENV":"production","PUBLIC_PATH":"/react/build/"})['VSCODE_CWD'] || process_process.cwd(); },
|
|
|
nextTick(callback) { return process_process.nextTick(callback); }
|
|
|
};
|
|
|
}
|
|
|
// Web environment
|
|
|
else {
|
|
|
safeProcess = {
|
|
|
// Supported
|
|
|
get platform() { return isWindows ? 'win32' : isMacintosh ? 'darwin' : 'linux'; },
|
|
|
get arch() { return undefined; /* arch is undefined in web */ },
|
|
|
nextTick(callback) { return setImmediate(callback); },
|
|
|
// Unsupported
|
|
|
get env() { return {}; },
|
|
|
cwd() { return '/'; }
|
|
|
};
|
|
|
}
|
|
|
/**
|
|
|
* Provides safe access to the `cwd` property in node.js, sandboxed or web
|
|
|
* environments.
|
|
|
*
|
|
|
* Note: in web, this property is hardcoded to be `/`.
|
|
|
*/
|
|
|
const cwd = safeProcess.cwd;
|
|
|
/**
|
|
|
* Provides safe access to the `env` property in node.js, sandboxed or web
|
|
|
* environments.
|
|
|
*
|
|
|
* Note: in web, this property is hardcoded to be `{}`.
|
|
|
*/
|
|
|
const env = safeProcess.env;
|
|
|
/**
|
|
|
* Provides safe access to the `platform` property in node.js, sandboxed or web
|
|
|
* environments.
|
|
|
*/
|
|
|
const platform = safeProcess.platform;
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/path.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
// NOTE: VSCode's copy of nodejs path library to be usable in common (non-node) namespace
|
|
|
// Copied from: https://github.com/nodejs/node/blob/v14.16.0/lib/path.js
|
|
|
/**
|
|
|
* Copyright Joyent, Inc. and other Node contributors.
|
|
|
*
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
* copy of this software and associated documentation files (the
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
|
* persons to whom the Software is furnished to do so, subject to the
|
|
|
* following conditions:
|
|
|
*
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
*
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
|
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
|
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
*/
|
|
|
|
|
|
const CHAR_UPPERCASE_A = 65; /* A */
|
|
|
const CHAR_LOWERCASE_A = 97; /* a */
|
|
|
const CHAR_UPPERCASE_Z = 90; /* Z */
|
|
|
const CHAR_LOWERCASE_Z = 122; /* z */
|
|
|
const CHAR_DOT = 46; /* . */
|
|
|
const CHAR_FORWARD_SLASH = 47; /* / */
|
|
|
const CHAR_BACKWARD_SLASH = 92; /* \ */
|
|
|
const CHAR_COLON = 58; /* : */
|
|
|
const CHAR_QUESTION_MARK = 63; /* ? */
|
|
|
class ErrorInvalidArgType extends Error {
|
|
|
constructor(name, expected, actual) {
|
|
|
// determiner: 'must be' or 'must not be'
|
|
|
let determiner;
|
|
|
if (typeof expected === 'string' && expected.indexOf('not ') === 0) {
|
|
|
determiner = 'must not be';
|
|
|
expected = expected.replace(/^not /, '');
|
|
|
}
|
|
|
else {
|
|
|
determiner = 'must be';
|
|
|
}
|
|
|
const type = name.indexOf('.') !== -1 ? 'property' : 'argument';
|
|
|
let msg = `The "${name}" ${type} ${determiner} of type ${expected}`;
|
|
|
msg += `. Received type ${typeof actual}`;
|
|
|
super(msg);
|
|
|
this.code = 'ERR_INVALID_ARG_TYPE';
|
|
|
}
|
|
|
}
|
|
|
function validateString(value, name) {
|
|
|
if (typeof value !== 'string') {
|
|
|
throw new ErrorInvalidArgType(name, 'string', value);
|
|
|
}
|
|
|
}
|
|
|
function isPathSeparator(code) {
|
|
|
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
|
|
|
}
|
|
|
function isPosixPathSeparator(code) {
|
|
|
return code === CHAR_FORWARD_SLASH;
|
|
|
}
|
|
|
function isWindowsDeviceRoot(code) {
|
|
|
return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
|
|
|
(code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);
|
|
|
}
|
|
|
// Resolves . and .. elements in a path with directory names
|
|
|
function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
|
|
|
let res = '';
|
|
|
let lastSegmentLength = 0;
|
|
|
let lastSlash = -1;
|
|
|
let dots = 0;
|
|
|
let code = 0;
|
|
|
for (let i = 0; i <= path.length; ++i) {
|
|
|
if (i < path.length) {
|
|
|
code = path.charCodeAt(i);
|
|
|
}
|
|
|
else if (isPathSeparator(code)) {
|
|
|
break;
|
|
|
}
|
|
|
else {
|
|
|
code = CHAR_FORWARD_SLASH;
|
|
|
}
|
|
|
if (isPathSeparator(code)) {
|
|
|
if (lastSlash === i - 1 || dots === 1) {
|
|
|
// NOOP
|
|
|
}
|
|
|
else if (dots === 2) {
|
|
|
if (res.length < 2 || lastSegmentLength !== 2 ||
|
|
|
res.charCodeAt(res.length - 1) !== CHAR_DOT ||
|
|
|
res.charCodeAt(res.length - 2) !== CHAR_DOT) {
|
|
|
if (res.length > 2) {
|
|
|
const lastSlashIndex = res.lastIndexOf(separator);
|
|
|
if (lastSlashIndex === -1) {
|
|
|
res = '';
|
|
|
lastSegmentLength = 0;
|
|
|
}
|
|
|
else {
|
|
|
res = res.slice(0, lastSlashIndex);
|
|
|
lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
|
|
|
}
|
|
|
lastSlash = i;
|
|
|
dots = 0;
|
|
|
continue;
|
|
|
}
|
|
|
else if (res.length !== 0) {
|
|
|
res = '';
|
|
|
lastSegmentLength = 0;
|
|
|
lastSlash = i;
|
|
|
dots = 0;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
if (allowAboveRoot) {
|
|
|
res += res.length > 0 ? `${separator}..` : '..';
|
|
|
lastSegmentLength = 2;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
if (res.length > 0) {
|
|
|
res += `${separator}${path.slice(lastSlash + 1, i)}`;
|
|
|
}
|
|
|
else {
|
|
|
res = path.slice(lastSlash + 1, i);
|
|
|
}
|
|
|
lastSegmentLength = i - lastSlash - 1;
|
|
|
}
|
|
|
lastSlash = i;
|
|
|
dots = 0;
|
|
|
}
|
|
|
else if (code === CHAR_DOT && dots !== -1) {
|
|
|
++dots;
|
|
|
}
|
|
|
else {
|
|
|
dots = -1;
|
|
|
}
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
function _format(sep, pathObject) {
|
|
|
if (pathObject === null || typeof pathObject !== 'object') {
|
|
|
throw new ErrorInvalidArgType('pathObject', 'Object', pathObject);
|
|
|
}
|
|
|
const dir = pathObject.dir || pathObject.root;
|
|
|
const base = pathObject.base ||
|
|
|
`${pathObject.name || ''}${pathObject.ext || ''}`;
|
|
|
if (!dir) {
|
|
|
return base;
|
|
|
}
|
|
|
return dir === pathObject.root ? `${dir}${base}` : `${dir}${sep}${base}`;
|
|
|
}
|
|
|
const win32 = {
|
|
|
// path.resolve([from ...], to)
|
|
|
resolve(...pathSegments) {
|
|
|
let resolvedDevice = '';
|
|
|
let resolvedTail = '';
|
|
|
let resolvedAbsolute = false;
|
|
|
for (let i = pathSegments.length - 1; i >= -1; i--) {
|
|
|
let path;
|
|
|
if (i >= 0) {
|
|
|
path = pathSegments[i];
|
|
|
validateString(path, 'path');
|
|
|
// Skip empty entries
|
|
|
if (path.length === 0) {
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
else if (resolvedDevice.length === 0) {
|
|
|
path = cwd();
|
|
|
}
|
|
|
else {
|
|
|
// Windows has the concept of drive-specific current working
|
|
|
// directories. If we've resolved a drive letter but not yet an
|
|
|
// absolute path, get cwd for that drive, or the process cwd if
|
|
|
// the drive cwd is not available. We're sure the device is not
|
|
|
// a UNC path at this points, because UNC paths are always absolute.
|
|
|
path = ({"NODE_ENV":"production","PUBLIC_PATH":"/react/build/"})[`=${resolvedDevice}`] || cwd();
|
|
|
// Verify that a cwd was found and that it actually points
|
|
|
// to our drive. If not, default to the drive's root.
|
|
|
if (path === undefined ||
|
|
|
(path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&
|
|
|
path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {
|
|
|
path = `${resolvedDevice}\\`;
|
|
|
}
|
|
|
}
|
|
|
const len = path.length;
|
|
|
let rootEnd = 0;
|
|
|
let device = '';
|
|
|
let isAbsolute = false;
|
|
|
const code = path.charCodeAt(0);
|
|
|
// Try to match a root
|
|
|
if (len === 1) {
|
|
|
if (isPathSeparator(code)) {
|
|
|
// `path` contains just a path separator
|
|
|
rootEnd = 1;
|
|
|
isAbsolute = true;
|
|
|
}
|
|
|
}
|
|
|
else if (isPathSeparator(code)) {
|
|
|
// Possible UNC root
|
|
|
// If we started with a separator, we know we at least have an
|
|
|
// absolute path of some kind (UNC or otherwise)
|
|
|
isAbsolute = true;
|
|
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|
|
// Matched double path separator at beginning
|
|
|
let j = 2;
|
|
|
let last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
const firstPart = path.slice(last, j);
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more path separators
|
|
|
while (j < len && isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j === len || j !== last) {
|
|
|
// We matched a UNC root
|
|
|
device = `\\\\${firstPart}\\${path.slice(last, j)}`;
|
|
|
rootEnd = j;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
rootEnd = 1;
|
|
|
}
|
|
|
}
|
|
|
else if (isWindowsDeviceRoot(code) &&
|
|
|
path.charCodeAt(1) === CHAR_COLON) {
|
|
|
// Possible device root
|
|
|
device = path.slice(0, 2);
|
|
|
rootEnd = 2;
|
|
|
if (len > 2 && isPathSeparator(path.charCodeAt(2))) {
|
|
|
// Treat separator following drive name as an absolute path
|
|
|
// indicator
|
|
|
isAbsolute = true;
|
|
|
rootEnd = 3;
|
|
|
}
|
|
|
}
|
|
|
if (device.length > 0) {
|
|
|
if (resolvedDevice.length > 0) {
|
|
|
if (device.toLowerCase() !== resolvedDevice.toLowerCase()) {
|
|
|
// This path points to another device so it is not applicable
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
resolvedDevice = device;
|
|
|
}
|
|
|
}
|
|
|
if (resolvedAbsolute) {
|
|
|
if (resolvedDevice.length > 0) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
|
|
|
resolvedAbsolute = isAbsolute;
|
|
|
if (isAbsolute && resolvedDevice.length > 0) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// At this point the path should be resolved to a full absolute path,
|
|
|
// but handle relative paths to be safe (might happen when process.cwd()
|
|
|
// fails)
|
|
|
// Normalize the tail path
|
|
|
resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', isPathSeparator);
|
|
|
return resolvedAbsolute ?
|
|
|
`${resolvedDevice}\\${resolvedTail}` :
|
|
|
`${resolvedDevice}${resolvedTail}` || '.';
|
|
|
},
|
|
|
normalize(path) {
|
|
|
validateString(path, 'path');
|
|
|
const len = path.length;
|
|
|
if (len === 0) {
|
|
|
return '.';
|
|
|
}
|
|
|
let rootEnd = 0;
|
|
|
let device;
|
|
|
let isAbsolute = false;
|
|
|
const code = path.charCodeAt(0);
|
|
|
// Try to match a root
|
|
|
if (len === 1) {
|
|
|
// `path` contains just a single char, exit early to avoid
|
|
|
// unnecessary work
|
|
|
return isPosixPathSeparator(code) ? '\\' : path;
|
|
|
}
|
|
|
if (isPathSeparator(code)) {
|
|
|
// Possible UNC root
|
|
|
// If we started with a separator, we know we at least have an absolute
|
|
|
// path of some kind (UNC or otherwise)
|
|
|
isAbsolute = true;
|
|
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|
|
// Matched double path separator at beginning
|
|
|
let j = 2;
|
|
|
let last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
const firstPart = path.slice(last, j);
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more path separators
|
|
|
while (j < len && isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j === len) {
|
|
|
// We matched a UNC root only
|
|
|
// Return the normalized version of the UNC root since there
|
|
|
// is nothing left to process
|
|
|
return `\\\\${firstPart}\\${path.slice(last)}\\`;
|
|
|
}
|
|
|
if (j !== last) {
|
|
|
// We matched a UNC root with leftovers
|
|
|
device = `\\\\${firstPart}\\${path.slice(last, j)}`;
|
|
|
rootEnd = j;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
rootEnd = 1;
|
|
|
}
|
|
|
}
|
|
|
else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
|
|
|
// Possible device root
|
|
|
device = path.slice(0, 2);
|
|
|
rootEnd = 2;
|
|
|
if (len > 2 && isPathSeparator(path.charCodeAt(2))) {
|
|
|
// Treat separator following drive name as an absolute path
|
|
|
// indicator
|
|
|
isAbsolute = true;
|
|
|
rootEnd = 3;
|
|
|
}
|
|
|
}
|
|
|
let tail = rootEnd < len ?
|
|
|
normalizeString(path.slice(rootEnd), !isAbsolute, '\\', isPathSeparator) :
|
|
|
'';
|
|
|
if (tail.length === 0 && !isAbsolute) {
|
|
|
tail = '.';
|
|
|
}
|
|
|
if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) {
|
|
|
tail += '\\';
|
|
|
}
|
|
|
if (device === undefined) {
|
|
|
return isAbsolute ? `\\${tail}` : tail;
|
|
|
}
|
|
|
return isAbsolute ? `${device}\\${tail}` : `${device}${tail}`;
|
|
|
},
|
|
|
isAbsolute(path) {
|
|
|
validateString(path, 'path');
|
|
|
const len = path.length;
|
|
|
if (len === 0) {
|
|
|
return false;
|
|
|
}
|
|
|
const code = path.charCodeAt(0);
|
|
|
return isPathSeparator(code) ||
|
|
|
// Possible device root
|
|
|
(len > 2 &&
|
|
|
isWindowsDeviceRoot(code) &&
|
|
|
path.charCodeAt(1) === CHAR_COLON &&
|
|
|
isPathSeparator(path.charCodeAt(2)));
|
|
|
},
|
|
|
join(...paths) {
|
|
|
if (paths.length === 0) {
|
|
|
return '.';
|
|
|
}
|
|
|
let joined;
|
|
|
let firstPart;
|
|
|
for (let i = 0; i < paths.length; ++i) {
|
|
|
const arg = paths[i];
|
|
|
validateString(arg, 'path');
|
|
|
if (arg.length > 0) {
|
|
|
if (joined === undefined) {
|
|
|
joined = firstPart = arg;
|
|
|
}
|
|
|
else {
|
|
|
joined += `\\${arg}`;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (joined === undefined) {
|
|
|
return '.';
|
|
|
}
|
|
|
// Make sure that the joined path doesn't start with two slashes, because
|
|
|
// normalize() will mistake it for a UNC path then.
|
|
|
//
|
|
|
// This step is skipped when it is very clear that the user actually
|
|
|
// intended to point at a UNC path. This is assumed when the first
|
|
|
// non-empty string arguments starts with exactly two slashes followed by
|
|
|
// at least one more non-slash character.
|
|
|
//
|
|
|
// Note that for normalize() to treat a path as a UNC path it needs to
|
|
|
// have at least 2 components, so we don't filter for that here.
|
|
|
// This means that the user can use join to construct UNC paths from
|
|
|
// a server name and a share name; for example:
|
|
|
// path.join('//server', 'share') -> '\\\\server\\share\\')
|
|
|
let needsReplace = true;
|
|
|
let slashCount = 0;
|
|
|
if (typeof firstPart === 'string' && isPathSeparator(firstPart.charCodeAt(0))) {
|
|
|
++slashCount;
|
|
|
const firstLen = firstPart.length;
|
|
|
if (firstLen > 1 && isPathSeparator(firstPart.charCodeAt(1))) {
|
|
|
++slashCount;
|
|
|
if (firstLen > 2) {
|
|
|
if (isPathSeparator(firstPart.charCodeAt(2))) {
|
|
|
++slashCount;
|
|
|
}
|
|
|
else {
|
|
|
// We matched a UNC path in the first part
|
|
|
needsReplace = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (needsReplace) {
|
|
|
// Find any more consecutive slashes we need to replace
|
|
|
while (slashCount < joined.length &&
|
|
|
isPathSeparator(joined.charCodeAt(slashCount))) {
|
|
|
slashCount++;
|
|
|
}
|
|
|
// Replace the slashes if needed
|
|
|
if (slashCount >= 2) {
|
|
|
joined = `\\${joined.slice(slashCount)}`;
|
|
|
}
|
|
|
}
|
|
|
return win32.normalize(joined);
|
|
|
},
|
|
|
// It will solve the relative path from `from` to `to`, for instance:
|
|
|
// from = 'C:\\orandea\\test\\aaa'
|
|
|
// to = 'C:\\orandea\\impl\\bbb'
|
|
|
// The output of the function should be: '..\\..\\impl\\bbb'
|
|
|
relative(from, to) {
|
|
|
validateString(from, 'from');
|
|
|
validateString(to, 'to');
|
|
|
if (from === to) {
|
|
|
return '';
|
|
|
}
|
|
|
const fromOrig = win32.resolve(from);
|
|
|
const toOrig = win32.resolve(to);
|
|
|
if (fromOrig === toOrig) {
|
|
|
return '';
|
|
|
}
|
|
|
from = fromOrig.toLowerCase();
|
|
|
to = toOrig.toLowerCase();
|
|
|
if (from === to) {
|
|
|
return '';
|
|
|
}
|
|
|
// Trim any leading backslashes
|
|
|
let fromStart = 0;
|
|
|
while (fromStart < from.length &&
|
|
|
from.charCodeAt(fromStart) === CHAR_BACKWARD_SLASH) {
|
|
|
fromStart++;
|
|
|
}
|
|
|
// Trim trailing backslashes (applicable to UNC paths only)
|
|
|
let fromEnd = from.length;
|
|
|
while (fromEnd - 1 > fromStart &&
|
|
|
from.charCodeAt(fromEnd - 1) === CHAR_BACKWARD_SLASH) {
|
|
|
fromEnd--;
|
|
|
}
|
|
|
const fromLen = fromEnd - fromStart;
|
|
|
// Trim any leading backslashes
|
|
|
let toStart = 0;
|
|
|
while (toStart < to.length &&
|
|
|
to.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {
|
|
|
toStart++;
|
|
|
}
|
|
|
// Trim trailing backslashes (applicable to UNC paths only)
|
|
|
let toEnd = to.length;
|
|
|
while (toEnd - 1 > toStart &&
|
|
|
to.charCodeAt(toEnd - 1) === CHAR_BACKWARD_SLASH) {
|
|
|
toEnd--;
|
|
|
}
|
|
|
const toLen = toEnd - toStart;
|
|
|
// Compare paths to find the longest common path from root
|
|
|
const length = fromLen < toLen ? fromLen : toLen;
|
|
|
let lastCommonSep = -1;
|
|
|
let i = 0;
|
|
|
for (; i < length; i++) {
|
|
|
const fromCode = from.charCodeAt(fromStart + i);
|
|
|
if (fromCode !== to.charCodeAt(toStart + i)) {
|
|
|
break;
|
|
|
}
|
|
|
else if (fromCode === CHAR_BACKWARD_SLASH) {
|
|
|
lastCommonSep = i;
|
|
|
}
|
|
|
}
|
|
|
// We found a mismatch before the first common path separator was seen, so
|
|
|
// return the original `to`.
|
|
|
if (i !== length) {
|
|
|
if (lastCommonSep === -1) {
|
|
|
return toOrig;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
if (toLen > length) {
|
|
|
if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) {
|
|
|
// We get here if `from` is the exact base path for `to`.
|
|
|
// For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz'
|
|
|
return toOrig.slice(toStart + i + 1);
|
|
|
}
|
|
|
if (i === 2) {
|
|
|
// We get here if `from` is the device root.
|
|
|
// For example: from='C:\\'; to='C:\\foo'
|
|
|
return toOrig.slice(toStart + i);
|
|
|
}
|
|
|
}
|
|
|
if (fromLen > length) {
|
|
|
if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) {
|
|
|
// We get here if `to` is the exact base path for `from`.
|
|
|
// For example: from='C:\\foo\\bar'; to='C:\\foo'
|
|
|
lastCommonSep = i;
|
|
|
}
|
|
|
else if (i === 2) {
|
|
|
// We get here if `to` is the device root.
|
|
|
// For example: from='C:\\foo\\bar'; to='C:\\'
|
|
|
lastCommonSep = 3;
|
|
|
}
|
|
|
}
|
|
|
if (lastCommonSep === -1) {
|
|
|
lastCommonSep = 0;
|
|
|
}
|
|
|
}
|
|
|
let out = '';
|
|
|
// Generate the relative path based on the path difference between `to` and
|
|
|
// `from`
|
|
|
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
|
|
|
if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) {
|
|
|
out += out.length === 0 ? '..' : '\\..';
|
|
|
}
|
|
|
}
|
|
|
toStart += lastCommonSep;
|
|
|
// Lastly, append the rest of the destination (`to`) path that comes after
|
|
|
// the common path parts
|
|
|
if (out.length > 0) {
|
|
|
return `${out}${toOrig.slice(toStart, toEnd)}`;
|
|
|
}
|
|
|
if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {
|
|
|
++toStart;
|
|
|
}
|
|
|
return toOrig.slice(toStart, toEnd);
|
|
|
},
|
|
|
toNamespacedPath(path) {
|
|
|
// Note: this will *probably* throw somewhere.
|
|
|
if (typeof path !== 'string') {
|
|
|
return path;
|
|
|
}
|
|
|
if (path.length === 0) {
|
|
|
return '';
|
|
|
}
|
|
|
const resolvedPath = win32.resolve(path);
|
|
|
if (resolvedPath.length <= 2) {
|
|
|
return path;
|
|
|
}
|
|
|
if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) {
|
|
|
// Possible UNC root
|
|
|
if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) {
|
|
|
const code = resolvedPath.charCodeAt(2);
|
|
|
if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) {
|
|
|
// Matched non-long UNC root, convert the path to a long UNC path
|
|
|
return `\\\\?\\UNC\\${resolvedPath.slice(2)}`;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0)) &&
|
|
|
resolvedPath.charCodeAt(1) === CHAR_COLON &&
|
|
|
resolvedPath.charCodeAt(2) === CHAR_BACKWARD_SLASH) {
|
|
|
// Matched device root, convert the path to a long UNC path
|
|
|
return `\\\\?\\${resolvedPath}`;
|
|
|
}
|
|
|
return path;
|
|
|
},
|
|
|
dirname(path) {
|
|
|
validateString(path, 'path');
|
|
|
const len = path.length;
|
|
|
if (len === 0) {
|
|
|
return '.';
|
|
|
}
|
|
|
let rootEnd = -1;
|
|
|
let offset = 0;
|
|
|
const code = path.charCodeAt(0);
|
|
|
if (len === 1) {
|
|
|
// `path` contains just a path separator, exit early to avoid
|
|
|
// unnecessary work or a dot.
|
|
|
return isPathSeparator(code) ? path : '.';
|
|
|
}
|
|
|
// Try to match a root
|
|
|
if (isPathSeparator(code)) {
|
|
|
// Possible UNC root
|
|
|
rootEnd = offset = 1;
|
|
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|
|
// Matched double path separator at beginning
|
|
|
let j = 2;
|
|
|
let last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more path separators
|
|
|
while (j < len && isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j === len) {
|
|
|
// We matched a UNC root only
|
|
|
return path;
|
|
|
}
|
|
|
if (j !== last) {
|
|
|
// We matched a UNC root with leftovers
|
|
|
// Offset by 1 to include the separator after the UNC root to
|
|
|
// treat it as a "normal root" on top of a (UNC) root
|
|
|
rootEnd = offset = j + 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// Possible device root
|
|
|
}
|
|
|
else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
|
|
|
rootEnd = len > 2 && isPathSeparator(path.charCodeAt(2)) ? 3 : 2;
|
|
|
offset = rootEnd;
|
|
|
}
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
for (let i = len - 1; i >= offset; --i) {
|
|
|
if (isPathSeparator(path.charCodeAt(i))) {
|
|
|
if (!matchedSlash) {
|
|
|
end = i;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// We saw the first non-path separator
|
|
|
matchedSlash = false;
|
|
|
}
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
if (rootEnd === -1) {
|
|
|
return '.';
|
|
|
}
|
|
|
end = rootEnd;
|
|
|
}
|
|
|
return path.slice(0, end);
|
|
|
},
|
|
|
basename(path, ext) {
|
|
|
if (ext !== undefined) {
|
|
|
validateString(ext, 'ext');
|
|
|
}
|
|
|
validateString(path, 'path');
|
|
|
let start = 0;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
let i;
|
|
|
// Check for a drive letter prefix so as not to mistake the following
|
|
|
// path separator as an extra separator at the end of the path that can be
|
|
|
// disregarded
|
|
|
if (path.length >= 2 &&
|
|
|
isWindowsDeviceRoot(path.charCodeAt(0)) &&
|
|
|
path.charCodeAt(1) === CHAR_COLON) {
|
|
|
start = 2;
|
|
|
}
|
|
|
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
|
|
if (ext === path) {
|
|
|
return '';
|
|
|
}
|
|
|
let extIdx = ext.length - 1;
|
|
|
let firstNonSlashEnd = -1;
|
|
|
for (i = path.length - 1; i >= start; --i) {
|
|
|
const code = path.charCodeAt(i);
|
|
|
if (isPathSeparator(code)) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
start = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
if (firstNonSlashEnd === -1) {
|
|
|
// We saw the first non-path separator, remember this index in case
|
|
|
// we need it if the extension ends up not matching
|
|
|
matchedSlash = false;
|
|
|
firstNonSlashEnd = i + 1;
|
|
|
}
|
|
|
if (extIdx >= 0) {
|
|
|
// Try to match the explicit extension
|
|
|
if (code === ext.charCodeAt(extIdx)) {
|
|
|
if (--extIdx === -1) {
|
|
|
// We matched the extension, so mark this as the end of our path
|
|
|
// component
|
|
|
end = i;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// Extension does not match, so our result is the entire path
|
|
|
// component
|
|
|
extIdx = -1;
|
|
|
end = firstNonSlashEnd;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (start === end) {
|
|
|
end = firstNonSlashEnd;
|
|
|
}
|
|
|
else if (end === -1) {
|
|
|
end = path.length;
|
|
|
}
|
|
|
return path.slice(start, end);
|
|
|
}
|
|
|
for (i = path.length - 1; i >= start; --i) {
|
|
|
if (isPathSeparator(path.charCodeAt(i))) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
start = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else if (end === -1) {
|
|
|
// We saw the first non-path separator, mark this as the end of our
|
|
|
// path component
|
|
|
matchedSlash = false;
|
|
|
end = i + 1;
|
|
|
}
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
return '';
|
|
|
}
|
|
|
return path.slice(start, end);
|
|
|
},
|
|
|
extname(path) {
|
|
|
validateString(path, 'path');
|
|
|
let start = 0;
|
|
|
let startDot = -1;
|
|
|
let startPart = 0;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
// Track the state of characters (if any) we see before our first dot and
|
|
|
// after any path separator we find
|
|
|
let preDotState = 0;
|
|
|
// Check for a drive letter prefix so as not to mistake the following
|
|
|
// path separator as an extra separator at the end of the path that can be
|
|
|
// disregarded
|
|
|
if (path.length >= 2 &&
|
|
|
path.charCodeAt(1) === CHAR_COLON &&
|
|
|
isWindowsDeviceRoot(path.charCodeAt(0))) {
|
|
|
start = startPart = 2;
|
|
|
}
|
|
|
for (let i = path.length - 1; i >= start; --i) {
|
|
|
const code = path.charCodeAt(i);
|
|
|
if (isPathSeparator(code)) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
startPart = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
// We saw the first non-path separator, mark this as the end of our
|
|
|
// extension
|
|
|
matchedSlash = false;
|
|
|
end = i + 1;
|
|
|
}
|
|
|
if (code === CHAR_DOT) {
|
|
|
// If this is our first dot, mark it as the start of our extension
|
|
|
if (startDot === -1) {
|
|
|
startDot = i;
|
|
|
}
|
|
|
else if (preDotState !== 1) {
|
|
|
preDotState = 1;
|
|
|
}
|
|
|
}
|
|
|
else if (startDot !== -1) {
|
|
|
// We saw a non-dot and non-path separator before our dot, so we should
|
|
|
// have a good chance at having a non-empty extension
|
|
|
preDotState = -1;
|
|
|
}
|
|
|
}
|
|
|
if (startDot === -1 ||
|
|
|
end === -1 ||
|
|
|
// We saw a non-dot character immediately before the dot
|
|
|
preDotState === 0 ||
|
|
|
// The (right-most) trimmed path component is exactly '..'
|
|
|
(preDotState === 1 &&
|
|
|
startDot === end - 1 &&
|
|
|
startDot === startPart + 1)) {
|
|
|
return '';
|
|
|
}
|
|
|
return path.slice(startDot, end);
|
|
|
},
|
|
|
format: _format.bind(null, '\\'),
|
|
|
parse(path) {
|
|
|
validateString(path, 'path');
|
|
|
const ret = { root: '', dir: '', base: '', ext: '', name: '' };
|
|
|
if (path.length === 0) {
|
|
|
return ret;
|
|
|
}
|
|
|
const len = path.length;
|
|
|
let rootEnd = 0;
|
|
|
let code = path.charCodeAt(0);
|
|
|
if (len === 1) {
|
|
|
if (isPathSeparator(code)) {
|
|
|
// `path` contains just a path separator, exit early to avoid
|
|
|
// unnecessary work
|
|
|
ret.root = ret.dir = path;
|
|
|
return ret;
|
|
|
}
|
|
|
ret.base = ret.name = path;
|
|
|
return ret;
|
|
|
}
|
|
|
// Try to match a root
|
|
|
if (isPathSeparator(code)) {
|
|
|
// Possible UNC root
|
|
|
rootEnd = 1;
|
|
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|
|
// Matched double path separator at beginning
|
|
|
let j = 2;
|
|
|
let last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more path separators
|
|
|
while (j < len && isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j < len && j !== last) {
|
|
|
// Matched!
|
|
|
last = j;
|
|
|
// Match 1 or more non-path separators
|
|
|
while (j < len && !isPathSeparator(path.charCodeAt(j))) {
|
|
|
j++;
|
|
|
}
|
|
|
if (j === len) {
|
|
|
// We matched a UNC root only
|
|
|
rootEnd = j;
|
|
|
}
|
|
|
else if (j !== last) {
|
|
|
// We matched a UNC root with leftovers
|
|
|
rootEnd = j + 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
|
|
|
// Possible device root
|
|
|
if (len <= 2) {
|
|
|
// `path` contains just a drive root, exit early to avoid
|
|
|
// unnecessary work
|
|
|
ret.root = ret.dir = path;
|
|
|
return ret;
|
|
|
}
|
|
|
rootEnd = 2;
|
|
|
if (isPathSeparator(path.charCodeAt(2))) {
|
|
|
if (len === 3) {
|
|
|
// `path` contains just a drive root, exit early to avoid
|
|
|
// unnecessary work
|
|
|
ret.root = ret.dir = path;
|
|
|
return ret;
|
|
|
}
|
|
|
rootEnd = 3;
|
|
|
}
|
|
|
}
|
|
|
if (rootEnd > 0) {
|
|
|
ret.root = path.slice(0, rootEnd);
|
|
|
}
|
|
|
let startDot = -1;
|
|
|
let startPart = rootEnd;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
let i = path.length - 1;
|
|
|
// Track the state of characters (if any) we see before our first dot and
|
|
|
// after any path separator we find
|
|
|
let preDotState = 0;
|
|
|
// Get non-dir info
|
|
|
for (; i >= rootEnd; --i) {
|
|
|
code = path.charCodeAt(i);
|
|
|
if (isPathSeparator(code)) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
startPart = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
// We saw the first non-path separator, mark this as the end of our
|
|
|
// extension
|
|
|
matchedSlash = false;
|
|
|
end = i + 1;
|
|
|
}
|
|
|
if (code === CHAR_DOT) {
|
|
|
// If this is our first dot, mark it as the start of our extension
|
|
|
if (startDot === -1) {
|
|
|
startDot = i;
|
|
|
}
|
|
|
else if (preDotState !== 1) {
|
|
|
preDotState = 1;
|
|
|
}
|
|
|
}
|
|
|
else if (startDot !== -1) {
|
|
|
// We saw a non-dot and non-path separator before our dot, so we should
|
|
|
// have a good chance at having a non-empty extension
|
|
|
preDotState = -1;
|
|
|
}
|
|
|
}
|
|
|
if (end !== -1) {
|
|
|
if (startDot === -1 ||
|
|
|
// We saw a non-dot character immediately before the dot
|
|
|
preDotState === 0 ||
|
|
|
// The (right-most) trimmed path component is exactly '..'
|
|
|
(preDotState === 1 &&
|
|
|
startDot === end - 1 &&
|
|
|
startDot === startPart + 1)) {
|
|
|
ret.base = ret.name = path.slice(startPart, end);
|
|
|
}
|
|
|
else {
|
|
|
ret.name = path.slice(startPart, startDot);
|
|
|
ret.base = path.slice(startPart, end);
|
|
|
ret.ext = path.slice(startDot, end);
|
|
|
}
|
|
|
}
|
|
|
// If the directory is the root, use the entire root as the `dir` including
|
|
|
// the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the
|
|
|
// trailing slash (`C:\abc\def` -> `C:\abc`).
|
|
|
if (startPart > 0 && startPart !== rootEnd) {
|
|
|
ret.dir = path.slice(0, startPart - 1);
|
|
|
}
|
|
|
else {
|
|
|
ret.dir = ret.root;
|
|
|
}
|
|
|
return ret;
|
|
|
},
|
|
|
sep: '\\',
|
|
|
delimiter: ';',
|
|
|
win32: null,
|
|
|
posix: null
|
|
|
};
|
|
|
const posix = {
|
|
|
// path.resolve([from ...], to)
|
|
|
resolve(...pathSegments) {
|
|
|
let resolvedPath = '';
|
|
|
let resolvedAbsolute = false;
|
|
|
for (let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
|
|
const path = i >= 0 ? pathSegments[i] : cwd();
|
|
|
validateString(path, 'path');
|
|
|
// Skip empty entries
|
|
|
if (path.length === 0) {
|
|
|
continue;
|
|
|
}
|
|
|
resolvedPath = `${path}/${resolvedPath}`;
|
|
|
resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
|
|
|
}
|
|
|
// At this point the path should be resolved to a full absolute path, but
|
|
|
// handle relative paths to be safe (might happen when process.cwd() fails)
|
|
|
// Normalize the path
|
|
|
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', isPosixPathSeparator);
|
|
|
if (resolvedAbsolute) {
|
|
|
return `/${resolvedPath}`;
|
|
|
}
|
|
|
return resolvedPath.length > 0 ? resolvedPath : '.';
|
|
|
},
|
|
|
normalize(path) {
|
|
|
validateString(path, 'path');
|
|
|
if (path.length === 0) {
|
|
|
return '.';
|
|
|
}
|
|
|
const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
|
|
|
const trailingSeparator = path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH;
|
|
|
// Normalize the path
|
|
|
path = normalizeString(path, !isAbsolute, '/', isPosixPathSeparator);
|
|
|
if (path.length === 0) {
|
|
|
if (isAbsolute) {
|
|
|
return '/';
|
|
|
}
|
|
|
return trailingSeparator ? './' : '.';
|
|
|
}
|
|
|
if (trailingSeparator) {
|
|
|
path += '/';
|
|
|
}
|
|
|
return isAbsolute ? `/${path}` : path;
|
|
|
},
|
|
|
isAbsolute(path) {
|
|
|
validateString(path, 'path');
|
|
|
return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH;
|
|
|
},
|
|
|
join(...paths) {
|
|
|
if (paths.length === 0) {
|
|
|
return '.';
|
|
|
}
|
|
|
let joined;
|
|
|
for (let i = 0; i < paths.length; ++i) {
|
|
|
const arg = paths[i];
|
|
|
validateString(arg, 'path');
|
|
|
if (arg.length > 0) {
|
|
|
if (joined === undefined) {
|
|
|
joined = arg;
|
|
|
}
|
|
|
else {
|
|
|
joined += `/${arg}`;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (joined === undefined) {
|
|
|
return '.';
|
|
|
}
|
|
|
return posix.normalize(joined);
|
|
|
},
|
|
|
relative(from, to) {
|
|
|
validateString(from, 'from');
|
|
|
validateString(to, 'to');
|
|
|
if (from === to) {
|
|
|
return '';
|
|
|
}
|
|
|
// Trim leading forward slashes.
|
|
|
from = posix.resolve(from);
|
|
|
to = posix.resolve(to);
|
|
|
if (from === to) {
|
|
|
return '';
|
|
|
}
|
|
|
const fromStart = 1;
|
|
|
const fromEnd = from.length;
|
|
|
const fromLen = fromEnd - fromStart;
|
|
|
const toStart = 1;
|
|
|
const toLen = to.length - toStart;
|
|
|
// Compare paths to find the longest common path from root
|
|
|
const length = (fromLen < toLen ? fromLen : toLen);
|
|
|
let lastCommonSep = -1;
|
|
|
let i = 0;
|
|
|
for (; i < length; i++) {
|
|
|
const fromCode = from.charCodeAt(fromStart + i);
|
|
|
if (fromCode !== to.charCodeAt(toStart + i)) {
|
|
|
break;
|
|
|
}
|
|
|
else if (fromCode === CHAR_FORWARD_SLASH) {
|
|
|
lastCommonSep = i;
|
|
|
}
|
|
|
}
|
|
|
if (i === length) {
|
|
|
if (toLen > length) {
|
|
|
if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) {
|
|
|
// We get here if `from` is the exact base path for `to`.
|
|
|
// For example: from='/foo/bar'; to='/foo/bar/baz'
|
|
|
return to.slice(toStart + i + 1);
|
|
|
}
|
|
|
if (i === 0) {
|
|
|
// We get here if `from` is the root
|
|
|
// For example: from='/'; to='/foo'
|
|
|
return to.slice(toStart + i);
|
|
|
}
|
|
|
}
|
|
|
else if (fromLen > length) {
|
|
|
if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) {
|
|
|
// We get here if `to` is the exact base path for `from`.
|
|
|
// For example: from='/foo/bar/baz'; to='/foo/bar'
|
|
|
lastCommonSep = i;
|
|
|
}
|
|
|
else if (i === 0) {
|
|
|
// We get here if `to` is the root.
|
|
|
// For example: from='/foo/bar'; to='/'
|
|
|
lastCommonSep = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
let out = '';
|
|
|
// Generate the relative path based on the path difference between `to`
|
|
|
// and `from`.
|
|
|
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
|
|
|
if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) {
|
|
|
out += out.length === 0 ? '..' : '/..';
|
|
|
}
|
|
|
}
|
|
|
// Lastly, append the rest of the destination (`to`) path that comes after
|
|
|
// the common path parts.
|
|
|
return `${out}${to.slice(toStart + lastCommonSep)}`;
|
|
|
},
|
|
|
toNamespacedPath(path) {
|
|
|
// Non-op on posix systems
|
|
|
return path;
|
|
|
},
|
|
|
dirname(path) {
|
|
|
validateString(path, 'path');
|
|
|
if (path.length === 0) {
|
|
|
return '.';
|
|
|
}
|
|
|
const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
for (let i = path.length - 1; i >= 1; --i) {
|
|
|
if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) {
|
|
|
if (!matchedSlash) {
|
|
|
end = i;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// We saw the first non-path separator
|
|
|
matchedSlash = false;
|
|
|
}
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
return hasRoot ? '/' : '.';
|
|
|
}
|
|
|
if (hasRoot && end === 1) {
|
|
|
return '//';
|
|
|
}
|
|
|
return path.slice(0, end);
|
|
|
},
|
|
|
basename(path, ext) {
|
|
|
if (ext !== undefined) {
|
|
|
validateString(ext, 'ext');
|
|
|
}
|
|
|
validateString(path, 'path');
|
|
|
let start = 0;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
let i;
|
|
|
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
|
|
if (ext === path) {
|
|
|
return '';
|
|
|
}
|
|
|
let extIdx = ext.length - 1;
|
|
|
let firstNonSlashEnd = -1;
|
|
|
for (i = path.length - 1; i >= 0; --i) {
|
|
|
const code = path.charCodeAt(i);
|
|
|
if (code === CHAR_FORWARD_SLASH) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
start = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
if (firstNonSlashEnd === -1) {
|
|
|
// We saw the first non-path separator, remember this index in case
|
|
|
// we need it if the extension ends up not matching
|
|
|
matchedSlash = false;
|
|
|
firstNonSlashEnd = i + 1;
|
|
|
}
|
|
|
if (extIdx >= 0) {
|
|
|
// Try to match the explicit extension
|
|
|
if (code === ext.charCodeAt(extIdx)) {
|
|
|
if (--extIdx === -1) {
|
|
|
// We matched the extension, so mark this as the end of our path
|
|
|
// component
|
|
|
end = i;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// Extension does not match, so our result is the entire path
|
|
|
// component
|
|
|
extIdx = -1;
|
|
|
end = firstNonSlashEnd;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (start === end) {
|
|
|
end = firstNonSlashEnd;
|
|
|
}
|
|
|
else if (end === -1) {
|
|
|
end = path.length;
|
|
|
}
|
|
|
return path.slice(start, end);
|
|
|
}
|
|
|
for (i = path.length - 1; i >= 0; --i) {
|
|
|
if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
start = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else if (end === -1) {
|
|
|
// We saw the first non-path separator, mark this as the end of our
|
|
|
// path component
|
|
|
matchedSlash = false;
|
|
|
end = i + 1;
|
|
|
}
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
return '';
|
|
|
}
|
|
|
return path.slice(start, end);
|
|
|
},
|
|
|
extname(path) {
|
|
|
validateString(path, 'path');
|
|
|
let startDot = -1;
|
|
|
let startPart = 0;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
// Track the state of characters (if any) we see before our first dot and
|
|
|
// after any path separator we find
|
|
|
let preDotState = 0;
|
|
|
for (let i = path.length - 1; i >= 0; --i) {
|
|
|
const code = path.charCodeAt(i);
|
|
|
if (code === CHAR_FORWARD_SLASH) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
startPart = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
// We saw the first non-path separator, mark this as the end of our
|
|
|
// extension
|
|
|
matchedSlash = false;
|
|
|
end = i + 1;
|
|
|
}
|
|
|
if (code === CHAR_DOT) {
|
|
|
// If this is our first dot, mark it as the start of our extension
|
|
|
if (startDot === -1) {
|
|
|
startDot = i;
|
|
|
}
|
|
|
else if (preDotState !== 1) {
|
|
|
preDotState = 1;
|
|
|
}
|
|
|
}
|
|
|
else if (startDot !== -1) {
|
|
|
// We saw a non-dot and non-path separator before our dot, so we should
|
|
|
// have a good chance at having a non-empty extension
|
|
|
preDotState = -1;
|
|
|
}
|
|
|
}
|
|
|
if (startDot === -1 ||
|
|
|
end === -1 ||
|
|
|
// We saw a non-dot character immediately before the dot
|
|
|
preDotState === 0 ||
|
|
|
// The (right-most) trimmed path component is exactly '..'
|
|
|
(preDotState === 1 &&
|
|
|
startDot === end - 1 &&
|
|
|
startDot === startPart + 1)) {
|
|
|
return '';
|
|
|
}
|
|
|
return path.slice(startDot, end);
|
|
|
},
|
|
|
format: _format.bind(null, '/'),
|
|
|
parse(path) {
|
|
|
validateString(path, 'path');
|
|
|
const ret = { root: '', dir: '', base: '', ext: '', name: '' };
|
|
|
if (path.length === 0) {
|
|
|
return ret;
|
|
|
}
|
|
|
const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
|
|
|
let start;
|
|
|
if (isAbsolute) {
|
|
|
ret.root = '/';
|
|
|
start = 1;
|
|
|
}
|
|
|
else {
|
|
|
start = 0;
|
|
|
}
|
|
|
let startDot = -1;
|
|
|
let startPart = 0;
|
|
|
let end = -1;
|
|
|
let matchedSlash = true;
|
|
|
let i = path.length - 1;
|
|
|
// Track the state of characters (if any) we see before our first dot and
|
|
|
// after any path separator we find
|
|
|
let preDotState = 0;
|
|
|
// Get non-dir info
|
|
|
for (; i >= start; --i) {
|
|
|
const code = path.charCodeAt(i);
|
|
|
if (code === CHAR_FORWARD_SLASH) {
|
|
|
// If we reached a path separator that was not part of a set of path
|
|
|
// separators at the end of the string, stop now
|
|
|
if (!matchedSlash) {
|
|
|
startPart = i + 1;
|
|
|
break;
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
if (end === -1) {
|
|
|
// We saw the first non-path separator, mark this as the end of our
|
|
|
// extension
|
|
|
matchedSlash = false;
|
|
|
end = i + 1;
|
|
|
}
|
|
|
if (code === CHAR_DOT) {
|
|
|
// If this is our first dot, mark it as the start of our extension
|
|
|
if (startDot === -1) {
|
|
|
startDot = i;
|
|
|
}
|
|
|
else if (preDotState !== 1) {
|
|
|
preDotState = 1;
|
|
|
}
|
|
|
}
|
|
|
else if (startDot !== -1) {
|
|
|
// We saw a non-dot and non-path separator before our dot, so we should
|
|
|
// have a good chance at having a non-empty extension
|
|
|
preDotState = -1;
|
|
|
}
|
|
|
}
|
|
|
if (end !== -1) {
|
|
|
const start = startPart === 0 && isAbsolute ? 1 : startPart;
|
|
|
if (startDot === -1 ||
|
|
|
// We saw a non-dot character immediately before the dot
|
|
|
preDotState === 0 ||
|
|
|
// The (right-most) trimmed path component is exactly '..'
|
|
|
(preDotState === 1 &&
|
|
|
startDot === end - 1 &&
|
|
|
startDot === startPart + 1)) {
|
|
|
ret.base = ret.name = path.slice(start, end);
|
|
|
}
|
|
|
else {
|
|
|
ret.name = path.slice(start, startDot);
|
|
|
ret.base = path.slice(start, end);
|
|
|
ret.ext = path.slice(startDot, end);
|
|
|
}
|
|
|
}
|
|
|
if (startPart > 0) {
|
|
|
ret.dir = path.slice(0, startPart - 1);
|
|
|
}
|
|
|
else if (isAbsolute) {
|
|
|
ret.dir = '/';
|
|
|
}
|
|
|
return ret;
|
|
|
},
|
|
|
sep: '/',
|
|
|
delimiter: ':',
|
|
|
win32: null,
|
|
|
posix: null
|
|
|
};
|
|
|
posix.win32 = win32.win32 = win32;
|
|
|
posix.posix = win32.posix = posix;
|
|
|
const normalize = (platform === 'win32' ? win32.normalize : posix.normalize);
|
|
|
const resolve = (platform === 'win32' ? win32.resolve : posix.resolve);
|
|
|
const relative = (platform === 'win32' ? win32.relative : posix.relative);
|
|
|
const dirname = (platform === 'win32' ? win32.dirname : posix.dirname);
|
|
|
const basename = (platform === 'win32' ? win32.basename : posix.basename);
|
|
|
const extname = (platform === 'win32' ? win32.extname : posix.extname);
|
|
|
const sep = (platform === 'win32' ? win32.sep : posix.sep);
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/uri.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
const _schemePattern = /^\w[\w\d+.-]*$/;
|
|
|
const _singleSlashStart = /^\//;
|
|
|
const _doubleSlashStart = /^\/\//;
|
|
|
function _validateUri(ret, _strict) {
|
|
|
// scheme, must be set
|
|
|
if (!ret.scheme && _strict) {
|
|
|
throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`);
|
|
|
}
|
|
|
// scheme, https://tools.ietf.org/html/rfc3986#section-3.1
|
|
|
// ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
|
|
if (ret.scheme && !_schemePattern.test(ret.scheme)) {
|
|
|
throw new Error('[UriError]: Scheme contains illegal characters.');
|
|
|
}
|
|
|
// path, http://tools.ietf.org/html/rfc3986#section-3.3
|
|
|
// If a URI contains an authority component, then the path component
|
|
|
// must either be empty or begin with a slash ("/") character. If a URI
|
|
|
// does not contain an authority component, then the path cannot begin
|
|
|
// with two slash characters ("//").
|
|
|
if (ret.path) {
|
|
|
if (ret.authority) {
|
|
|
if (!_singleSlashStart.test(ret.path)) {
|
|
|
throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character');
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
if (_doubleSlashStart.test(ret.path)) {
|
|
|
throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")');
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// for a while we allowed uris *without* schemes and this is the migration
|
|
|
// for them, e.g. an uri without scheme and without strict-mode warns and falls
|
|
|
// back to the file-scheme. that should cause the least carnage and still be a
|
|
|
// clear warning
|
|
|
function _schemeFix(scheme, _strict) {
|
|
|
if (!scheme && !_strict) {
|
|
|
return 'file';
|
|
|
}
|
|
|
return scheme;
|
|
|
}
|
|
|
// implements a bit of https://tools.ietf.org/html/rfc3986#section-5
|
|
|
function _referenceResolution(scheme, path) {
|
|
|
// the slash-character is our 'default base' as we don't
|
|
|
// support constructing URIs relative to other URIs. This
|
|
|
// also means that we alter and potentially break paths.
|
|
|
// see https://tools.ietf.org/html/rfc3986#section-5.1.4
|
|
|
switch (scheme) {
|
|
|
case 'https':
|
|
|
case 'http':
|
|
|
case 'file':
|
|
|
if (!path) {
|
|
|
path = _slash;
|
|
|
}
|
|
|
else if (path[0] !== _slash) {
|
|
|
path = _slash + path;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
return path;
|
|
|
}
|
|
|
const _empty = '';
|
|
|
const _slash = '/';
|
|
|
const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
|
|
|
/**
|
|
|
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
|
|
|
* This class is a simple parser which creates the basic component parts
|
|
|
* (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
|
|
|
* and encoding.
|
|
|
*
|
|
|
* ```txt
|
|
|
* foo://example.com:8042/over/there?name=ferret#nose
|
|
|
* \_/ \______________/\_________/ \_________/ \__/
|
|
|
* | | | | |
|
|
|
* scheme authority path query fragment
|
|
|
* | _____________________|__
|
|
|
* / \ / \
|
|
|
* urn:example:animal:ferret:nose
|
|
|
* ```
|
|
|
*/
|
|
|
class URI {
|
|
|
/**
|
|
|
* @internal
|
|
|
*/
|
|
|
constructor(schemeOrData, authority, path, query, fragment, _strict = false) {
|
|
|
if (typeof schemeOrData === 'object') {
|
|
|
this.scheme = schemeOrData.scheme || _empty;
|
|
|
this.authority = schemeOrData.authority || _empty;
|
|
|
this.path = schemeOrData.path || _empty;
|
|
|
this.query = schemeOrData.query || _empty;
|
|
|
this.fragment = schemeOrData.fragment || _empty;
|
|
|
// no validation because it's this URI
|
|
|
// that creates uri components.
|
|
|
// _validateUri(this);
|
|
|
}
|
|
|
else {
|
|
|
this.scheme = _schemeFix(schemeOrData, _strict);
|
|
|
this.authority = authority || _empty;
|
|
|
this.path = _referenceResolution(this.scheme, path || _empty);
|
|
|
this.query = query || _empty;
|
|
|
this.fragment = fragment || _empty;
|
|
|
_validateUri(this, _strict);
|
|
|
}
|
|
|
}
|
|
|
static isUri(thing) {
|
|
|
if (thing instanceof URI) {
|
|
|
return true;
|
|
|
}
|
|
|
if (!thing) {
|
|
|
return false;
|
|
|
}
|
|
|
return typeof thing.authority === 'string'
|
|
|
&& typeof thing.fragment === 'string'
|
|
|
&& typeof thing.path === 'string'
|
|
|
&& typeof thing.query === 'string'
|
|
|
&& typeof thing.scheme === 'string'
|
|
|
&& typeof thing.fsPath === 'string'
|
|
|
&& typeof thing.with === 'function'
|
|
|
&& typeof thing.toString === 'function';
|
|
|
}
|
|
|
// ---- filesystem path -----------------------
|
|
|
/**
|
|
|
* Returns a string representing the corresponding file system path of this URI.
|
|
|
* Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the
|
|
|
* platform specific path separator.
|
|
|
*
|
|
|
* * Will *not* validate the path for invalid characters and semantics.
|
|
|
* * Will *not* look at the scheme of this URI.
|
|
|
* * The result shall *not* be used for display purposes but for accessing a file on disk.
|
|
|
*
|
|
|
*
|
|
|
* The *difference* to `URI#path` is the use of the platform specific separator and the handling
|
|
|
* of UNC paths. See the below sample of a file-uri with an authority (UNC path).
|
|
|
*
|
|
|
* ```ts
|
|
|
const u = URI.parse('file://server/c$/folder/file.txt')
|
|
|
u.authority === 'server'
|
|
|
u.path === '/shares/c$/file.txt'
|
|
|
u.fsPath === '\\server\c$\folder\file.txt'
|
|
|
```
|
|
|
*
|
|
|
* Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,
|
|
|
* namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working
|
|
|
* with URIs that represent files on disk (`file` scheme).
|
|
|
*/
|
|
|
get fsPath() {
|
|
|
// if (this.scheme !== 'file') {
|
|
|
// console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);
|
|
|
// }
|
|
|
return uriToFsPath(this, false);
|
|
|
}
|
|
|
// ---- modify to new -------------------------
|
|
|
with(change) {
|
|
|
if (!change) {
|
|
|
return this;
|
|
|
}
|
|
|
let { scheme, authority, path, query, fragment } = change;
|
|
|
if (scheme === undefined) {
|
|
|
scheme = this.scheme;
|
|
|
}
|
|
|
else if (scheme === null) {
|
|
|
scheme = _empty;
|
|
|
}
|
|
|
if (authority === undefined) {
|
|
|
authority = this.authority;
|
|
|
}
|
|
|
else if (authority === null) {
|
|
|
authority = _empty;
|
|
|
}
|
|
|
if (path === undefined) {
|
|
|
path = this.path;
|
|
|
}
|
|
|
else if (path === null) {
|
|
|
path = _empty;
|
|
|
}
|
|
|
if (query === undefined) {
|
|
|
query = this.query;
|
|
|
}
|
|
|
else if (query === null) {
|
|
|
query = _empty;
|
|
|
}
|
|
|
if (fragment === undefined) {
|
|
|
fragment = this.fragment;
|
|
|
}
|
|
|
else if (fragment === null) {
|
|
|
fragment = _empty;
|
|
|
}
|
|
|
if (scheme === this.scheme
|
|
|
&& authority === this.authority
|
|
|
&& path === this.path
|
|
|
&& query === this.query
|
|
|
&& fragment === this.fragment) {
|
|
|
return this;
|
|
|
}
|
|
|
return new Uri(scheme, authority, path, query, fragment);
|
|
|
}
|
|
|
// ---- parse & validate ------------------------
|
|
|
/**
|
|
|
* Creates a new URI from a string, e.g. `http://www.msft.com/some/path`,
|
|
|
* `file:///usr/home`, or `scheme:with/path`.
|
|
|
*
|
|
|
* @param value A string which represents an URI (see `URI#toString`).
|
|
|
*/
|
|
|
static parse(value, _strict = false) {
|
|
|
const match = _regexp.exec(value);
|
|
|
if (!match) {
|
|
|
return new Uri(_empty, _empty, _empty, _empty, _empty);
|
|
|
}
|
|
|
return new Uri(match[2] || _empty, percentDecode(match[4] || _empty), percentDecode(match[5] || _empty), percentDecode(match[7] || _empty), percentDecode(match[9] || _empty), _strict);
|
|
|
}
|
|
|
/**
|
|
|
* Creates a new URI from a file system path, e.g. `c:\my\files`,
|
|
|
* `/usr/home`, or `\\server\share\some\path`.
|
|
|
*
|
|
|
* The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument
|
|
|
* as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**
|
|
|
* `URI.parse('file://' + path)` because the path might contain characters that are
|
|
|
* interpreted (# and ?). See the following sample:
|
|
|
* ```ts
|
|
|
const good = URI.file('/coding/c#/project1');
|
|
|
good.scheme === 'file';
|
|
|
good.path === '/coding/c#/project1';
|
|
|
good.fragment === '';
|
|
|
const bad = URI.parse('file://' + '/coding/c#/project1');
|
|
|
bad.scheme === 'file';
|
|
|
bad.path === '/coding/c'; // path is now broken
|
|
|
bad.fragment === '/project1';
|
|
|
```
|
|
|
*
|
|
|
* @param path A file system path (see `URI#fsPath`)
|
|
|
*/
|
|
|
static file(path) {
|
|
|
let authority = _empty;
|
|
|
// normalize to fwd-slashes on windows,
|
|
|
// on other systems bwd-slashes are valid
|
|
|
// filename character, eg /f\oo/ba\r.txt
|
|
|
if (isWindows) {
|
|
|
path = path.replace(/\\/g, _slash);
|
|
|
}
|
|
|
// check for authority as used in UNC shares
|
|
|
// or use the path as given
|
|
|
if (path[0] === _slash && path[1] === _slash) {
|
|
|
const idx = path.indexOf(_slash, 2);
|
|
|
if (idx === -1) {
|
|
|
authority = path.substring(2);
|
|
|
path = _slash;
|
|
|
}
|
|
|
else {
|
|
|
authority = path.substring(2, idx);
|
|
|
path = path.substring(idx) || _slash;
|
|
|
}
|
|
|
}
|
|
|
return new Uri('file', authority, path, _empty, _empty);
|
|
|
}
|
|
|
static from(components) {
|
|
|
const result = new Uri(components.scheme, components.authority, components.path, components.query, components.fragment);
|
|
|
_validateUri(result, true);
|
|
|
return result;
|
|
|
}
|
|
|
/**
|
|
|
* Join a URI path with path fragments and normalizes the resulting path.
|
|
|
*
|
|
|
* @param uri The input URI.
|
|
|
* @param pathFragment The path fragment to add to the URI path.
|
|
|
* @returns The resulting URI.
|
|
|
*/
|
|
|
static joinPath(uri, ...pathFragment) {
|
|
|
if (!uri.path) {
|
|
|
throw new Error(`[UriError]: cannot call joinPath on URI without path`);
|
|
|
}
|
|
|
let newPath;
|
|
|
if (isWindows && uri.scheme === 'file') {
|
|
|
newPath = URI.file(win32.join(uriToFsPath(uri, true), ...pathFragment)).path;
|
|
|
}
|
|
|
else {
|
|
|
newPath = posix.join(uri.path, ...pathFragment);
|
|
|
}
|
|
|
return uri.with({ path: newPath });
|
|
|
}
|
|
|
// ---- printing/externalize ---------------------------
|
|
|
/**
|
|
|
* Creates a string representation for this URI. It's guaranteed that calling
|
|
|
* `URI.parse` with the result of this function creates an URI which is equal
|
|
|
* to this URI.
|
|
|
*
|
|
|
* * The result shall *not* be used for display purposes but for externalization or transport.
|
|
|
* * The result will be encoded using the percentage encoding and encoding happens mostly
|
|
|
* ignore the scheme-specific encoding rules.
|
|
|
*
|
|
|
* @param skipEncoding Do not encode the result, default is `false`
|
|
|
*/
|
|
|
toString(skipEncoding = false) {
|
|
|
return _asFormatted(this, skipEncoding);
|
|
|
}
|
|
|
toJSON() {
|
|
|
return this;
|
|
|
}
|
|
|
static revive(data) {
|
|
|
if (!data) {
|
|
|
return data;
|
|
|
}
|
|
|
else if (data instanceof URI) {
|
|
|
return data;
|
|
|
}
|
|
|
else {
|
|
|
const result = new Uri(data);
|
|
|
result._formatted = data.external;
|
|
|
result._fsPath = data._sep === _pathSepMarker ? data.fsPath : null;
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
const _pathSepMarker = isWindows ? 1 : undefined;
|
|
|
// This class exists so that URI is compatible with vscode.Uri (API).
|
|
|
class Uri extends URI {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this._formatted = null;
|
|
|
this._fsPath = null;
|
|
|
}
|
|
|
get fsPath() {
|
|
|
if (!this._fsPath) {
|
|
|
this._fsPath = uriToFsPath(this, false);
|
|
|
}
|
|
|
return this._fsPath;
|
|
|
}
|
|
|
toString(skipEncoding = false) {
|
|
|
if (!skipEncoding) {
|
|
|
if (!this._formatted) {
|
|
|
this._formatted = _asFormatted(this, false);
|
|
|
}
|
|
|
return this._formatted;
|
|
|
}
|
|
|
else {
|
|
|
// we don't cache that
|
|
|
return _asFormatted(this, true);
|
|
|
}
|
|
|
}
|
|
|
toJSON() {
|
|
|
const res = {
|
|
|
$mid: 1 /* Uri */
|
|
|
};
|
|
|
// cached state
|
|
|
if (this._fsPath) {
|
|
|
res.fsPath = this._fsPath;
|
|
|
res._sep = _pathSepMarker;
|
|
|
}
|
|
|
if (this._formatted) {
|
|
|
res.external = this._formatted;
|
|
|
}
|
|
|
// uri components
|
|
|
if (this.path) {
|
|
|
res.path = this.path;
|
|
|
}
|
|
|
if (this.scheme) {
|
|
|
res.scheme = this.scheme;
|
|
|
}
|
|
|
if (this.authority) {
|
|
|
res.authority = this.authority;
|
|
|
}
|
|
|
if (this.query) {
|
|
|
res.query = this.query;
|
|
|
}
|
|
|
if (this.fragment) {
|
|
|
res.fragment = this.fragment;
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
}
|
|
|
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
|
|
|
const encodeTable = {
|
|
|
[58 /* Colon */]: '%3A',
|
|
|
[47 /* Slash */]: '%2F',
|
|
|
[63 /* QuestionMark */]: '%3F',
|
|
|
[35 /* Hash */]: '%23',
|
|
|
[91 /* OpenSquareBracket */]: '%5B',
|
|
|
[93 /* CloseSquareBracket */]: '%5D',
|
|
|
[64 /* AtSign */]: '%40',
|
|
|
[33 /* ExclamationMark */]: '%21',
|
|
|
[36 /* DollarSign */]: '%24',
|
|
|
[38 /* Ampersand */]: '%26',
|
|
|
[39 /* SingleQuote */]: '%27',
|
|
|
[40 /* OpenParen */]: '%28',
|
|
|
[41 /* CloseParen */]: '%29',
|
|
|
[42 /* Asterisk */]: '%2A',
|
|
|
[43 /* Plus */]: '%2B',
|
|
|
[44 /* Comma */]: '%2C',
|
|
|
[59 /* Semicolon */]: '%3B',
|
|
|
[61 /* Equals */]: '%3D',
|
|
|
[32 /* Space */]: '%20',
|
|
|
};
|
|
|
function encodeURIComponentFast(uriComponent, allowSlash) {
|
|
|
let res = undefined;
|
|
|
let nativeEncodePos = -1;
|
|
|
for (let pos = 0; pos < uriComponent.length; pos++) {
|
|
|
const code = uriComponent.charCodeAt(pos);
|
|
|
// unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3
|
|
|
if ((code >= 97 /* a */ && code <= 122 /* z */)
|
|
|
|| (code >= 65 /* A */ && code <= 90 /* Z */)
|
|
|
|| (code >= 48 /* Digit0 */ && code <= 57 /* Digit9 */)
|
|
|
|| code === 45 /* Dash */
|
|
|
|| code === 46 /* Period */
|
|
|
|| code === 95 /* Underline */
|
|
|
|| code === 126 /* Tilde */
|
|
|
|| (allowSlash && code === 47 /* Slash */)) {
|
|
|
// check if we are delaying native encode
|
|
|
if (nativeEncodePos !== -1) {
|
|
|
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
|
|
|
nativeEncodePos = -1;
|
|
|
}
|
|
|
// check if we write into a new string (by default we try to return the param)
|
|
|
if (res !== undefined) {
|
|
|
res += uriComponent.charAt(pos);
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// encoding needed, we need to allocate a new string
|
|
|
if (res === undefined) {
|
|
|
res = uriComponent.substr(0, pos);
|
|
|
}
|
|
|
// check with default table first
|
|
|
const escaped = encodeTable[code];
|
|
|
if (escaped !== undefined) {
|
|
|
// check if we are delaying native encode
|
|
|
if (nativeEncodePos !== -1) {
|
|
|
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
|
|
|
nativeEncodePos = -1;
|
|
|
}
|
|
|
// append escaped variant to result
|
|
|
res += escaped;
|
|
|
}
|
|
|
else if (nativeEncodePos === -1) {
|
|
|
// use native encode only when needed
|
|
|
nativeEncodePos = pos;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (nativeEncodePos !== -1) {
|
|
|
res += encodeURIComponent(uriComponent.substring(nativeEncodePos));
|
|
|
}
|
|
|
return res !== undefined ? res : uriComponent;
|
|
|
}
|
|
|
function encodeURIComponentMinimal(path) {
|
|
|
let res = undefined;
|
|
|
for (let pos = 0; pos < path.length; pos++) {
|
|
|
const code = path.charCodeAt(pos);
|
|
|
if (code === 35 /* Hash */ || code === 63 /* QuestionMark */) {
|
|
|
if (res === undefined) {
|
|
|
res = path.substr(0, pos);
|
|
|
}
|
|
|
res += encodeTable[code];
|
|
|
}
|
|
|
else {
|
|
|
if (res !== undefined) {
|
|
|
res += path[pos];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return res !== undefined ? res : path;
|
|
|
}
|
|
|
/**
|
|
|
* Compute `fsPath` for the given uri
|
|
|
*/
|
|
|
function uriToFsPath(uri, keepDriveLetterCasing) {
|
|
|
let value;
|
|
|
if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
|
|
|
// unc path: file://shares/c$/far/boo
|
|
|
value = `//${uri.authority}${uri.path}`;
|
|
|
}
|
|
|
else if (uri.path.charCodeAt(0) === 47 /* Slash */
|
|
|
&& (uri.path.charCodeAt(1) >= 65 /* A */ && uri.path.charCodeAt(1) <= 90 /* Z */ || uri.path.charCodeAt(1) >= 97 /* a */ && uri.path.charCodeAt(1) <= 122 /* z */)
|
|
|
&& uri.path.charCodeAt(2) === 58 /* Colon */) {
|
|
|
if (!keepDriveLetterCasing) {
|
|
|
// windows drive letter: file:///c:/far/boo
|
|
|
value = uri.path[1].toLowerCase() + uri.path.substr(2);
|
|
|
}
|
|
|
else {
|
|
|
value = uri.path.substr(1);
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// other path
|
|
|
value = uri.path;
|
|
|
}
|
|
|
if (isWindows) {
|
|
|
value = value.replace(/\//g, '\\');
|
|
|
}
|
|
|
return value;
|
|
|
}
|
|
|
/**
|
|
|
* Create the external version of a uri
|
|
|
*/
|
|
|
function _asFormatted(uri, skipEncoding) {
|
|
|
const encoder = !skipEncoding
|
|
|
? encodeURIComponentFast
|
|
|
: encodeURIComponentMinimal;
|
|
|
let res = '';
|
|
|
let { scheme, authority, path, query, fragment } = uri;
|
|
|
if (scheme) {
|
|
|
res += scheme;
|
|
|
res += ':';
|
|
|
}
|
|
|
if (authority || scheme === 'file') {
|
|
|
res += _slash;
|
|
|
res += _slash;
|
|
|
}
|
|
|
if (authority) {
|
|
|
let idx = authority.indexOf('@');
|
|
|
if (idx !== -1) {
|
|
|
// <user>@<auth>
|
|
|
const userinfo = authority.substr(0, idx);
|
|
|
authority = authority.substr(idx + 1);
|
|
|
idx = userinfo.indexOf(':');
|
|
|
if (idx === -1) {
|
|
|
res += encoder(userinfo, false);
|
|
|
}
|
|
|
else {
|
|
|
// <user>:<pass>@<auth>
|
|
|
res += encoder(userinfo.substr(0, idx), false);
|
|
|
res += ':';
|
|
|
res += encoder(userinfo.substr(idx + 1), false);
|
|
|
}
|
|
|
res += '@';
|
|
|
}
|
|
|
authority = authority.toLowerCase();
|
|
|
idx = authority.indexOf(':');
|
|
|
if (idx === -1) {
|
|
|
res += encoder(authority, false);
|
|
|
}
|
|
|
else {
|
|
|
// <auth>:<port>
|
|
|
res += encoder(authority.substr(0, idx), false);
|
|
|
res += authority.substr(idx);
|
|
|
}
|
|
|
}
|
|
|
if (path) {
|
|
|
// lower-case windows drive letters in /C:/fff or C:/fff
|
|
|
if (path.length >= 3 && path.charCodeAt(0) === 47 /* Slash */ && path.charCodeAt(2) === 58 /* Colon */) {
|
|
|
const code = path.charCodeAt(1);
|
|
|
if (code >= 65 /* A */ && code <= 90 /* Z */) {
|
|
|
path = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // "/c:".length === 3
|
|
|
}
|
|
|
}
|
|
|
else if (path.length >= 2 && path.charCodeAt(1) === 58 /* Colon */) {
|
|
|
const code = path.charCodeAt(0);
|
|
|
if (code >= 65 /* A */ && code <= 90 /* Z */) {
|
|
|
path = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // "/c:".length === 3
|
|
|
}
|
|
|
}
|
|
|
// encode the rest of the path
|
|
|
res += encoder(path, true);
|
|
|
}
|
|
|
if (query) {
|
|
|
res += '?';
|
|
|
res += encoder(query, false);
|
|
|
}
|
|
|
if (fragment) {
|
|
|
res += '#';
|
|
|
res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment;
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
// --- decode
|
|
|
function decodeURIComponentGraceful(str) {
|
|
|
try {
|
|
|
return decodeURIComponent(str);
|
|
|
}
|
|
|
catch (_a) {
|
|
|
if (str.length > 3) {
|
|
|
return str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));
|
|
|
}
|
|
|
else {
|
|
|
return str;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
const _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;
|
|
|
function percentDecode(str) {
|
|
|
if (!str.match(_rEncodedAsHex)) {
|
|
|
return str;
|
|
|
}
|
|
|
return str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match));
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/core/position.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
/**
|
|
|
* A position in the editor.
|
|
|
*/
|
|
|
class Position {
|
|
|
constructor(lineNumber, column) {
|
|
|
this.lineNumber = lineNumber;
|
|
|
this.column = column;
|
|
|
}
|
|
|
/**
|
|
|
* Create a new position from this position.
|
|
|
*
|
|
|
* @param newLineNumber new line number
|
|
|
* @param newColumn new column
|
|
|
*/
|
|
|
with(newLineNumber = this.lineNumber, newColumn = this.column) {
|
|
|
if (newLineNumber === this.lineNumber && newColumn === this.column) {
|
|
|
return this;
|
|
|
}
|
|
|
else {
|
|
|
return new Position(newLineNumber, newColumn);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Derive a new position from this position.
|
|
|
*
|
|
|
* @param deltaLineNumber line number delta
|
|
|
* @param deltaColumn column delta
|
|
|
*/
|
|
|
delta(deltaLineNumber = 0, deltaColumn = 0) {
|
|
|
return this.with(this.lineNumber + deltaLineNumber, this.column + deltaColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Test if this position equals other position
|
|
|
*/
|
|
|
equals(other) {
|
|
|
return Position.equals(this, other);
|
|
|
}
|
|
|
/**
|
|
|
* Test if position `a` equals position `b`
|
|
|
*/
|
|
|
static equals(a, b) {
|
|
|
if (!a && !b) {
|
|
|
return true;
|
|
|
}
|
|
|
return (!!a &&
|
|
|
!!b &&
|
|
|
a.lineNumber === b.lineNumber &&
|
|
|
a.column === b.column);
|
|
|
}
|
|
|
/**
|
|
|
* Test if this position is before other position.
|
|
|
* If the two positions are equal, the result will be false.
|
|
|
*/
|
|
|
isBefore(other) {
|
|
|
return Position.isBefore(this, other);
|
|
|
}
|
|
|
/**
|
|
|
* Test if position `a` is before position `b`.
|
|
|
* If the two positions are equal, the result will be false.
|
|
|
*/
|
|
|
static isBefore(a, b) {
|
|
|
if (a.lineNumber < b.lineNumber) {
|
|
|
return true;
|
|
|
}
|
|
|
if (b.lineNumber < a.lineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
return a.column < b.column;
|
|
|
}
|
|
|
/**
|
|
|
* Test if this position is before other position.
|
|
|
* If the two positions are equal, the result will be true.
|
|
|
*/
|
|
|
isBeforeOrEqual(other) {
|
|
|
return Position.isBeforeOrEqual(this, other);
|
|
|
}
|
|
|
/**
|
|
|
* Test if position `a` is before position `b`.
|
|
|
* If the two positions are equal, the result will be true.
|
|
|
*/
|
|
|
static isBeforeOrEqual(a, b) {
|
|
|
if (a.lineNumber < b.lineNumber) {
|
|
|
return true;
|
|
|
}
|
|
|
if (b.lineNumber < a.lineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
return a.column <= b.column;
|
|
|
}
|
|
|
/**
|
|
|
* A function that compares positions, useful for sorting
|
|
|
*/
|
|
|
static compare(a, b) {
|
|
|
let aLineNumber = a.lineNumber | 0;
|
|
|
let bLineNumber = b.lineNumber | 0;
|
|
|
if (aLineNumber === bLineNumber) {
|
|
|
let aColumn = a.column | 0;
|
|
|
let bColumn = b.column | 0;
|
|
|
return aColumn - bColumn;
|
|
|
}
|
|
|
return aLineNumber - bLineNumber;
|
|
|
}
|
|
|
/**
|
|
|
* Clone this position.
|
|
|
*/
|
|
|
clone() {
|
|
|
return new Position(this.lineNumber, this.column);
|
|
|
}
|
|
|
/**
|
|
|
* Convert to a human-readable representation.
|
|
|
*/
|
|
|
toString() {
|
|
|
return '(' + this.lineNumber + ',' + this.column + ')';
|
|
|
}
|
|
|
// ---
|
|
|
/**
|
|
|
* Create a `Position` from an `IPosition`.
|
|
|
*/
|
|
|
static lift(pos) {
|
|
|
return new Position(pos.lineNumber, pos.column);
|
|
|
}
|
|
|
/**
|
|
|
* Test if `obj` is an `IPosition`.
|
|
|
*/
|
|
|
static isIPosition(obj) {
|
|
|
return (obj
|
|
|
&& (typeof obj.lineNumber === 'number')
|
|
|
&& (typeof obj.column === 'number'));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/core/range.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
/**
|
|
|
* A range in the editor. (startLineNumber,startColumn) is <= (endLineNumber,endColumn)
|
|
|
*/
|
|
|
class Range {
|
|
|
constructor(startLineNumber, startColumn, endLineNumber, endColumn) {
|
|
|
if ((startLineNumber > endLineNumber) || (startLineNumber === endLineNumber && startColumn > endColumn)) {
|
|
|
this.startLineNumber = endLineNumber;
|
|
|
this.startColumn = endColumn;
|
|
|
this.endLineNumber = startLineNumber;
|
|
|
this.endColumn = startColumn;
|
|
|
}
|
|
|
else {
|
|
|
this.startLineNumber = startLineNumber;
|
|
|
this.startColumn = startColumn;
|
|
|
this.endLineNumber = endLineNumber;
|
|
|
this.endColumn = endColumn;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Test if this range is empty.
|
|
|
*/
|
|
|
isEmpty() {
|
|
|
return Range.isEmpty(this);
|
|
|
}
|
|
|
/**
|
|
|
* Test if `range` is empty.
|
|
|
*/
|
|
|
static isEmpty(range) {
|
|
|
return (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Test if position is in this range. If the position is at the edges, will return true.
|
|
|
*/
|
|
|
containsPosition(position) {
|
|
|
return Range.containsPosition(this, position);
|
|
|
}
|
|
|
/**
|
|
|
* Test if `position` is in `range`. If the position is at the edges, will return true.
|
|
|
*/
|
|
|
static containsPosition(range, position) {
|
|
|
if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
if (position.lineNumber === range.startLineNumber && position.column < range.startColumn) {
|
|
|
return false;
|
|
|
}
|
|
|
if (position.lineNumber === range.endLineNumber && position.column > range.endColumn) {
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
/**
|
|
|
* Test if range is in this range. If the range is equal to this range, will return true.
|
|
|
*/
|
|
|
containsRange(range) {
|
|
|
return Range.containsRange(this, range);
|
|
|
}
|
|
|
/**
|
|
|
* Test if `otherRange` is in `range`. If the ranges are equal, will return true.
|
|
|
*/
|
|
|
static containsRange(range, otherRange) {
|
|
|
if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn < range.startColumn) {
|
|
|
return false;
|
|
|
}
|
|
|
if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn > range.endColumn) {
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
/**
|
|
|
* Test if `range` is strictly in this range. `range` must start after and end before this range for the result to be true.
|
|
|
*/
|
|
|
strictContainsRange(range) {
|
|
|
return Range.strictContainsRange(this, range);
|
|
|
}
|
|
|
/**
|
|
|
* Test if `otherRange` is strictly in `range` (must start after, and end before). If the ranges are equal, will return false.
|
|
|
*/
|
|
|
static strictContainsRange(range, otherRange) {
|
|
|
if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
|
|
|
return false;
|
|
|
}
|
|
|
if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn <= range.startColumn) {
|
|
|
return false;
|
|
|
}
|
|
|
if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn >= range.endColumn) {
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
/**
|
|
|
* A reunion of the two ranges.
|
|
|
* The smallest position will be used as the start point, and the largest one as the end point.
|
|
|
*/
|
|
|
plusRange(range) {
|
|
|
return Range.plusRange(this, range);
|
|
|
}
|
|
|
/**
|
|
|
* A reunion of the two ranges.
|
|
|
* The smallest position will be used as the start point, and the largest one as the end point.
|
|
|
*/
|
|
|
static plusRange(a, b) {
|
|
|
let startLineNumber;
|
|
|
let startColumn;
|
|
|
let endLineNumber;
|
|
|
let endColumn;
|
|
|
if (b.startLineNumber < a.startLineNumber) {
|
|
|
startLineNumber = b.startLineNumber;
|
|
|
startColumn = b.startColumn;
|
|
|
}
|
|
|
else if (b.startLineNumber === a.startLineNumber) {
|
|
|
startLineNumber = b.startLineNumber;
|
|
|
startColumn = Math.min(b.startColumn, a.startColumn);
|
|
|
}
|
|
|
else {
|
|
|
startLineNumber = a.startLineNumber;
|
|
|
startColumn = a.startColumn;
|
|
|
}
|
|
|
if (b.endLineNumber > a.endLineNumber) {
|
|
|
endLineNumber = b.endLineNumber;
|
|
|
endColumn = b.endColumn;
|
|
|
}
|
|
|
else if (b.endLineNumber === a.endLineNumber) {
|
|
|
endLineNumber = b.endLineNumber;
|
|
|
endColumn = Math.max(b.endColumn, a.endColumn);
|
|
|
}
|
|
|
else {
|
|
|
endLineNumber = a.endLineNumber;
|
|
|
endColumn = a.endColumn;
|
|
|
}
|
|
|
return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* A intersection of the two ranges.
|
|
|
*/
|
|
|
intersectRanges(range) {
|
|
|
return Range.intersectRanges(this, range);
|
|
|
}
|
|
|
/**
|
|
|
* A intersection of the two ranges.
|
|
|
*/
|
|
|
static intersectRanges(a, b) {
|
|
|
let resultStartLineNumber = a.startLineNumber;
|
|
|
let resultStartColumn = a.startColumn;
|
|
|
let resultEndLineNumber = a.endLineNumber;
|
|
|
let resultEndColumn = a.endColumn;
|
|
|
let otherStartLineNumber = b.startLineNumber;
|
|
|
let otherStartColumn = b.startColumn;
|
|
|
let otherEndLineNumber = b.endLineNumber;
|
|
|
let otherEndColumn = b.endColumn;
|
|
|
if (resultStartLineNumber < otherStartLineNumber) {
|
|
|
resultStartLineNumber = otherStartLineNumber;
|
|
|
resultStartColumn = otherStartColumn;
|
|
|
}
|
|
|
else if (resultStartLineNumber === otherStartLineNumber) {
|
|
|
resultStartColumn = Math.max(resultStartColumn, otherStartColumn);
|
|
|
}
|
|
|
if (resultEndLineNumber > otherEndLineNumber) {
|
|
|
resultEndLineNumber = otherEndLineNumber;
|
|
|
resultEndColumn = otherEndColumn;
|
|
|
}
|
|
|
else if (resultEndLineNumber === otherEndLineNumber) {
|
|
|
resultEndColumn = Math.min(resultEndColumn, otherEndColumn);
|
|
|
}
|
|
|
// Check if selection is now empty
|
|
|
if (resultStartLineNumber > resultEndLineNumber) {
|
|
|
return null;
|
|
|
}
|
|
|
if (resultStartLineNumber === resultEndLineNumber && resultStartColumn > resultEndColumn) {
|
|
|
return null;
|
|
|
}
|
|
|
return new Range(resultStartLineNumber, resultStartColumn, resultEndLineNumber, resultEndColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Test if this range equals other.
|
|
|
*/
|
|
|
equalsRange(other) {
|
|
|
return Range.equalsRange(this, other);
|
|
|
}
|
|
|
/**
|
|
|
* Test if range `a` equals `b`.
|
|
|
*/
|
|
|
static equalsRange(a, b) {
|
|
|
return (!!a &&
|
|
|
!!b &&
|
|
|
a.startLineNumber === b.startLineNumber &&
|
|
|
a.startColumn === b.startColumn &&
|
|
|
a.endLineNumber === b.endLineNumber &&
|
|
|
a.endColumn === b.endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Return the end position (which will be after or equal to the start position)
|
|
|
*/
|
|
|
getEndPosition() {
|
|
|
return Range.getEndPosition(this);
|
|
|
}
|
|
|
/**
|
|
|
* Return the end position (which will be after or equal to the start position)
|
|
|
*/
|
|
|
static getEndPosition(range) {
|
|
|
return new Position(range.endLineNumber, range.endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Return the start position (which will be before or equal to the end position)
|
|
|
*/
|
|
|
getStartPosition() {
|
|
|
return Range.getStartPosition(this);
|
|
|
}
|
|
|
/**
|
|
|
* Return the start position (which will be before or equal to the end position)
|
|
|
*/
|
|
|
static getStartPosition(range) {
|
|
|
return new Position(range.startLineNumber, range.startColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Transform to a user presentable string representation.
|
|
|
*/
|
|
|
toString() {
|
|
|
return '[' + this.startLineNumber + ',' + this.startColumn + ' -> ' + this.endLineNumber + ',' + this.endColumn + ']';
|
|
|
}
|
|
|
/**
|
|
|
* Create a new range using this range's start position, and using endLineNumber and endColumn as the end position.
|
|
|
*/
|
|
|
setEndPosition(endLineNumber, endColumn) {
|
|
|
return new Range(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Create a new range using this range's end position, and using startLineNumber and startColumn as the start position.
|
|
|
*/
|
|
|
setStartPosition(startLineNumber, startColumn) {
|
|
|
return new Range(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Create a new empty range using this range's start position.
|
|
|
*/
|
|
|
collapseToStart() {
|
|
|
return Range.collapseToStart(this);
|
|
|
}
|
|
|
/**
|
|
|
* Create a new empty range using this range's start position.
|
|
|
*/
|
|
|
static collapseToStart(range) {
|
|
|
return new Range(range.startLineNumber, range.startColumn, range.startLineNumber, range.startColumn);
|
|
|
}
|
|
|
// ---
|
|
|
static fromPositions(start, end = start) {
|
|
|
return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
|
|
|
}
|
|
|
static lift(range) {
|
|
|
if (!range) {
|
|
|
return null;
|
|
|
}
|
|
|
return new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Test if `obj` is an `IRange`.
|
|
|
*/
|
|
|
static isIRange(obj) {
|
|
|
return (obj
|
|
|
&& (typeof obj.startLineNumber === 'number')
|
|
|
&& (typeof obj.startColumn === 'number')
|
|
|
&& (typeof obj.endLineNumber === 'number')
|
|
|
&& (typeof obj.endColumn === 'number'));
|
|
|
}
|
|
|
/**
|
|
|
* Test if the two ranges are touching in any way.
|
|
|
*/
|
|
|
static areIntersectingOrTouching(a, b) {
|
|
|
// Check if `a` is before `b`
|
|
|
if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn < b.startColumn)) {
|
|
|
return false;
|
|
|
}
|
|
|
// Check if `b` is before `a`
|
|
|
if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn < a.startColumn)) {
|
|
|
return false;
|
|
|
}
|
|
|
// These ranges must intersect
|
|
|
return true;
|
|
|
}
|
|
|
/**
|
|
|
* Test if the two ranges are intersecting. If the ranges are touching it returns true.
|
|
|
*/
|
|
|
static areIntersecting(a, b) {
|
|
|
// Check if `a` is before `b`
|
|
|
if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn <= b.startColumn)) {
|
|
|
return false;
|
|
|
}
|
|
|
// Check if `b` is before `a`
|
|
|
if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn <= a.startColumn)) {
|
|
|
return false;
|
|
|
}
|
|
|
// These ranges must intersect
|
|
|
return true;
|
|
|
}
|
|
|
/**
|
|
|
* A function that compares ranges, useful for sorting ranges
|
|
|
* It will first compare ranges on the startPosition and then on the endPosition
|
|
|
*/
|
|
|
static compareRangesUsingStarts(a, b) {
|
|
|
if (a && b) {
|
|
|
const aStartLineNumber = a.startLineNumber | 0;
|
|
|
const bStartLineNumber = b.startLineNumber | 0;
|
|
|
if (aStartLineNumber === bStartLineNumber) {
|
|
|
const aStartColumn = a.startColumn | 0;
|
|
|
const bStartColumn = b.startColumn | 0;
|
|
|
if (aStartColumn === bStartColumn) {
|
|
|
const aEndLineNumber = a.endLineNumber | 0;
|
|
|
const bEndLineNumber = b.endLineNumber | 0;
|
|
|
if (aEndLineNumber === bEndLineNumber) {
|
|
|
const aEndColumn = a.endColumn | 0;
|
|
|
const bEndColumn = b.endColumn | 0;
|
|
|
return aEndColumn - bEndColumn;
|
|
|
}
|
|
|
return aEndLineNumber - bEndLineNumber;
|
|
|
}
|
|
|
return aStartColumn - bStartColumn;
|
|
|
}
|
|
|
return aStartLineNumber - bStartLineNumber;
|
|
|
}
|
|
|
const aExists = (a ? 1 : 0);
|
|
|
const bExists = (b ? 1 : 0);
|
|
|
return aExists - bExists;
|
|
|
}
|
|
|
/**
|
|
|
* A function that compares ranges, useful for sorting ranges
|
|
|
* It will first compare ranges on the endPosition and then on the startPosition
|
|
|
*/
|
|
|
static compareRangesUsingEnds(a, b) {
|
|
|
if (a.endLineNumber === b.endLineNumber) {
|
|
|
if (a.endColumn === b.endColumn) {
|
|
|
if (a.startLineNumber === b.startLineNumber) {
|
|
|
return a.startColumn - b.startColumn;
|
|
|
}
|
|
|
return a.startLineNumber - b.startLineNumber;
|
|
|
}
|
|
|
return a.endColumn - b.endColumn;
|
|
|
}
|
|
|
return a.endLineNumber - b.endLineNumber;
|
|
|
}
|
|
|
/**
|
|
|
* Test if the range spans multiple lines.
|
|
|
*/
|
|
|
static spansMultipleLines(range) {
|
|
|
return range.endLineNumber > range.startLineNumber;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/diff/diffComputer.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
const MINIMUM_MATCHING_CHARACTER_LENGTH = 3;
|
|
|
function computeDiff(originalSequence, modifiedSequence, continueProcessingPredicate, pretty) {
|
|
|
const diffAlgo = new LcsDiff(originalSequence, modifiedSequence, continueProcessingPredicate);
|
|
|
return diffAlgo.ComputeDiff(pretty);
|
|
|
}
|
|
|
class LineSequence {
|
|
|
constructor(lines) {
|
|
|
const startColumns = [];
|
|
|
const endColumns = [];
|
|
|
for (let i = 0, length = lines.length; i < length; i++) {
|
|
|
startColumns[i] = getFirstNonBlankColumn(lines[i], 1);
|
|
|
endColumns[i] = getLastNonBlankColumn(lines[i], 1);
|
|
|
}
|
|
|
this.lines = lines;
|
|
|
this._startColumns = startColumns;
|
|
|
this._endColumns = endColumns;
|
|
|
}
|
|
|
getElements() {
|
|
|
const elements = [];
|
|
|
for (let i = 0, len = this.lines.length; i < len; i++) {
|
|
|
elements[i] = this.lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1);
|
|
|
}
|
|
|
return elements;
|
|
|
}
|
|
|
getStrictElement(index) {
|
|
|
return this.lines[index];
|
|
|
}
|
|
|
getStartLineNumber(i) {
|
|
|
return i + 1;
|
|
|
}
|
|
|
getEndLineNumber(i) {
|
|
|
return i + 1;
|
|
|
}
|
|
|
createCharSequence(shouldIgnoreTrimWhitespace, startIndex, endIndex) {
|
|
|
const charCodes = [];
|
|
|
const lineNumbers = [];
|
|
|
const columns = [];
|
|
|
let len = 0;
|
|
|
for (let index = startIndex; index <= endIndex; index++) {
|
|
|
const lineContent = this.lines[index];
|
|
|
const startColumn = (shouldIgnoreTrimWhitespace ? this._startColumns[index] : 1);
|
|
|
const endColumn = (shouldIgnoreTrimWhitespace ? this._endColumns[index] : lineContent.length + 1);
|
|
|
for (let col = startColumn; col < endColumn; col++) {
|
|
|
charCodes[len] = lineContent.charCodeAt(col - 1);
|
|
|
lineNumbers[len] = index + 1;
|
|
|
columns[len] = col;
|
|
|
len++;
|
|
|
}
|
|
|
}
|
|
|
return new CharSequence(charCodes, lineNumbers, columns);
|
|
|
}
|
|
|
}
|
|
|
class CharSequence {
|
|
|
constructor(charCodes, lineNumbers, columns) {
|
|
|
this._charCodes = charCodes;
|
|
|
this._lineNumbers = lineNumbers;
|
|
|
this._columns = columns;
|
|
|
}
|
|
|
getElements() {
|
|
|
return this._charCodes;
|
|
|
}
|
|
|
getStartLineNumber(i) {
|
|
|
return this._lineNumbers[i];
|
|
|
}
|
|
|
getStartColumn(i) {
|
|
|
return this._columns[i];
|
|
|
}
|
|
|
getEndLineNumber(i) {
|
|
|
return this._lineNumbers[i];
|
|
|
}
|
|
|
getEndColumn(i) {
|
|
|
return this._columns[i] + 1;
|
|
|
}
|
|
|
}
|
|
|
class CharChange {
|
|
|
constructor(originalStartLineNumber, originalStartColumn, originalEndLineNumber, originalEndColumn, modifiedStartLineNumber, modifiedStartColumn, modifiedEndLineNumber, modifiedEndColumn) {
|
|
|
this.originalStartLineNumber = originalStartLineNumber;
|
|
|
this.originalStartColumn = originalStartColumn;
|
|
|
this.originalEndLineNumber = originalEndLineNumber;
|
|
|
this.originalEndColumn = originalEndColumn;
|
|
|
this.modifiedStartLineNumber = modifiedStartLineNumber;
|
|
|
this.modifiedStartColumn = modifiedStartColumn;
|
|
|
this.modifiedEndLineNumber = modifiedEndLineNumber;
|
|
|
this.modifiedEndColumn = modifiedEndColumn;
|
|
|
}
|
|
|
static createFromDiffChange(diffChange, originalCharSequence, modifiedCharSequence) {
|
|
|
let originalStartLineNumber;
|
|
|
let originalStartColumn;
|
|
|
let originalEndLineNumber;
|
|
|
let originalEndColumn;
|
|
|
let modifiedStartLineNumber;
|
|
|
let modifiedStartColumn;
|
|
|
let modifiedEndLineNumber;
|
|
|
let modifiedEndColumn;
|
|
|
if (diffChange.originalLength === 0) {
|
|
|
originalStartLineNumber = 0;
|
|
|
originalStartColumn = 0;
|
|
|
originalEndLineNumber = 0;
|
|
|
originalEndColumn = 0;
|
|
|
}
|
|
|
else {
|
|
|
originalStartLineNumber = originalCharSequence.getStartLineNumber(diffChange.originalStart);
|
|
|
originalStartColumn = originalCharSequence.getStartColumn(diffChange.originalStart);
|
|
|
originalEndLineNumber = originalCharSequence.getEndLineNumber(diffChange.originalStart + diffChange.originalLength - 1);
|
|
|
originalEndColumn = originalCharSequence.getEndColumn(diffChange.originalStart + diffChange.originalLength - 1);
|
|
|
}
|
|
|
if (diffChange.modifiedLength === 0) {
|
|
|
modifiedStartLineNumber = 0;
|
|
|
modifiedStartColumn = 0;
|
|
|
modifiedEndLineNumber = 0;
|
|
|
modifiedEndColumn = 0;
|
|
|
}
|
|
|
else {
|
|
|
modifiedStartLineNumber = modifiedCharSequence.getStartLineNumber(diffChange.modifiedStart);
|
|
|
modifiedStartColumn = modifiedCharSequence.getStartColumn(diffChange.modifiedStart);
|
|
|
modifiedEndLineNumber = modifiedCharSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
|
modifiedEndColumn = modifiedCharSequence.getEndColumn(diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
|
}
|
|
|
return new CharChange(originalStartLineNumber, originalStartColumn, originalEndLineNumber, originalEndColumn, modifiedStartLineNumber, modifiedStartColumn, modifiedEndLineNumber, modifiedEndColumn);
|
|
|
}
|
|
|
}
|
|
|
function postProcessCharChanges(rawChanges) {
|
|
|
if (rawChanges.length <= 1) {
|
|
|
return rawChanges;
|
|
|
}
|
|
|
const result = [rawChanges[0]];
|
|
|
let prevChange = result[0];
|
|
|
for (let i = 1, len = rawChanges.length; i < len; i++) {
|
|
|
const currChange = rawChanges[i];
|
|
|
const originalMatchingLength = currChange.originalStart - (prevChange.originalStart + prevChange.originalLength);
|
|
|
const modifiedMatchingLength = currChange.modifiedStart - (prevChange.modifiedStart + prevChange.modifiedLength);
|
|
|
// Both of the above should be equal, but the continueProcessingPredicate may prevent this from being true
|
|
|
const matchingLength = Math.min(originalMatchingLength, modifiedMatchingLength);
|
|
|
if (matchingLength < MINIMUM_MATCHING_CHARACTER_LENGTH) {
|
|
|
// Merge the current change into the previous one
|
|
|
prevChange.originalLength = (currChange.originalStart + currChange.originalLength) - prevChange.originalStart;
|
|
|
prevChange.modifiedLength = (currChange.modifiedStart + currChange.modifiedLength) - prevChange.modifiedStart;
|
|
|
}
|
|
|
else {
|
|
|
// Add the current change
|
|
|
result.push(currChange);
|
|
|
prevChange = currChange;
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
class LineChange {
|
|
|
constructor(originalStartLineNumber, originalEndLineNumber, modifiedStartLineNumber, modifiedEndLineNumber, charChanges) {
|
|
|
this.originalStartLineNumber = originalStartLineNumber;
|
|
|
this.originalEndLineNumber = originalEndLineNumber;
|
|
|
this.modifiedStartLineNumber = modifiedStartLineNumber;
|
|
|
this.modifiedEndLineNumber = modifiedEndLineNumber;
|
|
|
this.charChanges = charChanges;
|
|
|
}
|
|
|
static createFromDiffResult(shouldIgnoreTrimWhitespace, diffChange, originalLineSequence, modifiedLineSequence, continueCharDiff, shouldComputeCharChanges, shouldPostProcessCharChanges) {
|
|
|
let originalStartLineNumber;
|
|
|
let originalEndLineNumber;
|
|
|
let modifiedStartLineNumber;
|
|
|
let modifiedEndLineNumber;
|
|
|
let charChanges = undefined;
|
|
|
if (diffChange.originalLength === 0) {
|
|
|
originalStartLineNumber = originalLineSequence.getStartLineNumber(diffChange.originalStart) - 1;
|
|
|
originalEndLineNumber = 0;
|
|
|
}
|
|
|
else {
|
|
|
originalStartLineNumber = originalLineSequence.getStartLineNumber(diffChange.originalStart);
|
|
|
originalEndLineNumber = originalLineSequence.getEndLineNumber(diffChange.originalStart + diffChange.originalLength - 1);
|
|
|
}
|
|
|
if (diffChange.modifiedLength === 0) {
|
|
|
modifiedStartLineNumber = modifiedLineSequence.getStartLineNumber(diffChange.modifiedStart) - 1;
|
|
|
modifiedEndLineNumber = 0;
|
|
|
}
|
|
|
else {
|
|
|
modifiedStartLineNumber = modifiedLineSequence.getStartLineNumber(diffChange.modifiedStart);
|
|
|
modifiedEndLineNumber = modifiedLineSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
|
}
|
|
|
if (shouldComputeCharChanges && diffChange.originalLength > 0 && diffChange.originalLength < 20 && diffChange.modifiedLength > 0 && diffChange.modifiedLength < 20 && continueCharDiff()) {
|
|
|
// Compute character changes for diff chunks of at most 20 lines...
|
|
|
const originalCharSequence = originalLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1);
|
|
|
const modifiedCharSequence = modifiedLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
|
let rawChanges = computeDiff(originalCharSequence, modifiedCharSequence, continueCharDiff, true).changes;
|
|
|
if (shouldPostProcessCharChanges) {
|
|
|
rawChanges = postProcessCharChanges(rawChanges);
|
|
|
}
|
|
|
charChanges = [];
|
|
|
for (let i = 0, length = rawChanges.length; i < length; i++) {
|
|
|
charChanges.push(CharChange.createFromDiffChange(rawChanges[i], originalCharSequence, modifiedCharSequence));
|
|
|
}
|
|
|
}
|
|
|
return new LineChange(originalStartLineNumber, originalEndLineNumber, modifiedStartLineNumber, modifiedEndLineNumber, charChanges);
|
|
|
}
|
|
|
}
|
|
|
class DiffComputer {
|
|
|
constructor(originalLines, modifiedLines, opts) {
|
|
|
this.shouldComputeCharChanges = opts.shouldComputeCharChanges;
|
|
|
this.shouldPostProcessCharChanges = opts.shouldPostProcessCharChanges;
|
|
|
this.shouldIgnoreTrimWhitespace = opts.shouldIgnoreTrimWhitespace;
|
|
|
this.shouldMakePrettyDiff = opts.shouldMakePrettyDiff;
|
|
|
this.originalLines = originalLines;
|
|
|
this.modifiedLines = modifiedLines;
|
|
|
this.original = new LineSequence(originalLines);
|
|
|
this.modified = new LineSequence(modifiedLines);
|
|
|
this.continueLineDiff = createContinueProcessingPredicate(opts.maxComputationTime);
|
|
|
this.continueCharDiff = createContinueProcessingPredicate(opts.maxComputationTime === 0 ? 0 : Math.min(opts.maxComputationTime, 5000)); // never run after 5s for character changes...
|
|
|
}
|
|
|
computeDiff() {
|
|
|
if (this.original.lines.length === 1 && this.original.lines[0].length === 0) {
|
|
|
// empty original => fast path
|
|
|
if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) {
|
|
|
return {
|
|
|
quitEarly: false,
|
|
|
changes: []
|
|
|
};
|
|
|
}
|
|
|
return {
|
|
|
quitEarly: false,
|
|
|
changes: [{
|
|
|
originalStartLineNumber: 1,
|
|
|
originalEndLineNumber: 1,
|
|
|
modifiedStartLineNumber: 1,
|
|
|
modifiedEndLineNumber: this.modified.lines.length,
|
|
|
charChanges: [{
|
|
|
modifiedEndColumn: 0,
|
|
|
modifiedEndLineNumber: 0,
|
|
|
modifiedStartColumn: 0,
|
|
|
modifiedStartLineNumber: 0,
|
|
|
originalEndColumn: 0,
|
|
|
originalEndLineNumber: 0,
|
|
|
originalStartColumn: 0,
|
|
|
originalStartLineNumber: 0
|
|
|
}]
|
|
|
}]
|
|
|
};
|
|
|
}
|
|
|
if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) {
|
|
|
// empty modified => fast path
|
|
|
return {
|
|
|
quitEarly: false,
|
|
|
changes: [{
|
|
|
originalStartLineNumber: 1,
|
|
|
originalEndLineNumber: this.original.lines.length,
|
|
|
modifiedStartLineNumber: 1,
|
|
|
modifiedEndLineNumber: 1,
|
|
|
charChanges: [{
|
|
|
modifiedEndColumn: 0,
|
|
|
modifiedEndLineNumber: 0,
|
|
|
modifiedStartColumn: 0,
|
|
|
modifiedStartLineNumber: 0,
|
|
|
originalEndColumn: 0,
|
|
|
originalEndLineNumber: 0,
|
|
|
originalStartColumn: 0,
|
|
|
originalStartLineNumber: 0
|
|
|
}]
|
|
|
}]
|
|
|
};
|
|
|
}
|
|
|
const diffResult = computeDiff(this.original, this.modified, this.continueLineDiff, this.shouldMakePrettyDiff);
|
|
|
const rawChanges = diffResult.changes;
|
|
|
const quitEarly = diffResult.quitEarly;
|
|
|
// The diff is always computed with ignoring trim whitespace
|
|
|
// This ensures we get the prettiest diff
|
|
|
if (this.shouldIgnoreTrimWhitespace) {
|
|
|
const lineChanges = [];
|
|
|
for (let i = 0, length = rawChanges.length; i < length; i++) {
|
|
|
lineChanges.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, rawChanges[i], this.original, this.modified, this.continueCharDiff, this.shouldComputeCharChanges, this.shouldPostProcessCharChanges));
|
|
|
}
|
|
|
return {
|
|
|
quitEarly: quitEarly,
|
|
|
changes: lineChanges
|
|
|
};
|
|
|
}
|
|
|
// Need to post-process and introduce changes where the trim whitespace is different
|
|
|
// Note that we are looping starting at -1 to also cover the lines before the first change
|
|
|
const result = [];
|
|
|
let originalLineIndex = 0;
|
|
|
let modifiedLineIndex = 0;
|
|
|
for (let i = -1 /* !!!! */, len = rawChanges.length; i < len; i++) {
|
|
|
const nextChange = (i + 1 < len ? rawChanges[i + 1] : null);
|
|
|
const originalStop = (nextChange ? nextChange.originalStart : this.originalLines.length);
|
|
|
const modifiedStop = (nextChange ? nextChange.modifiedStart : this.modifiedLines.length);
|
|
|
while (originalLineIndex < originalStop && modifiedLineIndex < modifiedStop) {
|
|
|
const originalLine = this.originalLines[originalLineIndex];
|
|
|
const modifiedLine = this.modifiedLines[modifiedLineIndex];
|
|
|
if (originalLine !== modifiedLine) {
|
|
|
// These lines differ only in trim whitespace
|
|
|
// Check the leading whitespace
|
|
|
{
|
|
|
let originalStartColumn = getFirstNonBlankColumn(originalLine, 1);
|
|
|
let modifiedStartColumn = getFirstNonBlankColumn(modifiedLine, 1);
|
|
|
while (originalStartColumn > 1 && modifiedStartColumn > 1) {
|
|
|
const originalChar = originalLine.charCodeAt(originalStartColumn - 2);
|
|
|
const modifiedChar = modifiedLine.charCodeAt(modifiedStartColumn - 2);
|
|
|
if (originalChar !== modifiedChar) {
|
|
|
break;
|
|
|
}
|
|
|
originalStartColumn--;
|
|
|
modifiedStartColumn--;
|
|
|
}
|
|
|
if (originalStartColumn > 1 || modifiedStartColumn > 1) {
|
|
|
this._pushTrimWhitespaceCharChange(result, originalLineIndex + 1, 1, originalStartColumn, modifiedLineIndex + 1, 1, modifiedStartColumn);
|
|
|
}
|
|
|
}
|
|
|
// Check the trailing whitespace
|
|
|
{
|
|
|
let originalEndColumn = getLastNonBlankColumn(originalLine, 1);
|
|
|
let modifiedEndColumn = getLastNonBlankColumn(modifiedLine, 1);
|
|
|
const originalMaxColumn = originalLine.length + 1;
|
|
|
const modifiedMaxColumn = modifiedLine.length + 1;
|
|
|
while (originalEndColumn < originalMaxColumn && modifiedEndColumn < modifiedMaxColumn) {
|
|
|
const originalChar = originalLine.charCodeAt(originalEndColumn - 1);
|
|
|
const modifiedChar = originalLine.charCodeAt(modifiedEndColumn - 1);
|
|
|
if (originalChar !== modifiedChar) {
|
|
|
break;
|
|
|
}
|
|
|
originalEndColumn++;
|
|
|
modifiedEndColumn++;
|
|
|
}
|
|
|
if (originalEndColumn < originalMaxColumn || modifiedEndColumn < modifiedMaxColumn) {
|
|
|
this._pushTrimWhitespaceCharChange(result, originalLineIndex + 1, originalEndColumn, originalMaxColumn, modifiedLineIndex + 1, modifiedEndColumn, modifiedMaxColumn);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
originalLineIndex++;
|
|
|
modifiedLineIndex++;
|
|
|
}
|
|
|
if (nextChange) {
|
|
|
// Emit the actual change
|
|
|
result.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, nextChange, this.original, this.modified, this.continueCharDiff, this.shouldComputeCharChanges, this.shouldPostProcessCharChanges));
|
|
|
originalLineIndex += nextChange.originalLength;
|
|
|
modifiedLineIndex += nextChange.modifiedLength;
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
quitEarly: quitEarly,
|
|
|
changes: result
|
|
|
};
|
|
|
}
|
|
|
_pushTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn) {
|
|
|
if (this._mergeTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn)) {
|
|
|
// Merged into previous
|
|
|
return;
|
|
|
}
|
|
|
let charChanges = undefined;
|
|
|
if (this.shouldComputeCharChanges) {
|
|
|
charChanges = [new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn)];
|
|
|
}
|
|
|
result.push(new LineChange(originalLineNumber, originalLineNumber, modifiedLineNumber, modifiedLineNumber, charChanges));
|
|
|
}
|
|
|
_mergeTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn) {
|
|
|
const len = result.length;
|
|
|
if (len === 0) {
|
|
|
return false;
|
|
|
}
|
|
|
const prevChange = result[len - 1];
|
|
|
if (prevChange.originalEndLineNumber === 0 || prevChange.modifiedEndLineNumber === 0) {
|
|
|
// Don't merge with inserts/deletes
|
|
|
return false;
|
|
|
}
|
|
|
if (prevChange.originalEndLineNumber + 1 === originalLineNumber && prevChange.modifiedEndLineNumber + 1 === modifiedLineNumber) {
|
|
|
prevChange.originalEndLineNumber = originalLineNumber;
|
|
|
prevChange.modifiedEndLineNumber = modifiedLineNumber;
|
|
|
if (this.shouldComputeCharChanges && prevChange.charChanges) {
|
|
|
prevChange.charChanges.push(new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn));
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
function getFirstNonBlankColumn(txt, defaultValue) {
|
|
|
const r = firstNonWhitespaceIndex(txt);
|
|
|
if (r === -1) {
|
|
|
return defaultValue;
|
|
|
}
|
|
|
return r + 1;
|
|
|
}
|
|
|
function getLastNonBlankColumn(txt, defaultValue) {
|
|
|
const r = lastNonWhitespaceIndex(txt);
|
|
|
if (r === -1) {
|
|
|
return defaultValue;
|
|
|
}
|
|
|
return r + 2;
|
|
|
}
|
|
|
function createContinueProcessingPredicate(maximumRuntime) {
|
|
|
if (maximumRuntime === 0) {
|
|
|
return () => true;
|
|
|
}
|
|
|
const startTime = Date.now();
|
|
|
return () => {
|
|
|
return Date.now() - startTime < maximumRuntime;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/uint.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
function toUint8(v) {
|
|
|
if (v < 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (v > 255 /* MAX_UINT_8 */) {
|
|
|
return 255 /* MAX_UINT_8 */;
|
|
|
}
|
|
|
return v | 0;
|
|
|
}
|
|
|
function toUint32(v) {
|
|
|
if (v < 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (v > 4294967295 /* MAX_UINT_32 */) {
|
|
|
return 4294967295 /* MAX_UINT_32 */;
|
|
|
}
|
|
|
return v | 0;
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/viewModel/prefixSumComputer.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
class PrefixSumIndexOfResult {
|
|
|
constructor(index, remainder) {
|
|
|
this._prefixSumIndexOfResultBrand = undefined;
|
|
|
this.index = index;
|
|
|
this.remainder = remainder;
|
|
|
}
|
|
|
}
|
|
|
class PrefixSumComputer {
|
|
|
constructor(values) {
|
|
|
this.values = values;
|
|
|
this.prefixSum = new Uint32Array(values.length);
|
|
|
this.prefixSumValidIndex = new Int32Array(1);
|
|
|
this.prefixSumValidIndex[0] = -1;
|
|
|
}
|
|
|
insertValues(insertIndex, insertValues) {
|
|
|
insertIndex = toUint32(insertIndex);
|
|
|
const oldValues = this.values;
|
|
|
const oldPrefixSum = this.prefixSum;
|
|
|
const insertValuesLen = insertValues.length;
|
|
|
if (insertValuesLen === 0) {
|
|
|
return false;
|
|
|
}
|
|
|
this.values = new Uint32Array(oldValues.length + insertValuesLen);
|
|
|
this.values.set(oldValues.subarray(0, insertIndex), 0);
|
|
|
this.values.set(oldValues.subarray(insertIndex), insertIndex + insertValuesLen);
|
|
|
this.values.set(insertValues, insertIndex);
|
|
|
if (insertIndex - 1 < this.prefixSumValidIndex[0]) {
|
|
|
this.prefixSumValidIndex[0] = insertIndex - 1;
|
|
|
}
|
|
|
this.prefixSum = new Uint32Array(this.values.length);
|
|
|
if (this.prefixSumValidIndex[0] >= 0) {
|
|
|
this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
changeValue(index, value) {
|
|
|
index = toUint32(index);
|
|
|
value = toUint32(value);
|
|
|
if (this.values[index] === value) {
|
|
|
return false;
|
|
|
}
|
|
|
this.values[index] = value;
|
|
|
if (index - 1 < this.prefixSumValidIndex[0]) {
|
|
|
this.prefixSumValidIndex[0] = index - 1;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
removeValues(startIndex, count) {
|
|
|
startIndex = toUint32(startIndex);
|
|
|
count = toUint32(count);
|
|
|
const oldValues = this.values;
|
|
|
const oldPrefixSum = this.prefixSum;
|
|
|
if (startIndex >= oldValues.length) {
|
|
|
return false;
|
|
|
}
|
|
|
let maxCount = oldValues.length - startIndex;
|
|
|
if (count >= maxCount) {
|
|
|
count = maxCount;
|
|
|
}
|
|
|
if (count === 0) {
|
|
|
return false;
|
|
|
}
|
|
|
this.values = new Uint32Array(oldValues.length - count);
|
|
|
this.values.set(oldValues.subarray(0, startIndex), 0);
|
|
|
this.values.set(oldValues.subarray(startIndex + count), startIndex);
|
|
|
this.prefixSum = new Uint32Array(this.values.length);
|
|
|
if (startIndex - 1 < this.prefixSumValidIndex[0]) {
|
|
|
this.prefixSumValidIndex[0] = startIndex - 1;
|
|
|
}
|
|
|
if (this.prefixSumValidIndex[0] >= 0) {
|
|
|
this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
getTotalSum() {
|
|
|
if (this.values.length === 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
return this._getPrefixSum(this.values.length - 1);
|
|
|
}
|
|
|
getPrefixSum(index) {
|
|
|
if (index < 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
index = toUint32(index);
|
|
|
return this._getPrefixSum(index);
|
|
|
}
|
|
|
_getPrefixSum(index) {
|
|
|
if (index <= this.prefixSumValidIndex[0]) {
|
|
|
return this.prefixSum[index];
|
|
|
}
|
|
|
let startIndex = this.prefixSumValidIndex[0] + 1;
|
|
|
if (startIndex === 0) {
|
|
|
this.prefixSum[0] = this.values[0];
|
|
|
startIndex++;
|
|
|
}
|
|
|
if (index >= this.values.length) {
|
|
|
index = this.values.length - 1;
|
|
|
}
|
|
|
for (let i = startIndex; i <= index; i++) {
|
|
|
this.prefixSum[i] = this.prefixSum[i - 1] + this.values[i];
|
|
|
}
|
|
|
this.prefixSumValidIndex[0] = Math.max(this.prefixSumValidIndex[0], index);
|
|
|
return this.prefixSum[index];
|
|
|
}
|
|
|
getIndexOf(sum) {
|
|
|
sum = Math.floor(sum); //@perf
|
|
|
// Compute all sums (to get a fully valid prefixSum)
|
|
|
this.getTotalSum();
|
|
|
let low = 0;
|
|
|
let high = this.values.length - 1;
|
|
|
let mid = 0;
|
|
|
let midStop = 0;
|
|
|
let midStart = 0;
|
|
|
while (low <= high) {
|
|
|
mid = low + ((high - low) / 2) | 0;
|
|
|
midStop = this.prefixSum[mid];
|
|
|
midStart = midStop - this.values[mid];
|
|
|
if (sum < midStart) {
|
|
|
high = mid - 1;
|
|
|
}
|
|
|
else if (sum >= midStop) {
|
|
|
low = mid + 1;
|
|
|
}
|
|
|
else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return new PrefixSumIndexOfResult(mid, sum - midStart);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/model/mirrorTextModel.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
class MirrorTextModel {
|
|
|
constructor(uri, lines, eol, versionId) {
|
|
|
this._uri = uri;
|
|
|
this._lines = lines;
|
|
|
this._eol = eol;
|
|
|
this._versionId = versionId;
|
|
|
this._lineStarts = null;
|
|
|
this._cachedTextValue = null;
|
|
|
}
|
|
|
dispose() {
|
|
|
this._lines.length = 0;
|
|
|
}
|
|
|
get version() {
|
|
|
return this._versionId;
|
|
|
}
|
|
|
getText() {
|
|
|
if (this._cachedTextValue === null) {
|
|
|
this._cachedTextValue = this._lines.join(this._eol);
|
|
|
}
|
|
|
return this._cachedTextValue;
|
|
|
}
|
|
|
onEvents(e) {
|
|
|
if (e.eol && e.eol !== this._eol) {
|
|
|
this._eol = e.eol;
|
|
|
this._lineStarts = null;
|
|
|
}
|
|
|
// Update my lines
|
|
|
const changes = e.changes;
|
|
|
for (const change of changes) {
|
|
|
this._acceptDeleteRange(change.range);
|
|
|
this._acceptInsertText(new Position(change.range.startLineNumber, change.range.startColumn), change.text);
|
|
|
}
|
|
|
this._versionId = e.versionId;
|
|
|
this._cachedTextValue = null;
|
|
|
}
|
|
|
_ensureLineStarts() {
|
|
|
if (!this._lineStarts) {
|
|
|
const eolLength = this._eol.length;
|
|
|
const linesLength = this._lines.length;
|
|
|
const lineStartValues = new Uint32Array(linesLength);
|
|
|
for (let i = 0; i < linesLength; i++) {
|
|
|
lineStartValues[i] = this._lines[i].length + eolLength;
|
|
|
}
|
|
|
this._lineStarts = new PrefixSumComputer(lineStartValues);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* All changes to a line's text go through this method
|
|
|
*/
|
|
|
_setLineText(lineIndex, newValue) {
|
|
|
this._lines[lineIndex] = newValue;
|
|
|
if (this._lineStarts) {
|
|
|
// update prefix sum
|
|
|
this._lineStarts.changeValue(lineIndex, this._lines[lineIndex].length + this._eol.length);
|
|
|
}
|
|
|
}
|
|
|
_acceptDeleteRange(range) {
|
|
|
if (range.startLineNumber === range.endLineNumber) {
|
|
|
if (range.startColumn === range.endColumn) {
|
|
|
// Nothing to delete
|
|
|
return;
|
|
|
}
|
|
|
// Delete text on the affected line
|
|
|
this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)
|
|
|
+ this._lines[range.startLineNumber - 1].substring(range.endColumn - 1));
|
|
|
return;
|
|
|
}
|
|
|
// Take remaining text on last line and append it to remaining text on first line
|
|
|
this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)
|
|
|
+ this._lines[range.endLineNumber - 1].substring(range.endColumn - 1));
|
|
|
// Delete middle lines
|
|
|
this._lines.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber);
|
|
|
if (this._lineStarts) {
|
|
|
// update prefix sum
|
|
|
this._lineStarts.removeValues(range.startLineNumber, range.endLineNumber - range.startLineNumber);
|
|
|
}
|
|
|
}
|
|
|
_acceptInsertText(position, insertText) {
|
|
|
if (insertText.length === 0) {
|
|
|
// Nothing to insert
|
|
|
return;
|
|
|
}
|
|
|
let insertLines = splitLines(insertText);
|
|
|
if (insertLines.length === 1) {
|
|
|
// Inserting text on one line
|
|
|
this._setLineText(position.lineNumber - 1, this._lines[position.lineNumber - 1].substring(0, position.column - 1)
|
|
|
+ insertLines[0]
|
|
|
+ this._lines[position.lineNumber - 1].substring(position.column - 1));
|
|
|
return;
|
|
|
}
|
|
|
// Append overflowing text from first line to the end of text to insert
|
|
|
insertLines[insertLines.length - 1] += this._lines[position.lineNumber - 1].substring(position.column - 1);
|
|
|
// Delete overflowing text from first line and insert text on first line
|
|
|
this._setLineText(position.lineNumber - 1, this._lines[position.lineNumber - 1].substring(0, position.column - 1)
|
|
|
+ insertLines[0]);
|
|
|
// Insert new lines & store lengths
|
|
|
let newLengths = new Uint32Array(insertLines.length - 1);
|
|
|
for (let i = 1; i < insertLines.length; i++) {
|
|
|
this._lines.splice(position.lineNumber + i - 1, 0, insertLines[i]);
|
|
|
newLengths[i - 1] = insertLines[i].length + this._eol.length;
|
|
|
}
|
|
|
if (this._lineStarts) {
|
|
|
// update prefix sum
|
|
|
this._lineStarts.insertValues(position.lineNumber, newLengths);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/model/wordHelper.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
const USUAL_WORD_SEPARATORS = '`~!@#$%^&*()-=+[{]}\\|;:\'",.<>/?';
|
|
|
/**
|
|
|
* Create a word definition regular expression based on default word separators.
|
|
|
* Optionally provide allowed separators that should be included in words.
|
|
|
*
|
|
|
* The default would look like this:
|
|
|
* /(-?\d*\.\d\w*)|([^\`\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
|
|
|
*/
|
|
|
function createWordRegExp(allowInWords = '') {
|
|
|
let source = '(-?\\d*\\.\\d\\w*)|([^';
|
|
|
for (const sep of USUAL_WORD_SEPARATORS) {
|
|
|
if (allowInWords.indexOf(sep) >= 0) {
|
|
|
continue;
|
|
|
}
|
|
|
source += '\\' + sep;
|
|
|
}
|
|
|
source += '\\s]+)';
|
|
|
return new RegExp(source, 'g');
|
|
|
}
|
|
|
// catches numbers (including floating numbers) in the first group, and alphanum in the second
|
|
|
const DEFAULT_WORD_REGEXP = createWordRegExp();
|
|
|
function ensureValidWordDefinition(wordDefinition) {
|
|
|
let result = DEFAULT_WORD_REGEXP;
|
|
|
if (wordDefinition && (wordDefinition instanceof RegExp)) {
|
|
|
if (!wordDefinition.global) {
|
|
|
let flags = 'g';
|
|
|
if (wordDefinition.ignoreCase) {
|
|
|
flags += 'i';
|
|
|
}
|
|
|
if (wordDefinition.multiline) {
|
|
|
flags += 'm';
|
|
|
}
|
|
|
if (wordDefinition.unicode) {
|
|
|
flags += 'u';
|
|
|
}
|
|
|
result = new RegExp(wordDefinition.source, flags);
|
|
|
}
|
|
|
else {
|
|
|
result = wordDefinition;
|
|
|
}
|
|
|
}
|
|
|
result.lastIndex = 0;
|
|
|
return result;
|
|
|
}
|
|
|
const _defaultConfig = {
|
|
|
maxLen: 1000,
|
|
|
windowSize: 15,
|
|
|
timeBudget: 150
|
|
|
};
|
|
|
function getWordAtText(column, wordDefinition, text, textOffset, config = _defaultConfig) {
|
|
|
if (text.length > config.maxLen) {
|
|
|
// don't throw strings that long at the regexp
|
|
|
// but use a sub-string in which a word must occur
|
|
|
let start = column - config.maxLen / 2;
|
|
|
if (start < 0) {
|
|
|
start = 0;
|
|
|
}
|
|
|
else {
|
|
|
textOffset += start;
|
|
|
}
|
|
|
text = text.substring(start, column + config.maxLen / 2);
|
|
|
return getWordAtText(column, wordDefinition, text, textOffset, config);
|
|
|
}
|
|
|
const t1 = Date.now();
|
|
|
const pos = column - 1 - textOffset;
|
|
|
let prevRegexIndex = -1;
|
|
|
let match = null;
|
|
|
for (let i = 1;; i++) {
|
|
|
// check time budget
|
|
|
if (Date.now() - t1 >= config.timeBudget) {
|
|
|
break;
|
|
|
}
|
|
|
// reset the index at which the regexp should start matching, also know where it
|
|
|
// should stop so that subsequent search don't repeat previous searches
|
|
|
const regexIndex = pos - config.windowSize * i;
|
|
|
wordDefinition.lastIndex = Math.max(0, regexIndex);
|
|
|
const thisMatch = _findRegexMatchEnclosingPosition(wordDefinition, text, pos, prevRegexIndex);
|
|
|
if (!thisMatch && match) {
|
|
|
// stop: we have something
|
|
|
break;
|
|
|
}
|
|
|
match = thisMatch;
|
|
|
// stop: searched at start
|
|
|
if (regexIndex <= 0) {
|
|
|
break;
|
|
|
}
|
|
|
prevRegexIndex = regexIndex;
|
|
|
}
|
|
|
if (match) {
|
|
|
let result = {
|
|
|
word: match[0],
|
|
|
startColumn: textOffset + 1 + match.index,
|
|
|
endColumn: textOffset + 1 + match.index + match[0].length
|
|
|
};
|
|
|
wordDefinition.lastIndex = 0;
|
|
|
return result;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
function _findRegexMatchEnclosingPosition(wordDefinition, text, pos, stopPos) {
|
|
|
let match;
|
|
|
while (match = wordDefinition.exec(text)) {
|
|
|
const matchIndex = match.index || 0;
|
|
|
if (matchIndex <= pos && wordDefinition.lastIndex >= pos) {
|
|
|
return match;
|
|
|
}
|
|
|
else if (stopPos > 0 && matchIndex > stopPos) {
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/core/characterClassifier.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
/**
|
|
|
* A fast character classifier that uses a compact array for ASCII values.
|
|
|
*/
|
|
|
class CharacterClassifier {
|
|
|
constructor(_defaultValue) {
|
|
|
let defaultValue = toUint8(_defaultValue);
|
|
|
this._defaultValue = defaultValue;
|
|
|
this._asciiMap = CharacterClassifier._createAsciiMap(defaultValue);
|
|
|
this._map = new Map();
|
|
|
}
|
|
|
static _createAsciiMap(defaultValue) {
|
|
|
let asciiMap = new Uint8Array(256);
|
|
|
for (let i = 0; i < 256; i++) {
|
|
|
asciiMap[i] = defaultValue;
|
|
|
}
|
|
|
return asciiMap;
|
|
|
}
|
|
|
set(charCode, _value) {
|
|
|
let value = toUint8(_value);
|
|
|
if (charCode >= 0 && charCode < 256) {
|
|
|
this._asciiMap[charCode] = value;
|
|
|
}
|
|
|
else {
|
|
|
this._map.set(charCode, value);
|
|
|
}
|
|
|
}
|
|
|
get(charCode) {
|
|
|
if (charCode >= 0 && charCode < 256) {
|
|
|
return this._asciiMap[charCode];
|
|
|
}
|
|
|
else {
|
|
|
return (this._map.get(charCode) || this._defaultValue);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
class CharacterSet {
|
|
|
constructor() {
|
|
|
this._actual = new CharacterClassifier(0 /* False */);
|
|
|
}
|
|
|
add(charCode) {
|
|
|
this._actual.set(charCode, 1 /* True */);
|
|
|
}
|
|
|
has(charCode) {
|
|
|
return (this._actual.get(charCode) === 1 /* True */);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/modes/linkComputer.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
class Uint8Matrix {
|
|
|
constructor(rows, cols, defaultValue) {
|
|
|
const data = new Uint8Array(rows * cols);
|
|
|
for (let i = 0, len = rows * cols; i < len; i++) {
|
|
|
data[i] = defaultValue;
|
|
|
}
|
|
|
this._data = data;
|
|
|
this.rows = rows;
|
|
|
this.cols = cols;
|
|
|
}
|
|
|
get(row, col) {
|
|
|
return this._data[row * this.cols + col];
|
|
|
}
|
|
|
set(row, col, value) {
|
|
|
this._data[row * this.cols + col] = value;
|
|
|
}
|
|
|
}
|
|
|
class StateMachine {
|
|
|
constructor(edges) {
|
|
|
let maxCharCode = 0;
|
|
|
let maxState = 0 /* Invalid */;
|
|
|
for (let i = 0, len = edges.length; i < len; i++) {
|
|
|
let [from, chCode, to] = edges[i];
|
|
|
if (chCode > maxCharCode) {
|
|
|
maxCharCode = chCode;
|
|
|
}
|
|
|
if (from > maxState) {
|
|
|
maxState = from;
|
|
|
}
|
|
|
if (to > maxState) {
|
|
|
maxState = to;
|
|
|
}
|
|
|
}
|
|
|
maxCharCode++;
|
|
|
maxState++;
|
|
|
let states = new Uint8Matrix(maxState, maxCharCode, 0 /* Invalid */);
|
|
|
for (let i = 0, len = edges.length; i < len; i++) {
|
|
|
let [from, chCode, to] = edges[i];
|
|
|
states.set(from, chCode, to);
|
|
|
}
|
|
|
this._states = states;
|
|
|
this._maxCharCode = maxCharCode;
|
|
|
}
|
|
|
nextState(currentState, chCode) {
|
|
|
if (chCode < 0 || chCode >= this._maxCharCode) {
|
|
|
return 0 /* Invalid */;
|
|
|
}
|
|
|
return this._states.get(currentState, chCode);
|
|
|
}
|
|
|
}
|
|
|
// State machine for http:// or https:// or file://
|
|
|
let _stateMachine = null;
|
|
|
function getStateMachine() {
|
|
|
if (_stateMachine === null) {
|
|
|
_stateMachine = new StateMachine([
|
|
|
[1 /* Start */, 104 /* h */, 2 /* H */],
|
|
|
[1 /* Start */, 72 /* H */, 2 /* H */],
|
|
|
[1 /* Start */, 102 /* f */, 6 /* F */],
|
|
|
[1 /* Start */, 70 /* F */, 6 /* F */],
|
|
|
[2 /* H */, 116 /* t */, 3 /* HT */],
|
|
|
[2 /* H */, 84 /* T */, 3 /* HT */],
|
|
|
[3 /* HT */, 116 /* t */, 4 /* HTT */],
|
|
|
[3 /* HT */, 84 /* T */, 4 /* HTT */],
|
|
|
[4 /* HTT */, 112 /* p */, 5 /* HTTP */],
|
|
|
[4 /* HTT */, 80 /* P */, 5 /* HTTP */],
|
|
|
[5 /* HTTP */, 115 /* s */, 9 /* BeforeColon */],
|
|
|
[5 /* HTTP */, 83 /* S */, 9 /* BeforeColon */],
|
|
|
[5 /* HTTP */, 58 /* Colon */, 10 /* AfterColon */],
|
|
|
[6 /* F */, 105 /* i */, 7 /* FI */],
|
|
|
[6 /* F */, 73 /* I */, 7 /* FI */],
|
|
|
[7 /* FI */, 108 /* l */, 8 /* FIL */],
|
|
|
[7 /* FI */, 76 /* L */, 8 /* FIL */],
|
|
|
[8 /* FIL */, 101 /* e */, 9 /* BeforeColon */],
|
|
|
[8 /* FIL */, 69 /* E */, 9 /* BeforeColon */],
|
|
|
[9 /* BeforeColon */, 58 /* Colon */, 10 /* AfterColon */],
|
|
|
[10 /* AfterColon */, 47 /* Slash */, 11 /* AlmostThere */],
|
|
|
[11 /* AlmostThere */, 47 /* Slash */, 12 /* End */],
|
|
|
]);
|
|
|
}
|
|
|
return _stateMachine;
|
|
|
}
|
|
|
let _classifier = null;
|
|
|
function getClassifier() {
|
|
|
if (_classifier === null) {
|
|
|
_classifier = new CharacterClassifier(0 /* None */);
|
|
|
const FORCE_TERMINATION_CHARACTERS = ' \t<>\'\"、。。、,.:;‘〈「『〔([{「」}])〕』」〉’`~…';
|
|
|
for (let i = 0; i < FORCE_TERMINATION_CHARACTERS.length; i++) {
|
|
|
_classifier.set(FORCE_TERMINATION_CHARACTERS.charCodeAt(i), 1 /* ForceTermination */);
|
|
|
}
|
|
|
const CANNOT_END_WITH_CHARACTERS = '.,;';
|
|
|
for (let i = 0; i < CANNOT_END_WITH_CHARACTERS.length; i++) {
|
|
|
_classifier.set(CANNOT_END_WITH_CHARACTERS.charCodeAt(i), 2 /* CannotEndIn */);
|
|
|
}
|
|
|
}
|
|
|
return _classifier;
|
|
|
}
|
|
|
class LinkComputer {
|
|
|
static _createLink(classifier, line, lineNumber, linkBeginIndex, linkEndIndex) {
|
|
|
// Do not allow to end link in certain characters...
|
|
|
let lastIncludedCharIndex = linkEndIndex - 1;
|
|
|
do {
|
|
|
const chCode = line.charCodeAt(lastIncludedCharIndex);
|
|
|
const chClass = classifier.get(chCode);
|
|
|
if (chClass !== 2 /* CannotEndIn */) {
|
|
|
break;
|
|
|
}
|
|
|
lastIncludedCharIndex--;
|
|
|
} while (lastIncludedCharIndex > linkBeginIndex);
|
|
|
// Handle links enclosed in parens, square brackets and curlys.
|
|
|
if (linkBeginIndex > 0) {
|
|
|
const charCodeBeforeLink = line.charCodeAt(linkBeginIndex - 1);
|
|
|
const lastCharCodeInLink = line.charCodeAt(lastIncludedCharIndex);
|
|
|
if ((charCodeBeforeLink === 40 /* OpenParen */ && lastCharCodeInLink === 41 /* CloseParen */)
|
|
|
|| (charCodeBeforeLink === 91 /* OpenSquareBracket */ && lastCharCodeInLink === 93 /* CloseSquareBracket */)
|
|
|
|| (charCodeBeforeLink === 123 /* OpenCurlyBrace */ && lastCharCodeInLink === 125 /* CloseCurlyBrace */)) {
|
|
|
// Do not end in ) if ( is before the link start
|
|
|
// Do not end in ] if [ is before the link start
|
|
|
// Do not end in } if { is before the link start
|
|
|
lastIncludedCharIndex--;
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
range: {
|
|
|
startLineNumber: lineNumber,
|
|
|
startColumn: linkBeginIndex + 1,
|
|
|
endLineNumber: lineNumber,
|
|
|
endColumn: lastIncludedCharIndex + 2
|
|
|
},
|
|
|
url: line.substring(linkBeginIndex, lastIncludedCharIndex + 1)
|
|
|
};
|
|
|
}
|
|
|
static computeLinks(model, stateMachine = getStateMachine()) {
|
|
|
const classifier = getClassifier();
|
|
|
let result = [];
|
|
|
for (let i = 1, lineCount = model.getLineCount(); i <= lineCount; i++) {
|
|
|
const line = model.getLineContent(i);
|
|
|
const len = line.length;
|
|
|
let j = 0;
|
|
|
let linkBeginIndex = 0;
|
|
|
let linkBeginChCode = 0;
|
|
|
let state = 1 /* Start */;
|
|
|
let hasOpenParens = false;
|
|
|
let hasOpenSquareBracket = false;
|
|
|
let inSquareBrackets = false;
|
|
|
let hasOpenCurlyBracket = false;
|
|
|
while (j < len) {
|
|
|
let resetStateMachine = false;
|
|
|
const chCode = line.charCodeAt(j);
|
|
|
if (state === 13 /* Accept */) {
|
|
|
let chClass;
|
|
|
switch (chCode) {
|
|
|
case 40 /* OpenParen */:
|
|
|
hasOpenParens = true;
|
|
|
chClass = 0 /* None */;
|
|
|
break;
|
|
|
case 41 /* CloseParen */:
|
|
|
chClass = (hasOpenParens ? 0 /* None */ : 1 /* ForceTermination */);
|
|
|
break;
|
|
|
case 91 /* OpenSquareBracket */:
|
|
|
inSquareBrackets = true;
|
|
|
hasOpenSquareBracket = true;
|
|
|
chClass = 0 /* None */;
|
|
|
break;
|
|
|
case 93 /* CloseSquareBracket */:
|
|
|
inSquareBrackets = false;
|
|
|
chClass = (hasOpenSquareBracket ? 0 /* None */ : 1 /* ForceTermination */);
|
|
|
break;
|
|
|
case 123 /* OpenCurlyBrace */:
|
|
|
hasOpenCurlyBracket = true;
|
|
|
chClass = 0 /* None */;
|
|
|
break;
|
|
|
case 125 /* CloseCurlyBrace */:
|
|
|
chClass = (hasOpenCurlyBracket ? 0 /* None */ : 1 /* ForceTermination */);
|
|
|
break;
|
|
|
/* The following three rules make it that ' or " or ` are allowed inside links if the link began with a different one */
|
|
|
case 39 /* SingleQuote */:
|
|
|
chClass = (linkBeginChCode === 34 /* DoubleQuote */ || linkBeginChCode === 96 /* BackTick */) ? 0 /* None */ : 1 /* ForceTermination */;
|
|
|
break;
|
|
|
case 34 /* DoubleQuote */:
|
|
|
chClass = (linkBeginChCode === 39 /* SingleQuote */ || linkBeginChCode === 96 /* BackTick */) ? 0 /* None */ : 1 /* ForceTermination */;
|
|
|
break;
|
|
|
case 96 /* BackTick */:
|
|
|
chClass = (linkBeginChCode === 39 /* SingleQuote */ || linkBeginChCode === 34 /* DoubleQuote */) ? 0 /* None */ : 1 /* ForceTermination */;
|
|
|
break;
|
|
|
case 42 /* Asterisk */:
|
|
|
// `*` terminates a link if the link began with `*`
|
|
|
chClass = (linkBeginChCode === 42 /* Asterisk */) ? 1 /* ForceTermination */ : 0 /* None */;
|
|
|
break;
|
|
|
case 124 /* Pipe */:
|
|
|
// `|` terminates a link if the link began with `|`
|
|
|
chClass = (linkBeginChCode === 124 /* Pipe */) ? 1 /* ForceTermination */ : 0 /* None */;
|
|
|
break;
|
|
|
case 32 /* Space */:
|
|
|
// ` ` allow space in between [ and ]
|
|
|
chClass = (inSquareBrackets ? 0 /* None */ : 1 /* ForceTermination */);
|
|
|
break;
|
|
|
default:
|
|
|
chClass = classifier.get(chCode);
|
|
|
}
|
|
|
// Check if character terminates link
|
|
|
if (chClass === 1 /* ForceTermination */) {
|
|
|
result.push(LinkComputer._createLink(classifier, line, i, linkBeginIndex, j));
|
|
|
resetStateMachine = true;
|
|
|
}
|
|
|
}
|
|
|
else if (state === 12 /* End */) {
|
|
|
let chClass;
|
|
|
if (chCode === 91 /* OpenSquareBracket */) {
|
|
|
// Allow for the authority part to contain ipv6 addresses which contain [ and ]
|
|
|
hasOpenSquareBracket = true;
|
|
|
chClass = 0 /* None */;
|
|
|
}
|
|
|
else {
|
|
|
chClass = classifier.get(chCode);
|
|
|
}
|
|
|
// Check if character terminates link
|
|
|
if (chClass === 1 /* ForceTermination */) {
|
|
|
resetStateMachine = true;
|
|
|
}
|
|
|
else {
|
|
|
state = 13 /* Accept */;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
state = stateMachine.nextState(state, chCode);
|
|
|
if (state === 0 /* Invalid */) {
|
|
|
resetStateMachine = true;
|
|
|
}
|
|
|
}
|
|
|
if (resetStateMachine) {
|
|
|
state = 1 /* Start */;
|
|
|
hasOpenParens = false;
|
|
|
hasOpenSquareBracket = false;
|
|
|
hasOpenCurlyBracket = false;
|
|
|
// Record where the link started
|
|
|
linkBeginIndex = j + 1;
|
|
|
linkBeginChCode = chCode;
|
|
|
}
|
|
|
j++;
|
|
|
}
|
|
|
if (state === 13 /* Accept */) {
|
|
|
result.push(LinkComputer._createLink(classifier, line, i, linkBeginIndex, len));
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Returns an array of all links contains in the provided
|
|
|
* document. *Note* that this operation is computational
|
|
|
* expensive and should not run in the UI thread.
|
|
|
*/
|
|
|
function computeLinks(model) {
|
|
|
if (!model || typeof model.getLineCount !== 'function' || typeof model.getLineContent !== 'function') {
|
|
|
// Unknown caller!
|
|
|
return [];
|
|
|
}
|
|
|
return LinkComputer.computeLinks(model);
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/modes/supports/inplaceReplaceSupport.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
class BasicInplaceReplace {
|
|
|
constructor() {
|
|
|
this._defaultValueSet = [
|
|
|
['true', 'false'],
|
|
|
['True', 'False'],
|
|
|
['Private', 'Public', 'Friend', 'ReadOnly', 'Partial', 'Protected', 'WriteOnly'],
|
|
|
['public', 'protected', 'private'],
|
|
|
];
|
|
|
}
|
|
|
navigateValueSet(range1, text1, range2, text2, up) {
|
|
|
if (range1 && text1) {
|
|
|
let result = this.doNavigateValueSet(text1, up);
|
|
|
if (result) {
|
|
|
return {
|
|
|
range: range1,
|
|
|
value: result
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
if (range2 && text2) {
|
|
|
let result = this.doNavigateValueSet(text2, up);
|
|
|
if (result) {
|
|
|
return {
|
|
|
range: range2,
|
|
|
value: result
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
doNavigateValueSet(text, up) {
|
|
|
let numberResult = this.numberReplace(text, up);
|
|
|
if (numberResult !== null) {
|
|
|
return numberResult;
|
|
|
}
|
|
|
return this.textReplace(text, up);
|
|
|
}
|
|
|
numberReplace(value, up) {
|
|
|
let precision = Math.pow(10, value.length - (value.lastIndexOf('.') + 1));
|
|
|
let n1 = Number(value);
|
|
|
let n2 = parseFloat(value);
|
|
|
if (!isNaN(n1) && !isNaN(n2) && n1 === n2) {
|
|
|
if (n1 === 0 && !up) {
|
|
|
return null; // don't do negative
|
|
|
// } else if(n1 === 9 && up) {
|
|
|
// return null; // don't insert 10 into a number
|
|
|
}
|
|
|
else {
|
|
|
n1 = Math.floor(n1 * precision);
|
|
|
n1 += up ? precision : -precision;
|
|
|
return String(n1 / precision);
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
textReplace(value, up) {
|
|
|
return this.valueSetsReplace(this._defaultValueSet, value, up);
|
|
|
}
|
|
|
valueSetsReplace(valueSets, value, up) {
|
|
|
let result = null;
|
|
|
for (let i = 0, len = valueSets.length; result === null && i < len; i++) {
|
|
|
result = this.valueSetReplace(valueSets[i], value, up);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
valueSetReplace(valueSet, value, up) {
|
|
|
let idx = valueSet.indexOf(value);
|
|
|
if (idx >= 0) {
|
|
|
idx += up ? +1 : -1;
|
|
|
if (idx < 0) {
|
|
|
idx = valueSet.length - 1;
|
|
|
}
|
|
|
else {
|
|
|
idx %= valueSet.length;
|
|
|
}
|
|
|
return valueSet[idx];
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
BasicInplaceReplace.INSTANCE = new BasicInplaceReplace();
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/cancellation.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
const shortcutEvent = Object.freeze(function (callback, context) {
|
|
|
const handle = setTimeout(callback.bind(context), 0);
|
|
|
return { dispose() { clearTimeout(handle); } };
|
|
|
});
|
|
|
var CancellationToken;
|
|
|
(function (CancellationToken) {
|
|
|
function isCancellationToken(thing) {
|
|
|
if (thing === CancellationToken.None || thing === CancellationToken.Cancelled) {
|
|
|
return true;
|
|
|
}
|
|
|
if (thing instanceof MutableToken) {
|
|
|
return true;
|
|
|
}
|
|
|
if (!thing || typeof thing !== 'object') {
|
|
|
return false;
|
|
|
}
|
|
|
return typeof thing.isCancellationRequested === 'boolean'
|
|
|
&& typeof thing.onCancellationRequested === 'function';
|
|
|
}
|
|
|
CancellationToken.isCancellationToken = isCancellationToken;
|
|
|
CancellationToken.None = Object.freeze({
|
|
|
isCancellationRequested: false,
|
|
|
onCancellationRequested: Event.None
|
|
|
});
|
|
|
CancellationToken.Cancelled = Object.freeze({
|
|
|
isCancellationRequested: true,
|
|
|
onCancellationRequested: shortcutEvent
|
|
|
});
|
|
|
})(CancellationToken || (CancellationToken = {}));
|
|
|
class MutableToken {
|
|
|
constructor() {
|
|
|
this._isCancelled = false;
|
|
|
this._emitter = null;
|
|
|
}
|
|
|
cancel() {
|
|
|
if (!this._isCancelled) {
|
|
|
this._isCancelled = true;
|
|
|
if (this._emitter) {
|
|
|
this._emitter.fire(undefined);
|
|
|
this.dispose();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
get isCancellationRequested() {
|
|
|
return this._isCancelled;
|
|
|
}
|
|
|
get onCancellationRequested() {
|
|
|
if (this._isCancelled) {
|
|
|
return shortcutEvent;
|
|
|
}
|
|
|
if (!this._emitter) {
|
|
|
this._emitter = new Emitter();
|
|
|
}
|
|
|
return this._emitter.event;
|
|
|
}
|
|
|
dispose() {
|
|
|
if (this._emitter) {
|
|
|
this._emitter.dispose();
|
|
|
this._emitter = null;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
class CancellationTokenSource {
|
|
|
constructor(parent) {
|
|
|
this._token = undefined;
|
|
|
this._parentListener = undefined;
|
|
|
this._parentListener = parent && parent.onCancellationRequested(this.cancel, this);
|
|
|
}
|
|
|
get token() {
|
|
|
if (!this._token) {
|
|
|
// be lazy and create the token only when
|
|
|
// actually needed
|
|
|
this._token = new MutableToken();
|
|
|
}
|
|
|
return this._token;
|
|
|
}
|
|
|
cancel() {
|
|
|
if (!this._token) {
|
|
|
// save an object by returning the default
|
|
|
// cancelled token when cancellation happens
|
|
|
// before someone asks for the token
|
|
|
this._token = CancellationToken.Cancelled;
|
|
|
}
|
|
|
else if (this._token instanceof MutableToken) {
|
|
|
// actually cancel
|
|
|
this._token.cancel();
|
|
|
}
|
|
|
}
|
|
|
dispose(cancel = false) {
|
|
|
if (cancel) {
|
|
|
this.cancel();
|
|
|
}
|
|
|
if (this._parentListener) {
|
|
|
this._parentListener.dispose();
|
|
|
}
|
|
|
if (!this._token) {
|
|
|
// ensure to initialize with an empty token if we had none
|
|
|
this._token = CancellationToken.None;
|
|
|
}
|
|
|
else if (this._token instanceof MutableToken) {
|
|
|
// actually dispose
|
|
|
this._token.dispose();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/base/common/keyCodes.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
class KeyCodeStrMap {
|
|
|
constructor() {
|
|
|
this._keyCodeToStr = [];
|
|
|
this._strToKeyCode = Object.create(null);
|
|
|
}
|
|
|
define(keyCode, str) {
|
|
|
this._keyCodeToStr[keyCode] = str;
|
|
|
this._strToKeyCode[str.toLowerCase()] = keyCode;
|
|
|
}
|
|
|
keyCodeToStr(keyCode) {
|
|
|
return this._keyCodeToStr[keyCode];
|
|
|
}
|
|
|
strToKeyCode(str) {
|
|
|
return this._strToKeyCode[str.toLowerCase()] || 0 /* Unknown */;
|
|
|
}
|
|
|
}
|
|
|
const uiMap = new KeyCodeStrMap();
|
|
|
const userSettingsUSMap = new KeyCodeStrMap();
|
|
|
const userSettingsGeneralMap = new KeyCodeStrMap();
|
|
|
const EVENT_KEY_CODE_MAP = new Array(230);
|
|
|
const NATIVE_WINDOWS_KEY_CODE_TO_KEY_CODE = {};
|
|
|
const scanCodeIntToStr = [];
|
|
|
const scanCodeStrToInt = Object.create(null);
|
|
|
const scanCodeLowerCaseStrToInt = Object.create(null);
|
|
|
/**
|
|
|
* -1 if a ScanCode => KeyCode mapping depends on kb layout.
|
|
|
*/
|
|
|
const IMMUTABLE_CODE_TO_KEY_CODE = [];
|
|
|
/**
|
|
|
* -1 if a KeyCode => ScanCode mapping depends on kb layout.
|
|
|
*/
|
|
|
const IMMUTABLE_KEY_CODE_TO_CODE = [];
|
|
|
for (let i = 0; i <= 193 /* MAX_VALUE */; i++) {
|
|
|
IMMUTABLE_CODE_TO_KEY_CODE[i] = -1 /* DependsOnKbLayout */;
|
|
|
}
|
|
|
for (let i = 0; i <= 126 /* MAX_VALUE */; i++) {
|
|
|
IMMUTABLE_KEY_CODE_TO_CODE[i] = -1 /* DependsOnKbLayout */;
|
|
|
}
|
|
|
(function () {
|
|
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
|
|
|
// See https://github.com/microsoft/node-native-keymap/blob/master/deps/chromium/keyboard_codes_win.h
|
|
|
const empty = '';
|
|
|
const mappings = [
|
|
|
// keyCodeOrd, immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel
|
|
|
[0, 1, 0 /* None */, 'None', 0 /* Unknown */, 'unknown', 0, 'VK_UNKNOWN', empty, empty],
|
|
|
[0, 1, 1 /* Hyper */, 'Hyper', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 2 /* Super */, 'Super', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 3 /* Fn */, 'Fn', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 4 /* FnLock */, 'FnLock', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 5 /* Suspend */, 'Suspend', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 6 /* Resume */, 'Resume', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 7 /* Turbo */, 'Turbo', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 8 /* Sleep */, 'Sleep', 0 /* Unknown */, empty, 0, 'VK_SLEEP', empty, empty],
|
|
|
[0, 1, 9 /* WakeUp */, 'WakeUp', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[31, 0, 10 /* KeyA */, 'KeyA', 31 /* KeyA */, 'A', 65, 'VK_A', empty, empty],
|
|
|
[32, 0, 11 /* KeyB */, 'KeyB', 32 /* KeyB */, 'B', 66, 'VK_B', empty, empty],
|
|
|
[33, 0, 12 /* KeyC */, 'KeyC', 33 /* KeyC */, 'C', 67, 'VK_C', empty, empty],
|
|
|
[34, 0, 13 /* KeyD */, 'KeyD', 34 /* KeyD */, 'D', 68, 'VK_D', empty, empty],
|
|
|
[35, 0, 14 /* KeyE */, 'KeyE', 35 /* KeyE */, 'E', 69, 'VK_E', empty, empty],
|
|
|
[36, 0, 15 /* KeyF */, 'KeyF', 36 /* KeyF */, 'F', 70, 'VK_F', empty, empty],
|
|
|
[37, 0, 16 /* KeyG */, 'KeyG', 37 /* KeyG */, 'G', 71, 'VK_G', empty, empty],
|
|
|
[38, 0, 17 /* KeyH */, 'KeyH', 38 /* KeyH */, 'H', 72, 'VK_H', empty, empty],
|
|
|
[39, 0, 18 /* KeyI */, 'KeyI', 39 /* KeyI */, 'I', 73, 'VK_I', empty, empty],
|
|
|
[40, 0, 19 /* KeyJ */, 'KeyJ', 40 /* KeyJ */, 'J', 74, 'VK_J', empty, empty],
|
|
|
[41, 0, 20 /* KeyK */, 'KeyK', 41 /* KeyK */, 'K', 75, 'VK_K', empty, empty],
|
|
|
[42, 0, 21 /* KeyL */, 'KeyL', 42 /* KeyL */, 'L', 76, 'VK_L', empty, empty],
|
|
|
[43, 0, 22 /* KeyM */, 'KeyM', 43 /* KeyM */, 'M', 77, 'VK_M', empty, empty],
|
|
|
[44, 0, 23 /* KeyN */, 'KeyN', 44 /* KeyN */, 'N', 78, 'VK_N', empty, empty],
|
|
|
[45, 0, 24 /* KeyO */, 'KeyO', 45 /* KeyO */, 'O', 79, 'VK_O', empty, empty],
|
|
|
[46, 0, 25 /* KeyP */, 'KeyP', 46 /* KeyP */, 'P', 80, 'VK_P', empty, empty],
|
|
|
[47, 0, 26 /* KeyQ */, 'KeyQ', 47 /* KeyQ */, 'Q', 81, 'VK_Q', empty, empty],
|
|
|
[48, 0, 27 /* KeyR */, 'KeyR', 48 /* KeyR */, 'R', 82, 'VK_R', empty, empty],
|
|
|
[49, 0, 28 /* KeyS */, 'KeyS', 49 /* KeyS */, 'S', 83, 'VK_S', empty, empty],
|
|
|
[50, 0, 29 /* KeyT */, 'KeyT', 50 /* KeyT */, 'T', 84, 'VK_T', empty, empty],
|
|
|
[51, 0, 30 /* KeyU */, 'KeyU', 51 /* KeyU */, 'U', 85, 'VK_U', empty, empty],
|
|
|
[52, 0, 31 /* KeyV */, 'KeyV', 52 /* KeyV */, 'V', 86, 'VK_V', empty, empty],
|
|
|
[53, 0, 32 /* KeyW */, 'KeyW', 53 /* KeyW */, 'W', 87, 'VK_W', empty, empty],
|
|
|
[54, 0, 33 /* KeyX */, 'KeyX', 54 /* KeyX */, 'X', 88, 'VK_X', empty, empty],
|
|
|
[55, 0, 34 /* KeyY */, 'KeyY', 55 /* KeyY */, 'Y', 89, 'VK_Y', empty, empty],
|
|
|
[56, 0, 35 /* KeyZ */, 'KeyZ', 56 /* KeyZ */, 'Z', 90, 'VK_Z', empty, empty],
|
|
|
[22, 0, 36 /* Digit1 */, 'Digit1', 22 /* Digit1 */, '1', 49, 'VK_1', empty, empty],
|
|
|
[23, 0, 37 /* Digit2 */, 'Digit2', 23 /* Digit2 */, '2', 50, 'VK_2', empty, empty],
|
|
|
[24, 0, 38 /* Digit3 */, 'Digit3', 24 /* Digit3 */, '3', 51, 'VK_3', empty, empty],
|
|
|
[25, 0, 39 /* Digit4 */, 'Digit4', 25 /* Digit4 */, '4', 52, 'VK_4', empty, empty],
|
|
|
[26, 0, 40 /* Digit5 */, 'Digit5', 26 /* Digit5 */, '5', 53, 'VK_5', empty, empty],
|
|
|
[27, 0, 41 /* Digit6 */, 'Digit6', 27 /* Digit6 */, '6', 54, 'VK_6', empty, empty],
|
|
|
[28, 0, 42 /* Digit7 */, 'Digit7', 28 /* Digit7 */, '7', 55, 'VK_7', empty, empty],
|
|
|
[29, 0, 43 /* Digit8 */, 'Digit8', 29 /* Digit8 */, '8', 56, 'VK_8', empty, empty],
|
|
|
[30, 0, 44 /* Digit9 */, 'Digit9', 30 /* Digit9 */, '9', 57, 'VK_9', empty, empty],
|
|
|
[21, 0, 45 /* Digit0 */, 'Digit0', 21 /* Digit0 */, '0', 48, 'VK_0', empty, empty],
|
|
|
[3, 1, 46 /* Enter */, 'Enter', 3 /* Enter */, 'Enter', 13, 'VK_RETURN', empty, empty],
|
|
|
[9, 1, 47 /* Escape */, 'Escape', 9 /* Escape */, 'Escape', 27, 'VK_ESCAPE', empty, empty],
|
|
|
[1, 1, 48 /* Backspace */, 'Backspace', 1 /* Backspace */, 'Backspace', 8, 'VK_BACK', empty, empty],
|
|
|
[2, 1, 49 /* Tab */, 'Tab', 2 /* Tab */, 'Tab', 9, 'VK_TAB', empty, empty],
|
|
|
[10, 1, 50 /* Space */, 'Space', 10 /* Space */, 'Space', 32, 'VK_SPACE', empty, empty],
|
|
|
[83, 0, 51 /* Minus */, 'Minus', 83 /* Minus */, '-', 189, 'VK_OEM_MINUS', '-', 'OEM_MINUS'],
|
|
|
[81, 0, 52 /* Equal */, 'Equal', 81 /* Equal */, '=', 187, 'VK_OEM_PLUS', '=', 'OEM_PLUS'],
|
|
|
[87, 0, 53 /* BracketLeft */, 'BracketLeft', 87 /* BracketLeft */, '[', 219, 'VK_OEM_4', '[', 'OEM_4'],
|
|
|
[89, 0, 54 /* BracketRight */, 'BracketRight', 89 /* BracketRight */, ']', 221, 'VK_OEM_6', ']', 'OEM_6'],
|
|
|
[88, 0, 55 /* Backslash */, 'Backslash', 88 /* Backslash */, '\\', 220, 'VK_OEM_5', '\\', 'OEM_5'],
|
|
|
[0, 0, 56 /* IntlHash */, 'IntlHash', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[80, 0, 57 /* Semicolon */, 'Semicolon', 80 /* Semicolon */, ';', 186, 'VK_OEM_1', ';', 'OEM_1'],
|
|
|
[90, 0, 58 /* Quote */, 'Quote', 90 /* Quote */, '\'', 222, 'VK_OEM_7', '\'', 'OEM_7'],
|
|
|
[86, 0, 59 /* Backquote */, 'Backquote', 86 /* Backquote */, '`', 192, 'VK_OEM_3', '`', 'OEM_3'],
|
|
|
[82, 0, 60 /* Comma */, 'Comma', 82 /* Comma */, ',', 188, 'VK_OEM_COMMA', ',', 'OEM_COMMA'],
|
|
|
[84, 0, 61 /* Period */, 'Period', 84 /* Period */, '.', 190, 'VK_OEM_PERIOD', '.', 'OEM_PERIOD'],
|
|
|
[85, 0, 62 /* Slash */, 'Slash', 85 /* Slash */, '/', 191, 'VK_OEM_2', '/', 'OEM_2'],
|
|
|
[8, 1, 63 /* CapsLock */, 'CapsLock', 8 /* CapsLock */, 'CapsLock', 20, 'VK_CAPITAL', empty, empty],
|
|
|
[59, 1, 64 /* F1 */, 'F1', 59 /* F1 */, 'F1', 112, 'VK_F1', empty, empty],
|
|
|
[60, 1, 65 /* F2 */, 'F2', 60 /* F2 */, 'F2', 113, 'VK_F2', empty, empty],
|
|
|
[61, 1, 66 /* F3 */, 'F3', 61 /* F3 */, 'F3', 114, 'VK_F3', empty, empty],
|
|
|
[62, 1, 67 /* F4 */, 'F4', 62 /* F4 */, 'F4', 115, 'VK_F4', empty, empty],
|
|
|
[63, 1, 68 /* F5 */, 'F5', 63 /* F5 */, 'F5', 116, 'VK_F5', empty, empty],
|
|
|
[64, 1, 69 /* F6 */, 'F6', 64 /* F6 */, 'F6', 117, 'VK_F6', empty, empty],
|
|
|
[65, 1, 70 /* F7 */, 'F7', 65 /* F7 */, 'F7', 118, 'VK_F7', empty, empty],
|
|
|
[66, 1, 71 /* F8 */, 'F8', 66 /* F8 */, 'F8', 119, 'VK_F8', empty, empty],
|
|
|
[67, 1, 72 /* F9 */, 'F9', 67 /* F9 */, 'F9', 120, 'VK_F9', empty, empty],
|
|
|
[68, 1, 73 /* F10 */, 'F10', 68 /* F10 */, 'F10', 121, 'VK_F10', empty, empty],
|
|
|
[69, 1, 74 /* F11 */, 'F11', 69 /* F11 */, 'F11', 122, 'VK_F11', empty, empty],
|
|
|
[70, 1, 75 /* F12 */, 'F12', 70 /* F12 */, 'F12', 123, 'VK_F12', empty, empty],
|
|
|
[0, 1, 76 /* PrintScreen */, 'PrintScreen', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[79, 1, 77 /* ScrollLock */, 'ScrollLock', 79 /* ScrollLock */, 'ScrollLock', 145, 'VK_SCROLL', empty, empty],
|
|
|
[7, 1, 78 /* Pause */, 'Pause', 7 /* PauseBreak */, 'PauseBreak', 19, 'VK_PAUSE', empty, empty],
|
|
|
[19, 1, 79 /* Insert */, 'Insert', 19 /* Insert */, 'Insert', 45, 'VK_INSERT', empty, empty],
|
|
|
[14, 1, 80 /* Home */, 'Home', 14 /* Home */, 'Home', 36, 'VK_HOME', empty, empty],
|
|
|
[11, 1, 81 /* PageUp */, 'PageUp', 11 /* PageUp */, 'PageUp', 33, 'VK_PRIOR', empty, empty],
|
|
|
[20, 1, 82 /* Delete */, 'Delete', 20 /* Delete */, 'Delete', 46, 'VK_DELETE', empty, empty],
|
|
|
[13, 1, 83 /* End */, 'End', 13 /* End */, 'End', 35, 'VK_END', empty, empty],
|
|
|
[12, 1, 84 /* PageDown */, 'PageDown', 12 /* PageDown */, 'PageDown', 34, 'VK_NEXT', empty, empty],
|
|
|
[17, 1, 85 /* ArrowRight */, 'ArrowRight', 17 /* RightArrow */, 'RightArrow', 39, 'VK_RIGHT', 'Right', empty],
|
|
|
[15, 1, 86 /* ArrowLeft */, 'ArrowLeft', 15 /* LeftArrow */, 'LeftArrow', 37, 'VK_LEFT', 'Left', empty],
|
|
|
[18, 1, 87 /* ArrowDown */, 'ArrowDown', 18 /* DownArrow */, 'DownArrow', 40, 'VK_DOWN', 'Down', empty],
|
|
|
[16, 1, 88 /* ArrowUp */, 'ArrowUp', 16 /* UpArrow */, 'UpArrow', 38, 'VK_UP', 'Up', empty],
|
|
|
[78, 1, 89 /* NumLock */, 'NumLock', 78 /* NumLock */, 'NumLock', 144, 'VK_NUMLOCK', empty, empty],
|
|
|
[108, 1, 90 /* NumpadDivide */, 'NumpadDivide', 108 /* NumpadDivide */, 'NumPad_Divide', 111, 'VK_DIVIDE', empty, empty],
|
|
|
[103, 1, 91 /* NumpadMultiply */, 'NumpadMultiply', 103 /* NumpadMultiply */, 'NumPad_Multiply', 106, 'VK_MULTIPLY', empty, empty],
|
|
|
[106, 1, 92 /* NumpadSubtract */, 'NumpadSubtract', 106 /* NumpadSubtract */, 'NumPad_Subtract', 109, 'VK_SUBTRACT', empty, empty],
|
|
|
[104, 1, 93 /* NumpadAdd */, 'NumpadAdd', 104 /* NumpadAdd */, 'NumPad_Add', 107, 'VK_ADD', empty, empty],
|
|
|
[3, 1, 94 /* NumpadEnter */, 'NumpadEnter', 3 /* Enter */, empty, 0, empty, empty, empty],
|
|
|
[94, 1, 95 /* Numpad1 */, 'Numpad1', 94 /* Numpad1 */, 'NumPad1', 97, 'VK_NUMPAD1', empty, empty],
|
|
|
[95, 1, 96 /* Numpad2 */, 'Numpad2', 95 /* Numpad2 */, 'NumPad2', 98, 'VK_NUMPAD2', empty, empty],
|
|
|
[96, 1, 97 /* Numpad3 */, 'Numpad3', 96 /* Numpad3 */, 'NumPad3', 99, 'VK_NUMPAD3', empty, empty],
|
|
|
[97, 1, 98 /* Numpad4 */, 'Numpad4', 97 /* Numpad4 */, 'NumPad4', 100, 'VK_NUMPAD4', empty, empty],
|
|
|
[98, 1, 99 /* Numpad5 */, 'Numpad5', 98 /* Numpad5 */, 'NumPad5', 101, 'VK_NUMPAD5', empty, empty],
|
|
|
[99, 1, 100 /* Numpad6 */, 'Numpad6', 99 /* Numpad6 */, 'NumPad6', 102, 'VK_NUMPAD6', empty, empty],
|
|
|
[100, 1, 101 /* Numpad7 */, 'Numpad7', 100 /* Numpad7 */, 'NumPad7', 103, 'VK_NUMPAD7', empty, empty],
|
|
|
[101, 1, 102 /* Numpad8 */, 'Numpad8', 101 /* Numpad8 */, 'NumPad8', 104, 'VK_NUMPAD8', empty, empty],
|
|
|
[102, 1, 103 /* Numpad9 */, 'Numpad9', 102 /* Numpad9 */, 'NumPad9', 105, 'VK_NUMPAD9', empty, empty],
|
|
|
[93, 1, 104 /* Numpad0 */, 'Numpad0', 93 /* Numpad0 */, 'NumPad0', 96, 'VK_NUMPAD0', empty, empty],
|
|
|
[107, 1, 105 /* NumpadDecimal */, 'NumpadDecimal', 107 /* NumpadDecimal */, 'NumPad_Decimal', 110, 'VK_DECIMAL', empty, empty],
|
|
|
[92, 0, 106 /* IntlBackslash */, 'IntlBackslash', 92 /* IntlBackslash */, 'OEM_102', 226, 'VK_OEM_102', empty, empty],
|
|
|
[58, 1, 107 /* ContextMenu */, 'ContextMenu', 58 /* ContextMenu */, 'ContextMenu', 93, empty, empty, empty],
|
|
|
[0, 1, 108 /* Power */, 'Power', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 109 /* NumpadEqual */, 'NumpadEqual', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[71, 1, 110 /* F13 */, 'F13', 71 /* F13 */, 'F13', 124, 'VK_F13', empty, empty],
|
|
|
[72, 1, 111 /* F14 */, 'F14', 72 /* F14 */, 'F14', 125, 'VK_F14', empty, empty],
|
|
|
[73, 1, 112 /* F15 */, 'F15', 73 /* F15 */, 'F15', 126, 'VK_F15', empty, empty],
|
|
|
[74, 1, 113 /* F16 */, 'F16', 74 /* F16 */, 'F16', 127, 'VK_F16', empty, empty],
|
|
|
[75, 1, 114 /* F17 */, 'F17', 75 /* F17 */, 'F17', 128, 'VK_F17', empty, empty],
|
|
|
[76, 1, 115 /* F18 */, 'F18', 76 /* F18 */, 'F18', 129, 'VK_F18', empty, empty],
|
|
|
[77, 1, 116 /* F19 */, 'F19', 77 /* F19 */, 'F19', 130, 'VK_F19', empty, empty],
|
|
|
[0, 1, 117 /* F20 */, 'F20', 0 /* Unknown */, empty, 0, 'VK_F20', empty, empty],
|
|
|
[0, 1, 118 /* F21 */, 'F21', 0 /* Unknown */, empty, 0, 'VK_F21', empty, empty],
|
|
|
[0, 1, 119 /* F22 */, 'F22', 0 /* Unknown */, empty, 0, 'VK_F22', empty, empty],
|
|
|
[0, 1, 120 /* F23 */, 'F23', 0 /* Unknown */, empty, 0, 'VK_F23', empty, empty],
|
|
|
[0, 1, 121 /* F24 */, 'F24', 0 /* Unknown */, empty, 0, 'VK_F24', empty, empty],
|
|
|
[0, 1, 122 /* Open */, 'Open', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 123 /* Help */, 'Help', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 124 /* Select */, 'Select', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 125 /* Again */, 'Again', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 126 /* Undo */, 'Undo', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 127 /* Cut */, 'Cut', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 128 /* Copy */, 'Copy', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 129 /* Paste */, 'Paste', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 130 /* Find */, 'Find', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 131 /* AudioVolumeMute */, 'AudioVolumeMute', 112 /* AudioVolumeMute */, 'AudioVolumeMute', 173, 'VK_VOLUME_MUTE', empty, empty],
|
|
|
[0, 1, 132 /* AudioVolumeUp */, 'AudioVolumeUp', 113 /* AudioVolumeUp */, 'AudioVolumeUp', 175, 'VK_VOLUME_UP', empty, empty],
|
|
|
[0, 1, 133 /* AudioVolumeDown */, 'AudioVolumeDown', 114 /* AudioVolumeDown */, 'AudioVolumeDown', 174, 'VK_VOLUME_DOWN', empty, empty],
|
|
|
[105, 1, 134 /* NumpadComma */, 'NumpadComma', 105 /* NUMPAD_SEPARATOR */, 'NumPad_Separator', 108, 'VK_SEPARATOR', empty, empty],
|
|
|
[110, 0, 135 /* IntlRo */, 'IntlRo', 110 /* ABNT_C1 */, 'ABNT_C1', 193, 'VK_ABNT_C1', empty, empty],
|
|
|
[0, 1, 136 /* KanaMode */, 'KanaMode', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 0, 137 /* IntlYen */, 'IntlYen', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 138 /* Convert */, 'Convert', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 139 /* NonConvert */, 'NonConvert', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 140 /* Lang1 */, 'Lang1', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 141 /* Lang2 */, 'Lang2', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 142 /* Lang3 */, 'Lang3', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 143 /* Lang4 */, 'Lang4', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 144 /* Lang5 */, 'Lang5', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 145 /* Abort */, 'Abort', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 146 /* Props */, 'Props', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 147 /* NumpadParenLeft */, 'NumpadParenLeft', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 148 /* NumpadParenRight */, 'NumpadParenRight', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 149 /* NumpadBackspace */, 'NumpadBackspace', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 150 /* NumpadMemoryStore */, 'NumpadMemoryStore', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 151 /* NumpadMemoryRecall */, 'NumpadMemoryRecall', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 152 /* NumpadMemoryClear */, 'NumpadMemoryClear', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 153 /* NumpadMemoryAdd */, 'NumpadMemoryAdd', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 154 /* NumpadMemorySubtract */, 'NumpadMemorySubtract', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 155 /* NumpadClear */, 'NumpadClear', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 156 /* NumpadClearEntry */, 'NumpadClearEntry', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[5, 1, 0 /* None */, empty, 5 /* Ctrl */, 'Ctrl', 17, 'VK_CONTROL', empty, empty],
|
|
|
[4, 1, 0 /* None */, empty, 4 /* Shift */, 'Shift', 16, 'VK_SHIFT', empty, empty],
|
|
|
[6, 1, 0 /* None */, empty, 6 /* Alt */, 'Alt', 18, 'VK_MENU', empty, empty],
|
|
|
[57, 1, 0 /* None */, empty, 57 /* Meta */, 'Meta', 0, 'VK_COMMAND', empty, empty],
|
|
|
[5, 1, 157 /* ControlLeft */, 'ControlLeft', 5 /* Ctrl */, empty, 0, 'VK_LCONTROL', empty, empty],
|
|
|
[4, 1, 158 /* ShiftLeft */, 'ShiftLeft', 4 /* Shift */, empty, 0, 'VK_LSHIFT', empty, empty],
|
|
|
[6, 1, 159 /* AltLeft */, 'AltLeft', 6 /* Alt */, empty, 0, 'VK_LMENU', empty, empty],
|
|
|
[57, 1, 160 /* MetaLeft */, 'MetaLeft', 57 /* Meta */, empty, 0, 'VK_LWIN', empty, empty],
|
|
|
[5, 1, 161 /* ControlRight */, 'ControlRight', 5 /* Ctrl */, empty, 0, 'VK_RCONTROL', empty, empty],
|
|
|
[4, 1, 162 /* ShiftRight */, 'ShiftRight', 4 /* Shift */, empty, 0, 'VK_RSHIFT', empty, empty],
|
|
|
[6, 1, 163 /* AltRight */, 'AltRight', 6 /* Alt */, empty, 0, 'VK_RMENU', empty, empty],
|
|
|
[57, 1, 164 /* MetaRight */, 'MetaRight', 57 /* Meta */, empty, 0, 'VK_RWIN', empty, empty],
|
|
|
[0, 1, 165 /* BrightnessUp */, 'BrightnessUp', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 166 /* BrightnessDown */, 'BrightnessDown', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 167 /* MediaPlay */, 'MediaPlay', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 168 /* MediaRecord */, 'MediaRecord', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 169 /* MediaFastForward */, 'MediaFastForward', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 170 /* MediaRewind */, 'MediaRewind', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[114, 1, 171 /* MediaTrackNext */, 'MediaTrackNext', 119 /* MediaTrackNext */, 'MediaTrackNext', 176, 'VK_MEDIA_NEXT_TRACK', empty, empty],
|
|
|
[115, 1, 172 /* MediaTrackPrevious */, 'MediaTrackPrevious', 120 /* MediaTrackPrevious */, 'MediaTrackPrevious', 177, 'VK_MEDIA_PREV_TRACK', empty, empty],
|
|
|
[116, 1, 173 /* MediaStop */, 'MediaStop', 121 /* MediaStop */, 'MediaStop', 178, 'VK_MEDIA_STOP', empty, empty],
|
|
|
[0, 1, 174 /* Eject */, 'Eject', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[117, 1, 175 /* MediaPlayPause */, 'MediaPlayPause', 122 /* MediaPlayPause */, 'MediaPlayPause', 179, 'VK_MEDIA_PLAY_PAUSE', empty, empty],
|
|
|
[0, 1, 176 /* MediaSelect */, 'MediaSelect', 123 /* LaunchMediaPlayer */, 'LaunchMediaPlayer', 181, 'VK_MEDIA_LAUNCH_MEDIA_SELECT', empty, empty],
|
|
|
[0, 1, 177 /* LaunchMail */, 'LaunchMail', 124 /* LaunchMail */, 'LaunchMail', 180, 'VK_MEDIA_LAUNCH_MAIL', empty, empty],
|
|
|
[0, 1, 178 /* LaunchApp2 */, 'LaunchApp2', 125 /* LaunchApp2 */, 'LaunchApp2', 183, 'VK_MEDIA_LAUNCH_APP2', empty, empty],
|
|
|
[0, 1, 179 /* LaunchApp1 */, 'LaunchApp1', 0 /* Unknown */, empty, 0, 'VK_MEDIA_LAUNCH_APP1', empty, empty],
|
|
|
[0, 1, 180 /* SelectTask */, 'SelectTask', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 181 /* LaunchScreenSaver */, 'LaunchScreenSaver', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 182 /* BrowserSearch */, 'BrowserSearch', 115 /* BrowserSearch */, 'BrowserSearch', 170, 'VK_BROWSER_SEARCH', empty, empty],
|
|
|
[0, 1, 183 /* BrowserHome */, 'BrowserHome', 116 /* BrowserHome */, 'BrowserHome', 172, 'VK_BROWSER_HOME', empty, empty],
|
|
|
[112, 1, 184 /* BrowserBack */, 'BrowserBack', 117 /* BrowserBack */, 'BrowserBack', 166, 'VK_BROWSER_BACK', empty, empty],
|
|
|
[113, 1, 185 /* BrowserForward */, 'BrowserForward', 118 /* BrowserForward */, 'BrowserForward', 167, 'VK_BROWSER_FORWARD', empty, empty],
|
|
|
[0, 1, 186 /* BrowserStop */, 'BrowserStop', 0 /* Unknown */, empty, 0, 'VK_BROWSER_STOP', empty, empty],
|
|
|
[0, 1, 187 /* BrowserRefresh */, 'BrowserRefresh', 0 /* Unknown */, empty, 0, 'VK_BROWSER_REFRESH', empty, empty],
|
|
|
[0, 1, 188 /* BrowserFavorites */, 'BrowserFavorites', 0 /* Unknown */, empty, 0, 'VK_BROWSER_FAVORITES', empty, empty],
|
|
|
[0, 1, 189 /* ZoomToggle */, 'ZoomToggle', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 190 /* MailReply */, 'MailReply', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 191 /* MailForward */, 'MailForward', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
[0, 1, 192 /* MailSend */, 'MailSend', 0 /* Unknown */, empty, 0, empty, empty, empty],
|
|
|
// See https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html
|
|
|
// If an Input Method Editor is processing key input and the event is keydown, return 229.
|
|
|
[109, 1, 0 /* None */, empty, 109 /* KEY_IN_COMPOSITION */, 'KeyInComposition', 229, empty, empty, empty],
|
|
|
[111, 1, 0 /* None */, empty, 111 /* ABNT_C2 */, 'ABNT_C2', 194, 'VK_ABNT_C2', empty, empty],
|
|
|
[91, 1, 0 /* None */, empty, 91 /* OEM_8 */, 'OEM_8', 223, 'VK_OEM_8', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_CLEAR', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_KANA', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_HANGUL', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_JUNJA', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_FINAL', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_HANJA', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_KANJI', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_CONVERT', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_NONCONVERT', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_ACCEPT', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_MODECHANGE', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_SELECT', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_PRINT', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_EXECUTE', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_SNAPSHOT', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_HELP', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_APPS', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_PROCESSKEY', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_PACKET', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_DBE_SBCSCHAR', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_DBE_DBCSCHAR', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_ATTN', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_CRSEL', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_EXSEL', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_EREOF', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_PLAY', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_ZOOM', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_NONAME', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_PA1', empty, empty],
|
|
|
[0, 1, 0 /* None */, empty, 0 /* Unknown */, empty, 0, 'VK_OEM_CLEAR', empty, empty],
|
|
|
];
|
|
|
let seenKeyCode = [];
|
|
|
let seenScanCode = [];
|
|
|
for (const mapping of mappings) {
|
|
|
const [_keyCodeOrd, immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel] = mapping;
|
|
|
if (!seenScanCode[scanCode]) {
|
|
|
seenScanCode[scanCode] = true;
|
|
|
scanCodeIntToStr[scanCode] = scanCodeStr;
|
|
|
scanCodeStrToInt[scanCodeStr] = scanCode;
|
|
|
scanCodeLowerCaseStrToInt[scanCodeStr.toLowerCase()] = scanCode;
|
|
|
if (immutable) {
|
|
|
IMMUTABLE_CODE_TO_KEY_CODE[scanCode] = keyCode;
|
|
|
if ((keyCode !== 0 /* Unknown */)
|
|
|
&& (keyCode !== 3 /* Enter */)
|
|
|
&& (keyCode !== 5 /* Ctrl */)
|
|
|
&& (keyCode !== 4 /* Shift */)
|
|
|
&& (keyCode !== 6 /* Alt */)
|
|
|
&& (keyCode !== 57 /* Meta */)) {
|
|
|
IMMUTABLE_KEY_CODE_TO_CODE[keyCode] = scanCode;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (!seenKeyCode[keyCode]) {
|
|
|
seenKeyCode[keyCode] = true;
|
|
|
if (!keyCodeStr) {
|
|
|
throw new Error(`String representation missing for key code ${keyCode} around scan code ${scanCodeStr}`);
|
|
|
}
|
|
|
uiMap.define(keyCode, keyCodeStr);
|
|
|
userSettingsUSMap.define(keyCode, usUserSettingsLabel || keyCodeStr);
|
|
|
userSettingsGeneralMap.define(keyCode, generalUserSettingsLabel || usUserSettingsLabel || keyCodeStr);
|
|
|
}
|
|
|
if (eventKeyCode) {
|
|
|
EVENT_KEY_CODE_MAP[eventKeyCode] = keyCode;
|
|
|
}
|
|
|
if (vkey) {
|
|
|
NATIVE_WINDOWS_KEY_CODE_TO_KEY_CODE[vkey] = keyCode;
|
|
|
}
|
|
|
}
|
|
|
// Manually added due to the exclusion above (due to duplication with NumpadEnter)
|
|
|
IMMUTABLE_KEY_CODE_TO_CODE[3 /* Enter */] = 46 /* Enter */;
|
|
|
})();
|
|
|
var KeyCodeUtils;
|
|
|
(function (KeyCodeUtils) {
|
|
|
function toString(keyCode) {
|
|
|
return uiMap.keyCodeToStr(keyCode);
|
|
|
}
|
|
|
KeyCodeUtils.toString = toString;
|
|
|
function fromString(key) {
|
|
|
return uiMap.strToKeyCode(key);
|
|
|
}
|
|
|
KeyCodeUtils.fromString = fromString;
|
|
|
function toUserSettingsUS(keyCode) {
|
|
|
return userSettingsUSMap.keyCodeToStr(keyCode);
|
|
|
}
|
|
|
KeyCodeUtils.toUserSettingsUS = toUserSettingsUS;
|
|
|
function toUserSettingsGeneral(keyCode) {
|
|
|
return userSettingsGeneralMap.keyCodeToStr(keyCode);
|
|
|
}
|
|
|
KeyCodeUtils.toUserSettingsGeneral = toUserSettingsGeneral;
|
|
|
function fromUserSettings(key) {
|
|
|
return userSettingsUSMap.strToKeyCode(key) || userSettingsGeneralMap.strToKeyCode(key);
|
|
|
}
|
|
|
KeyCodeUtils.fromUserSettings = fromUserSettings;
|
|
|
function toElectronAccelerator(keyCode) {
|
|
|
if (keyCode >= 93 /* Numpad0 */ && keyCode <= 108 /* NumpadDivide */) {
|
|
|
// [Electron Accelerators] Electron is able to parse numpad keys, but unfortunately it
|
|
|
// renders them just as regular keys in menus. For example, num0 is rendered as "0",
|
|
|
// numdiv is rendered as "/", numsub is rendered as "-".
|
|
|
//
|
|
|
// This can lead to incredible confusion, as it makes numpad based keybindings indistinguishable
|
|
|
// from keybindings based on regular keys.
|
|
|
//
|
|
|
// We therefore need to fall back to custom rendering for numpad keys.
|
|
|
return null;
|
|
|
}
|
|
|
switch (keyCode) {
|
|
|
case 16 /* UpArrow */:
|
|
|
return 'Up';
|
|
|
case 18 /* DownArrow */:
|
|
|
return 'Down';
|
|
|
case 15 /* LeftArrow */:
|
|
|
return 'Left';
|
|
|
case 17 /* RightArrow */:
|
|
|
return 'Right';
|
|
|
}
|
|
|
return uiMap.keyCodeToStr(keyCode);
|
|
|
}
|
|
|
KeyCodeUtils.toElectronAccelerator = toElectronAccelerator;
|
|
|
})(KeyCodeUtils || (KeyCodeUtils = {}));
|
|
|
function KeyChord(firstPart, secondPart) {
|
|
|
const chordPart = ((secondPart & 0x0000FFFF) << 16) >>> 0;
|
|
|
return (firstPart | chordPart) >>> 0;
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/core/selection.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
/**
|
|
|
* A selection in the editor.
|
|
|
* The selection is a range that has an orientation.
|
|
|
*/
|
|
|
class Selection extends Range {
|
|
|
constructor(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn) {
|
|
|
super(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn);
|
|
|
this.selectionStartLineNumber = selectionStartLineNumber;
|
|
|
this.selectionStartColumn = selectionStartColumn;
|
|
|
this.positionLineNumber = positionLineNumber;
|
|
|
this.positionColumn = positionColumn;
|
|
|
}
|
|
|
/**
|
|
|
* Transform to a human-readable representation.
|
|
|
*/
|
|
|
toString() {
|
|
|
return '[' + this.selectionStartLineNumber + ',' + this.selectionStartColumn + ' -> ' + this.positionLineNumber + ',' + this.positionColumn + ']';
|
|
|
}
|
|
|
/**
|
|
|
* Test if equals other selection.
|
|
|
*/
|
|
|
equalsSelection(other) {
|
|
|
return (Selection.selectionsEqual(this, other));
|
|
|
}
|
|
|
/**
|
|
|
* Test if the two selections are equal.
|
|
|
*/
|
|
|
static selectionsEqual(a, b) {
|
|
|
return (a.selectionStartLineNumber === b.selectionStartLineNumber &&
|
|
|
a.selectionStartColumn === b.selectionStartColumn &&
|
|
|
a.positionLineNumber === b.positionLineNumber &&
|
|
|
a.positionColumn === b.positionColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Get directions (LTR or RTL).
|
|
|
*/
|
|
|
getDirection() {
|
|
|
if (this.selectionStartLineNumber === this.startLineNumber && this.selectionStartColumn === this.startColumn) {
|
|
|
return 0 /* LTR */;
|
|
|
}
|
|
|
return 1 /* RTL */;
|
|
|
}
|
|
|
/**
|
|
|
* Create a new selection with a different `positionLineNumber` and `positionColumn`.
|
|
|
*/
|
|
|
setEndPosition(endLineNumber, endColumn) {
|
|
|
if (this.getDirection() === 0 /* LTR */) {
|
|
|
return new Selection(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
|
|
|
}
|
|
|
return new Selection(endLineNumber, endColumn, this.startLineNumber, this.startColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Get the position at `positionLineNumber` and `positionColumn`.
|
|
|
*/
|
|
|
getPosition() {
|
|
|
return new Position(this.positionLineNumber, this.positionColumn);
|
|
|
}
|
|
|
/**
|
|
|
* Create a new selection with a different `selectionStartLineNumber` and `selectionStartColumn`.
|
|
|
*/
|
|
|
setStartPosition(startLineNumber, startColumn) {
|
|
|
if (this.getDirection() === 0 /* LTR */) {
|
|
|
return new Selection(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
|
|
|
}
|
|
|
return new Selection(this.endLineNumber, this.endColumn, startLineNumber, startColumn);
|
|
|
}
|
|
|
// ----
|
|
|
/**
|
|
|
* Create a `Selection` from one or two positions
|
|
|
*/
|
|
|
static fromPositions(start, end = start) {
|
|
|
return new Selection(start.lineNumber, start.column, end.lineNumber, end.column);
|
|
|
}
|
|
|
/**
|
|
|
* Create a `Selection` from an `ISelection`.
|
|
|
*/
|
|
|
static liftSelection(sel) {
|
|
|
return new Selection(sel.selectionStartLineNumber, sel.selectionStartColumn, sel.positionLineNumber, sel.positionColumn);
|
|
|
}
|
|
|
/**
|
|
|
* `a` equals `b`.
|
|
|
*/
|
|
|
static selectionsArrEqual(a, b) {
|
|
|
if (a && !b || !a && b) {
|
|
|
return false;
|
|
|
}
|
|
|
if (!a && !b) {
|
|
|
return true;
|
|
|
}
|
|
|
if (a.length !== b.length) {
|
|
|
return false;
|
|
|
}
|
|
|
for (let i = 0, len = a.length; i < len; i++) {
|
|
|
if (!this.selectionsEqual(a[i], b[i])) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
/**
|
|
|
* Test if `obj` is an `ISelection`.
|
|
|
*/
|
|
|
static isISelection(obj) {
|
|
|
return (obj
|
|
|
&& (typeof obj.selectionStartLineNumber === 'number')
|
|
|
&& (typeof obj.selectionStartColumn === 'number')
|
|
|
&& (typeof obj.positionLineNumber === 'number')
|
|
|
&& (typeof obj.positionColumn === 'number'));
|
|
|
}
|
|
|
/**
|
|
|
* Create with a direction.
|
|
|
*/
|
|
|
static createWithDirection(startLineNumber, startColumn, endLineNumber, endColumn, direction) {
|
|
|
if (direction === 0 /* LTR */) {
|
|
|
return new Selection(startLineNumber, startColumn, endLineNumber, endColumn);
|
|
|
}
|
|
|
return new Selection(endLineNumber, endColumn, startLineNumber, startColumn);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/core/token.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
class Token {
|
|
|
constructor(offset, type, language) {
|
|
|
this._tokenBrand = undefined;
|
|
|
this.offset = offset | 0; // @perf
|
|
|
this.type = type;
|
|
|
this.language = language;
|
|
|
}
|
|
|
toString() {
|
|
|
return '(' + this.offset + ', ' + this.type + ')';
|
|
|
}
|
|
|
}
|
|
|
class TokenizationResult {
|
|
|
constructor(tokens, endState) {
|
|
|
this._tokenizationResultBrand = undefined;
|
|
|
this.tokens = tokens;
|
|
|
this.endState = endState;
|
|
|
}
|
|
|
}
|
|
|
class TokenizationResult2 {
|
|
|
constructor(tokens, endState) {
|
|
|
this._tokenizationResult2Brand = undefined;
|
|
|
this.tokens = tokens;
|
|
|
this.endState = endState;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/standalone/standaloneEnums.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.
|
|
|
var AccessibilitySupport;
|
|
|
(function (AccessibilitySupport) {
|
|
|
/**
|
|
|
* This should be the browser case where it is not known if a screen reader is attached or no.
|
|
|
*/
|
|
|
AccessibilitySupport[AccessibilitySupport["Unknown"] = 0] = "Unknown";
|
|
|
AccessibilitySupport[AccessibilitySupport["Disabled"] = 1] = "Disabled";
|
|
|
AccessibilitySupport[AccessibilitySupport["Enabled"] = 2] = "Enabled";
|
|
|
})(AccessibilitySupport || (AccessibilitySupport = {}));
|
|
|
var CompletionItemInsertTextRule;
|
|
|
(function (CompletionItemInsertTextRule) {
|
|
|
/**
|
|
|
* Adjust whitespace/indentation of multiline insert texts to
|
|
|
* match the current line indentation.
|
|
|
*/
|
|
|
CompletionItemInsertTextRule[CompletionItemInsertTextRule["KeepWhitespace"] = 1] = "KeepWhitespace";
|
|
|
/**
|
|
|
* `insertText` is a snippet.
|
|
|
*/
|
|
|
CompletionItemInsertTextRule[CompletionItemInsertTextRule["InsertAsSnippet"] = 4] = "InsertAsSnippet";
|
|
|
})(CompletionItemInsertTextRule || (CompletionItemInsertTextRule = {}));
|
|
|
var CompletionItemKind;
|
|
|
(function (CompletionItemKind) {
|
|
|
CompletionItemKind[CompletionItemKind["Method"] = 0] = "Method";
|
|
|
CompletionItemKind[CompletionItemKind["Function"] = 1] = "Function";
|
|
|
CompletionItemKind[CompletionItemKind["Constructor"] = 2] = "Constructor";
|
|
|
CompletionItemKind[CompletionItemKind["Field"] = 3] = "Field";
|
|
|
CompletionItemKind[CompletionItemKind["Variable"] = 4] = "Variable";
|
|
|
CompletionItemKind[CompletionItemKind["Class"] = 5] = "Class";
|
|
|
CompletionItemKind[CompletionItemKind["Struct"] = 6] = "Struct";
|
|
|
CompletionItemKind[CompletionItemKind["Interface"] = 7] = "Interface";
|
|
|
CompletionItemKind[CompletionItemKind["Module"] = 8] = "Module";
|
|
|
CompletionItemKind[CompletionItemKind["Property"] = 9] = "Property";
|
|
|
CompletionItemKind[CompletionItemKind["Event"] = 10] = "Event";
|
|
|
CompletionItemKind[CompletionItemKind["Operator"] = 11] = "Operator";
|
|
|
CompletionItemKind[CompletionItemKind["Unit"] = 12] = "Unit";
|
|
|
CompletionItemKind[CompletionItemKind["Value"] = 13] = "Value";
|
|
|
CompletionItemKind[CompletionItemKind["Constant"] = 14] = "Constant";
|
|
|
CompletionItemKind[CompletionItemKind["Enum"] = 15] = "Enum";
|
|
|
CompletionItemKind[CompletionItemKind["EnumMember"] = 16] = "EnumMember";
|
|
|
CompletionItemKind[CompletionItemKind["Keyword"] = 17] = "Keyword";
|
|
|
CompletionItemKind[CompletionItemKind["Text"] = 18] = "Text";
|
|
|
CompletionItemKind[CompletionItemKind["Color"] = 19] = "Color";
|
|
|
CompletionItemKind[CompletionItemKind["File"] = 20] = "File";
|
|
|
CompletionItemKind[CompletionItemKind["Reference"] = 21] = "Reference";
|
|
|
CompletionItemKind[CompletionItemKind["Customcolor"] = 22] = "Customcolor";
|
|
|
CompletionItemKind[CompletionItemKind["Folder"] = 23] = "Folder";
|
|
|
CompletionItemKind[CompletionItemKind["TypeParameter"] = 24] = "TypeParameter";
|
|
|
CompletionItemKind[CompletionItemKind["User"] = 25] = "User";
|
|
|
CompletionItemKind[CompletionItemKind["Issue"] = 26] = "Issue";
|
|
|
CompletionItemKind[CompletionItemKind["Snippet"] = 27] = "Snippet";
|
|
|
})(CompletionItemKind || (CompletionItemKind = {}));
|
|
|
var CompletionItemTag;
|
|
|
(function (CompletionItemTag) {
|
|
|
CompletionItemTag[CompletionItemTag["Deprecated"] = 1] = "Deprecated";
|
|
|
})(CompletionItemTag || (CompletionItemTag = {}));
|
|
|
/**
|
|
|
* How a suggest provider was triggered.
|
|
|
*/
|
|
|
var CompletionTriggerKind;
|
|
|
(function (CompletionTriggerKind) {
|
|
|
CompletionTriggerKind[CompletionTriggerKind["Invoke"] = 0] = "Invoke";
|
|
|
CompletionTriggerKind[CompletionTriggerKind["TriggerCharacter"] = 1] = "TriggerCharacter";
|
|
|
CompletionTriggerKind[CompletionTriggerKind["TriggerForIncompleteCompletions"] = 2] = "TriggerForIncompleteCompletions";
|
|
|
})(CompletionTriggerKind || (CompletionTriggerKind = {}));
|
|
|
/**
|
|
|
* A positioning preference for rendering content widgets.
|
|
|
*/
|
|
|
var ContentWidgetPositionPreference;
|
|
|
(function (ContentWidgetPositionPreference) {
|
|
|
/**
|
|
|
* Place the content widget exactly at a position
|
|
|
*/
|
|
|
ContentWidgetPositionPreference[ContentWidgetPositionPreference["EXACT"] = 0] = "EXACT";
|
|
|
/**
|
|
|
* Place the content widget above a position
|
|
|
*/
|
|
|
ContentWidgetPositionPreference[ContentWidgetPositionPreference["ABOVE"] = 1] = "ABOVE";
|
|
|
/**
|
|
|
* Place the content widget below a position
|
|
|
*/
|
|
|
ContentWidgetPositionPreference[ContentWidgetPositionPreference["BELOW"] = 2] = "BELOW";
|
|
|
})(ContentWidgetPositionPreference || (ContentWidgetPositionPreference = {}));
|
|
|
/**
|
|
|
* Describes the reason the cursor has changed its position.
|
|
|
*/
|
|
|
var CursorChangeReason;
|
|
|
(function (CursorChangeReason) {
|
|
|
/**
|
|
|
* Unknown or not set.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["NotSet"] = 0] = "NotSet";
|
|
|
/**
|
|
|
* A `model.setValue()` was called.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["ContentFlush"] = 1] = "ContentFlush";
|
|
|
/**
|
|
|
* The `model` has been changed outside of this cursor and the cursor recovers its position from associated markers.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["RecoverFromMarkers"] = 2] = "RecoverFromMarkers";
|
|
|
/**
|
|
|
* There was an explicit user gesture.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["Explicit"] = 3] = "Explicit";
|
|
|
/**
|
|
|
* There was a Paste.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["Paste"] = 4] = "Paste";
|
|
|
/**
|
|
|
* There was an Undo.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["Undo"] = 5] = "Undo";
|
|
|
/**
|
|
|
* There was a Redo.
|
|
|
*/
|
|
|
CursorChangeReason[CursorChangeReason["Redo"] = 6] = "Redo";
|
|
|
})(CursorChangeReason || (CursorChangeReason = {}));
|
|
|
/**
|
|
|
* The default end of line to use when instantiating models.
|
|
|
*/
|
|
|
var DefaultEndOfLine;
|
|
|
(function (DefaultEndOfLine) {
|
|
|
/**
|
|
|
* Use line feed (\n) as the end of line character.
|
|
|
*/
|
|
|
DefaultEndOfLine[DefaultEndOfLine["LF"] = 1] = "LF";
|
|
|
/**
|
|
|
* Use carriage return and line feed (\r\n) as the end of line character.
|
|
|
*/
|
|
|
DefaultEndOfLine[DefaultEndOfLine["CRLF"] = 2] = "CRLF";
|
|
|
})(DefaultEndOfLine || (DefaultEndOfLine = {}));
|
|
|
/**
|
|
|
* A document highlight kind.
|
|
|
*/
|
|
|
var DocumentHighlightKind;
|
|
|
(function (DocumentHighlightKind) {
|
|
|
/**
|
|
|
* A textual occurrence.
|
|
|
*/
|
|
|
DocumentHighlightKind[DocumentHighlightKind["Text"] = 0] = "Text";
|
|
|
/**
|
|
|
* Read-access of a symbol, like reading a variable.
|
|
|
*/
|
|
|
DocumentHighlightKind[DocumentHighlightKind["Read"] = 1] = "Read";
|
|
|
/**
|
|
|
* Write-access of a symbol, like writing to a variable.
|
|
|
*/
|
|
|
DocumentHighlightKind[DocumentHighlightKind["Write"] = 2] = "Write";
|
|
|
})(DocumentHighlightKind || (DocumentHighlightKind = {}));
|
|
|
/**
|
|
|
* Configuration options for auto indentation in the editor
|
|
|
*/
|
|
|
var EditorAutoIndentStrategy;
|
|
|
(function (EditorAutoIndentStrategy) {
|
|
|
EditorAutoIndentStrategy[EditorAutoIndentStrategy["None"] = 0] = "None";
|
|
|
EditorAutoIndentStrategy[EditorAutoIndentStrategy["Keep"] = 1] = "Keep";
|
|
|
EditorAutoIndentStrategy[EditorAutoIndentStrategy["Brackets"] = 2] = "Brackets";
|
|
|
EditorAutoIndentStrategy[EditorAutoIndentStrategy["Advanced"] = 3] = "Advanced";
|
|
|
EditorAutoIndentStrategy[EditorAutoIndentStrategy["Full"] = 4] = "Full";
|
|
|
})(EditorAutoIndentStrategy || (EditorAutoIndentStrategy = {}));
|
|
|
var EditorOption;
|
|
|
(function (EditorOption) {
|
|
|
EditorOption[EditorOption["acceptSuggestionOnCommitCharacter"] = 0] = "acceptSuggestionOnCommitCharacter";
|
|
|
EditorOption[EditorOption["acceptSuggestionOnEnter"] = 1] = "acceptSuggestionOnEnter";
|
|
|
EditorOption[EditorOption["accessibilitySupport"] = 2] = "accessibilitySupport";
|
|
|
EditorOption[EditorOption["accessibilityPageSize"] = 3] = "accessibilityPageSize";
|
|
|
EditorOption[EditorOption["ariaLabel"] = 4] = "ariaLabel";
|
|
|
EditorOption[EditorOption["autoClosingBrackets"] = 5] = "autoClosingBrackets";
|
|
|
EditorOption[EditorOption["autoClosingDelete"] = 6] = "autoClosingDelete";
|
|
|
EditorOption[EditorOption["autoClosingOvertype"] = 7] = "autoClosingOvertype";
|
|
|
EditorOption[EditorOption["autoClosingQuotes"] = 8] = "autoClosingQuotes";
|
|
|
EditorOption[EditorOption["autoIndent"] = 9] = "autoIndent";
|
|
|
EditorOption[EditorOption["automaticLayout"] = 10] = "automaticLayout";
|
|
|
EditorOption[EditorOption["autoSurround"] = 11] = "autoSurround";
|
|
|
EditorOption[EditorOption["bracketPairColorization"] = 12] = "bracketPairColorization";
|
|
|
EditorOption[EditorOption["guides"] = 13] = "guides";
|
|
|
EditorOption[EditorOption["codeLens"] = 14] = "codeLens";
|
|
|
EditorOption[EditorOption["codeLensFontFamily"] = 15] = "codeLensFontFamily";
|
|
|
EditorOption[EditorOption["codeLensFontSize"] = 16] = "codeLensFontSize";
|
|
|
EditorOption[EditorOption["colorDecorators"] = 17] = "colorDecorators";
|
|
|
EditorOption[EditorOption["columnSelection"] = 18] = "columnSelection";
|
|
|
EditorOption[EditorOption["comments"] = 19] = "comments";
|
|
|
EditorOption[EditorOption["contextmenu"] = 20] = "contextmenu";
|
|
|
EditorOption[EditorOption["copyWithSyntaxHighlighting"] = 21] = "copyWithSyntaxHighlighting";
|
|
|
EditorOption[EditorOption["cursorBlinking"] = 22] = "cursorBlinking";
|
|
|
EditorOption[EditorOption["cursorSmoothCaretAnimation"] = 23] = "cursorSmoothCaretAnimation";
|
|
|
EditorOption[EditorOption["cursorStyle"] = 24] = "cursorStyle";
|
|
|
EditorOption[EditorOption["cursorSurroundingLines"] = 25] = "cursorSurroundingLines";
|
|
|
EditorOption[EditorOption["cursorSurroundingLinesStyle"] = 26] = "cursorSurroundingLinesStyle";
|
|
|
EditorOption[EditorOption["cursorWidth"] = 27] = "cursorWidth";
|
|
|
EditorOption[EditorOption["disableLayerHinting"] = 28] = "disableLayerHinting";
|
|
|
EditorOption[EditorOption["disableMonospaceOptimizations"] = 29] = "disableMonospaceOptimizations";
|
|
|
EditorOption[EditorOption["domReadOnly"] = 30] = "domReadOnly";
|
|
|
EditorOption[EditorOption["dragAndDrop"] = 31] = "dragAndDrop";
|
|
|
EditorOption[EditorOption["emptySelectionClipboard"] = 32] = "emptySelectionClipboard";
|
|
|
EditorOption[EditorOption["extraEditorClassName"] = 33] = "extraEditorClassName";
|
|
|
EditorOption[EditorOption["fastScrollSensitivity"] = 34] = "fastScrollSensitivity";
|
|
|
EditorOption[EditorOption["find"] = 35] = "find";
|
|
|
EditorOption[EditorOption["fixedOverflowWidgets"] = 36] = "fixedOverflowWidgets";
|
|
|
EditorOption[EditorOption["folding"] = 37] = "folding";
|
|
|
EditorOption[EditorOption["foldingStrategy"] = 38] = "foldingStrategy";
|
|
|
EditorOption[EditorOption["foldingHighlight"] = 39] = "foldingHighlight";
|
|
|
EditorOption[EditorOption["foldingImportsByDefault"] = 40] = "foldingImportsByDefault";
|
|
|
EditorOption[EditorOption["unfoldOnClickAfterEndOfLine"] = 41] = "unfoldOnClickAfterEndOfLine";
|
|
|
EditorOption[EditorOption["fontFamily"] = 42] = "fontFamily";
|
|
|
EditorOption[EditorOption["fontInfo"] = 43] = "fontInfo";
|
|
|
EditorOption[EditorOption["fontLigatures"] = 44] = "fontLigatures";
|
|
|
EditorOption[EditorOption["fontSize"] = 45] = "fontSize";
|
|
|
EditorOption[EditorOption["fontWeight"] = 46] = "fontWeight";
|
|
|
EditorOption[EditorOption["formatOnPaste"] = 47] = "formatOnPaste";
|
|
|
EditorOption[EditorOption["formatOnType"] = 48] = "formatOnType";
|
|
|
EditorOption[EditorOption["glyphMargin"] = 49] = "glyphMargin";
|
|
|
EditorOption[EditorOption["gotoLocation"] = 50] = "gotoLocation";
|
|
|
EditorOption[EditorOption["hideCursorInOverviewRuler"] = 51] = "hideCursorInOverviewRuler";
|
|
|
EditorOption[EditorOption["hover"] = 52] = "hover";
|
|
|
EditorOption[EditorOption["inDiffEditor"] = 53] = "inDiffEditor";
|
|
|
EditorOption[EditorOption["inlineSuggest"] = 54] = "inlineSuggest";
|
|
|
EditorOption[EditorOption["letterSpacing"] = 55] = "letterSpacing";
|
|
|
EditorOption[EditorOption["lightbulb"] = 56] = "lightbulb";
|
|
|
EditorOption[EditorOption["lineDecorationsWidth"] = 57] = "lineDecorationsWidth";
|
|
|
EditorOption[EditorOption["lineHeight"] = 58] = "lineHeight";
|
|
|
EditorOption[EditorOption["lineNumbers"] = 59] = "lineNumbers";
|
|
|
EditorOption[EditorOption["lineNumbersMinChars"] = 60] = "lineNumbersMinChars";
|
|
|
EditorOption[EditorOption["linkedEditing"] = 61] = "linkedEditing";
|
|
|
EditorOption[EditorOption["links"] = 62] = "links";
|
|
|
EditorOption[EditorOption["matchBrackets"] = 63] = "matchBrackets";
|
|
|
EditorOption[EditorOption["minimap"] = 64] = "minimap";
|
|
|
EditorOption[EditorOption["mouseStyle"] = 65] = "mouseStyle";
|
|
|
EditorOption[EditorOption["mouseWheelScrollSensitivity"] = 66] = "mouseWheelScrollSensitivity";
|
|
|
EditorOption[EditorOption["mouseWheelZoom"] = 67] = "mouseWheelZoom";
|
|
|
EditorOption[EditorOption["multiCursorMergeOverlapping"] = 68] = "multiCursorMergeOverlapping";
|
|
|
EditorOption[EditorOption["multiCursorModifier"] = 69] = "multiCursorModifier";
|
|
|
EditorOption[EditorOption["multiCursorPaste"] = 70] = "multiCursorPaste";
|
|
|
EditorOption[EditorOption["occurrencesHighlight"] = 71] = "occurrencesHighlight";
|
|
|
EditorOption[EditorOption["overviewRulerBorder"] = 72] = "overviewRulerBorder";
|
|
|
EditorOption[EditorOption["overviewRulerLanes"] = 73] = "overviewRulerLanes";
|
|
|
EditorOption[EditorOption["padding"] = 74] = "padding";
|
|
|
EditorOption[EditorOption["parameterHints"] = 75] = "parameterHints";
|
|
|
EditorOption[EditorOption["peekWidgetDefaultFocus"] = 76] = "peekWidgetDefaultFocus";
|
|
|
EditorOption[EditorOption["definitionLinkOpensInPeek"] = 77] = "definitionLinkOpensInPeek";
|
|
|
EditorOption[EditorOption["quickSuggestions"] = 78] = "quickSuggestions";
|
|
|
EditorOption[EditorOption["quickSuggestionsDelay"] = 79] = "quickSuggestionsDelay";
|
|
|
EditorOption[EditorOption["readOnly"] = 80] = "readOnly";
|
|
|
EditorOption[EditorOption["renameOnType"] = 81] = "renameOnType";
|
|
|
EditorOption[EditorOption["renderControlCharacters"] = 82] = "renderControlCharacters";
|
|
|
EditorOption[EditorOption["renderFinalNewline"] = 83] = "renderFinalNewline";
|
|
|
EditorOption[EditorOption["renderLineHighlight"] = 84] = "renderLineHighlight";
|
|
|
EditorOption[EditorOption["renderLineHighlightOnlyWhenFocus"] = 85] = "renderLineHighlightOnlyWhenFocus";
|
|
|
EditorOption[EditorOption["renderValidationDecorations"] = 86] = "renderValidationDecorations";
|
|
|
EditorOption[EditorOption["renderWhitespace"] = 87] = "renderWhitespace";
|
|
|
EditorOption[EditorOption["revealHorizontalRightPadding"] = 88] = "revealHorizontalRightPadding";
|
|
|
EditorOption[EditorOption["roundedSelection"] = 89] = "roundedSelection";
|
|
|
EditorOption[EditorOption["rulers"] = 90] = "rulers";
|
|
|
EditorOption[EditorOption["scrollbar"] = 91] = "scrollbar";
|
|
|
EditorOption[EditorOption["scrollBeyondLastColumn"] = 92] = "scrollBeyondLastColumn";
|
|
|
EditorOption[EditorOption["scrollBeyondLastLine"] = 93] = "scrollBeyondLastLine";
|
|
|
EditorOption[EditorOption["scrollPredominantAxis"] = 94] = "scrollPredominantAxis";
|
|
|
EditorOption[EditorOption["selectionClipboard"] = 95] = "selectionClipboard";
|
|
|
EditorOption[EditorOption["selectionHighlight"] = 96] = "selectionHighlight";
|
|
|
EditorOption[EditorOption["selectOnLineNumbers"] = 97] = "selectOnLineNumbers";
|
|
|
EditorOption[EditorOption["showFoldingControls"] = 98] = "showFoldingControls";
|
|
|
EditorOption[EditorOption["showUnused"] = 99] = "showUnused";
|
|
|
EditorOption[EditorOption["snippetSuggestions"] = 100] = "snippetSuggestions";
|
|
|
EditorOption[EditorOption["smartSelect"] = 101] = "smartSelect";
|
|
|
EditorOption[EditorOption["smoothScrolling"] = 102] = "smoothScrolling";
|
|
|
EditorOption[EditorOption["stickyTabStops"] = 103] = "stickyTabStops";
|
|
|
EditorOption[EditorOption["stopRenderingLineAfter"] = 104] = "stopRenderingLineAfter";
|
|
|
EditorOption[EditorOption["suggest"] = 105] = "suggest";
|
|
|
EditorOption[EditorOption["suggestFontSize"] = 106] = "suggestFontSize";
|
|
|
EditorOption[EditorOption["suggestLineHeight"] = 107] = "suggestLineHeight";
|
|
|
EditorOption[EditorOption["suggestOnTriggerCharacters"] = 108] = "suggestOnTriggerCharacters";
|
|
|
EditorOption[EditorOption["suggestSelection"] = 109] = "suggestSelection";
|
|
|
EditorOption[EditorOption["tabCompletion"] = 110] = "tabCompletion";
|
|
|
EditorOption[EditorOption["tabIndex"] = 111] = "tabIndex";
|
|
|
EditorOption[EditorOption["unusualLineTerminators"] = 112] = "unusualLineTerminators";
|
|
|
EditorOption[EditorOption["useShadowDOM"] = 113] = "useShadowDOM";
|
|
|
EditorOption[EditorOption["useTabStops"] = 114] = "useTabStops";
|
|
|
EditorOption[EditorOption["wordSeparators"] = 115] = "wordSeparators";
|
|
|
EditorOption[EditorOption["wordWrap"] = 116] = "wordWrap";
|
|
|
EditorOption[EditorOption["wordWrapBreakAfterCharacters"] = 117] = "wordWrapBreakAfterCharacters";
|
|
|
EditorOption[EditorOption["wordWrapBreakBeforeCharacters"] = 118] = "wordWrapBreakBeforeCharacters";
|
|
|
EditorOption[EditorOption["wordWrapColumn"] = 119] = "wordWrapColumn";
|
|
|
EditorOption[EditorOption["wordWrapOverride1"] = 120] = "wordWrapOverride1";
|
|
|
EditorOption[EditorOption["wordWrapOverride2"] = 121] = "wordWrapOverride2";
|
|
|
EditorOption[EditorOption["wrappingIndent"] = 122] = "wrappingIndent";
|
|
|
EditorOption[EditorOption["wrappingStrategy"] = 123] = "wrappingStrategy";
|
|
|
EditorOption[EditorOption["showDeprecated"] = 124] = "showDeprecated";
|
|
|
EditorOption[EditorOption["inlayHints"] = 125] = "inlayHints";
|
|
|
EditorOption[EditorOption["editorClassName"] = 126] = "editorClassName";
|
|
|
EditorOption[EditorOption["pixelRatio"] = 127] = "pixelRatio";
|
|
|
EditorOption[EditorOption["tabFocusMode"] = 128] = "tabFocusMode";
|
|
|
EditorOption[EditorOption["layoutInfo"] = 129] = "layoutInfo";
|
|
|
EditorOption[EditorOption["wrappingInfo"] = 130] = "wrappingInfo";
|
|
|
})(EditorOption || (EditorOption = {}));
|
|
|
/**
|
|
|
* End of line character preference.
|
|
|
*/
|
|
|
var EndOfLinePreference;
|
|
|
(function (EndOfLinePreference) {
|
|
|
/**
|
|
|
* Use the end of line character identified in the text buffer.
|
|
|
*/
|
|
|
EndOfLinePreference[EndOfLinePreference["TextDefined"] = 0] = "TextDefined";
|
|
|
/**
|
|
|
* Use line feed (\n) as the end of line character.
|
|
|
*/
|
|
|
EndOfLinePreference[EndOfLinePreference["LF"] = 1] = "LF";
|
|
|
/**
|
|
|
* Use carriage return and line feed (\r\n) as the end of line character.
|
|
|
*/
|
|
|
EndOfLinePreference[EndOfLinePreference["CRLF"] = 2] = "CRLF";
|
|
|
})(EndOfLinePreference || (EndOfLinePreference = {}));
|
|
|
/**
|
|
|
* End of line character preference.
|
|
|
*/
|
|
|
var EndOfLineSequence;
|
|
|
(function (EndOfLineSequence) {
|
|
|
/**
|
|
|
* Use line feed (\n) as the end of line character.
|
|
|
*/
|
|
|
EndOfLineSequence[EndOfLineSequence["LF"] = 0] = "LF";
|
|
|
/**
|
|
|
* Use carriage return and line feed (\r\n) as the end of line character.
|
|
|
*/
|
|
|
EndOfLineSequence[EndOfLineSequence["CRLF"] = 1] = "CRLF";
|
|
|
})(EndOfLineSequence || (EndOfLineSequence = {}));
|
|
|
/**
|
|
|
* Describes what to do with the indentation when pressing Enter.
|
|
|
*/
|
|
|
var IndentAction;
|
|
|
(function (IndentAction) {
|
|
|
/**
|
|
|
* Insert new line and copy the previous line's indentation.
|
|
|
*/
|
|
|
IndentAction[IndentAction["None"] = 0] = "None";
|
|
|
/**
|
|
|
* Insert new line and indent once (relative to the previous line's indentation).
|
|
|
*/
|
|
|
IndentAction[IndentAction["Indent"] = 1] = "Indent";
|
|
|
/**
|
|
|
* Insert two new lines:
|
|
|
* - the first one indented which will hold the cursor
|
|
|
* - the second one at the same indentation level
|
|
|
*/
|
|
|
IndentAction[IndentAction["IndentOutdent"] = 2] = "IndentOutdent";
|
|
|
/**
|
|
|
* Insert new line and outdent once (relative to the previous line's indentation).
|
|
|
*/
|
|
|
IndentAction[IndentAction["Outdent"] = 3] = "Outdent";
|
|
|
})(IndentAction || (IndentAction = {}));
|
|
|
var InlayHintKind;
|
|
|
(function (InlayHintKind) {
|
|
|
InlayHintKind[InlayHintKind["Other"] = 0] = "Other";
|
|
|
InlayHintKind[InlayHintKind["Type"] = 1] = "Type";
|
|
|
InlayHintKind[InlayHintKind["Parameter"] = 2] = "Parameter";
|
|
|
})(InlayHintKind || (InlayHintKind = {}));
|
|
|
/**
|
|
|
* How an {@link InlineCompletionsProvider inline completion provider} was triggered.
|
|
|
*/
|
|
|
var InlineCompletionTriggerKind;
|
|
|
(function (InlineCompletionTriggerKind) {
|
|
|
/**
|
|
|
* Completion was triggered automatically while editing.
|
|
|
* It is sufficient to return a single completion item in this case.
|
|
|
*/
|
|
|
InlineCompletionTriggerKind[InlineCompletionTriggerKind["Automatic"] = 0] = "Automatic";
|
|
|
/**
|
|
|
* Completion was triggered explicitly by a user gesture.
|
|
|
* Return multiple completion items to enable cycling through them.
|
|
|
*/
|
|
|
InlineCompletionTriggerKind[InlineCompletionTriggerKind["Explicit"] = 1] = "Explicit";
|
|
|
})(InlineCompletionTriggerKind || (InlineCompletionTriggerKind = {}));
|
|
|
/**
|
|
|
* Virtual Key Codes, the value does not hold any inherent meaning.
|
|
|
* Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
|
|
|
* But these are "more general", as they should work across browsers & OS`s.
|
|
|
*/
|
|
|
var KeyCode;
|
|
|
(function (KeyCode) {
|
|
|
KeyCode[KeyCode["DependsOnKbLayout"] = -1] = "DependsOnKbLayout";
|
|
|
/**
|
|
|
* Placed first to cover the 0 value of the enum.
|
|
|
*/
|
|
|
KeyCode[KeyCode["Unknown"] = 0] = "Unknown";
|
|
|
KeyCode[KeyCode["Backspace"] = 1] = "Backspace";
|
|
|
KeyCode[KeyCode["Tab"] = 2] = "Tab";
|
|
|
KeyCode[KeyCode["Enter"] = 3] = "Enter";
|
|
|
KeyCode[KeyCode["Shift"] = 4] = "Shift";
|
|
|
KeyCode[KeyCode["Ctrl"] = 5] = "Ctrl";
|
|
|
KeyCode[KeyCode["Alt"] = 6] = "Alt";
|
|
|
KeyCode[KeyCode["PauseBreak"] = 7] = "PauseBreak";
|
|
|
KeyCode[KeyCode["CapsLock"] = 8] = "CapsLock";
|
|
|
KeyCode[KeyCode["Escape"] = 9] = "Escape";
|
|
|
KeyCode[KeyCode["Space"] = 10] = "Space";
|
|
|
KeyCode[KeyCode["PageUp"] = 11] = "PageUp";
|
|
|
KeyCode[KeyCode["PageDown"] = 12] = "PageDown";
|
|
|
KeyCode[KeyCode["End"] = 13] = "End";
|
|
|
KeyCode[KeyCode["Home"] = 14] = "Home";
|
|
|
KeyCode[KeyCode["LeftArrow"] = 15] = "LeftArrow";
|
|
|
KeyCode[KeyCode["UpArrow"] = 16] = "UpArrow";
|
|
|
KeyCode[KeyCode["RightArrow"] = 17] = "RightArrow";
|
|
|
KeyCode[KeyCode["DownArrow"] = 18] = "DownArrow";
|
|
|
KeyCode[KeyCode["Insert"] = 19] = "Insert";
|
|
|
KeyCode[KeyCode["Delete"] = 20] = "Delete";
|
|
|
KeyCode[KeyCode["Digit0"] = 21] = "Digit0";
|
|
|
KeyCode[KeyCode["Digit1"] = 22] = "Digit1";
|
|
|
KeyCode[KeyCode["Digit2"] = 23] = "Digit2";
|
|
|
KeyCode[KeyCode["Digit3"] = 24] = "Digit3";
|
|
|
KeyCode[KeyCode["Digit4"] = 25] = "Digit4";
|
|
|
KeyCode[KeyCode["Digit5"] = 26] = "Digit5";
|
|
|
KeyCode[KeyCode["Digit6"] = 27] = "Digit6";
|
|
|
KeyCode[KeyCode["Digit7"] = 28] = "Digit7";
|
|
|
KeyCode[KeyCode["Digit8"] = 29] = "Digit8";
|
|
|
KeyCode[KeyCode["Digit9"] = 30] = "Digit9";
|
|
|
KeyCode[KeyCode["KeyA"] = 31] = "KeyA";
|
|
|
KeyCode[KeyCode["KeyB"] = 32] = "KeyB";
|
|
|
KeyCode[KeyCode["KeyC"] = 33] = "KeyC";
|
|
|
KeyCode[KeyCode["KeyD"] = 34] = "KeyD";
|
|
|
KeyCode[KeyCode["KeyE"] = 35] = "KeyE";
|
|
|
KeyCode[KeyCode["KeyF"] = 36] = "KeyF";
|
|
|
KeyCode[KeyCode["KeyG"] = 37] = "KeyG";
|
|
|
KeyCode[KeyCode["KeyH"] = 38] = "KeyH";
|
|
|
KeyCode[KeyCode["KeyI"] = 39] = "KeyI";
|
|
|
KeyCode[KeyCode["KeyJ"] = 40] = "KeyJ";
|
|
|
KeyCode[KeyCode["KeyK"] = 41] = "KeyK";
|
|
|
KeyCode[KeyCode["KeyL"] = 42] = "KeyL";
|
|
|
KeyCode[KeyCode["KeyM"] = 43] = "KeyM";
|
|
|
KeyCode[KeyCode["KeyN"] = 44] = "KeyN";
|
|
|
KeyCode[KeyCode["KeyO"] = 45] = "KeyO";
|
|
|
KeyCode[KeyCode["KeyP"] = 46] = "KeyP";
|
|
|
KeyCode[KeyCode["KeyQ"] = 47] = "KeyQ";
|
|
|
KeyCode[KeyCode["KeyR"] = 48] = "KeyR";
|
|
|
KeyCode[KeyCode["KeyS"] = 49] = "KeyS";
|
|
|
KeyCode[KeyCode["KeyT"] = 50] = "KeyT";
|
|
|
KeyCode[KeyCode["KeyU"] = 51] = "KeyU";
|
|
|
KeyCode[KeyCode["KeyV"] = 52] = "KeyV";
|
|
|
KeyCode[KeyCode["KeyW"] = 53] = "KeyW";
|
|
|
KeyCode[KeyCode["KeyX"] = 54] = "KeyX";
|
|
|
KeyCode[KeyCode["KeyY"] = 55] = "KeyY";
|
|
|
KeyCode[KeyCode["KeyZ"] = 56] = "KeyZ";
|
|
|
KeyCode[KeyCode["Meta"] = 57] = "Meta";
|
|
|
KeyCode[KeyCode["ContextMenu"] = 58] = "ContextMenu";
|
|
|
KeyCode[KeyCode["F1"] = 59] = "F1";
|
|
|
KeyCode[KeyCode["F2"] = 60] = "F2";
|
|
|
KeyCode[KeyCode["F3"] = 61] = "F3";
|
|
|
KeyCode[KeyCode["F4"] = 62] = "F4";
|
|
|
KeyCode[KeyCode["F5"] = 63] = "F5";
|
|
|
KeyCode[KeyCode["F6"] = 64] = "F6";
|
|
|
KeyCode[KeyCode["F7"] = 65] = "F7";
|
|
|
KeyCode[KeyCode["F8"] = 66] = "F8";
|
|
|
KeyCode[KeyCode["F9"] = 67] = "F9";
|
|
|
KeyCode[KeyCode["F10"] = 68] = "F10";
|
|
|
KeyCode[KeyCode["F11"] = 69] = "F11";
|
|
|
KeyCode[KeyCode["F12"] = 70] = "F12";
|
|
|
KeyCode[KeyCode["F13"] = 71] = "F13";
|
|
|
KeyCode[KeyCode["F14"] = 72] = "F14";
|
|
|
KeyCode[KeyCode["F15"] = 73] = "F15";
|
|
|
KeyCode[KeyCode["F16"] = 74] = "F16";
|
|
|
KeyCode[KeyCode["F17"] = 75] = "F17";
|
|
|
KeyCode[KeyCode["F18"] = 76] = "F18";
|
|
|
KeyCode[KeyCode["F19"] = 77] = "F19";
|
|
|
KeyCode[KeyCode["NumLock"] = 78] = "NumLock";
|
|
|
KeyCode[KeyCode["ScrollLock"] = 79] = "ScrollLock";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the ';:' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Semicolon"] = 80] = "Semicolon";
|
|
|
/**
|
|
|
* For any country/region, the '+' key
|
|
|
* For the US standard keyboard, the '=+' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Equal"] = 81] = "Equal";
|
|
|
/**
|
|
|
* For any country/region, the ',' key
|
|
|
* For the US standard keyboard, the ',<' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Comma"] = 82] = "Comma";
|
|
|
/**
|
|
|
* For any country/region, the '-' key
|
|
|
* For the US standard keyboard, the '-_' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Minus"] = 83] = "Minus";
|
|
|
/**
|
|
|
* For any country/region, the '.' key
|
|
|
* For the US standard keyboard, the '.>' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Period"] = 84] = "Period";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the '/?' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Slash"] = 85] = "Slash";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the '`~' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Backquote"] = 86] = "Backquote";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the '[{' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["BracketLeft"] = 87] = "BracketLeft";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the '\|' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Backslash"] = 88] = "Backslash";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the ']}' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["BracketRight"] = 89] = "BracketRight";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
* For the US standard keyboard, the ''"' key
|
|
|
*/
|
|
|
KeyCode[KeyCode["Quote"] = 90] = "Quote";
|
|
|
/**
|
|
|
* Used for miscellaneous characters; it can vary by keyboard.
|
|
|
*/
|
|
|
KeyCode[KeyCode["OEM_8"] = 91] = "OEM_8";
|
|
|
/**
|
|
|
* Either the angle bracket key or the backslash key on the RT 102-key keyboard.
|
|
|
*/
|
|
|
KeyCode[KeyCode["IntlBackslash"] = 92] = "IntlBackslash";
|
|
|
KeyCode[KeyCode["Numpad0"] = 93] = "Numpad0";
|
|
|
KeyCode[KeyCode["Numpad1"] = 94] = "Numpad1";
|
|
|
KeyCode[KeyCode["Numpad2"] = 95] = "Numpad2";
|
|
|
KeyCode[KeyCode["Numpad3"] = 96] = "Numpad3";
|
|
|
KeyCode[KeyCode["Numpad4"] = 97] = "Numpad4";
|
|
|
KeyCode[KeyCode["Numpad5"] = 98] = "Numpad5";
|
|
|
KeyCode[KeyCode["Numpad6"] = 99] = "Numpad6";
|
|
|
KeyCode[KeyCode["Numpad7"] = 100] = "Numpad7";
|
|
|
KeyCode[KeyCode["Numpad8"] = 101] = "Numpad8";
|
|
|
KeyCode[KeyCode["Numpad9"] = 102] = "Numpad9";
|
|
|
KeyCode[KeyCode["NumpadMultiply"] = 103] = "NumpadMultiply";
|
|
|
KeyCode[KeyCode["NumpadAdd"] = 104] = "NumpadAdd";
|
|
|
KeyCode[KeyCode["NUMPAD_SEPARATOR"] = 105] = "NUMPAD_SEPARATOR";
|
|
|
KeyCode[KeyCode["NumpadSubtract"] = 106] = "NumpadSubtract";
|
|
|
KeyCode[KeyCode["NumpadDecimal"] = 107] = "NumpadDecimal";
|
|
|
KeyCode[KeyCode["NumpadDivide"] = 108] = "NumpadDivide";
|
|
|
/**
|
|
|
* Cover all key codes when IME is processing input.
|
|
|
*/
|
|
|
KeyCode[KeyCode["KEY_IN_COMPOSITION"] = 109] = "KEY_IN_COMPOSITION";
|
|
|
KeyCode[KeyCode["ABNT_C1"] = 110] = "ABNT_C1";
|
|
|
KeyCode[KeyCode["ABNT_C2"] = 111] = "ABNT_C2";
|
|
|
KeyCode[KeyCode["AudioVolumeMute"] = 112] = "AudioVolumeMute";
|
|
|
KeyCode[KeyCode["AudioVolumeUp"] = 113] = "AudioVolumeUp";
|
|
|
KeyCode[KeyCode["AudioVolumeDown"] = 114] = "AudioVolumeDown";
|
|
|
KeyCode[KeyCode["BrowserSearch"] = 115] = "BrowserSearch";
|
|
|
KeyCode[KeyCode["BrowserHome"] = 116] = "BrowserHome";
|
|
|
KeyCode[KeyCode["BrowserBack"] = 117] = "BrowserBack";
|
|
|
KeyCode[KeyCode["BrowserForward"] = 118] = "BrowserForward";
|
|
|
KeyCode[KeyCode["MediaTrackNext"] = 119] = "MediaTrackNext";
|
|
|
KeyCode[KeyCode["MediaTrackPrevious"] = 120] = "MediaTrackPrevious";
|
|
|
KeyCode[KeyCode["MediaStop"] = 121] = "MediaStop";
|
|
|
KeyCode[KeyCode["MediaPlayPause"] = 122] = "MediaPlayPause";
|
|
|
KeyCode[KeyCode["LaunchMediaPlayer"] = 123] = "LaunchMediaPlayer";
|
|
|
KeyCode[KeyCode["LaunchMail"] = 124] = "LaunchMail";
|
|
|
KeyCode[KeyCode["LaunchApp2"] = 125] = "LaunchApp2";
|
|
|
/**
|
|
|
* Placed last to cover the length of the enum.
|
|
|
* Please do not depend on this value!
|
|
|
*/
|
|
|
KeyCode[KeyCode["MAX_VALUE"] = 126] = "MAX_VALUE";
|
|
|
})(KeyCode || (KeyCode = {}));
|
|
|
var MarkerSeverity;
|
|
|
(function (MarkerSeverity) {
|
|
|
MarkerSeverity[MarkerSeverity["Hint"] = 1] = "Hint";
|
|
|
MarkerSeverity[MarkerSeverity["Info"] = 2] = "Info";
|
|
|
MarkerSeverity[MarkerSeverity["Warning"] = 4] = "Warning";
|
|
|
MarkerSeverity[MarkerSeverity["Error"] = 8] = "Error";
|
|
|
})(MarkerSeverity || (MarkerSeverity = {}));
|
|
|
var MarkerTag;
|
|
|
(function (MarkerTag) {
|
|
|
MarkerTag[MarkerTag["Unnecessary"] = 1] = "Unnecessary";
|
|
|
MarkerTag[MarkerTag["Deprecated"] = 2] = "Deprecated";
|
|
|
})(MarkerTag || (MarkerTag = {}));
|
|
|
/**
|
|
|
* Position in the minimap to render the decoration.
|
|
|
*/
|
|
|
var MinimapPosition;
|
|
|
(function (MinimapPosition) {
|
|
|
MinimapPosition[MinimapPosition["Inline"] = 1] = "Inline";
|
|
|
MinimapPosition[MinimapPosition["Gutter"] = 2] = "Gutter";
|
|
|
})(MinimapPosition || (MinimapPosition = {}));
|
|
|
/**
|
|
|
* Type of hit element with the mouse in the editor.
|
|
|
*/
|
|
|
var MouseTargetType;
|
|
|
(function (MouseTargetType) {
|
|
|
/**
|
|
|
* Mouse is on top of an unknown element.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["UNKNOWN"] = 0] = "UNKNOWN";
|
|
|
/**
|
|
|
* Mouse is on top of the textarea used for input.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["TEXTAREA"] = 1] = "TEXTAREA";
|
|
|
/**
|
|
|
* Mouse is on top of the glyph margin
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["GUTTER_GLYPH_MARGIN"] = 2] = "GUTTER_GLYPH_MARGIN";
|
|
|
/**
|
|
|
* Mouse is on top of the line numbers
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["GUTTER_LINE_NUMBERS"] = 3] = "GUTTER_LINE_NUMBERS";
|
|
|
/**
|
|
|
* Mouse is on top of the line decorations
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["GUTTER_LINE_DECORATIONS"] = 4] = "GUTTER_LINE_DECORATIONS";
|
|
|
/**
|
|
|
* Mouse is on top of the whitespace left in the gutter by a view zone.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["GUTTER_VIEW_ZONE"] = 5] = "GUTTER_VIEW_ZONE";
|
|
|
/**
|
|
|
* Mouse is on top of text in the content.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["CONTENT_TEXT"] = 6] = "CONTENT_TEXT";
|
|
|
/**
|
|
|
* Mouse is on top of empty space in the content (e.g. after line text or below last line)
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["CONTENT_EMPTY"] = 7] = "CONTENT_EMPTY";
|
|
|
/**
|
|
|
* Mouse is on top of a view zone in the content.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["CONTENT_VIEW_ZONE"] = 8] = "CONTENT_VIEW_ZONE";
|
|
|
/**
|
|
|
* Mouse is on top of a content widget.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["CONTENT_WIDGET"] = 9] = "CONTENT_WIDGET";
|
|
|
/**
|
|
|
* Mouse is on top of the decorations overview ruler.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["OVERVIEW_RULER"] = 10] = "OVERVIEW_RULER";
|
|
|
/**
|
|
|
* Mouse is on top of a scrollbar.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["SCROLLBAR"] = 11] = "SCROLLBAR";
|
|
|
/**
|
|
|
* Mouse is on top of an overlay widget.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["OVERLAY_WIDGET"] = 12] = "OVERLAY_WIDGET";
|
|
|
/**
|
|
|
* Mouse is outside of the editor.
|
|
|
*/
|
|
|
MouseTargetType[MouseTargetType["OUTSIDE_EDITOR"] = 13] = "OUTSIDE_EDITOR";
|
|
|
})(MouseTargetType || (MouseTargetType = {}));
|
|
|
/**
|
|
|
* A positioning preference for rendering overlay widgets.
|
|
|
*/
|
|
|
var OverlayWidgetPositionPreference;
|
|
|
(function (OverlayWidgetPositionPreference) {
|
|
|
/**
|
|
|
* Position the overlay widget in the top right corner
|
|
|
*/
|
|
|
OverlayWidgetPositionPreference[OverlayWidgetPositionPreference["TOP_RIGHT_CORNER"] = 0] = "TOP_RIGHT_CORNER";
|
|
|
/**
|
|
|
* Position the overlay widget in the bottom right corner
|
|
|
*/
|
|
|
OverlayWidgetPositionPreference[OverlayWidgetPositionPreference["BOTTOM_RIGHT_CORNER"] = 1] = "BOTTOM_RIGHT_CORNER";
|
|
|
/**
|
|
|
* Position the overlay widget in the top center
|
|
|
*/
|
|
|
OverlayWidgetPositionPreference[OverlayWidgetPositionPreference["TOP_CENTER"] = 2] = "TOP_CENTER";
|
|
|
})(OverlayWidgetPositionPreference || (OverlayWidgetPositionPreference = {}));
|
|
|
/**
|
|
|
* Vertical Lane in the overview ruler of the editor.
|
|
|
*/
|
|
|
var OverviewRulerLane;
|
|
|
(function (OverviewRulerLane) {
|
|
|
OverviewRulerLane[OverviewRulerLane["Left"] = 1] = "Left";
|
|
|
OverviewRulerLane[OverviewRulerLane["Center"] = 2] = "Center";
|
|
|
OverviewRulerLane[OverviewRulerLane["Right"] = 4] = "Right";
|
|
|
OverviewRulerLane[OverviewRulerLane["Full"] = 7] = "Full";
|
|
|
})(OverviewRulerLane || (OverviewRulerLane = {}));
|
|
|
var RenderLineNumbersType;
|
|
|
(function (RenderLineNumbersType) {
|
|
|
RenderLineNumbersType[RenderLineNumbersType["Off"] = 0] = "Off";
|
|
|
RenderLineNumbersType[RenderLineNumbersType["On"] = 1] = "On";
|
|
|
RenderLineNumbersType[RenderLineNumbersType["Relative"] = 2] = "Relative";
|
|
|
RenderLineNumbersType[RenderLineNumbersType["Interval"] = 3] = "Interval";
|
|
|
RenderLineNumbersType[RenderLineNumbersType["Custom"] = 4] = "Custom";
|
|
|
})(RenderLineNumbersType || (RenderLineNumbersType = {}));
|
|
|
var RenderMinimap;
|
|
|
(function (RenderMinimap) {
|
|
|
RenderMinimap[RenderMinimap["None"] = 0] = "None";
|
|
|
RenderMinimap[RenderMinimap["Text"] = 1] = "Text";
|
|
|
RenderMinimap[RenderMinimap["Blocks"] = 2] = "Blocks";
|
|
|
})(RenderMinimap || (RenderMinimap = {}));
|
|
|
var ScrollType;
|
|
|
(function (ScrollType) {
|
|
|
ScrollType[ScrollType["Smooth"] = 0] = "Smooth";
|
|
|
ScrollType[ScrollType["Immediate"] = 1] = "Immediate";
|
|
|
})(ScrollType || (ScrollType = {}));
|
|
|
var ScrollbarVisibility;
|
|
|
(function (ScrollbarVisibility) {
|
|
|
ScrollbarVisibility[ScrollbarVisibility["Auto"] = 1] = "Auto";
|
|
|
ScrollbarVisibility[ScrollbarVisibility["Hidden"] = 2] = "Hidden";
|
|
|
ScrollbarVisibility[ScrollbarVisibility["Visible"] = 3] = "Visible";
|
|
|
})(ScrollbarVisibility || (ScrollbarVisibility = {}));
|
|
|
/**
|
|
|
* The direction of a selection.
|
|
|
*/
|
|
|
var SelectionDirection;
|
|
|
(function (SelectionDirection) {
|
|
|
/**
|
|
|
* The selection starts above where it ends.
|
|
|
*/
|
|
|
SelectionDirection[SelectionDirection["LTR"] = 0] = "LTR";
|
|
|
/**
|
|
|
* The selection starts below where it ends.
|
|
|
*/
|
|
|
SelectionDirection[SelectionDirection["RTL"] = 1] = "RTL";
|
|
|
})(SelectionDirection || (SelectionDirection = {}));
|
|
|
var SignatureHelpTriggerKind;
|
|
|
(function (SignatureHelpTriggerKind) {
|
|
|
SignatureHelpTriggerKind[SignatureHelpTriggerKind["Invoke"] = 1] = "Invoke";
|
|
|
SignatureHelpTriggerKind[SignatureHelpTriggerKind["TriggerCharacter"] = 2] = "TriggerCharacter";
|
|
|
SignatureHelpTriggerKind[SignatureHelpTriggerKind["ContentChange"] = 3] = "ContentChange";
|
|
|
})(SignatureHelpTriggerKind || (SignatureHelpTriggerKind = {}));
|
|
|
/**
|
|
|
* A symbol kind.
|
|
|
*/
|
|
|
var SymbolKind;
|
|
|
(function (SymbolKind) {
|
|
|
SymbolKind[SymbolKind["File"] = 0] = "File";
|
|
|
SymbolKind[SymbolKind["Module"] = 1] = "Module";
|
|
|
SymbolKind[SymbolKind["Namespace"] = 2] = "Namespace";
|
|
|
SymbolKind[SymbolKind["Package"] = 3] = "Package";
|
|
|
SymbolKind[SymbolKind["Class"] = 4] = "Class";
|
|
|
SymbolKind[SymbolKind["Method"] = 5] = "Method";
|
|
|
SymbolKind[SymbolKind["Property"] = 6] = "Property";
|
|
|
SymbolKind[SymbolKind["Field"] = 7] = "Field";
|
|
|
SymbolKind[SymbolKind["Constructor"] = 8] = "Constructor";
|
|
|
SymbolKind[SymbolKind["Enum"] = 9] = "Enum";
|
|
|
SymbolKind[SymbolKind["Interface"] = 10] = "Interface";
|
|
|
SymbolKind[SymbolKind["Function"] = 11] = "Function";
|
|
|
SymbolKind[SymbolKind["Variable"] = 12] = "Variable";
|
|
|
SymbolKind[SymbolKind["Constant"] = 13] = "Constant";
|
|
|
SymbolKind[SymbolKind["String"] = 14] = "String";
|
|
|
SymbolKind[SymbolKind["Number"] = 15] = "Number";
|
|
|
SymbolKind[SymbolKind["Boolean"] = 16] = "Boolean";
|
|
|
SymbolKind[SymbolKind["Array"] = 17] = "Array";
|
|
|
SymbolKind[SymbolKind["Object"] = 18] = "Object";
|
|
|
SymbolKind[SymbolKind["Key"] = 19] = "Key";
|
|
|
SymbolKind[SymbolKind["Null"] = 20] = "Null";
|
|
|
SymbolKind[SymbolKind["EnumMember"] = 21] = "EnumMember";
|
|
|
SymbolKind[SymbolKind["Struct"] = 22] = "Struct";
|
|
|
SymbolKind[SymbolKind["Event"] = 23] = "Event";
|
|
|
SymbolKind[SymbolKind["Operator"] = 24] = "Operator";
|
|
|
SymbolKind[SymbolKind["TypeParameter"] = 25] = "TypeParameter";
|
|
|
})(SymbolKind || (SymbolKind = {}));
|
|
|
var SymbolTag;
|
|
|
(function (SymbolTag) {
|
|
|
SymbolTag[SymbolTag["Deprecated"] = 1] = "Deprecated";
|
|
|
})(SymbolTag || (SymbolTag = {}));
|
|
|
/**
|
|
|
* The kind of animation in which the editor's cursor should be rendered.
|
|
|
*/
|
|
|
var TextEditorCursorBlinkingStyle;
|
|
|
(function (TextEditorCursorBlinkingStyle) {
|
|
|
/**
|
|
|
* Hidden
|
|
|
*/
|
|
|
TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle["Hidden"] = 0] = "Hidden";
|
|
|
/**
|
|
|
* Blinking
|
|
|
*/
|
|
|
TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle["Blink"] = 1] = "Blink";
|
|
|
/**
|
|
|
* Blinking with smooth fading
|
|
|
*/
|
|
|
TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle["Smooth"] = 2] = "Smooth";
|
|
|
/**
|
|
|
* Blinking with prolonged filled state and smooth fading
|
|
|
*/
|
|
|
TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle["Phase"] = 3] = "Phase";
|
|
|
/**
|
|
|
* Expand collapse animation on the y axis
|
|
|
*/
|
|
|
TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle["Expand"] = 4] = "Expand";
|
|
|
/**
|
|
|
* No-Blinking
|
|
|
*/
|
|
|
TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle["Solid"] = 5] = "Solid";
|
|
|
})(TextEditorCursorBlinkingStyle || (TextEditorCursorBlinkingStyle = {}));
|
|
|
/**
|
|
|
* The style in which the editor's cursor should be rendered.
|
|
|
*/
|
|
|
var TextEditorCursorStyle;
|
|
|
(function (TextEditorCursorStyle) {
|
|
|
/**
|
|
|
* As a vertical line (sitting between two characters).
|
|
|
*/
|
|
|
TextEditorCursorStyle[TextEditorCursorStyle["Line"] = 1] = "Line";
|
|
|
/**
|
|
|
* As a block (sitting on top of a character).
|
|
|
*/
|
|
|
TextEditorCursorStyle[TextEditorCursorStyle["Block"] = 2] = "Block";
|
|
|
/**
|
|
|
* As a horizontal line (sitting under a character).
|
|
|
*/
|
|
|
TextEditorCursorStyle[TextEditorCursorStyle["Underline"] = 3] = "Underline";
|
|
|
/**
|
|
|
* As a thin vertical line (sitting between two characters).
|
|
|
*/
|
|
|
TextEditorCursorStyle[TextEditorCursorStyle["LineThin"] = 4] = "LineThin";
|
|
|
/**
|
|
|
* As an outlined block (sitting on top of a character).
|
|
|
*/
|
|
|
TextEditorCursorStyle[TextEditorCursorStyle["BlockOutline"] = 5] = "BlockOutline";
|
|
|
/**
|
|
|
* As a thin horizontal line (sitting under a character).
|
|
|
*/
|
|
|
TextEditorCursorStyle[TextEditorCursorStyle["UnderlineThin"] = 6] = "UnderlineThin";
|
|
|
})(TextEditorCursorStyle || (TextEditorCursorStyle = {}));
|
|
|
/**
|
|
|
* Describes the behavior of decorations when typing/editing near their edges.
|
|
|
* Note: Please do not edit the values, as they very carefully match `DecorationRangeBehavior`
|
|
|
*/
|
|
|
var TrackedRangeStickiness;
|
|
|
(function (TrackedRangeStickiness) {
|
|
|
TrackedRangeStickiness[TrackedRangeStickiness["AlwaysGrowsWhenTypingAtEdges"] = 0] = "AlwaysGrowsWhenTypingAtEdges";
|
|
|
TrackedRangeStickiness[TrackedRangeStickiness["NeverGrowsWhenTypingAtEdges"] = 1] = "NeverGrowsWhenTypingAtEdges";
|
|
|
TrackedRangeStickiness[TrackedRangeStickiness["GrowsOnlyWhenTypingBefore"] = 2] = "GrowsOnlyWhenTypingBefore";
|
|
|
TrackedRangeStickiness[TrackedRangeStickiness["GrowsOnlyWhenTypingAfter"] = 3] = "GrowsOnlyWhenTypingAfter";
|
|
|
})(TrackedRangeStickiness || (TrackedRangeStickiness = {}));
|
|
|
/**
|
|
|
* Describes how to indent wrapped lines.
|
|
|
*/
|
|
|
var WrappingIndent;
|
|
|
(function (WrappingIndent) {
|
|
|
/**
|
|
|
* No indentation => wrapped lines begin at column 1.
|
|
|
*/
|
|
|
WrappingIndent[WrappingIndent["None"] = 0] = "None";
|
|
|
/**
|
|
|
* Same => wrapped lines get the same indentation as the parent.
|
|
|
*/
|
|
|
WrappingIndent[WrappingIndent["Same"] = 1] = "Same";
|
|
|
/**
|
|
|
* Indent => wrapped lines get +1 indentation toward the parent.
|
|
|
*/
|
|
|
WrappingIndent[WrappingIndent["Indent"] = 2] = "Indent";
|
|
|
/**
|
|
|
* DeepIndent => wrapped lines get +2 indentation toward the parent.
|
|
|
*/
|
|
|
WrappingIndent[WrappingIndent["DeepIndent"] = 3] = "DeepIndent";
|
|
|
})(WrappingIndent || (WrappingIndent = {}));
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/standalone/standaloneBase.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class KeyMod {
|
|
|
static chord(firstPart, secondPart) {
|
|
|
return KeyChord(firstPart, secondPart);
|
|
|
}
|
|
|
}
|
|
|
KeyMod.CtrlCmd = 2048 /* CtrlCmd */;
|
|
|
KeyMod.Shift = 1024 /* Shift */;
|
|
|
KeyMod.Alt = 512 /* Alt */;
|
|
|
KeyMod.WinCtrl = 256 /* WinCtrl */;
|
|
|
function createMonacoBaseAPI() {
|
|
|
return {
|
|
|
editor: undefined,
|
|
|
languages: undefined,
|
|
|
CancellationTokenSource: CancellationTokenSource,
|
|
|
Emitter: Emitter,
|
|
|
KeyCode: KeyCode,
|
|
|
KeyMod: KeyMod,
|
|
|
Position: Position,
|
|
|
Range: Range,
|
|
|
Selection: Selection,
|
|
|
SelectionDirection: SelectionDirection,
|
|
|
MarkerSeverity: MarkerSeverity,
|
|
|
MarkerTag: MarkerTag,
|
|
|
Uri: URI,
|
|
|
Token: Token
|
|
|
};
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/common/services/editorSimpleWorker.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
});
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @internal
|
|
|
*/
|
|
|
class MirrorModel extends MirrorTextModel {
|
|
|
get uri() {
|
|
|
return this._uri;
|
|
|
}
|
|
|
get eol() {
|
|
|
return this._eol;
|
|
|
}
|
|
|
getValue() {
|
|
|
return this.getText();
|
|
|
}
|
|
|
getLinesContent() {
|
|
|
return this._lines.slice(0);
|
|
|
}
|
|
|
getLineCount() {
|
|
|
return this._lines.length;
|
|
|
}
|
|
|
getLineContent(lineNumber) {
|
|
|
return this._lines[lineNumber - 1];
|
|
|
}
|
|
|
getWordAtPosition(position, wordDefinition) {
|
|
|
let wordAtText = getWordAtText(position.column, ensureValidWordDefinition(wordDefinition), this._lines[position.lineNumber - 1], 0);
|
|
|
if (wordAtText) {
|
|
|
return new Range(position.lineNumber, wordAtText.startColumn, position.lineNumber, wordAtText.endColumn);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
words(wordDefinition) {
|
|
|
const lines = this._lines;
|
|
|
const wordenize = this._wordenize.bind(this);
|
|
|
let lineNumber = 0;
|
|
|
let lineText = '';
|
|
|
let wordRangesIdx = 0;
|
|
|
let wordRanges = [];
|
|
|
return {
|
|
|
*[Symbol.iterator]() {
|
|
|
while (true) {
|
|
|
if (wordRangesIdx < wordRanges.length) {
|
|
|
const value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end);
|
|
|
wordRangesIdx += 1;
|
|
|
yield value;
|
|
|
}
|
|
|
else {
|
|
|
if (lineNumber < lines.length) {
|
|
|
lineText = lines[lineNumber];
|
|
|
wordRanges = wordenize(lineText, wordDefinition);
|
|
|
wordRangesIdx = 0;
|
|
|
lineNumber += 1;
|
|
|
}
|
|
|
else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
getLineWords(lineNumber, wordDefinition) {
|
|
|
let content = this._lines[lineNumber - 1];
|
|
|
let ranges = this._wordenize(content, wordDefinition);
|
|
|
let words = [];
|
|
|
for (const range of ranges) {
|
|
|
words.push({
|
|
|
word: content.substring(range.start, range.end),
|
|
|
startColumn: range.start + 1,
|
|
|
endColumn: range.end + 1
|
|
|
});
|
|
|
}
|
|
|
return words;
|
|
|
}
|
|
|
_wordenize(content, wordDefinition) {
|
|
|
const result = [];
|
|
|
let match;
|
|
|
wordDefinition.lastIndex = 0; // reset lastIndex just to be sure
|
|
|
while (match = wordDefinition.exec(content)) {
|
|
|
if (match[0].length === 0) {
|
|
|
// it did match the empty string
|
|
|
break;
|
|
|
}
|
|
|
result.push({ start: match.index, end: match.index + match[0].length });
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
getValueInRange(range) {
|
|
|
range = this._validateRange(range);
|
|
|
if (range.startLineNumber === range.endLineNumber) {
|
|
|
return this._lines[range.startLineNumber - 1].substring(range.startColumn - 1, range.endColumn - 1);
|
|
|
}
|
|
|
let lineEnding = this._eol;
|
|
|
let startLineIndex = range.startLineNumber - 1;
|
|
|
let endLineIndex = range.endLineNumber - 1;
|
|
|
let resultLines = [];
|
|
|
resultLines.push(this._lines[startLineIndex].substring(range.startColumn - 1));
|
|
|
for (let i = startLineIndex + 1; i < endLineIndex; i++) {
|
|
|
resultLines.push(this._lines[i]);
|
|
|
}
|
|
|
resultLines.push(this._lines[endLineIndex].substring(0, range.endColumn - 1));
|
|
|
return resultLines.join(lineEnding);
|
|
|
}
|
|
|
offsetAt(position) {
|
|
|
position = this._validatePosition(position);
|
|
|
this._ensureLineStarts();
|
|
|
return this._lineStarts.getPrefixSum(position.lineNumber - 2) + (position.column - 1);
|
|
|
}
|
|
|
positionAt(offset) {
|
|
|
offset = Math.floor(offset);
|
|
|
offset = Math.max(0, offset);
|
|
|
this._ensureLineStarts();
|
|
|
let out = this._lineStarts.getIndexOf(offset);
|
|
|
let lineLength = this._lines[out.index].length;
|
|
|
// Ensure we return a valid position
|
|
|
return {
|
|
|
lineNumber: 1 + out.index,
|
|
|
column: 1 + Math.min(out.remainder, lineLength)
|
|
|
};
|
|
|
}
|
|
|
_validateRange(range) {
|
|
|
const start = this._validatePosition({ lineNumber: range.startLineNumber, column: range.startColumn });
|
|
|
const end = this._validatePosition({ lineNumber: range.endLineNumber, column: range.endColumn });
|
|
|
if (start.lineNumber !== range.startLineNumber
|
|
|
|| start.column !== range.startColumn
|
|
|
|| end.lineNumber !== range.endLineNumber
|
|
|
|| end.column !== range.endColumn) {
|
|
|
return {
|
|
|
startLineNumber: start.lineNumber,
|
|
|
startColumn: start.column,
|
|
|
endLineNumber: end.lineNumber,
|
|
|
endColumn: end.column
|
|
|
};
|
|
|
}
|
|
|
return range;
|
|
|
}
|
|
|
_validatePosition(position) {
|
|
|
if (!Position.isIPosition(position)) {
|
|
|
throw new Error('bad position');
|
|
|
}
|
|
|
let { lineNumber, column } = position;
|
|
|
let hasChanged = false;
|
|
|
if (lineNumber < 1) {
|
|
|
lineNumber = 1;
|
|
|
column = 1;
|
|
|
hasChanged = true;
|
|
|
}
|
|
|
else if (lineNumber > this._lines.length) {
|
|
|
lineNumber = this._lines.length;
|
|
|
column = this._lines[lineNumber - 1].length + 1;
|
|
|
hasChanged = true;
|
|
|
}
|
|
|
else {
|
|
|
let maxCharacter = this._lines[lineNumber - 1].length + 1;
|
|
|
if (column < 1) {
|
|
|
column = 1;
|
|
|
hasChanged = true;
|
|
|
}
|
|
|
else if (column > maxCharacter) {
|
|
|
column = maxCharacter;
|
|
|
hasChanged = true;
|
|
|
}
|
|
|
}
|
|
|
if (!hasChanged) {
|
|
|
return position;
|
|
|
}
|
|
|
else {
|
|
|
return { lineNumber, column };
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* @internal
|
|
|
*/
|
|
|
class EditorSimpleWorker {
|
|
|
constructor(host, foreignModuleFactory) {
|
|
|
this._host = host;
|
|
|
this._models = Object.create(null);
|
|
|
this._foreignModuleFactory = foreignModuleFactory;
|
|
|
this._foreignModule = null;
|
|
|
}
|
|
|
dispose() {
|
|
|
this._models = Object.create(null);
|
|
|
}
|
|
|
_getModel(uri) {
|
|
|
return this._models[uri];
|
|
|
}
|
|
|
_getModels() {
|
|
|
let all = [];
|
|
|
Object.keys(this._models).forEach((key) => all.push(this._models[key]));
|
|
|
return all;
|
|
|
}
|
|
|
acceptNewModel(data) {
|
|
|
this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId);
|
|
|
}
|
|
|
acceptModelChanged(strURL, e) {
|
|
|
if (!this._models[strURL]) {
|
|
|
return;
|
|
|
}
|
|
|
let model = this._models[strURL];
|
|
|
model.onEvents(e);
|
|
|
}
|
|
|
acceptRemovedModel(strURL) {
|
|
|
if (!this._models[strURL]) {
|
|
|
return;
|
|
|
}
|
|
|
delete this._models[strURL];
|
|
|
}
|
|
|
// ---- BEGIN diff --------------------------------------------------------------------------
|
|
|
computeDiff(originalUrl, modifiedUrl, ignoreTrimWhitespace, maxComputationTime) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const original = this._getModel(originalUrl);
|
|
|
const modified = this._getModel(modifiedUrl);
|
|
|
if (!original || !modified) {
|
|
|
return null;
|
|
|
}
|
|
|
const originalLines = original.getLinesContent();
|
|
|
const modifiedLines = modified.getLinesContent();
|
|
|
const diffComputer = new DiffComputer(originalLines, modifiedLines, {
|
|
|
shouldComputeCharChanges: true,
|
|
|
shouldPostProcessCharChanges: true,
|
|
|
shouldIgnoreTrimWhitespace: ignoreTrimWhitespace,
|
|
|
shouldMakePrettyDiff: true,
|
|
|
maxComputationTime: maxComputationTime
|
|
|
});
|
|
|
const diffResult = diffComputer.computeDiff();
|
|
|
const identical = (diffResult.changes.length > 0 ? false : this._modelsAreIdentical(original, modified));
|
|
|
return {
|
|
|
quitEarly: diffResult.quitEarly,
|
|
|
identical: identical,
|
|
|
changes: diffResult.changes
|
|
|
};
|
|
|
});
|
|
|
}
|
|
|
_modelsAreIdentical(original, modified) {
|
|
|
const originalLineCount = original.getLineCount();
|
|
|
const modifiedLineCount = modified.getLineCount();
|
|
|
if (originalLineCount !== modifiedLineCount) {
|
|
|
return false;
|
|
|
}
|
|
|
for (let line = 1; line <= originalLineCount; line++) {
|
|
|
const originalLine = original.getLineContent(line);
|
|
|
const modifiedLine = modified.getLineContent(line);
|
|
|
if (originalLine !== modifiedLine) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
computeMoreMinimalEdits(modelUrl, edits) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const model = this._getModel(modelUrl);
|
|
|
if (!model) {
|
|
|
return edits;
|
|
|
}
|
|
|
const result = [];
|
|
|
let lastEol = undefined;
|
|
|
edits = edits.slice(0).sort((a, b) => {
|
|
|
if (a.range && b.range) {
|
|
|
return Range.compareRangesUsingStarts(a.range, b.range);
|
|
|
}
|
|
|
// eol only changes should go to the end
|
|
|
let aRng = a.range ? 0 : 1;
|
|
|
let bRng = b.range ? 0 : 1;
|
|
|
return aRng - bRng;
|
|
|
});
|
|
|
for (let { range, text, eol } of edits) {
|
|
|
if (typeof eol === 'number') {
|
|
|
lastEol = eol;
|
|
|
}
|
|
|
if (Range.isEmpty(range) && !text) {
|
|
|
// empty change
|
|
|
continue;
|
|
|
}
|
|
|
const original = model.getValueInRange(range);
|
|
|
text = text.replace(/\r\n|\n|\r/g, model.eol);
|
|
|
if (original === text) {
|
|
|
// noop
|
|
|
continue;
|
|
|
}
|
|
|
// make sure diff won't take too long
|
|
|
if (Math.max(text.length, original.length) > EditorSimpleWorker._diffLimit) {
|
|
|
result.push({ range, text });
|
|
|
continue;
|
|
|
}
|
|
|
// compute diff between original and edit.text
|
|
|
const changes = stringDiff(original, text, false);
|
|
|
const editOffset = model.offsetAt(Range.lift(range).getStartPosition());
|
|
|
for (const change of changes) {
|
|
|
const start = model.positionAt(editOffset + change.originalStart);
|
|
|
const end = model.positionAt(editOffset + change.originalStart + change.originalLength);
|
|
|
const newEdit = {
|
|
|
text: text.substr(change.modifiedStart, change.modifiedLength),
|
|
|
range: { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column }
|
|
|
};
|
|
|
if (model.getValueInRange(newEdit.range) !== newEdit.text) {
|
|
|
result.push(newEdit);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (typeof lastEol === 'number') {
|
|
|
result.push({ eol: lastEol, text: '', range: { startLineNumber: 0, startColumn: 0, endLineNumber: 0, endColumn: 0 } });
|
|
|
}
|
|
|
return result;
|
|
|
});
|
|
|
}
|
|
|
// ---- END minimal edits ---------------------------------------------------------------
|
|
|
computeLinks(modelUrl) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
let model = this._getModel(modelUrl);
|
|
|
if (!model) {
|
|
|
return null;
|
|
|
}
|
|
|
return computeLinks(model);
|
|
|
});
|
|
|
}
|
|
|
textualSuggest(modelUrls, leadingWord, wordDef, wordDefFlags) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const sw = new StopWatch(true);
|
|
|
const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
|
|
|
const seen = new Set();
|
|
|
outer: for (let url of modelUrls) {
|
|
|
const model = this._getModel(url);
|
|
|
if (!model) {
|
|
|
continue;
|
|
|
}
|
|
|
for (let word of model.words(wordDefRegExp)) {
|
|
|
if (word === leadingWord || !isNaN(Number(word))) {
|
|
|
continue;
|
|
|
}
|
|
|
seen.add(word);
|
|
|
if (seen.size > EditorSimpleWorker._suggestionsLimit) {
|
|
|
break outer;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return { words: Array.from(seen), duration: sw.elapsed() };
|
|
|
});
|
|
|
}
|
|
|
// ---- END suggest --------------------------------------------------------------------------
|
|
|
//#region -- word ranges --
|
|
|
computeWordRanges(modelUrl, range, wordDef, wordDefFlags) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
let model = this._getModel(modelUrl);
|
|
|
if (!model) {
|
|
|
return Object.create(null);
|
|
|
}
|
|
|
const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
|
|
|
const result = Object.create(null);
|
|
|
for (let line = range.startLineNumber; line < range.endLineNumber; line++) {
|
|
|
let words = model.getLineWords(line, wordDefRegExp);
|
|
|
for (const word of words) {
|
|
|
if (!isNaN(Number(word.word))) {
|
|
|
continue;
|
|
|
}
|
|
|
let array = result[word.word];
|
|
|
if (!array) {
|
|
|
array = [];
|
|
|
result[word.word] = array;
|
|
|
}
|
|
|
array.push({
|
|
|
startLineNumber: line,
|
|
|
startColumn: word.startColumn,
|
|
|
endLineNumber: line,
|
|
|
endColumn: word.endColumn
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
|
});
|
|
|
}
|
|
|
//#endregion
|
|
|
navigateValueSet(modelUrl, range, up, wordDef, wordDefFlags) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
let model = this._getModel(modelUrl);
|
|
|
if (!model) {
|
|
|
return null;
|
|
|
}
|
|
|
let wordDefRegExp = new RegExp(wordDef, wordDefFlags);
|
|
|
if (range.startColumn === range.endColumn) {
|
|
|
range = {
|
|
|
startLineNumber: range.startLineNumber,
|
|
|
startColumn: range.startColumn,
|
|
|
endLineNumber: range.endLineNumber,
|
|
|
endColumn: range.endColumn + 1
|
|
|
};
|
|
|
}
|
|
|
let selectionText = model.getValueInRange(range);
|
|
|
let wordRange = model.getWordAtPosition({ lineNumber: range.startLineNumber, column: range.startColumn }, wordDefRegExp);
|
|
|
if (!wordRange) {
|
|
|
return null;
|
|
|
}
|
|
|
let word = model.getValueInRange(wordRange);
|
|
|
let result = BasicInplaceReplace.INSTANCE.navigateValueSet(range, selectionText, wordRange, word, up);
|
|
|
return result;
|
|
|
});
|
|
|
}
|
|
|
// ---- BEGIN foreign module support --------------------------------------------------------------------------
|
|
|
loadForeignModule(moduleId, createData, foreignHostMethods) {
|
|
|
const proxyMethodRequest = (method, args) => {
|
|
|
return this._host.fhr(method, args);
|
|
|
};
|
|
|
const foreignHost = createProxyObject(foreignHostMethods, proxyMethodRequest);
|
|
|
let ctx = {
|
|
|
host: foreignHost,
|
|
|
getMirrorModels: () => {
|
|
|
return this._getModels();
|
|
|
}
|
|
|
};
|
|
|
if (this._foreignModuleFactory) {
|
|
|
this._foreignModule = this._foreignModuleFactory(ctx, createData);
|
|
|
// static foreing module
|
|
|
return Promise.resolve(getAllMethodNames(this._foreignModule));
|
|
|
}
|
|
|
// ESM-comment-begin
|
|
|
// return new Promise<any>((resolve, reject) => {
|
|
|
// require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => {
|
|
|
// this._foreignModule = foreignModule.create(ctx, createData);
|
|
|
//
|
|
|
// resolve(types.getAllMethodNames(this._foreignModule));
|
|
|
//
|
|
|
// }, reject);
|
|
|
// });
|
|
|
// ESM-comment-end
|
|
|
// ESM-uncomment-begin
|
|
|
return Promise.reject(new Error(`Unexpected usage`));
|
|
|
// ESM-uncomment-end
|
|
|
}
|
|
|
// foreign method request
|
|
|
fmr(method, args) {
|
|
|
if (!this._foreignModule || typeof this._foreignModule[method] !== 'function') {
|
|
|
return Promise.reject(new Error('Missing requestHandler or method: ' + method));
|
|
|
}
|
|
|
try {
|
|
|
return Promise.resolve(this._foreignModule[method].apply(this._foreignModule, args));
|
|
|
}
|
|
|
catch (e) {
|
|
|
return Promise.reject(e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// ---- END diff --------------------------------------------------------------------------
|
|
|
// ---- BEGIN minimal edits ---------------------------------------------------------------
|
|
|
EditorSimpleWorker._diffLimit = 100000;
|
|
|
// ---- BEGIN suggest --------------------------------------------------------------------------
|
|
|
EditorSimpleWorker._suggestionsLimit = 10000;
|
|
|
/**
|
|
|
* Called on the worker side
|
|
|
* @internal
|
|
|
*/
|
|
|
function editorSimpleWorker_create(host) {
|
|
|
return new EditorSimpleWorker(host, null);
|
|
|
}
|
|
|
if (typeof importScripts === 'function') {
|
|
|
// Running in a web worker
|
|
|
platform_globals.monaco = createMonacoBaseAPI();
|
|
|
}
|
|
|
|
|
|
;// CONCATENATED MODULE: ./node_modules/_monaco-editor@0.30.0@monaco-editor/esm/vs/editor/editor.worker.js
|
|
|
/*---------------------------------------------------------------------------------------------
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
let initialized = false;
|
|
|
function initialize(foreignModule) {
|
|
|
if (initialized) {
|
|
|
return;
|
|
|
}
|
|
|
initialized = true;
|
|
|
const simpleWorker = new SimpleWorkerServer((msg) => {
|
|
|
self.postMessage(msg);
|
|
|
}, (host) => new EditorSimpleWorker(host, foreignModule));
|
|
|
self.onmessage = (e) => {
|
|
|
simpleWorker.onmessage(e.data);
|
|
|
};
|
|
|
}
|
|
|
self.onmessage = (e) => {
|
|
|
// Ignore first message in this case and initialize if not yet initialized
|
|
|
if (!initialized) {
|
|
|
initialize(null);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
}();
|
|
|
/******/ })()
|
|
|
; |