All Downloads are FREE. Search and download functionalities are using the official Maven repository.

theme.keycloak.v2.admin.resources.assets.CodeEditor-e0b9ac78.js.map Maven / Gradle / Ivy

There is a newer version: 25.0.1
Show newest version
{"version":3,"file":"CodeEditor-e0b9ac78.js","sources":["../../../../node_modules/.pnpm/[email protected]/node_modules/file-selector/dist/es5/file.js","../../../../node_modules/.pnpm/[email protected]/node_modules/file-selector/dist/es5/file-selector.js","../../../../node_modules/.pnpm/[email protected]/node_modules/prop-types/lib/ReactPropTypesSecret.js","../../../../node_modules/.pnpm/[email protected]/node_modules/prop-types/factoryWithThrowingShims.js","../../../../node_modules/.pnpm/[email protected]/node_modules/prop-types/index.js","../../../../node_modules/.pnpm/[email protected]/node_modules/attr-accept/dist/index.js","../../../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dropzone/dist/es/utils/index.js","../../../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dropzone/dist/es/index.js","../../../../node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@patternfly/react-icons/dist/esm/icons/code-icon.js","../../../../node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@patternfly/react-icons/dist/esm/icons/download-icon.js","../../../../node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@patternfly/react-icons/dist/esm/icons/upload-icon.js","../../../../node_modules/.pnpm/@[email protected]/node_modules/@patternfly/react-styles/css/components/CodeEditor/code-editor.mjs","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/arrays.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/types.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/objects.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/nls.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/platform.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/textModelDefaults.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/iterator.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/linkedList.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/wordHelper.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/config/editorOptions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/errors.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/functional.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/lifecycle.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/stopwatch.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/event.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/cancellation.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/keyCodes.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/process.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/path.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/uri.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/position.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/range.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/selection.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/codicons.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokenizationRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/standalone/standaloneEnums.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/editorBaseApi.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/cache.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/lazy.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/strings.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/browser.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/fastDomNode.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/domFontInfo.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/charWidthReader.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/config/editorZoom.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/config/fontInfo.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/fontMeasurements.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/instantiation/common/instantiation.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/codeEditorService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/assert.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/audioCues/browser/audioCueService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextkey/common/scanner.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextkey/common/contextkey.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/accessibility/common/accessibility.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffNavigator.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/editorCommon.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/languageConfiguration.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/characterPair.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/buffer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/stringBuilder.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/richEditBrackets.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/electricCharacter.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/indentRules.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/onEnter.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/configuration/common/configuration.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/language.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/instantiation/common/descriptors.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/instantiation/common/extensions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/registry/common/platform.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/mime.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/jsonschemas/common/jsonContributionRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/configuration/common/configurationRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/modesRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/languageBracketsConfiguration.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/languageConfigurationRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/nullTokenize.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/model.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/symbols.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/async.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/worker/simpleWorker.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/trustedTypes.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/defaultWorkerFactory.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/diff/diffChange.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/hash.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/diff/diff.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/uint.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/prefixSumComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/mirrorTextModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/characterClassifier.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/linkComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/inplaceReplaceSupport.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/wordCharacterClassifier.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/textModelSearch.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/unicodeTextModelHighlighter.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/lineRange.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/linesDiffComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/smartLinesDiffComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/offsetRange.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/algorithms/diffAlgorithm.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/algorithms/utils.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/algorithms/joinSequenceDiffs.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/algorithms/myersDiffAlgorithm.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/standardLinesDiffComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/diff/linesDiffComputers.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/color.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/defaultDocumentColorsComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/editorSimpleWorker.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/textResourceConfiguration.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/log/common/log.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/languageFeatures.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/editorWorkerService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/webWorker.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/encodedTokenAttributes.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokens/lineTokens.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewLayout/lineDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewLayout/linePart.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewLayout/viewLineRenderer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/common/monarch/monarchCommon.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/common/monarch/monarchLexer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/colorizer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/canIUse.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/keybindings.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/keyboardEvent.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/iframe.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/mouseEvent.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/dompurify/dompurify.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/network.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/dom.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/aria/aria.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/markerDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/resolverService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/actions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/themables.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/commands/common/commands.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/actions/common/actions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/telemetry/common/telemetry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/editorExtensions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/markerDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/elementSizeObserver.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/migrateOptions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/tabFocus.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/config/editorConfiguration.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/decorators.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/touch.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/globalPointerMoveMonitor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/theme/common/colorRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/editorDom.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewEventHandler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/viewPart.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/renderingContext.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/lines/rangeUtil.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/theme/common/theme.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/lines/viewLine.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/cursorColumns.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorAtomicMoveOperations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/controller/mouseTarget.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/widget.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/scrollbarArrow.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/abstractScrollbar.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/scrollbarState.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/horizontalScrollbar.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/verticalScrollbar.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/scrollable.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/scrollbar/scrollableElement.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/controller/mouseHandler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/event.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/performance.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/controller/textAreaState.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/controller/textAreaInput.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/controller/pointerHandler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/dynamicViewOverlay.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/theme/common/themeService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/editorColorRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/lineNumbers/lineNumbers.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/margin/margin.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/mouseCursor/mouseCursor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/ime.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/controller/textAreaHandler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/indentation.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursorCommon.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorColumnSelection.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/commands/replaceCommand.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorMoveOperations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorDeleteOperations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorWordOperations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorMoveCommands.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/enterAction.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/commands/shiftCommand.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/commands/surroundSelectionCommand.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/autoIndent.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorTypeOperations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/editorContextKeys.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/coreCommands.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/viewController.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/viewUserInputEvents.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/viewLayer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/viewOverlays.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/contentWidgets/contentWidgets.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/decorations/decorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/textModelPart.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/utils.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/textModelGuides.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/guidesTextModelPart.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/indentGuides/indentGuides.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/lines/domReadingContext.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/lines/viewLines.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/glyphMargin/glyphMargin.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/linesDecorations/linesDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/marginDecorations/marginDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/rgba.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/minimapTokensColorTracker.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/minimap/minimapCharSheet.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/minimap/minimapCharRenderer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/minimap/minimapPreBaked.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/minimap/minimapCharRendererFactory.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/minimap/minimap.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/overviewZoneManager.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/overviewRuler/overviewRuler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/rulers/rulers.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/selections/selections.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/viewCursors/viewCursor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/viewCursors/viewCursors.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/viewZones/viewZones.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/editorTheme.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/viewContext.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewLayout/viewLinesViewportData.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/blockDecorations/blockDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/viewParts/whitespace/whitespace.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/editorAction.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/eolCounter.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/textModelBracketPairs.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/smallImmutableSet.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/nodeReader.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/parser.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/textChange.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/extpath.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/resources.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/editStack.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/indentationGuesser.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/intervalTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/fixedArray.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokens/contiguousMultilineTokens.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokens/contiguousMultilineTokensBuilder.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/textModelTokens.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokens/contiguousTokensEditing.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokens/contiguousTokensStore.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/tokens/sparseTokensStore.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/tokenizationTextModelPart.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/textModelEvents.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/undoRedo/common/undoRedo.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/model/textModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/oneCursor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorCollection.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursorContext.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewEvents.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModelEventDispatcher.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/cursor/cursor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/textToHtmlTokenizer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewLayout/linesLayout.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewLayout/viewLayout.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/viewModelDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/modelLineProjection.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/viewModelLines.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/viewModelImpl.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/instantiation/common/serviceCollection.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/severity.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/notification/common/notification.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/modelLineProjectionData.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/viewModel/monospaceLineBreaksComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/view/domLineBreaksComputer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditor.contribution.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/codeEditorContributions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/sash/sash.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/map.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/filters.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/iconLabels.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/htmlContent.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/stableEditorScroll.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/dnd.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/iconLabel/iconLabelHover.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/formattedTextRenderer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/iconLabel/iconLabels.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/idGenerator.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/marked/marked.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/marshalling.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/markdownRenderer.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/splice.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/numbers.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/list.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/range.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/rangeMap.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/rowCache.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/listView.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/listWidget.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/selectBox/selectBoxCustom.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/selectBox/selectBoxNative.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/selectBox/selectBox.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/actionbar/actionViewItems.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/actionbar/actionbar.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/theme/common/iconRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffReview.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/inlineDiffMargin.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/editorWorker.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/workerBasedDocumentDiffProvider.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/clipboard/common/clipboardService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextview/browser/contextView.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/progress/common/progress.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/abstractCodeEditorService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneCodeEditorService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/layout/browser/layoutService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneLayoutService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/dialogs/common/dialogs.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/undoRedo/common/undoRedoService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/environment/common/environment.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/opener/common/opener.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/languageFeatureDebounce.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensProviderStyling.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensStyling.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/semanticTokensStylingService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/glob.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languageSelector.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languageFeatureRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/languageFeaturesService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/bulkEditService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/config/editorConfigurationSchema.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/core/editOperation.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/configuration/common/configurationModels.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/keybindingResolver.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/abstractKeybindingService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/keybinding.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/resolvedKeybindingItem.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/keybindingLabels.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/baseResolvedKeybinding.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/keybinding/common/usLayoutResolvedKeybinding.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/label/common/label.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/ternarySearchTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/workspace/common/workspace.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/standaloneStrings.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/workspace/common/workspaceTrust.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/contextview/contextview.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextview/browser/contextViewService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/languagesAssociations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/languagesRegistry.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/languageService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/dropdown/dropdown.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/dropdown/dropdownActionViewItem.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/action/common/action.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/parts/storage/common/storage.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/storage/common/storage.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/theme/browser/defaultStyles.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/actions/browser/menuEntryActionViewItem.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/menu/menu.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextview/browser/contextMenuHandler.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextview/browser/contextMenuService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/editor/common/editor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/services/openerService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/markers/common/markers.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/markerDecorationsService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/services/modelService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/list/listPaging.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/splitview/splitview.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/table/tableWidget.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/toggle/toggle.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/findinput/findInputToggles.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/navigator.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/history.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/inputbox/inputBox.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/findinput/findInput.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/tree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/indexTreeModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/collections.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/abstractTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/objectTreeModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/compressedObjectTreeModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/objectTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/asyncDataTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/tree/dataTree.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextkey/common/contextkeys.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/list/browser/listService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/common/quickAccess.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/common/quickInput.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/browser/quickAccess.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/button/button.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/countBadge/countBadge.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/progressbar/progressbar.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/browser/quickInputBox.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/highlightedlabel/highlightedLabel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/iconLabel/iconLabel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/browser/ui/keybindingLabel/keybindingLabel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/comparers.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/linkedText.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/browser/quickInputUtils.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/browser/quickInputList.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/browser/quickInput.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/quickinput/browser/quickInputService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/quickInput/standaloneQuickInputService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/languages/supports/tokenization.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/common/themes.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/theme/browser/iconsStyleSheet.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneThemeService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/common/standaloneTheme.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/accessibility/browser/accessibilityService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/actions/common/menuService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/clipboard/browser/clipboardService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/contextkey/browser/contextKeyService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/instantiation/common/graph.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/instantiation/common/instantiationService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/markers/common/markerService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/configuration/common/configurations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/log/common/logService.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/common/editorFeatures.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneServices.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/observableImpl/logging.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/observableImpl/base.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/observableImpl/derived.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/observableImpl/autorun.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/base/common/observableImpl/utils.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/decorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/utils.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffEditorSash.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffReview.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/inlineDiffDeletedCodeMargin.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/renderLines.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/delegatingEditorImpl.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneCodeEditor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneEditor.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/common/monarch/monarchCompile.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/standalone/browser/standaloneLanguages.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/contrib/editorState/browser/keybindingCancellation.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/platform/extensions/common/extensions.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/contrib/format/browser/format.js","../../../../node_modules/.pnpm/[email protected]/node_modules/monaco-editor/esm/vs/editor/editor.api.js","../../../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/react-monaco-editor/lib/utils.js","../../../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/react-monaco-editor/lib/diff.js","../../../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/react-monaco-editor/lib/editor.js","../../../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@patternfly/react-code-editor/dist/esm/components/CodeEditor/CodeEditorUtils.js","../../../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@patternfly/react-code-editor/dist/esm/components/CodeEditor/CodeEditorControl.js","../../../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@patternfly/react-code-editor/dist/esm/components/CodeEditor/CodeEditor.js"],"sourcesContent":["export var COMMON_MIME_TYPES = new Map([\n    ['avi', 'video/avi'],\n    ['gif', 'image/gif'],\n    ['ico', 'image/x-icon'],\n    ['jpeg', 'image/jpeg'],\n    ['jpg', 'image/jpeg'],\n    ['mkv', 'video/x-matroska'],\n    ['mov', 'video/quicktime'],\n    ['mp4', 'video/mp4'],\n    ['pdf', 'application/pdf'],\n    ['png', 'image/png'],\n    ['zip', 'application/zip'],\n    ['doc', 'application/msword'],\n    ['docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']\n]);\nexport function toFileWithPath(file, path) {\n    var f = withMimeType(file);\n    if (typeof f.path !== 'string') { // on electron, path is already set to the absolute path\n        var webkitRelativePath = file.webkitRelativePath;\n        Object.defineProperty(f, 'path', {\n            value: typeof path === 'string'\n                ? path\n                // If  is set,\n                // the File will have a {webkitRelativePath} property\n                // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory\n                : typeof webkitRelativePath === 'string' && webkitRelativePath.length > 0\n                    ? webkitRelativePath\n                    : file.name,\n            writable: false,\n            configurable: false,\n            enumerable: true\n        });\n    }\n    return f;\n}\nfunction withMimeType(file) {\n    var name = file.name;\n    var hasExtension = name && name.lastIndexOf('.') !== -1;\n    if (hasExtension && !file.type) {\n        var ext = name.split('.')\n            .pop().toLowerCase();\n        var type = COMMON_MIME_TYPES.get(ext);\n        if (type) {\n            Object.defineProperty(file, 'type', {\n                value: type,\n                writable: false,\n                configurable: false,\n                enumerable: true\n            });\n        }\n    }\n    return file;\n}\n//# sourceMappingURL=file.js.map","import { __awaiter, __generator, __read, __spread } from \"tslib\";\nimport { toFileWithPath } from './file';\nvar FILES_TO_IGNORE = [\n    // Thumbnail cache files for macOS and Windows\n    '.DS_Store',\n    'Thumbs.db' // Windows\n];\n/**\n * Convert a DragEvent's DataTrasfer object to a list of File objects\n * NOTE: If some of the items are folders,\n * everything will be flattened and placed in the same list but the paths will be kept as a {path} property.\n * @param evt\n */\nexport function fromEvent(evt) {\n    return __awaiter(this, void 0, void 0, function () {\n        return __generator(this, function (_a) {\n            return [2 /*return*/, isDragEvt(evt) && evt.dataTransfer\n                    ? getDataTransferFiles(evt.dataTransfer, evt.type)\n                    : getInputFiles(evt)];\n        });\n    });\n}\nfunction isDragEvt(value) {\n    return !!value.dataTransfer;\n}\nfunction getInputFiles(evt) {\n    var files = isInput(evt.target)\n        ? evt.target.files\n            ? fromList(evt.target.files)\n            : []\n        : [];\n    return files.map(function (file) { return toFileWithPath(file); });\n}\nfunction isInput(value) {\n    return value !== null;\n}\nfunction getDataTransferFiles(dt, type) {\n    return __awaiter(this, void 0, void 0, function () {\n        var items, files;\n        return __generator(this, function (_a) {\n            switch (_a.label) {\n                case 0:\n                    if (!dt.items) return [3 /*break*/, 2];\n                    items = fromList(dt.items)\n                        .filter(function (item) { return item.kind === 'file'; });\n                    // According to https://html.spec.whatwg.org/multipage/dnd.html#dndevents,\n                    // only 'dragstart' and 'drop' has access to the data (source node)\n                    if (type !== 'drop') {\n                        return [2 /*return*/, items];\n                    }\n                    return [4 /*yield*/, Promise.all(items.map(toFilePromises))];\n                case 1:\n                    files = _a.sent();\n                    return [2 /*return*/, noIgnoredFiles(flatten(files))];\n                case 2: return [2 /*return*/, noIgnoredFiles(fromList(dt.files)\n                        .map(function (file) { return toFileWithPath(file); }))];\n            }\n        });\n    });\n}\nfunction noIgnoredFiles(files) {\n    return files.filter(function (file) { return FILES_TO_IGNORE.indexOf(file.name) === -1; });\n}\n// IE11 does not support Array.from()\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibility\n// https://developer.mozilla.org/en-US/docs/Web/API/FileList\n// https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItemList\nfunction fromList(items) {\n    var files = [];\n    // tslint:disable: prefer-for-of\n    for (var i = 0; i < items.length; i++) {\n        var file = items[i];\n        files.push(file);\n    }\n    return files;\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem\nfunction toFilePromises(item) {\n    if (typeof item.webkitGetAsEntry !== 'function') {\n        return fromDataTransferItem(item);\n    }\n    var entry = item.webkitGetAsEntry();\n    // Safari supports dropping an image node from a different window and can be retrieved using\n    // the DataTransferItem.getAsFile() API\n    // NOTE: FileSystemEntry.file() throws if trying to get the file\n    if (entry && entry.isDirectory) {\n        return fromDirEntry(entry);\n    }\n    return fromDataTransferItem(item);\n}\nfunction flatten(items) {\n    return items.reduce(function (acc, files) { return __spread(acc, (Array.isArray(files) ? flatten(files) : [files])); }, []);\n}\nfunction fromDataTransferItem(item) {\n    var file = item.getAsFile();\n    if (!file) {\n        return Promise.reject(item + \" is not a File\");\n    }\n    var fwp = toFileWithPath(file);\n    return Promise.resolve(fwp);\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemEntry\nfunction fromEntry(entry) {\n    return __awaiter(this, void 0, void 0, function () {\n        return __generator(this, function (_a) {\n            return [2 /*return*/, entry.isDirectory ? fromDirEntry(entry) : fromFileEntry(entry)];\n        });\n    });\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryEntry\nfunction fromDirEntry(entry) {\n    var reader = entry.createReader();\n    return new Promise(function (resolve, reject) {\n        var entries = [];\n        function readEntries() {\n            var _this = this;\n            // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryEntry/createReader\n            // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryReader/readEntries\n            reader.readEntries(function (batch) { return __awaiter(_this, void 0, void 0, function () {\n                var files, err_1, items;\n                return __generator(this, function (_a) {\n                    switch (_a.label) {\n                        case 0:\n                            if (!!batch.length) return [3 /*break*/, 5];\n                            _a.label = 1;\n                        case 1:\n                            _a.trys.push([1, 3, , 4]);\n                            return [4 /*yield*/, Promise.all(entries)];\n                        case 2:\n                            files = _a.sent();\n                            resolve(files);\n                            return [3 /*break*/, 4];\n                        case 3:\n                            err_1 = _a.sent();\n                            reject(err_1);\n                            return [3 /*break*/, 4];\n                        case 4: return [3 /*break*/, 6];\n                        case 5:\n                            items = Promise.all(batch.map(fromEntry));\n                            entries.push(items);\n                            // Continue reading\n                            readEntries();\n                            _a.label = 6;\n                        case 6: return [2 /*return*/];\n                    }\n                });\n            }); }, function (err) {\n                reject(err);\n            });\n        }\n        readEntries();\n    });\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry\nfunction fromFileEntry(entry) {\n    return __awaiter(this, void 0, void 0, function () {\n        return __generator(this, function (_a) {\n            return [2 /*return*/, new Promise(function (resolve, reject) {\n                    entry.file(function (file) {\n                        var fwp = toFileWithPath(file, entry.fullPath);\n                        resolve(fwp);\n                    }, function (err) {\n                        reject(err);\n                    });\n                })];\n        });\n    });\n}\n//# sourceMappingURL=file-selector.js.map","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n  function shim(props, propName, componentName, location, propFullName, secret) {\n    if (secret === ReactPropTypesSecret) {\n      // It is still safe when called from React.\n      return;\n    }\n    var err = new Error(\n      'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n      'Use PropTypes.checkPropTypes() to call them. ' +\n      'Read more at http://fb.me/use-check-prop-types'\n    );\n    err.name = 'Invariant Violation';\n    throw err;\n  };\n  shim.isRequired = shim;\n  function getShim() {\n    return shim;\n  };\n  // Important!\n  // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n  var ReactPropTypes = {\n    array: shim,\n    bigint: shim,\n    bool: shim,\n    func: shim,\n    number: shim,\n    object: shim,\n    string: shim,\n    symbol: shim,\n\n    any: shim,\n    arrayOf: getShim,\n    element: shim,\n    elementType: shim,\n    instanceOf: getShim,\n    node: shim,\n    objectOf: getShim,\n    oneOf: getShim,\n    oneOfType: getShim,\n    shape: getShim,\n    exact: getShim,\n\n    checkPropTypes: emptyFunctionWithReset,\n    resetWarningCache: emptyFunction\n  };\n\n  ReactPropTypes.PropTypes = ReactPropTypes;\n\n  return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n  var ReactIs = require('react-is');\n\n  // By explicitly using `prop-types` you are opting into new development behavior.\n  // http://fb.me/prop-types-in-prod\n  var throwOnDirectAccess = true;\n  module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n  // By explicitly using `prop-types` you are opting into new production behavior.\n  // http://fb.me/prop-types-in-prod\n  module.exports = require('./factoryWithThrowingShims')();\n}\n","module.exports=function(t){function n(e){if(r[e])return r[e].exports;var o=r[e]={i:e,l:!1,exports:{}};return t[e].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r={};return n.m=t,n.c=r,n.d=function(t,r,e){n.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(r,\"a\",r),r},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p=\"\",n(n.s=13)}([function(t,n){var r=t.exports=\"undefined\"!=typeof window&&window.Math==Math?window:\"undefined\"!=typeof self&&self.Math==Math?self:Function(\"return this\")();\"number\"==typeof __g&&(__g=r)},function(t,n){t.exports=function(t){return\"object\"==typeof t?null!==t:\"function\"==typeof t}},function(t,n){var r=t.exports={version:\"2.5.0\"};\"number\"==typeof __e&&(__e=r)},function(t,n,r){t.exports=!r(4)(function(){return 7!=Object.defineProperty({},\"a\",{get:function(){return 7}}).a})},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n,r){var e=r(32)(\"wks\"),o=r(9),i=r(0).Symbol,u=\"function\"==typeof i;(t.exports=function(t){return e[t]||(e[t]=u&&i[t]||(u?i:o)(\"Symbol.\"+t))}).store=e},function(t,n,r){var e=r(0),o=r(2),i=r(8),u=r(22),c=r(10),f=function(t,n,r){var a,s,p,l,v=t&f.F,y=t&f.G,h=t&f.S,d=t&f.P,x=t&f.B,g=y?e:h?e[n]||(e[n]={}):(e[n]||{}).prototype,m=y?o:o[n]||(o[n]={}),b=m.prototype||(m.prototype={});y&&(r=n);for(a in r)s=!v&&g&&void 0!==g[a],p=(s?g:r)[a],l=x&&s?c(p,e):d&&\"function\"==typeof p?c(Function.call,p):p,g&&u(g,a,p,t&f.U),m[a]!=p&&i(m,a,l),d&&b[a]!=p&&(b[a]=p)};e.core=o,f.F=1,f.G=2,f.S=4,f.P=8,f.B=16,f.W=32,f.U=64,f.R=128,t.exports=f},function(t,n,r){var e=r(16),o=r(21);t.exports=r(3)?function(t,n,r){return e.f(t,n,o(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return\"Symbol(\".concat(void 0===t?\"\":t,\")_\",(++r+e).toString(36))}},function(t,n,r){var e=r(24);t.exports=function(t,n,r){if(e(t),void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 2:return function(r,e){return t.call(n,r,e)};case 3:return function(r,e,o){return t.call(n,r,e,o)}}return function(){return t.apply(n,arguments)}}},function(t,n){t.exports=function(t){if(void 0==t)throw TypeError(\"Can't call method on  \"+t);return t}},function(t,n,r){var e=r(28),o=Math.min;t.exports=function(t){return t>0?o(e(t),9007199254740991):0}},function(t,n,r){\"use strict\";n.__esModule=!0,n.default=function(t,n){if(t&&n){var r=Array.isArray(n)?n:n.split(\",\"),e=t.name||\"\",o=t.type||\"\",i=o.replace(/\\/.*$/,\"\");return r.some(function(t){var n=t.trim();return\".\"===n.charAt(0)?e.toLowerCase().endsWith(n.toLowerCase()):n.endsWith(\"/*\")?i===n.replace(/\\/.*$/,\"\"):o===n})}return!0},r(14),r(34)},function(t,n,r){r(15),t.exports=r(2).Array.some},function(t,n,r){\"use strict\";var e=r(7),o=r(25)(3);e(e.P+e.F*!r(33)([].some,!0),\"Array\",{some:function(t){return o(this,t,arguments[1])}})},function(t,n,r){var e=r(17),o=r(18),i=r(20),u=Object.defineProperty;n.f=r(3)?Object.defineProperty:function(t,n,r){if(e(t),n=i(n,!0),e(r),o)try{return u(t,n,r)}catch(t){}if(\"get\"in r||\"set\"in r)throw TypeError(\"Accessors not supported!\");return\"value\"in r&&(t[n]=r.value),t}},function(t,n,r){var e=r(1);t.exports=function(t){if(!e(t))throw TypeError(t+\" is not an object!\");return t}},function(t,n,r){t.exports=!r(3)&&!r(4)(function(){return 7!=Object.defineProperty(r(19)(\"div\"),\"a\",{get:function(){return 7}}).a})},function(t,n,r){var e=r(1),o=r(0).document,i=e(o)&&e(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},function(t,n,r){var e=r(1);t.exports=function(t,n){if(!e(t))return t;var r,o;if(n&&\"function\"==typeof(r=t.toString)&&!e(o=r.call(t)))return o;if(\"function\"==typeof(r=t.valueOf)&&!e(o=r.call(t)))return o;if(!n&&\"function\"==typeof(r=t.toString)&&!e(o=r.call(t)))return o;throw TypeError(\"Can't convert object to primitive value\")}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n,r){var e=r(0),o=r(8),i=r(23),u=r(9)(\"src\"),c=Function.toString,f=(\"\"+c).split(\"toString\");r(2).inspectSource=function(t){return c.call(t)},(t.exports=function(t,n,r,c){var a=\"function\"==typeof r;a&&(i(r,\"name\")||o(r,\"name\",n)),t[n]!==r&&(a&&(i(r,u)||o(r,u,t[n]?\"\"+t[n]:f.join(String(n)))),t===e?t[n]=r:c?t[n]?t[n]=r:o(t,n,r):(delete t[n],o(t,n,r)))})(Function.prototype,\"toString\",function(){return\"function\"==typeof this&&this[u]||c.call(this)})},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n){t.exports=function(t){if(\"function\"!=typeof t)throw TypeError(t+\" is not a function!\");return t}},function(t,n,r){var e=r(10),o=r(26),i=r(27),u=r(12),c=r(29);t.exports=function(t,n){var r=1==t,f=2==t,a=3==t,s=4==t,p=6==t,l=5==t||p,v=n||c;return function(n,c,y){for(var h,d,x=i(n),g=o(x),m=e(c,y,3),b=u(g.length),_=0,w=r?v(n,b):f?v(n,0):void 0;b>_;_++)if((l||_ in g)&&(h=g[_],d=m(h,_,x),t))if(r)w[_]=d;else if(d)switch(t){case 3:return!0;case 5:return h;case 6:return _;case 2:w.push(h)}else if(s)return!1;return p?-1:a||s?s:w}}},function(t,n,r){var e=r(5);t.exports=Object(\"z\").propertyIsEnumerable(0)?Object:function(t){return\"String\"==e(t)?t.split(\"\"):Object(t)}},function(t,n,r){var e=r(11);t.exports=function(t){return Object(e(t))}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?e:r)(t)}},function(t,n,r){var e=r(30);t.exports=function(t,n){return new(e(t))(n)}},function(t,n,r){var e=r(1),o=r(31),i=r(6)(\"species\");t.exports=function(t){var n;return o(t)&&(n=t.constructor,\"function\"!=typeof n||n!==Array&&!o(n.prototype)||(n=void 0),e(n)&&null===(n=n[i])&&(n=void 0)),void 0===n?Array:n}},function(t,n,r){var e=r(5);t.exports=Array.isArray||function(t){return\"Array\"==e(t)}},function(t,n,r){var e=r(0),o=e[\"__core-js_shared__\"]||(e[\"__core-js_shared__\"]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,n,r){\"use strict\";var e=r(4);t.exports=function(t,n){return!!t&&e(function(){n?t.call(null,function(){},1):t.call(null)})}},function(t,n,r){r(35),t.exports=r(2).String.endsWith},function(t,n,r){\"use strict\";var e=r(7),o=r(12),i=r(36),u=\"\".endsWith;e(e.P+e.F*r(38)(\"endsWith\"),\"String\",{endsWith:function(t){var n=i(this,t,\"endsWith\"),r=arguments.length>1?arguments[1]:void 0,e=o(n.length),c=void 0===r?e:Math.min(o(r),e),f=String(t);return u?u.call(n,f,c):n.slice(c-f.length,c)===f}})},function(t,n,r){var e=r(37),o=r(11);t.exports=function(t,n,r){if(e(n))throw TypeError(\"String#\"+r+\" doesn't accept regex!\");return String(o(t))}},function(t,n,r){var e=r(1),o=r(5),i=r(6)(\"match\");t.exports=function(t){var n;return e(t)&&(void 0!==(n=t[i])?!!n:\"RegExp\"==o(t))}},function(t,n,r){var e=r(6)(\"match\");t.exports=function(t){var n=/./;try{\"/./\"[t](n)}catch(r){try{return n[e]=!1,!\"/./\"[t](n)}catch(t){}}return!0}}]);","var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nimport accepts from 'attr-accept';\n\nexport var supportMultiple = typeof document !== 'undefined' && document && document.createElement ? 'multiple' in document.createElement('input') : true;\n\n// Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with\n// that MIME type will always be accepted\nexport function fileAccepted(file, accept) {\n  return file.type === 'application/x-moz-file' || accepts(file, accept);\n}\n\nexport function fileMatchSize(file, maxSize, minSize) {\n  return file.size <= maxSize && file.size >= minSize;\n}\n\nexport function allFilesAccepted(files, accept) {\n  return files.every(function (file) {\n    return fileAccepted(file, accept);\n  });\n}\n\n// React's synthetic events has evt.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check evt.cancelBubble\nexport function isPropagationStopped(evt) {\n  if (typeof evt.isPropagationStopped === 'function') {\n    return evt.isPropagationStopped();\n  } else if (typeof evt.cancelBubble !== 'undefined') {\n    return evt.cancelBubble;\n  }\n  return false;\n}\n\n// React's synthetic events has evt.isDefaultPrevented,\n// but to remain compatibility with other libs (Preact) first\n// check evt.defaultPrevented\nexport function isDefaultPrevented(evt) {\n  if (typeof evt.defaultPrevented !== 'undefined') {\n    return evt.defaultPrevented;\n  } else if (typeof evt.isDefaultPrevented === 'function') {\n    return evt.isDefaultPrevented();\n  }\n  return false;\n}\n\nexport function isDragDataWithFiles(evt) {\n  if (!evt.dataTransfer) {\n    return true;\n  }\n  // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n  // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n  return Array.prototype.some.call(evt.dataTransfer.types, function (type) {\n    return type === 'Files' || type === 'application/x-moz-file';\n  });\n}\n\nexport function isKindFile(item) {\n  return (typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' && item !== null && item.kind === 'file';\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(evt) {\n  evt.preventDefault();\n}\n\nfunction isIe(userAgent) {\n  return userAgent.indexOf('MSIE') !== -1 || userAgent.indexOf('Trident/') !== -1;\n}\n\nfunction isEdge(userAgent) {\n  return userAgent.indexOf('Edge/') !== -1;\n}\n\nexport function isIeOrEdge() {\n  var userAgent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.navigator.userAgent;\n\n  return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers\n * They are executed in order until one of them calls `event.preventDefault()`.\n * Not sure this is the best way to do this, but it seems legit.\n * @param {Function} fns the event hanlder functions\n * @return {Function} the event handler to add to an element\n */\nexport function composeEventHandlers() {\n  for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) {\n    fns[_key] = arguments[_key];\n  }\n\n  return function (event) {\n    for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n      args[_key2 - 1] = arguments[_key2];\n    }\n\n    return fns.some(function (fn) {\n      fn && fn.apply(undefined, [event].concat(args));\n      return event.defaultPrevented;\n    });\n  };\n}","var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n/* eslint prefer-template: 0 */\n\nimport React from 'react';\nimport { fromEvent } from 'file-selector';\nimport PropTypes from 'prop-types';\nimport { isDragDataWithFiles, supportMultiple, fileAccepted, allFilesAccepted, fileMatchSize, onDocumentDragOver, isIeOrEdge, composeEventHandlers, isPropagationStopped, isDefaultPrevented } from './utils';\n\nvar Dropzone = function (_React$Component) {\n  _inherits(Dropzone, _React$Component);\n\n  function Dropzone() {\n    var _ref;\n\n    var _temp, _this, _ret;\n\n    _classCallCheck(this, Dropzone);\n\n    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call.apply(_ref, [this].concat(args))), _this), _this.state = {\n      draggedFiles: [],\n      acceptedFiles: [],\n      rejectedFiles: []\n    }, _this.isFileDialogActive = false, _this.onDocumentDrop = function (evt) {\n      if (_this.node && _this.node.contains(evt.target)) {\n        // if we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n        return;\n      }\n      evt.preventDefault();\n      _this.dragTargets = [];\n    }, _this.onDragStart = function (evt) {\n      evt.persist();\n      if (_this.props.onDragStart && isDragDataWithFiles(evt)) {\n        _this.props.onDragStart.call(_this, evt);\n      }\n    }, _this.onDragEnter = function (evt) {\n      evt.preventDefault();\n\n      // Count the dropzone and any children that are entered.\n      if (_this.dragTargets.indexOf(evt.target) === -1) {\n        _this.dragTargets.push(evt.target);\n      }\n\n      evt.persist();\n\n      if (isDragDataWithFiles(evt)) {\n        Promise.resolve(_this.props.getDataTransferItems(evt)).then(function (draggedFiles) {\n          if (isPropagationStopped(evt)) {\n            return;\n          }\n\n          _this.setState({\n            draggedFiles: draggedFiles,\n            // Do not rely on files for the drag state. It doesn't work in Safari.\n            isDragActive: true\n          });\n        });\n\n        if (_this.props.onDragEnter) {\n          _this.props.onDragEnter.call(_this, evt);\n        }\n      }\n    }, _this.onDragOver = function (evt) {\n      // eslint-disable-line class-methods-use-this\n      evt.preventDefault();\n      evt.persist();\n\n      if (evt.dataTransfer) {\n        evt.dataTransfer.dropEffect = 'copy';\n      }\n\n      if (_this.props.onDragOver && isDragDataWithFiles(evt)) {\n        _this.props.onDragOver.call(_this, evt);\n      }\n\n      return false;\n    }, _this.onDragLeave = function (evt) {\n      evt.preventDefault();\n      evt.persist();\n\n      // Only deactivate once the dropzone and all children have been left.\n      _this.dragTargets = _this.dragTargets.filter(function (el) {\n        return el !== evt.target && _this.node.contains(el);\n      });\n      if (_this.dragTargets.length > 0) {\n        return;\n      }\n\n      // Clear dragging files state\n      _this.setState({\n        isDragActive: false,\n        draggedFiles: []\n      });\n\n      if (_this.props.onDragLeave && isDragDataWithFiles(evt)) {\n        _this.props.onDragLeave.call(_this, evt);\n      }\n    }, _this.onDrop = function (evt) {\n      var _this$props = _this.props,\n          onDrop = _this$props.onDrop,\n          onDropAccepted = _this$props.onDropAccepted,\n          onDropRejected = _this$props.onDropRejected,\n          multiple = _this$props.multiple,\n          accept = _this$props.accept,\n          getDataTransferItems = _this$props.getDataTransferItems;\n\n      // Stop default browser behavior\n\n      evt.preventDefault();\n\n      // Persist event for later usage\n      evt.persist();\n\n      // Reset the counter along with the drag on a drop.\n      _this.dragTargets = [];\n      _this.isFileDialogActive = false;\n\n      // Clear files value\n      _this.draggedFiles = null;\n\n      // Reset drag state\n      _this.setState({\n        isDragActive: false,\n        draggedFiles: []\n      });\n\n      if (isDragDataWithFiles(evt)) {\n        Promise.resolve(getDataTransferItems(evt)).then(function (fileList) {\n          var acceptedFiles = [];\n          var rejectedFiles = [];\n\n          if (isPropagationStopped(evt)) {\n            return;\n          }\n\n          fileList.forEach(function (file) {\n            if (fileAccepted(file, accept) && fileMatchSize(file, _this.props.maxSize, _this.props.minSize)) {\n              acceptedFiles.push(file);\n            } else {\n              rejectedFiles.push(file);\n            }\n          });\n\n          if (!multiple && acceptedFiles.length > 1) {\n            // if not in multi mode add any extra accepted files to rejected.\n            // This will allow end users to easily ignore a multi file drop in \"single\" mode.\n            rejectedFiles.push.apply(rejectedFiles, _toConsumableArray(acceptedFiles.splice(0)));\n          }\n\n          // Update `acceptedFiles` and `rejectedFiles` state\n          // This will make children render functions receive the appropriate\n          // values\n          _this.setState({ acceptedFiles: acceptedFiles, rejectedFiles: rejectedFiles }, function () {\n            if (onDrop) {\n              onDrop.call(_this, acceptedFiles, rejectedFiles, evt);\n            }\n\n            if (rejectedFiles.length > 0 && onDropRejected) {\n              onDropRejected.call(_this, rejectedFiles, evt);\n            }\n\n            if (acceptedFiles.length > 0 && onDropAccepted) {\n              onDropAccepted.call(_this, acceptedFiles, evt);\n            }\n          });\n        });\n      }\n    }, _this.onClick = function (evt) {\n      var onClick = _this.props.onClick;\n\n      // if onClick prop is given, run it first\n\n      if (onClick) {\n        onClick.call(_this, evt);\n      }\n\n      // If the event hasn't been default prevented from within\n      // the onClick listener, open the file dialog\n      if (!isDefaultPrevented(evt)) {\n        evt.stopPropagation();\n\n        // in IE11/Edge the file-browser dialog is blocking, ensure this is behind setTimeout\n        // this is so react can handle state changes in the onClick prop above above\n        // see: https://github.com/react-dropzone/react-dropzone/issues/450\n        if (isIeOrEdge()) {\n          setTimeout(_this.open, 0);\n        } else {\n          _this.open();\n        }\n      }\n    }, _this.onInputElementClick = function (evt) {\n      evt.stopPropagation();\n    }, _this.onFileDialogCancel = function () {\n      // timeout will not recognize context of this method\n      var onFileDialogCancel = _this.props.onFileDialogCancel;\n      // execute the timeout only if the FileDialog is opened in the browser\n\n      if (_this.isFileDialogActive) {\n        setTimeout(function () {\n          if (_this.input != null) {\n            // Returns an object as FileList\n            var files = _this.input.files;\n\n\n            if (!files.length) {\n              _this.isFileDialogActive = false;\n\n              if (typeof onFileDialogCancel === 'function') {\n                onFileDialogCancel();\n              }\n            }\n          }\n        }, 300);\n      }\n    }, _this.onFocus = function (evt) {\n      var onFocus = _this.props.onFocus;\n\n      if (onFocus) {\n        onFocus.call(_this, evt);\n      }\n      if (!isDefaultPrevented(evt)) {\n        _this.setState({ isFocused: true });\n      }\n    }, _this.onBlur = function (evt) {\n      var onBlur = _this.props.onBlur;\n\n      if (onBlur) {\n        onBlur.call(_this, evt);\n      }\n      if (!isDefaultPrevented(evt)) {\n        _this.setState({ isFocused: false });\n      }\n    }, _this.onKeyDown = function (evt) {\n      var onKeyDown = _this.props.onKeyDown;\n\n      if (!_this.node.isEqualNode(evt.target)) {\n        return;\n      }\n\n      if (onKeyDown) {\n        onKeyDown.call(_this, evt);\n      }\n\n      if (!isDefaultPrevented(evt) && (evt.keyCode === 32 || evt.keyCode === 13)) {\n        evt.preventDefault();\n        _this.open();\n      }\n    }, _this.composeHandler = function (handler) {\n      if (_this.props.disabled) {\n        return null;\n      }\n      return handler;\n    }, _this.getRootProps = function () {\n      var _extends2;\n\n      var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      var _ref2$refKey = _ref2.refKey,\n          refKey = _ref2$refKey === undefined ? 'ref' : _ref2$refKey,\n          onKeyDown = _ref2.onKeyDown,\n          onFocus = _ref2.onFocus,\n          onBlur = _ref2.onBlur,\n          onClick = _ref2.onClick,\n          onDragStart = _ref2.onDragStart,\n          onDragEnter = _ref2.onDragEnter,\n          onDragOver = _ref2.onDragOver,\n          onDragLeave = _ref2.onDragLeave,\n          onDrop = _ref2.onDrop,\n          rest = _objectWithoutProperties(_ref2, ['refKey', 'onKeyDown', 'onFocus', 'onBlur', 'onClick', 'onDragStart', 'onDragEnter', 'onDragOver', 'onDragLeave', 'onDrop']);\n\n      return _extends((_extends2 = {\n        onKeyDown: _this.composeHandler(onKeyDown ? composeEventHandlers(onKeyDown, _this.onKeyDown) : _this.onKeyDown),\n        onFocus: _this.composeHandler(onFocus ? composeEventHandlers(onFocus, _this.onFocus) : _this.onFocus),\n        onBlur: _this.composeHandler(onBlur ? composeEventHandlers(onBlur, _this.onBlur) : _this.onBlur),\n        onClick: _this.composeHandler(onClick ? composeEventHandlers(onClick, _this.onClick) : _this.onClick),\n        onDragStart: _this.composeHandler(onDragStart ? composeEventHandlers(onDragStart, _this.onDragStart) : _this.onDragStart),\n        onDragEnter: _this.composeHandler(onDragEnter ? composeEventHandlers(onDragEnter, _this.onDragEnter) : _this.onDragEnter),\n        onDragOver: _this.composeHandler(onDragOver ? composeEventHandlers(onDragOver, _this.onDragOver) : _this.onDragOver),\n        onDragLeave: _this.composeHandler(onDragLeave ? composeEventHandlers(onDragLeave, _this.onDragLeave) : _this.onDragLeave),\n        onDrop: _this.composeHandler(onDrop ? composeEventHandlers(onDrop, _this.onDrop) : _this.onDrop)\n      }, _defineProperty(_extends2, refKey, _this.setNodeRef), _defineProperty(_extends2, 'tabIndex', _this.props.disabled ? -1 : 0), _extends2), rest);\n    }, _this.getInputProps = function () {\n      var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      var _ref3$refKey = _ref3.refKey,\n          refKey = _ref3$refKey === undefined ? 'ref' : _ref3$refKey,\n          onChange = _ref3.onChange,\n          onClick = _ref3.onClick,\n          rest = _objectWithoutProperties(_ref3, ['refKey', 'onChange', 'onClick']);\n\n      var _this$props2 = _this.props,\n          accept = _this$props2.accept,\n          multiple = _this$props2.multiple,\n          name = _this$props2.name;\n\n      var inputProps = _defineProperty({\n        accept: accept,\n        type: 'file',\n        style: { display: 'none' },\n        multiple: supportMultiple && multiple,\n        onChange: composeEventHandlers(onChange, _this.onDrop),\n        onClick: composeEventHandlers(onClick, _this.onInputElementClick),\n        autoComplete: 'off',\n        tabIndex: -1\n      }, refKey, _this.setInputRef);\n      if (name && name.length) {\n        inputProps.name = name;\n      }\n      return _extends({}, inputProps, rest);\n    }, _this.setNodeRef = function (node) {\n      _this.node = node;\n    }, _this.setInputRef = function (input) {\n      _this.input = input;\n    }, _this.open = function () {\n      _this.isFileDialogActive = true;\n      if (_this.input) {\n        _this.input.value = null;\n        _this.input.click();\n      }\n    }, _temp), _possibleConstructorReturn(_this, _ret);\n  }\n\n  _createClass(Dropzone, [{\n    key: 'componentDidMount',\n    value: function componentDidMount() {\n      var preventDropOnDocument = this.props.preventDropOnDocument;\n\n      this.dragTargets = [];\n\n      if (preventDropOnDocument) {\n        document.addEventListener('dragover', onDocumentDragOver, false);\n        document.addEventListener('drop', this.onDocumentDrop, false);\n      }\n\n      window.addEventListener('focus', this.onFileDialogCancel, false);\n    }\n  }, {\n    key: 'componentWillUnmount',\n    value: function componentWillUnmount() {\n      var preventDropOnDocument = this.props.preventDropOnDocument;\n\n      if (preventDropOnDocument) {\n        document.removeEventListener('dragover', onDocumentDragOver);\n        document.removeEventListener('drop', this.onDocumentDrop);\n      }\n\n      window.removeEventListener('focus', this.onFileDialogCancel, false);\n    }\n\n    /**\n     * Open system file upload dialog.\n     *\n     * @public\n     */\n\n  }, {\n    key: 'render',\n    value: function render() {\n      var _props = this.props,\n          children = _props.children,\n          multiple = _props.multiple,\n          disabled = _props.disabled;\n      var _state = this.state,\n          isDragActive = _state.isDragActive,\n          isFocused = _state.isFocused,\n          draggedFiles = _state.draggedFiles,\n          acceptedFiles = _state.acceptedFiles,\n          rejectedFiles = _state.rejectedFiles;\n\n\n      var filesCount = draggedFiles.length;\n      var isMultipleAllowed = multiple || filesCount <= 1;\n      var isDragAccept = filesCount > 0 && allFilesAccepted(draggedFiles, this.props.accept);\n      var isDragReject = filesCount > 0 && (!isDragAccept || !isMultipleAllowed);\n\n      return children({\n        isDragActive: isDragActive,\n        isDragAccept: isDragAccept,\n        isDragReject: isDragReject,\n        draggedFiles: draggedFiles,\n        acceptedFiles: acceptedFiles,\n        rejectedFiles: rejectedFiles,\n        isFocused: isFocused && !disabled,\n        getRootProps: this.getRootProps,\n        getInputProps: this.getInputProps,\n        open: this.open\n      });\n    }\n  }]);\n\n  return Dropzone;\n}(React.Component);\n\nexport default Dropzone;\n\nDropzone.propTypes = {\n  /**\n   * Allow specific types of files. See https://github.com/okonet/attr-accept for more information.\n   * Keep in mind that mime type determination is not reliable across platforms. CSV files,\n   * for example, are reported as text/plain under macOS but as application/vnd.ms-excel under\n   * Windows. In some cases there might not be a mime type set at all.\n   * See: https://github.com/react-dropzone/react-dropzone/issues/276\n   */\n  accept: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),\n\n  /**\n   * Render function that renders the actual component\n   *\n   * @param {Object} props\n   * @param {Function} props.getRootProps Returns the props you should apply to the root drop container you render\n   * @param {Function} props.getInputProps Returns the props you should apply to hidden file input you render\n   * @param {Function} props.open Open the native file selection dialog\n   * @param {Boolean} props.isFocused Dropzone area is in focus\n   * @param {Boolean} props.isDragActive Active drag is in progress\n   * @param {Boolean} props.isDragAccept Dragged files are accepted\n   * @param {Boolean} props.isDragReject Some dragged files are rejected\n   * @param {Array} props.draggedFiles Files in active drag\n   * @param {Array} props.acceptedFiles Accepted files\n   * @param {Array} props.rejectedFiles Rejected files\n   */\n  children: PropTypes.func,\n\n  /**\n   * Enable/disable the dropzone entirely\n   */\n  disabled: PropTypes.bool,\n\n  /**\n   * If false, allow dropped items to take over the current browser window\n   */\n  preventDropOnDocument: PropTypes.bool,\n\n  /**\n   * Allow dropping multiple files\n   */\n  multiple: PropTypes.bool,\n\n  /**\n   * `name` attribute for the input tag\n   */\n  name: PropTypes.string,\n\n  /**\n   * Maximum file size (in bytes)\n   */\n  maxSize: PropTypes.number,\n\n  /**\n   * Minimum file size (in bytes)\n   */\n  minSize: PropTypes.number,\n\n  /**\n   * getDataTransferItems handler\n   * @param {Event} event\n   * @returns {Array} array of File objects\n   */\n  getDataTransferItems: PropTypes.func,\n\n  /**\n   * onClick callback\n   * @param {Event} event\n   */\n  onClick: PropTypes.func,\n\n  /**\n   * onFocus callback\n   */\n  onFocus: PropTypes.func,\n\n  /**\n   * onBlur callback\n   */\n  onBlur: PropTypes.func,\n\n  /**\n   * onKeyDown callback\n   */\n  onKeyDown: PropTypes.func,\n\n  /**\n   * The `onDrop` method that accepts two arguments.\n   * The first argument represents the accepted files and the second argument the rejected files.\n   *\n   * ```javascript\n   * function onDrop(acceptedFiles, rejectedFiles) {\n   *   // do stuff with files...\n   * }\n   * ```\n   *\n   * Files are accepted or rejected based on the `accept` prop.\n   * This must be a valid [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml) according to [input element specification](https://www.w3.org/wiki/HTML/Elements/input/file) or a valid file extension.\n   *\n   * Note that the `onDrop` callback will always be called regardless if the dropped files were accepted or rejected.\n   * You can use the `onDropAccepted`/`onDropRejected` props if you'd like to react to a specific event instead of the `onDrop` prop.\n   *\n   * The `onDrop` callback will provide you with an array of [Files](https://developer.mozilla.org/en-US/docs/Web/API/File) which you can then process and send to a server.\n   * For example, with [SuperAgent](https://github.com/visionmedia/superagent) as a http/ajax library:\n   *\n   * ```javascript\n   * function onDrop(acceptedFiles) {\n   *   const req = request.post('/upload')\n   *   acceptedFiles.forEach(file => {\n   *     req.attach(file.name, file)\n   *   })\n   *   req.end(callback)\n   * }\n   * ```\n   */\n  onDrop: PropTypes.func,\n\n  /**\n   * onDropAccepted callback\n   */\n  onDropAccepted: PropTypes.func,\n\n  /**\n   * onDropRejected callback\n   */\n  onDropRejected: PropTypes.func,\n\n  /**\n   * onDragStart callback\n   */\n  onDragStart: PropTypes.func,\n\n  /**\n   * onDragEnter callback\n   */\n  onDragEnter: PropTypes.func,\n\n  /**\n   * onDragOver callback\n   */\n  onDragOver: PropTypes.func,\n\n  /**\n   * onDragLeave callback\n   */\n  onDragLeave: PropTypes.func,\n\n  /**\n   * Provide a callback on clicking the cancel button of the file dialog\n   */\n  onFileDialogCancel: PropTypes.func\n};\n\nDropzone.defaultProps = {\n  preventDropOnDocument: true,\n  disabled: false,\n  multiple: true,\n  maxSize: Infinity,\n  minSize: 0,\n  getDataTransferItems: fromEvent\n};","import { createIcon } from '../createIcon';\n\nexport const CodeIconConfig = {\n  name: 'CodeIcon',\n  height: 512,\n  width: 640,\n  svgPath: 'M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z',\n  yOffset: 0,\n  xOffset: 0,\n};\n\nexport const CodeIcon = createIcon(CodeIconConfig);\n\nexport default CodeIcon;","import { createIcon } from '../createIcon';\n\nexport const DownloadIconConfig = {\n  name: 'DownloadIcon',\n  height: 512,\n  width: 512,\n  svgPath: 'M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z',\n  yOffset: 0,\n  xOffset: 0,\n};\n\nexport const DownloadIcon = createIcon(DownloadIconConfig);\n\nexport default DownloadIcon;","import { createIcon } from '../createIcon';\n\nexport const UploadIconConfig = {\n  name: 'UploadIcon',\n  height: 512,\n  width: 512,\n  svgPath: 'M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z',\n  yOffset: 0,\n  xOffset: 0,\n};\n\nexport const UploadIcon = createIcon(UploadIconConfig);\n\nexport default UploadIcon;","import './code-editor.css';\nexport default {\n  \"button\": \"pf-c-button\",\n  \"codeEditor\": \"pf-c-code-editor\",\n  \"codeEditorCode\": \"pf-c-code-editor__code\",\n  \"codeEditorCodePre\": \"pf-c-code-editor__code-pre\",\n  \"codeEditorControls\": \"pf-c-code-editor__controls\",\n  \"codeEditorHeader\": \"pf-c-code-editor__header\",\n  \"codeEditorHeaderMain\": \"pf-c-code-editor__header-main\",\n  \"codeEditorMain\": \"pf-c-code-editor__main\",\n  \"codeEditorTab\": \"pf-c-code-editor__tab\",\n  \"codeEditorTabIcon\": \"pf-c-code-editor__tab-icon\",\n  \"codeEditorTabText\": \"pf-c-code-editor__tab-text\",\n  \"modifiers\": {\n    \"readOnly\": \"pf-m-read-only\",\n    \"control\": \"pf-m-control\",\n    \"dragHover\": \"pf-m-drag-hover\"\n  },\n  \"monacoEditor\": \"monaco-editor\",\n  \"themeDark\": \"pf-theme-dark\"\n};","/**\n * Returns the last element of an array.\n * @param array The array.\n * @param n Which element from the end (default is zero).\n */\nexport function tail(array, n = 0) {\n    return array[array.length - (1 + n)];\n}\nexport function tail2(arr) {\n    if (arr.length === 0) {\n        throw new Error('Invalid tail call');\n    }\n    return [arr.slice(0, arr.length - 1), arr[arr.length - 1]];\n}\nexport function equals(one, other, itemEquals = (a, b) => a === b) {\n    if (one === other) {\n        return true;\n    }\n    if (!one || !other) {\n        return false;\n    }\n    if (one.length !== other.length) {\n        return false;\n    }\n    for (let i = 0, len = one.length; i < len; i++) {\n        if (!itemEquals(one[i], other[i])) {\n            return false;\n        }\n    }\n    return true;\n}\n/**\n * Remove the element at `index` by replacing it with the last element. This is faster than `splice`\n * but changes the order of the array\n */\nexport function removeFastWithoutKeepingOrder(array, index) {\n    const last = array.length - 1;\n    if (index < last) {\n        array[index] = array[last];\n    }\n    array.pop();\n}\n/**\n * Performs a binary search algorithm over a sorted array.\n *\n * @param array The array being searched.\n * @param key The value we search for.\n * @param comparator A function that takes two array elements and returns zero\n *   if they are equal, a negative number if the first element precedes the\n *   second one in the sorting order, or a positive number if the second element\n *   precedes the first one.\n * @return See {@link binarySearch2}\n */\nexport function binarySearch(array, key, comparator) {\n    return binarySearch2(array.length, i => comparator(array[i], key));\n}\n/**\n * Performs a binary search algorithm over a sorted collection. Useful for cases\n * when we need to perform a binary search over something that isn't actually an\n * array, and converting data to an array would defeat the use of binary search\n * in the first place.\n *\n * @param length The collection length.\n * @param compareToKey A function that takes an index of an element in the\n *   collection and returns zero if the value at this index is equal to the\n *   search key, a negative number if the value precedes the search key in the\n *   sorting order, or a positive number if the search key precedes the value.\n * @return A non-negative index of an element, if found. If not found, the\n *   result is -(n+1) (or ~n, using bitwise notation), where n is the index\n *   where the key should be inserted to maintain the sorting order.\n */\nexport function binarySearch2(length, compareToKey) {\n    let low = 0, high = length - 1;\n    while (low <= high) {\n        const mid = ((low + high) / 2) | 0;\n        const comp = compareToKey(mid);\n        if (comp < 0) {\n            low = mid + 1;\n        }\n        else if (comp > 0) {\n            high = mid - 1;\n        }\n        else {\n            return mid;\n        }\n    }\n    return -(low + 1);\n}\n/**\n * Takes a sorted array and a function p. The array is sorted in such a way that all elements where p(x) is false\n * are located before all elements where p(x) is true.\n * @returns the least x for which p(x) is true or array.length if no element fullfills the given function.\n */\nexport function findFirstInSorted(array, p) {\n    let low = 0, high = array.length;\n    if (high === 0) {\n        return 0; // no children\n    }\n    while (low < high) {\n        const mid = Math.floor((low + high) / 2);\n        if (p(array[mid])) {\n            high = mid;\n        }\n        else {\n            low = mid + 1;\n        }\n    }\n    return low;\n}\nexport function quickSelect(nth, data, compare) {\n    nth = nth | 0;\n    if (nth >= data.length) {\n        throw new TypeError('invalid index');\n    }\n    const pivotValue = data[Math.floor(data.length * Math.random())];\n    const lower = [];\n    const higher = [];\n    const pivots = [];\n    for (const value of data) {\n        const val = compare(value, pivotValue);\n        if (val < 0) {\n            lower.push(value);\n        }\n        else if (val > 0) {\n            higher.push(value);\n        }\n        else {\n            pivots.push(value);\n        }\n    }\n    if (nth < lower.length) {\n        return quickSelect(nth, lower, compare);\n    }\n    else if (nth < lower.length + pivots.length) {\n        return pivots[0];\n    }\n    else {\n        return quickSelect(nth - (lower.length + pivots.length), higher, compare);\n    }\n}\nexport function groupBy(data, compare) {\n    const result = [];\n    let currentGroup = undefined;\n    for (const element of data.slice(0).sort(compare)) {\n        if (!currentGroup || compare(currentGroup[0], element) !== 0) {\n            currentGroup = [element];\n            result.push(currentGroup);\n        }\n        else {\n            currentGroup.push(element);\n        }\n    }\n    return result;\n}\n/**\n * @returns New array with all falsy values removed. The original array IS NOT modified.\n */\nexport function coalesce(array) {\n    return array.filter(e => !!e);\n}\n/**\n * Remove all falsy values from `array`. The original array IS modified.\n */\nexport function coalesceInPlace(array) {\n    let to = 0;\n    for (let i = 0; i < array.length; i++) {\n        if (!!array[i]) {\n            array[to] = array[i];\n            to += 1;\n        }\n    }\n    array.length = to;\n}\n/**\n * @returns false if the provided object is an array and not empty.\n */\nexport function isFalsyOrEmpty(obj) {\n    return !Array.isArray(obj) || obj.length === 0;\n}\nexport function isNonEmptyArray(obj) {\n    return Array.isArray(obj) && obj.length > 0;\n}\n/**\n * Removes duplicates from the given array. The optional keyFn allows to specify\n * how elements are checked for equality by returning an alternate value for each.\n */\nexport function distinct(array, keyFn = value => value) {\n    const seen = new Set();\n    return array.filter(element => {\n        const key = keyFn(element);\n        if (seen.has(key)) {\n            return false;\n        }\n        seen.add(key);\n        return true;\n    });\n}\nexport function findLast(arr, predicate) {\n    const idx = lastIndex(arr, predicate);\n    if (idx === -1) {\n        return undefined;\n    }\n    return arr[idx];\n}\nexport function lastIndex(array, fn) {\n    for (let i = array.length - 1; i >= 0; i--) {\n        const element = array[i];\n        if (fn(element)) {\n            return i;\n        }\n    }\n    return -1;\n}\nexport function firstOrDefault(array, notFoundValue) {\n    return array.length > 0 ? array[0] : notFoundValue;\n}\nexport function range(arg, to) {\n    let from = typeof to === 'number' ? arg : 0;\n    if (typeof to === 'number') {\n        from = arg;\n    }\n    else {\n        from = 0;\n        to = arg;\n    }\n    const result = [];\n    if (from <= to) {\n        for (let i = from; i < to; i++) {\n            result.push(i);\n        }\n    }\n    else {\n        for (let i = from; i > to; i--) {\n            result.push(i);\n        }\n    }\n    return result;\n}\n/**\n * Insert `insertArr` inside `target` at `insertIndex`.\n * Please don't touch unless you understand https://jsperf.com/inserting-an-array-within-an-array\n */\nexport function arrayInsert(target, insertIndex, insertArr) {\n    const before = target.slice(0, insertIndex);\n    const after = target.slice(insertIndex);\n    return before.concat(insertArr, after);\n}\n/**\n * Pushes an element to the start of the array, if found.\n */\nexport function pushToStart(arr, value) {\n    const index = arr.indexOf(value);\n    if (index > -1) {\n        arr.splice(index, 1);\n        arr.unshift(value);\n    }\n}\n/**\n * Pushes an element to the end of the array, if found.\n */\nexport function pushToEnd(arr, value) {\n    const index = arr.indexOf(value);\n    if (index > -1) {\n        arr.splice(index, 1);\n        arr.push(value);\n    }\n}\nexport function pushMany(arr, items) {\n    for (const item of items) {\n        arr.push(item);\n    }\n}\nexport function asArray(x) {\n    return Array.isArray(x) ? x : [x];\n}\n/**\n * Returns the first mapped value of the array which is not undefined.\n */\nexport function mapFind(array, mapFn) {\n    for (const value of array) {\n        const mapped = mapFn(value);\n        if (mapped !== undefined) {\n            return mapped;\n        }\n    }\n    return undefined;\n}\n/**\n * Insert the new items in the array.\n * @param array The original array.\n * @param start The zero-based location in the array from which to start inserting elements.\n * @param newItems The items to be inserted\n */\nexport function insertInto(array, start, newItems) {\n    const startIdx = getActualStartIndex(array, start);\n    const originalLength = array.length;\n    const newItemsLength = newItems.length;\n    array.length = originalLength + newItemsLength;\n    // Move the items after the start index, start from the end so that we don't overwrite any value.\n    for (let i = originalLength - 1; i >= startIdx; i--) {\n        array[i + newItemsLength] = array[i];\n    }\n    for (let i = 0; i < newItemsLength; i++) {\n        array[i + startIdx] = newItems[i];\n    }\n}\n/**\n * Removes elements from an array and inserts new elements in their place, returning the deleted elements. Alternative to the native Array.splice method, it\n * can only support limited number of items due to the maximum call stack size limit.\n * @param array The original array.\n * @param start The zero-based location in the array from which to start removing elements.\n * @param deleteCount The number of elements to remove.\n * @returns An array containing the elements that were deleted.\n */\nexport function splice(array, start, deleteCount, newItems) {\n    const index = getActualStartIndex(array, start);\n    const result = array.splice(index, deleteCount);\n    insertInto(array, index, newItems);\n    return result;\n}\n/**\n * Determine the actual start index (same logic as the native splice() or slice())\n * If greater than the length of the array, start will be set to the length of the array. In this case, no element will be deleted but the method will behave as an adding function, adding as many element as item[n*] provided.\n * If negative, it will begin that many elements from the end of the array. (In this case, the origin -1, meaning -n is the index of the nth last element, and is therefore equivalent to the index of array.length - n.) If array.length + start is less than 0, it will begin from index 0.\n * @param array The target array.\n * @param start The operation index.\n */\nfunction getActualStartIndex(array, start) {\n    return start < 0 ? Math.max(start + array.length, 0) : Math.min(start, array.length);\n}\nexport var CompareResult;\n(function (CompareResult) {\n    function isLessThan(result) {\n        return result < 0;\n    }\n    CompareResult.isLessThan = isLessThan;\n    function isGreaterThan(result) {\n        return result > 0;\n    }\n    CompareResult.isGreaterThan = isGreaterThan;\n    function isNeitherLessOrGreaterThan(result) {\n        return result === 0;\n    }\n    CompareResult.isNeitherLessOrGreaterThan = isNeitherLessOrGreaterThan;\n    CompareResult.greaterThan = 1;\n    CompareResult.lessThan = -1;\n    CompareResult.neitherLessOrGreaterThan = 0;\n})(CompareResult || (CompareResult = {}));\nexport function compareBy(selector, comparator) {\n    return (a, b) => comparator(selector(a), selector(b));\n}\n/**\n * The natural order on numbers.\n*/\nexport const numberComparator = (a, b) => a - b;\n/**\n * Returns the first item that is equal to or greater than every other item.\n*/\nexport function findMaxBy(items, comparator) {\n    if (items.length === 0) {\n        return undefined;\n    }\n    let max = items[0];\n    for (let i = 1; i < items.length; i++) {\n        const item = items[i];\n        if (comparator(item, max) > 0) {\n            max = item;\n        }\n    }\n    return max;\n}\n/**\n * Returns the last item that is equal to or greater than every other item.\n*/\nexport function findLastMaxBy(items, comparator) {\n    if (items.length === 0) {\n        return undefined;\n    }\n    let max = items[0];\n    for (let i = 1; i < items.length; i++) {\n        const item = items[i];\n        if (comparator(item, max) >= 0) {\n            max = item;\n        }\n    }\n    return max;\n}\n/**\n * Returns the first item that is equal to or less than every other item.\n*/\nexport function findMinBy(items, comparator) {\n    return findMaxBy(items, (a, b) => -comparator(a, b));\n}\nexport class ArrayQueue {\n    /**\n     * Constructs a queue that is backed by the given array. Runtime is O(1).\n    */\n    constructor(items) {\n        this.items = items;\n        this.firstIdx = 0;\n        this.lastIdx = this.items.length - 1;\n    }\n    get length() {\n        return this.lastIdx - this.firstIdx + 1;\n    }\n    /**\n     * Consumes elements from the beginning of the queue as long as the predicate returns true.\n     * If no elements were consumed, `null` is returned. Has a runtime of O(result.length).\n    */\n    takeWhile(predicate) {\n        // P(k) := k <= this.lastIdx && predicate(this.items[k])\n        // Find s := min { k | k >= this.firstIdx && !P(k) } and return this.data[this.firstIdx...s)\n        let startIdx = this.firstIdx;\n        while (startIdx < this.items.length && predicate(this.items[startIdx])) {\n            startIdx++;\n        }\n        const result = startIdx === this.firstIdx ? null : this.items.slice(this.firstIdx, startIdx);\n        this.firstIdx = startIdx;\n        return result;\n    }\n    /**\n     * Consumes elements from the end of the queue as long as the predicate returns true.\n     * If no elements were consumed, `null` is returned.\n     * The result has the same order as the underlying array!\n    */\n    takeFromEndWhile(predicate) {\n        // P(k) := this.firstIdx >= k && predicate(this.items[k])\n        // Find s := max { k | k <= this.lastIdx && !P(k) } and return this.data(s...this.lastIdx]\n        let endIdx = this.lastIdx;\n        while (endIdx >= 0 && predicate(this.items[endIdx])) {\n            endIdx--;\n        }\n        const result = endIdx === this.lastIdx ? null : this.items.slice(endIdx + 1, this.lastIdx + 1);\n        this.lastIdx = endIdx;\n        return result;\n    }\n    peek() {\n        if (this.length === 0) {\n            return undefined;\n        }\n        return this.items[this.firstIdx];\n    }\n    dequeue() {\n        const result = this.items[this.firstIdx];\n        this.firstIdx++;\n        return result;\n    }\n    takeCount(count) {\n        const result = this.items.slice(this.firstIdx, this.firstIdx + count);\n        this.firstIdx += count;\n        return result;\n    }\n}\n/**\n * This class is faster than an iterator and array for lazy computed data.\n*/\nexport class CallbackIterable {\n    constructor(\n    /**\n     * Calls the callback for every item.\n     * Stops when the callback returns false.\n    */\n    iterate) {\n        this.iterate = iterate;\n    }\n    toArray() {\n        const result = [];\n        this.iterate(item => { result.push(item); return true; });\n        return result;\n    }\n    filter(predicate) {\n        return new CallbackIterable(cb => this.iterate(item => predicate(item) ? cb(item) : true));\n    }\n    map(mapFn) {\n        return new CallbackIterable(cb => this.iterate(item => cb(mapFn(item))));\n    }\n    findLast(predicate) {\n        let result;\n        this.iterate(item => {\n            if (predicate(item)) {\n                result = item;\n            }\n            return true;\n        });\n        return result;\n    }\n    findLastMaxBy(comparator) {\n        let result;\n        let first = true;\n        this.iterate(item => {\n            if (first || CompareResult.isGreaterThan(comparator(item, result))) {\n                first = false;\n                result = item;\n            }\n            return true;\n        });\n        return result;\n    }\n}\nCallbackIterable.empty = new CallbackIterable(_callback => { });\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * @returns whether the provided parameter is a JavaScript String or not.\n */\nexport function isString(str) {\n    return (typeof str === 'string');\n}\n/**\n * @returns whether the provided parameter is of type `object` but **not**\n *\t`null`, an `array`, a `regexp`, nor a `date`.\n */\nexport function isObject(obj) {\n    // The method can't do a type cast since there are type (like strings) which\n    // are subclasses of any put not positvely matched by the function. Hence type\n    // narrowing results in wrong results.\n    return typeof obj === 'object'\n        && obj !== null\n        && !Array.isArray(obj)\n        && !(obj instanceof RegExp)\n        && !(obj instanceof Date);\n}\n/**\n * @returns whether the provided parameter is of type `Buffer` or Uint8Array dervived type\n */\nexport function isTypedArray(obj) {\n    const TypedArray = Object.getPrototypeOf(Uint8Array);\n    return typeof obj === 'object'\n        && obj instanceof TypedArray;\n}\n/**\n * In **contrast** to just checking `typeof` this will return `false` for `NaN`.\n * @returns whether the provided parameter is a JavaScript Number or not.\n */\nexport function isNumber(obj) {\n    return (typeof obj === 'number' && !isNaN(obj));\n}\n/**\n * @returns whether the provided parameter is an Iterable, casting to the given generic\n */\nexport function isIterable(obj) {\n    return !!obj && typeof obj[Symbol.iterator] === 'function';\n}\n/**\n * @returns whether the provided parameter is a JavaScript Boolean or not.\n */\nexport function isBoolean(obj) {\n    return (obj === true || obj === false);\n}\n/**\n * @returns whether the provided parameter is undefined.\n */\nexport function isUndefined(obj) {\n    return (typeof obj === 'undefined');\n}\n/**\n * @returns whether the provided parameter is defined.\n */\nexport function isDefined(arg) {\n    return !isUndefinedOrNull(arg);\n}\n/**\n * @returns whether the provided parameter is undefined or null.\n */\nexport function isUndefinedOrNull(obj) {\n    return (isUndefined(obj) || obj === null);\n}\nexport function assertType(condition, type) {\n    if (!condition) {\n        throw new Error(type ? `Unexpected type, expected '${type}'` : 'Unexpected type');\n    }\n}\n/**\n * Asserts that the argument passed in is neither undefined nor null.\n */\nexport function assertIsDefined(arg) {\n    if (isUndefinedOrNull(arg)) {\n        throw new Error('Assertion Failed: argument is undefined or null');\n    }\n    return arg;\n}\n/**\n * @returns whether the provided parameter is a JavaScript Function or not.\n */\nexport function isFunction(obj) {\n    return (typeof obj === 'function');\n}\nexport function validateConstraints(args, constraints) {\n    const len = Math.min(args.length, constraints.length);\n    for (let i = 0; i < len; i++) {\n        validateConstraint(args[i], constraints[i]);\n    }\n}\nexport function validateConstraint(arg, constraint) {\n    if (isString(constraint)) {\n        if (typeof arg !== constraint) {\n            throw new Error(`argument does not match constraint: typeof ${constraint}`);\n        }\n    }\n    else if (isFunction(constraint)) {\n        try {\n            if (arg instanceof constraint) {\n                return;\n            }\n        }\n        catch (_a) {\n            // ignore\n        }\n        if (!isUndefinedOrNull(arg) && arg.constructor === constraint) {\n            return;\n        }\n        if (constraint.length === 1 && constraint.call(undefined, arg) === true) {\n            return;\n        }\n        throw new Error(`argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true`);\n    }\n}\n/**\n * Converts null to undefined, passes all other values through.\n */\nexport function withNullAsUndefined(x) {\n    return x === null ? undefined : x;\n}\n/**\n * Converts undefined to null, passes all other values through.\n */\nexport function withUndefinedAsNull(x) {\n    return typeof x === 'undefined' ? null : x;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { isTypedArray, isObject, isUndefinedOrNull } from './types.js';\nexport function deepClone(obj) {\n    if (!obj || typeof obj !== 'object') {\n        return obj;\n    }\n    if (obj instanceof RegExp) {\n        return obj;\n    }\n    const result = Array.isArray(obj) ? [] : {};\n    Object.entries(obj).forEach(([key, value]) => {\n        result[key] = value && typeof value === 'object' ? deepClone(value) : value;\n    });\n    return result;\n}\nexport function deepFreeze(obj) {\n    if (!obj || typeof obj !== 'object') {\n        return obj;\n    }\n    const stack = [obj];\n    while (stack.length > 0) {\n        const obj = stack.shift();\n        Object.freeze(obj);\n        for (const key in obj) {\n            if (_hasOwnProperty.call(obj, key)) {\n                const prop = obj[key];\n                if (typeof prop === 'object' && !Object.isFrozen(prop) && !isTypedArray(prop)) {\n                    stack.push(prop);\n                }\n            }\n        }\n    }\n    return obj;\n}\nconst _hasOwnProperty = Object.prototype.hasOwnProperty;\nexport function cloneAndChange(obj, changer) {\n    return _cloneAndChange(obj, changer, new Set());\n}\nfunction _cloneAndChange(obj, changer, seen) {\n    if (isUndefinedOrNull(obj)) {\n        return obj;\n    }\n    const changed = changer(obj);\n    if (typeof changed !== 'undefined') {\n        return changed;\n    }\n    if (Array.isArray(obj)) {\n        const r1 = [];\n        for (const e of obj) {\n            r1.push(_cloneAndChange(e, changer, seen));\n        }\n        return r1;\n    }\n    if (isObject(obj)) {\n        if (seen.has(obj)) {\n            throw new Error('Cannot clone recursive data-structure');\n        }\n        seen.add(obj);\n        const r2 = {};\n        for (const i2 in obj) {\n            if (_hasOwnProperty.call(obj, i2)) {\n                r2[i2] = _cloneAndChange(obj[i2], changer, seen);\n            }\n        }\n        seen.delete(obj);\n        return r2;\n    }\n    return obj;\n}\n/**\n * Copies all properties of source into destination. The optional parameter \"overwrite\" allows to control\n * if existing properties on the destination should be overwritten or not. Defaults to true (overwrite).\n */\nexport function mixin(destination, source, overwrite = true) {\n    if (!isObject(destination)) {\n        return source;\n    }\n    if (isObject(source)) {\n        Object.keys(source).forEach(key => {\n            if (key in destination) {\n                if (overwrite) {\n                    if (isObject(destination[key]) && isObject(source[key])) {\n                        mixin(destination[key], source[key], overwrite);\n                    }\n                    else {\n                        destination[key] = source[key];\n                    }\n                }\n            }\n            else {\n                destination[key] = source[key];\n            }\n        });\n    }\n    return destination;\n}\nexport function equals(one, other) {\n    if (one === other) {\n        return true;\n    }\n    if (one === null || one === undefined || other === null || other === undefined) {\n        return false;\n    }\n    if (typeof one !== typeof other) {\n        return false;\n    }\n    if (typeof one !== 'object') {\n        return false;\n    }\n    if ((Array.isArray(one)) !== (Array.isArray(other))) {\n        return false;\n    }\n    let i;\n    let key;\n    if (Array.isArray(one)) {\n        if (one.length !== other.length) {\n            return false;\n        }\n        for (i = 0; i < one.length; i++) {\n            if (!equals(one[i], other[i])) {\n                return false;\n            }\n        }\n    }\n    else {\n        const oneKeys = [];\n        for (key in one) {\n            oneKeys.push(key);\n        }\n        oneKeys.sort();\n        const otherKeys = [];\n        for (key in other) {\n            otherKeys.push(key);\n        }\n        otherKeys.sort();\n        if (!equals(oneKeys, otherKeys)) {\n            return false;\n        }\n        for (i = 0; i < oneKeys.length; i++) {\n            if (!equals(one[oneKeys[i]], other[oneKeys[i]])) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\nexport function getAllPropertyNames(obj) {\n    let res = [];\n    let proto = Object.getPrototypeOf(obj);\n    while (Object.prototype !== proto) {\n        res = res.concat(Object.getOwnPropertyNames(proto));\n        proto = Object.getPrototypeOf(proto);\n    }\n    return res;\n}\nexport function getAllMethodNames(obj) {\n    const methods = [];\n    for (const prop of getAllPropertyNames(obj)) {\n        if (typeof obj[prop] === 'function') {\n            methods.push(prop);\n        }\n    }\n    return methods;\n}\nexport function createProxyObject(methodNames, invoke) {\n    const createProxyMethod = (method) => {\n        return function () {\n            const args = Array.prototype.slice.call(arguments, 0);\n            return invoke(method, args);\n        };\n    };\n    const result = {};\n    for (const methodName of methodNames) {\n        result[methodName] = createProxyMethod(methodName);\n    }\n    return result;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nlet isPseudo = (typeof document !== 'undefined' && document.location && document.location.hash.indexOf('pseudo=true') >= 0);\nconst DEFAULT_TAG = 'i-default';\nfunction _format(message, args) {\n    let result;\n    if (args.length === 0) {\n        result = message;\n    }\n    else {\n        result = message.replace(/\\{(\\d+)\\}/g, (match, rest) => {\n            const index = rest[0];\n            const arg = args[index];\n            let result = match;\n            if (typeof arg === 'string') {\n                result = arg;\n            }\n            else if (typeof arg === 'number' || typeof arg === 'boolean' || arg === void 0 || arg === null) {\n                result = String(arg);\n            }\n            return result;\n        });\n    }\n    if (isPseudo) {\n        // FF3B and FF3D is the Unicode zenkaku representation for [ and ]\n        result = '\\uFF3B' + result.replace(/[aouei]/g, '$&$&') + '\\uFF3D';\n    }\n    return result;\n}\nfunction findLanguageForModule(config, name) {\n    let result = config[name];\n    if (result) {\n        return result;\n    }\n    result = config['*'];\n    if (result) {\n        return result;\n    }\n    return null;\n}\nfunction endWithSlash(path) {\n    if (path.charAt(path.length - 1) === '/') {\n        return path;\n    }\n    return path + '/';\n}\nfunction getMessagesFromTranslationsService(translationServiceUrl, language, name) {\n    return __awaiter(this, void 0, void 0, function* () {\n        const url = endWithSlash(translationServiceUrl) + endWithSlash(language) + 'vscode/' + endWithSlash(name);\n        const res = yield fetch(url);\n        if (res.ok) {\n            const messages = yield res.json();\n            return messages;\n        }\n        throw new Error(`${res.status} - ${res.statusText}`);\n    });\n}\nfunction createScopedLocalize(scope) {\n    return function (idx, defaultValue) {\n        const restArgs = Array.prototype.slice.call(arguments, 2);\n        return _format(scope[idx], restArgs);\n    };\n}\n/**\n * @skipMangle\n */\nexport function localize(data, message, ...args) {\n    return _format(message, args);\n}\n/**\n * @skipMangle\n */\nexport function getConfiguredDefaultLocale(_) {\n    // This returns undefined because this implementation isn't used and is overwritten by the loader\n    // when loaded.\n    return undefined;\n}\n/**\n * @skipMangle\n */\nexport function setPseudoTranslation(value) {\n    isPseudo = value;\n}\n/**\n * Invoked in a built product at run-time\n * @skipMangle\n */\nexport function create(key, data) {\n    var _a;\n    return {\n        localize: createScopedLocalize(data[key]),\n        getConfiguredDefaultLocale: (_a = data.getConfiguredDefaultLocale) !== null && _a !== void 0 ? _a : ((_) => undefined)\n    };\n}\n/**\n * Invoked by the loader at run-time\n * @skipMangle\n */\nexport function load(name, req, load, config) {\n    var _a;\n    const pluginConfig = (_a = config['vs/nls']) !== null && _a !== void 0 ? _a : {};\n    if (!name || name.length === 0) {\n        // TODO: We need to give back the mangled names here\n        return load({\n            localize: localize,\n            getConfiguredDefaultLocale: () => { var _a; return (_a = pluginConfig.availableLanguages) === null || _a === void 0 ? void 0 : _a['*']; }\n        });\n    }\n    const language = pluginConfig.availableLanguages ? findLanguageForModule(pluginConfig.availableLanguages, name) : null;\n    const useDefaultLanguage = language === null || language === DEFAULT_TAG;\n    let suffix = '.nls';\n    if (!useDefaultLanguage) {\n        suffix = suffix + '.' + language;\n    }\n    const messagesLoaded = (messages) => {\n        if (Array.isArray(messages)) {\n            messages.localize = createScopedLocalize(messages);\n        }\n        else {\n            messages.localize = createScopedLocalize(messages[name]);\n        }\n        messages.getConfiguredDefaultLocale = () => { var _a; return (_a = pluginConfig.availableLanguages) === null || _a === void 0 ? void 0 : _a['*']; };\n        load(messages);\n    };\n    if (typeof pluginConfig.loadBundle === 'function') {\n        pluginConfig.loadBundle(name, language, (err, messages) => {\n            // We have an error. Load the English default strings to not fail\n            if (err) {\n                req([name + '.nls'], messagesLoaded);\n            }\n            else {\n                messagesLoaded(messages);\n            }\n        });\n    }\n    else if (pluginConfig.translationServiceUrl && !useDefaultLanguage) {\n        (() => __awaiter(this, void 0, void 0, function* () {\n            var _b;\n            try {\n                const messages = yield getMessagesFromTranslationsService(pluginConfig.translationServiceUrl, language, name);\n                return messagesLoaded(messages);\n            }\n            catch (err) {\n                // Language is already as generic as it gets, so require default messages\n                if (!language.includes('-')) {\n                    console.error(err);\n                    return req([name + '.nls'], messagesLoaded);\n                }\n                try {\n                    // Since there is a dash, the language configured is a specific sub-language of the same generic language.\n                    // Since we were unable to load the specific language, try to load the generic language. Ex. we failed to find a\n                    // Swiss German (de-CH), so try to load the generic German (de) messages instead.\n                    const genericLanguage = language.split('-')[0];\n                    const messages = yield getMessagesFromTranslationsService(pluginConfig.translationServiceUrl, genericLanguage, name);\n                    // We got some messages, so we configure the configuration to use the generic language for this session.\n                    (_b = pluginConfig.availableLanguages) !== null && _b !== void 0 ? _b : (pluginConfig.availableLanguages = {});\n                    pluginConfig.availableLanguages['*'] = genericLanguage;\n                    return messagesLoaded(messages);\n                }\n                catch (err) {\n                    console.error(err);\n                    return req([name + '.nls'], messagesLoaded);\n                }\n            }\n        }))();\n    }\n    else {\n        req([name + suffix], messagesLoaded, (err) => {\n            if (suffix === '.nls') {\n                console.error('Failed trying to load default language strings', err);\n                return;\n            }\n            console.error(`Failed to load message bundle for language ${language}. Falling back to the default language:`, err);\n            req([name + '.nls'], messagesLoaded);\n        });\n    }\n}\n","var _a;\n/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as nls from '../../nls.js';\nexport const LANGUAGE_DEFAULT = 'en';\nlet _isWindows = false;\nlet _isMacintosh = false;\nlet _isLinux = false;\nlet _isLinuxSnap = false;\nlet _isNative = false;\nlet _isWeb = false;\nlet _isElectron = false;\nlet _isIOS = false;\nlet _isCI = false;\nlet _isMobile = false;\nlet _locale = undefined;\nlet _language = LANGUAGE_DEFAULT;\nlet _platformLocale = LANGUAGE_DEFAULT;\nlet _translationsConfigFile = undefined;\nlet _userAgent = undefined;\n/**\n * @deprecated use `globalThis` instead\n */\nexport const globals = (typeof self === 'object' ? self : typeof global === 'object' ? global : {});\nlet nodeProcess = undefined;\nif (typeof globals.vscode !== 'undefined' && typeof globals.vscode.process !== 'undefined') {\n    // Native environment (sandboxed)\n    nodeProcess = globals.vscode.process;\n}\nelse if (typeof process !== 'undefined') {\n    // Native environment (non-sandboxed)\n    nodeProcess = process;\n}\nconst isElectronProcess = typeof ((_a = nodeProcess === null || nodeProcess === void 0 ? void 0 : nodeProcess.versions) === null || _a === void 0 ? void 0 : _a.electron) === 'string';\nconst isElectronRenderer = isElectronProcess && (nodeProcess === null || nodeProcess === void 0 ? void 0 : nodeProcess.type) === 'renderer';\n// Web environment\nif (typeof navigator === 'object' && !isElectronRenderer) {\n    _userAgent = navigator.userAgent;\n    _isWindows = _userAgent.indexOf('Windows') >= 0;\n    _isMacintosh = _userAgent.indexOf('Macintosh') >= 0;\n    _isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0;\n    _isLinux = _userAgent.indexOf('Linux') >= 0;\n    _isMobile = (_userAgent === null || _userAgent === void 0 ? void 0 : _userAgent.indexOf('Mobi')) >= 0;\n    _isWeb = true;\n    const configuredLocale = nls.getConfiguredDefaultLocale(\n    // This call _must_ be done in the file that calls `nls.getConfiguredDefaultLocale`\n    // to ensure that the NLS AMD Loader plugin has been loaded and configured.\n    // This is because the loader plugin decides what the default locale is based on\n    // how it's able to resolve the strings.\n    nls.localize({ key: 'ensureLoaderPluginIsLoaded', comment: ['{Locked}'] }, '_'));\n    _locale = configuredLocale || LANGUAGE_DEFAULT;\n    _language = _locale;\n    _platformLocale = navigator.language;\n}\n// Native environment\nelse if (typeof nodeProcess === 'object') {\n    _isWindows = (nodeProcess.platform === 'win32');\n    _isMacintosh = (nodeProcess.platform === 'darwin');\n    _isLinux = (nodeProcess.platform === 'linux');\n    _isLinuxSnap = _isLinux && !!nodeProcess.env['SNAP'] && !!nodeProcess.env['SNAP_REVISION'];\n    _isElectron = isElectronProcess;\n    _isCI = !!nodeProcess.env['CI'] || !!nodeProcess.env['BUILD_ARTIFACTSTAGINGDIRECTORY'];\n    _locale = LANGUAGE_DEFAULT;\n    _language = LANGUAGE_DEFAULT;\n    const rawNlsConfig = nodeProcess.env['VSCODE_NLS_CONFIG'];\n    if (rawNlsConfig) {\n        try {\n            const nlsConfig = JSON.parse(rawNlsConfig);\n            const resolved = nlsConfig.availableLanguages['*'];\n            _locale = nlsConfig.locale;\n            _platformLocale = nlsConfig.osLocale;\n            // VSCode's default language is 'en'\n            _language = resolved ? resolved : LANGUAGE_DEFAULT;\n            _translationsConfigFile = nlsConfig._translationsConfigFile;\n        }\n        catch (e) {\n        }\n    }\n    _isNative = true;\n}\n// Unknown environment\nelse {\n    console.error('Unable to resolve platform.');\n}\nlet _platform = 0 /* Platform.Web */;\nif (_isMacintosh) {\n    _platform = 1 /* Platform.Mac */;\n}\nelse if (_isWindows) {\n    _platform = 3 /* Platform.Windows */;\n}\nelse if (_isLinux) {\n    _platform = 2 /* Platform.Linux */;\n}\nexport const isWindows = _isWindows;\nexport const isMacintosh = _isMacintosh;\nexport const isLinux = _isLinux;\nexport const isNative = _isNative;\nexport const isWeb = _isWeb;\nexport const isWebWorker = (_isWeb && typeof globals.importScripts === 'function');\nexport const isIOS = _isIOS;\nexport const isMobile = _isMobile;\nexport const userAgent = _userAgent;\n/**\n * The language used for the user interface. The format of\n * the string is all lower case (e.g. zh-tw for Traditional\n * Chinese)\n */\nexport const language = _language;\nexport const setTimeout0IsFaster = (typeof globals.postMessage === 'function' && !globals.importScripts);\n/**\n * See https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#:~:text=than%204%2C%20then-,set%20timeout%20to%204,-.\n *\n * Works similarly to `setTimeout(0)` but doesn't suffer from the 4ms artificial delay\n * that browsers set when the nesting level is > 5.\n */\nexport const setTimeout0 = (() => {\n    if (setTimeout0IsFaster) {\n        const pending = [];\n        globals.addEventListener('message', (e) => {\n            if (e.data && e.data.vscodeScheduleAsyncWork) {\n                for (let i = 0, len = pending.length; i < len; i++) {\n                    const candidate = pending[i];\n                    if (candidate.id === e.data.vscodeScheduleAsyncWork) {\n                        pending.splice(i, 1);\n                        candidate.callback();\n                        return;\n                    }\n                }\n            }\n        });\n        let lastId = 0;\n        return (callback) => {\n            const myId = ++lastId;\n            pending.push({\n                id: myId,\n                callback: callback\n            });\n            globals.postMessage({ vscodeScheduleAsyncWork: myId }, '*');\n        };\n    }\n    return (callback) => setTimeout(callback);\n})();\nexport const OS = (_isMacintosh || _isIOS ? 2 /* OperatingSystem.Macintosh */ : (_isWindows ? 1 /* OperatingSystem.Windows */ : 3 /* OperatingSystem.Linux */));\nlet _isLittleEndian = true;\nlet _isLittleEndianComputed = false;\nexport function isLittleEndian() {\n    if (!_isLittleEndianComputed) {\n        _isLittleEndianComputed = true;\n        const test = new Uint8Array(2);\n        test[0] = 1;\n        test[1] = 2;\n        const view = new Uint16Array(test.buffer);\n        _isLittleEndian = (view[0] === (2 << 8) + 1);\n    }\n    return _isLittleEndian;\n}\nexport const isChrome = !!(userAgent && userAgent.indexOf('Chrome') >= 0);\nexport const isFirefox = !!(userAgent && userAgent.indexOf('Firefox') >= 0);\nexport const isSafari = !!(!isChrome && (userAgent && userAgent.indexOf('Safari') >= 0));\nexport const isEdge = !!(userAgent && userAgent.indexOf('Edg/') >= 0);\nexport const isAndroid = !!(userAgent && userAgent.indexOf('Android') >= 0);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport const EDITOR_MODEL_DEFAULTS = {\n    tabSize: 4,\n    indentSize: 4,\n    insertSpaces: true,\n    detectIndentation: true,\n    trimAutoWhitespace: true,\n    largeFileOptimizations: true,\n    bracketPairColorizationOptions: {\n        enabled: true,\n        independentColorPoolPerBracketType: false,\n    },\n};\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport var Iterable;\n(function (Iterable) {\n    function is(thing) {\n        return thing && typeof thing === 'object' && typeof thing[Symbol.iterator] === 'function';\n    }\n    Iterable.is = is;\n    const _empty = Object.freeze([]);\n    function empty() {\n        return _empty;\n    }\n    Iterable.empty = empty;\n    function* single(element) {\n        yield element;\n    }\n    Iterable.single = single;\n    function wrap(iterableOrElement) {\n        if (is(iterableOrElement)) {\n            return iterableOrElement;\n        }\n        else {\n            return single(iterableOrElement);\n        }\n    }\n    Iterable.wrap = wrap;\n    function from(iterable) {\n        return iterable || _empty;\n    }\n    Iterable.from = from;\n    function isEmpty(iterable) {\n        return !iterable || iterable[Symbol.iterator]().next().done === true;\n    }\n    Iterable.isEmpty = isEmpty;\n    function first(iterable) {\n        return iterable[Symbol.iterator]().next().value;\n    }\n    Iterable.first = first;\n    function some(iterable, predicate) {\n        for (const element of iterable) {\n            if (predicate(element)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    Iterable.some = some;\n    function find(iterable, predicate) {\n        for (const element of iterable) {\n            if (predicate(element)) {\n                return element;\n            }\n        }\n        return undefined;\n    }\n    Iterable.find = find;\n    function* filter(iterable, predicate) {\n        for (const element of iterable) {\n            if (predicate(element)) {\n                yield element;\n            }\n        }\n    }\n    Iterable.filter = filter;\n    function* map(iterable, fn) {\n        let index = 0;\n        for (const element of iterable) {\n            yield fn(element, index++);\n        }\n    }\n    Iterable.map = map;\n    function* concat(...iterables) {\n        for (const iterable of iterables) {\n            for (const element of iterable) {\n                yield element;\n            }\n        }\n    }\n    Iterable.concat = concat;\n    function reduce(iterable, reducer, initialValue) {\n        let value = initialValue;\n        for (const element of iterable) {\n            value = reducer(value, element);\n        }\n        return value;\n    }\n    Iterable.reduce = reduce;\n    /**\n     * Returns an iterable slice of the array, with the same semantics as `array.slice()`.\n     */\n    function* slice(arr, from, to = arr.length) {\n        if (from < 0) {\n            from += arr.length;\n        }\n        if (to < 0) {\n            to += arr.length;\n        }\n        else if (to > arr.length) {\n            to = arr.length;\n        }\n        for (; from < to; from++) {\n            yield arr[from];\n        }\n    }\n    Iterable.slice = slice;\n    /**\n     * Consumes `atMost` elements from iterable and returns the consumed elements,\n     * and an iterable for the rest of the elements.\n     */\n    function consume(iterable, atMost = Number.POSITIVE_INFINITY) {\n        const consumed = [];\n        if (atMost === 0) {\n            return [consumed, iterable];\n        }\n        const iterator = iterable[Symbol.iterator]();\n        for (let i = 0; i < atMost; i++) {\n            const next = iterator.next();\n            if (next.done) {\n                return [consumed, Iterable.empty()];\n            }\n            consumed.push(next.value);\n        }\n        return [consumed, { [Symbol.iterator]() { return iterator; } }];\n    }\n    Iterable.consume = consume;\n})(Iterable || (Iterable = {}));\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nclass Node {\n    constructor(element) {\n        this.element = element;\n        this.next = Node.Undefined;\n        this.prev = Node.Undefined;\n    }\n}\nNode.Undefined = new Node(undefined);\nexport class LinkedList {\n    constructor() {\n        this._first = Node.Undefined;\n        this._last = Node.Undefined;\n        this._size = 0;\n    }\n    get size() {\n        return this._size;\n    }\n    isEmpty() {\n        return this._first === Node.Undefined;\n    }\n    clear() {\n        let node = this._first;\n        while (node !== Node.Undefined) {\n            const next = node.next;\n            node.prev = Node.Undefined;\n            node.next = Node.Undefined;\n            node = next;\n        }\n        this._first = Node.Undefined;\n        this._last = Node.Undefined;\n        this._size = 0;\n    }\n    unshift(element) {\n        return this._insert(element, false);\n    }\n    push(element) {\n        return this._insert(element, true);\n    }\n    _insert(element, atTheEnd) {\n        const newNode = new Node(element);\n        if (this._first === Node.Undefined) {\n            this._first = newNode;\n            this._last = newNode;\n        }\n        else if (atTheEnd) {\n            // push\n            const oldLast = this._last;\n            this._last = newNode;\n            newNode.prev = oldLast;\n            oldLast.next = newNode;\n        }\n        else {\n            // unshift\n            const oldFirst = this._first;\n            this._first = newNode;\n            newNode.next = oldFirst;\n            oldFirst.prev = newNode;\n        }\n        this._size += 1;\n        let didRemove = false;\n        return () => {\n            if (!didRemove) {\n                didRemove = true;\n                this._remove(newNode);\n            }\n        };\n    }\n    shift() {\n        if (this._first === Node.Undefined) {\n            return undefined;\n        }\n        else {\n            const res = this._first.element;\n            this._remove(this._first);\n            return res;\n        }\n    }\n    pop() {\n        if (this._last === Node.Undefined) {\n            return undefined;\n        }\n        else {\n            const res = this._last.element;\n            this._remove(this._last);\n            return res;\n        }\n    }\n    _remove(node) {\n        if (node.prev !== Node.Undefined && node.next !== Node.Undefined) {\n            // middle\n            const anchor = node.prev;\n            anchor.next = node.next;\n            node.next.prev = anchor;\n        }\n        else if (node.prev === Node.Undefined && node.next === Node.Undefined) {\n            // only node\n            this._first = Node.Undefined;\n            this._last = Node.Undefined;\n        }\n        else if (node.next === Node.Undefined) {\n            // last\n            this._last = this._last.prev;\n            this._last.next = Node.Undefined;\n        }\n        else if (node.prev === Node.Undefined) {\n            // first\n            this._first = this._first.next;\n            this._first.prev = Node.Undefined;\n        }\n        // done\n        this._size -= 1;\n    }\n    *[Symbol.iterator]() {\n        let node = this._first;\n        while (node !== Node.Undefined) {\n            yield node.element;\n            node = node.next;\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Iterable } from '../../../base/common/iterator.js';\nimport { LinkedList } from '../../../base/common/linkedList.js';\nexport const USUAL_WORD_SEPARATORS = '`~!@#$%^&*()-=+[{]}\\\\|;:\\'\",.<>/?';\n/**\n * Create a word definition regular expression based on default word separators.\n * Optionally provide allowed separators that should be included in words.\n *\n * The default would look like this:\n * /(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)/g\n */\nfunction createWordRegExp(allowInWords = '') {\n    let source = '(-?\\\\d*\\\\.\\\\d\\\\w*)|([^';\n    for (const sep of USUAL_WORD_SEPARATORS) {\n        if (allowInWords.indexOf(sep) >= 0) {\n            continue;\n        }\n        source += '\\\\' + sep;\n    }\n    source += '\\\\s]+)';\n    return new RegExp(source, 'g');\n}\n// catches numbers (including floating numbers) in the first group, and alphanum in the second\nexport const DEFAULT_WORD_REGEXP = createWordRegExp();\nexport function ensureValidWordDefinition(wordDefinition) {\n    let result = DEFAULT_WORD_REGEXP;\n    if (wordDefinition && (wordDefinition instanceof RegExp)) {\n        if (!wordDefinition.global) {\n            let flags = 'g';\n            if (wordDefinition.ignoreCase) {\n                flags += 'i';\n            }\n            if (wordDefinition.multiline) {\n                flags += 'm';\n            }\n            if (wordDefinition.unicode) {\n                flags += 'u';\n            }\n            result = new RegExp(wordDefinition.source, flags);\n        }\n        else {\n            result = wordDefinition;\n        }\n    }\n    result.lastIndex = 0;\n    return result;\n}\nconst _defaultConfig = new LinkedList();\n_defaultConfig.unshift({\n    maxLen: 1000,\n    windowSize: 15,\n    timeBudget: 150\n});\nexport function getWordAtText(column, wordDefinition, text, textOffset, config) {\n    if (!config) {\n        config = Iterable.first(_defaultConfig);\n    }\n    if (text.length > config.maxLen) {\n        // don't throw strings that long at the regexp\n        // but use a sub-string in which a word must occur\n        let start = column - config.maxLen / 2;\n        if (start < 0) {\n            start = 0;\n        }\n        else {\n            textOffset += start;\n        }\n        text = text.substring(start, column + config.maxLen / 2);\n        return getWordAtText(column, wordDefinition, text, textOffset, config);\n    }\n    const t1 = Date.now();\n    const pos = column - 1 - textOffset;\n    let prevRegexIndex = -1;\n    let match = null;\n    for (let i = 1;; i++) {\n        // check time budget\n        if (Date.now() - t1 >= config.timeBudget) {\n            break;\n        }\n        // reset the index at which the regexp should start matching, also know where it\n        // should stop so that subsequent search don't repeat previous searches\n        const regexIndex = pos - config.windowSize * i;\n        wordDefinition.lastIndex = Math.max(0, regexIndex);\n        const thisMatch = _findRegexMatchEnclosingPosition(wordDefinition, text, pos, prevRegexIndex);\n        if (!thisMatch && match) {\n            // stop: we have something\n            break;\n        }\n        match = thisMatch;\n        // stop: searched at start\n        if (regexIndex <= 0) {\n            break;\n        }\n        prevRegexIndex = regexIndex;\n    }\n    if (match) {\n        const result = {\n            word: match[0],\n            startColumn: textOffset + 1 + match.index,\n            endColumn: textOffset + 1 + match.index + match[0].length\n        };\n        wordDefinition.lastIndex = 0;\n        return result;\n    }\n    return null;\n}\nfunction _findRegexMatchEnclosingPosition(wordDefinition, text, pos, stopPos) {\n    let match;\n    while (match = wordDefinition.exec(text)) {\n        const matchIndex = match.index || 0;\n        if (matchIndex <= pos && wordDefinition.lastIndex >= pos) {\n            return match;\n        }\n        else if (stopPos > 0 && matchIndex > stopPos) {\n            return null;\n        }\n    }\n    return null;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as arrays from '../../../base/common/arrays.js';\nimport * as objects from '../../../base/common/objects.js';\nimport * as platform from '../../../base/common/platform.js';\nimport { EDITOR_MODEL_DEFAULTS } from '../core/textModelDefaults.js';\nimport { USUAL_WORD_SEPARATORS } from '../core/wordHelper.js';\nimport * as nls from '../../../nls.js';\n/**\n * @internal\n * The width of the minimap gutter, in pixels.\n */\nexport const MINIMAP_GUTTER_WIDTH = 8;\n//#endregion\n/**\n * An event describing that the configuration of the editor has changed.\n */\nexport class ConfigurationChangedEvent {\n    /**\n     * @internal\n     */\n    constructor(values) {\n        this._values = values;\n    }\n    hasChanged(id) {\n        return this._values[id];\n    }\n}\n/**\n * @internal\n */\nexport class ComputeOptionsMemory {\n    constructor() {\n        this.stableMinimapLayoutInput = null;\n        this.stableFitMaxMinimapScale = 0;\n        this.stableFitRemainingWidth = 0;\n    }\n}\n/**\n * @internal\n */\nclass BaseEditorOption {\n    constructor(id, name, defaultValue, schema) {\n        this.id = id;\n        this.name = name;\n        this.defaultValue = defaultValue;\n        this.schema = schema;\n    }\n    applyUpdate(value, update) {\n        return applyUpdate(value, update);\n    }\n    compute(env, options, value) {\n        return value;\n    }\n}\nexport class ApplyUpdateResult {\n    constructor(newValue, didChange) {\n        this.newValue = newValue;\n        this.didChange = didChange;\n    }\n}\nfunction applyUpdate(value, update) {\n    if (typeof value !== 'object' || typeof update !== 'object' || !value || !update) {\n        return new ApplyUpdateResult(update, value !== update);\n    }\n    if (Array.isArray(value) || Array.isArray(update)) {\n        const arrayEquals = Array.isArray(value) && Array.isArray(update) && arrays.equals(value, update);\n        return new ApplyUpdateResult(update, !arrayEquals);\n    }\n    let didChange = false;\n    for (const key in update) {\n        if (update.hasOwnProperty(key)) {\n            const result = applyUpdate(value[key], update[key]);\n            if (result.didChange) {\n                value[key] = result.newValue;\n                didChange = true;\n            }\n        }\n    }\n    return new ApplyUpdateResult(value, didChange);\n}\n/**\n * @internal\n */\nclass ComputedEditorOption {\n    constructor(id) {\n        this.schema = undefined;\n        this.id = id;\n        this.name = '_never_';\n        this.defaultValue = undefined;\n    }\n    applyUpdate(value, update) {\n        return applyUpdate(value, update);\n    }\n    validate(input) {\n        return this.defaultValue;\n    }\n}\nclass SimpleEditorOption {\n    constructor(id, name, defaultValue, schema) {\n        this.id = id;\n        this.name = name;\n        this.defaultValue = defaultValue;\n        this.schema = schema;\n    }\n    applyUpdate(value, update) {\n        return applyUpdate(value, update);\n    }\n    validate(input) {\n        if (typeof input === 'undefined') {\n            return this.defaultValue;\n        }\n        return input;\n    }\n    compute(env, options, value) {\n        return value;\n    }\n}\n/**\n * @internal\n */\nexport function boolean(value, defaultValue) {\n    if (typeof value === 'undefined') {\n        return defaultValue;\n    }\n    if (value === 'false') {\n        // treat the string 'false' as false\n        return false;\n    }\n    return Boolean(value);\n}\nclass EditorBooleanOption extends SimpleEditorOption {\n    constructor(id, name, defaultValue, schema = undefined) {\n        if (typeof schema !== 'undefined') {\n            schema.type = 'boolean';\n            schema.default = defaultValue;\n        }\n        super(id, name, defaultValue, schema);\n    }\n    validate(input) {\n        return boolean(input, this.defaultValue);\n    }\n}\n/**\n * @internal\n */\nexport function clampedInt(value, defaultValue, minimum, maximum) {\n    if (typeof value === 'undefined') {\n        return defaultValue;\n    }\n    let r = parseInt(value, 10);\n    if (isNaN(r)) {\n        return defaultValue;\n    }\n    r = Math.max(minimum, r);\n    r = Math.min(maximum, r);\n    return r | 0;\n}\nclass EditorIntOption extends SimpleEditorOption {\n    static clampedInt(value, defaultValue, minimum, maximum) {\n        return clampedInt(value, defaultValue, minimum, maximum);\n    }\n    constructor(id, name, defaultValue, minimum, maximum, schema = undefined) {\n        if (typeof schema !== 'undefined') {\n            schema.type = 'integer';\n            schema.default = defaultValue;\n            schema.minimum = minimum;\n            schema.maximum = maximum;\n        }\n        super(id, name, defaultValue, schema);\n        this.minimum = minimum;\n        this.maximum = maximum;\n    }\n    validate(input) {\n        return EditorIntOption.clampedInt(input, this.defaultValue, this.minimum, this.maximum);\n    }\n}\n/**\n * @internal\n */\nexport function clampedFloat(value, defaultValue, minimum, maximum) {\n    if (typeof value === 'undefined') {\n        return defaultValue;\n    }\n    const r = EditorFloatOption.float(value, defaultValue);\n    return EditorFloatOption.clamp(r, minimum, maximum);\n}\nclass EditorFloatOption extends SimpleEditorOption {\n    static clamp(n, min, max) {\n        if (n < min) {\n            return min;\n        }\n        if (n > max) {\n            return max;\n        }\n        return n;\n    }\n    static float(value, defaultValue) {\n        if (typeof value === 'number') {\n            return value;\n        }\n        if (typeof value === 'undefined') {\n            return defaultValue;\n        }\n        const r = parseFloat(value);\n        return (isNaN(r) ? defaultValue : r);\n    }\n    constructor(id, name, defaultValue, validationFn, schema) {\n        if (typeof schema !== 'undefined') {\n            schema.type = 'number';\n            schema.default = defaultValue;\n        }\n        super(id, name, defaultValue, schema);\n        this.validationFn = validationFn;\n    }\n    validate(input) {\n        return this.validationFn(EditorFloatOption.float(input, this.defaultValue));\n    }\n}\nclass EditorStringOption extends SimpleEditorOption {\n    static string(value, defaultValue) {\n        if (typeof value !== 'string') {\n            return defaultValue;\n        }\n        return value;\n    }\n    constructor(id, name, defaultValue, schema = undefined) {\n        if (typeof schema !== 'undefined') {\n            schema.type = 'string';\n            schema.default = defaultValue;\n        }\n        super(id, name, defaultValue, schema);\n    }\n    validate(input) {\n        return EditorStringOption.string(input, this.defaultValue);\n    }\n}\n/**\n * @internal\n */\nexport function stringSet(value, defaultValue, allowedValues, renamedValues) {\n    if (typeof value !== 'string') {\n        return defaultValue;\n    }\n    if (renamedValues && value in renamedValues) {\n        return renamedValues[value];\n    }\n    if (allowedValues.indexOf(value) === -1) {\n        return defaultValue;\n    }\n    return value;\n}\nclass EditorStringEnumOption extends SimpleEditorOption {\n    constructor(id, name, defaultValue, allowedValues, schema = undefined) {\n        if (typeof schema !== 'undefined') {\n            schema.type = 'string';\n            schema.enum = allowedValues;\n            schema.default = defaultValue;\n        }\n        super(id, name, defaultValue, schema);\n        this._allowedValues = allowedValues;\n    }\n    validate(input) {\n        return stringSet(input, this.defaultValue, this._allowedValues);\n    }\n}\nclass EditorEnumOption extends BaseEditorOption {\n    constructor(id, name, defaultValue, defaultStringValue, allowedValues, convert, schema = undefined) {\n        if (typeof schema !== 'undefined') {\n            schema.type = 'string';\n            schema.enum = allowedValues;\n            schema.default = defaultStringValue;\n        }\n        super(id, name, defaultValue, schema);\n        this._allowedValues = allowedValues;\n        this._convert = convert;\n    }\n    validate(input) {\n        if (typeof input !== 'string') {\n            return this.defaultValue;\n        }\n        if (this._allowedValues.indexOf(input) === -1) {\n            return this.defaultValue;\n        }\n        return this._convert(input);\n    }\n}\n//#endregion\n//#region autoIndent\nfunction _autoIndentFromString(autoIndent) {\n    switch (autoIndent) {\n        case 'none': return 0 /* EditorAutoIndentStrategy.None */;\n        case 'keep': return 1 /* EditorAutoIndentStrategy.Keep */;\n        case 'brackets': return 2 /* EditorAutoIndentStrategy.Brackets */;\n        case 'advanced': return 3 /* EditorAutoIndentStrategy.Advanced */;\n        case 'full': return 4 /* EditorAutoIndentStrategy.Full */;\n    }\n}\n//#endregion\n//#region accessibilitySupport\nclass EditorAccessibilitySupport extends BaseEditorOption {\n    constructor() {\n        super(2 /* EditorOption.accessibilitySupport */, 'accessibilitySupport', 0 /* AccessibilitySupport.Unknown */, {\n            type: 'string',\n            enum: ['auto', 'on', 'off'],\n            enumDescriptions: [\n                nls.localize('accessibilitySupport.auto', \"Use platform APIs to detect when a Screen Reader is attached\"),\n                nls.localize('accessibilitySupport.on', \"Optimize for usage with a Screen Reader\"),\n                nls.localize('accessibilitySupport.off', \"Assume a screen reader is not attached\"),\n            ],\n            default: 'auto',\n            tags: ['accessibility'],\n            description: nls.localize('accessibilitySupport', \"Controls if the UI should run in a mode where it is optimized for screen readers.\")\n        });\n    }\n    validate(input) {\n        switch (input) {\n            case 'auto': return 0 /* AccessibilitySupport.Unknown */;\n            case 'off': return 1 /* AccessibilitySupport.Disabled */;\n            case 'on': return 2 /* AccessibilitySupport.Enabled */;\n        }\n        return this.defaultValue;\n    }\n    compute(env, options, value) {\n        if (value === 0 /* AccessibilitySupport.Unknown */) {\n            // The editor reads the `accessibilitySupport` from the environment\n            return env.accessibilitySupport;\n        }\n        return value;\n    }\n}\nclass EditorComments extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            insertSpace: true,\n            ignoreEmptyLines: true,\n        };\n        super(21 /* EditorOption.comments */, 'comments', defaults, {\n            'editor.comments.insertSpace': {\n                type: 'boolean',\n                default: defaults.insertSpace,\n                description: nls.localize('comments.insertSpace', \"Controls whether a space character is inserted when commenting.\")\n            },\n            'editor.comments.ignoreEmptyLines': {\n                type: 'boolean',\n                default: defaults.ignoreEmptyLines,\n                description: nls.localize('comments.ignoreEmptyLines', 'Controls if empty lines should be ignored with toggle, add or remove actions for line comments.')\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            insertSpace: boolean(input.insertSpace, this.defaultValue.insertSpace),\n            ignoreEmptyLines: boolean(input.ignoreEmptyLines, this.defaultValue.ignoreEmptyLines),\n        };\n    }\n}\nfunction _cursorBlinkingStyleFromString(cursorBlinkingStyle) {\n    switch (cursorBlinkingStyle) {\n        case 'blink': return 1 /* TextEditorCursorBlinkingStyle.Blink */;\n        case 'smooth': return 2 /* TextEditorCursorBlinkingStyle.Smooth */;\n        case 'phase': return 3 /* TextEditorCursorBlinkingStyle.Phase */;\n        case 'expand': return 4 /* TextEditorCursorBlinkingStyle.Expand */;\n        case 'solid': return 5 /* TextEditorCursorBlinkingStyle.Solid */;\n    }\n}\n//#endregion\n//#region cursorStyle\n/**\n * The style in which the editor's cursor should be rendered.\n */\nexport var TextEditorCursorStyle;\n(function (TextEditorCursorStyle) {\n    /**\n     * As a vertical line (sitting between two characters).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"Line\"] = 1] = \"Line\";\n    /**\n     * As a block (sitting on top of a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"Block\"] = 2] = \"Block\";\n    /**\n     * As a horizontal line (sitting under a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"Underline\"] = 3] = \"Underline\";\n    /**\n     * As a thin vertical line (sitting between two characters).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"LineThin\"] = 4] = \"LineThin\";\n    /**\n     * As an outlined block (sitting on top of a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"BlockOutline\"] = 5] = \"BlockOutline\";\n    /**\n     * As a thin horizontal line (sitting under a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"UnderlineThin\"] = 6] = \"UnderlineThin\";\n})(TextEditorCursorStyle || (TextEditorCursorStyle = {}));\nfunction _cursorStyleFromString(cursorStyle) {\n    switch (cursorStyle) {\n        case 'line': return TextEditorCursorStyle.Line;\n        case 'block': return TextEditorCursorStyle.Block;\n        case 'underline': return TextEditorCursorStyle.Underline;\n        case 'line-thin': return TextEditorCursorStyle.LineThin;\n        case 'block-outline': return TextEditorCursorStyle.BlockOutline;\n        case 'underline-thin': return TextEditorCursorStyle.UnderlineThin;\n    }\n}\n//#endregion\n//#region editorClassName\nclass EditorClassName extends ComputedEditorOption {\n    constructor() {\n        super(138 /* EditorOption.editorClassName */);\n    }\n    compute(env, options, _) {\n        const classNames = ['monaco-editor'];\n        if (options.get(37 /* EditorOption.extraEditorClassName */)) {\n            classNames.push(options.get(37 /* EditorOption.extraEditorClassName */));\n        }\n        if (env.extraEditorClassName) {\n            classNames.push(env.extraEditorClassName);\n        }\n        if (options.get(71 /* EditorOption.mouseStyle */) === 'default') {\n            classNames.push('mouse-default');\n        }\n        else if (options.get(71 /* EditorOption.mouseStyle */) === 'copy') {\n            classNames.push('mouse-copy');\n        }\n        if (options.get(108 /* EditorOption.showUnused */)) {\n            classNames.push('showUnused');\n        }\n        if (options.get(136 /* EditorOption.showDeprecated */)) {\n            classNames.push('showDeprecated');\n        }\n        return classNames.join(' ');\n    }\n}\n//#endregion\n//#region emptySelectionClipboard\nclass EditorEmptySelectionClipboard extends EditorBooleanOption {\n    constructor() {\n        super(35 /* EditorOption.emptySelectionClipboard */, 'emptySelectionClipboard', true, { description: nls.localize('emptySelectionClipboard', \"Controls whether copying without a selection copies the current line.\") });\n    }\n    compute(env, options, value) {\n        return value && env.emptySelectionClipboard;\n    }\n}\nclass EditorFind extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            cursorMoveOnType: true,\n            seedSearchStringFromSelection: 'always',\n            autoFindInSelection: 'never',\n            globalFindClipboard: false,\n            addExtraSpaceOnTop: true,\n            loop: true\n        };\n        super(39 /* EditorOption.find */, 'find', defaults, {\n            'editor.find.cursorMoveOnType': {\n                type: 'boolean',\n                default: defaults.cursorMoveOnType,\n                description: nls.localize('find.cursorMoveOnType', \"Controls whether the cursor should jump to find matches while typing.\")\n            },\n            'editor.find.seedSearchStringFromSelection': {\n                type: 'string',\n                enum: ['never', 'always', 'selection'],\n                default: defaults.seedSearchStringFromSelection,\n                enumDescriptions: [\n                    nls.localize('editor.find.seedSearchStringFromSelection.never', 'Never seed search string from the editor selection.'),\n                    nls.localize('editor.find.seedSearchStringFromSelection.always', 'Always seed search string from the editor selection, including word at cursor position.'),\n                    nls.localize('editor.find.seedSearchStringFromSelection.selection', 'Only seed search string from the editor selection.')\n                ],\n                description: nls.localize('find.seedSearchStringFromSelection', \"Controls whether the search string in the Find Widget is seeded from the editor selection.\")\n            },\n            'editor.find.autoFindInSelection': {\n                type: 'string',\n                enum: ['never', 'always', 'multiline'],\n                default: defaults.autoFindInSelection,\n                enumDescriptions: [\n                    nls.localize('editor.find.autoFindInSelection.never', 'Never turn on Find in Selection automatically (default).'),\n                    nls.localize('editor.find.autoFindInSelection.always', 'Always turn on Find in Selection automatically.'),\n                    nls.localize('editor.find.autoFindInSelection.multiline', 'Turn on Find in Selection automatically when multiple lines of content are selected.')\n                ],\n                description: nls.localize('find.autoFindInSelection', \"Controls the condition for turning on Find in Selection automatically.\")\n            },\n            'editor.find.globalFindClipboard': {\n                type: 'boolean',\n                default: defaults.globalFindClipboard,\n                description: nls.localize('find.globalFindClipboard', \"Controls whether the Find Widget should read or modify the shared find clipboard on macOS.\"),\n                included: platform.isMacintosh\n            },\n            'editor.find.addExtraSpaceOnTop': {\n                type: 'boolean',\n                default: defaults.addExtraSpaceOnTop,\n                description: nls.localize('find.addExtraSpaceOnTop', \"Controls whether the Find Widget should add extra lines on top of the editor. When true, you can scroll beyond the first line when the Find Widget is visible.\")\n            },\n            'editor.find.loop': {\n                type: 'boolean',\n                default: defaults.loop,\n                description: nls.localize('find.loop', \"Controls whether the search automatically restarts from the beginning (or the end) when no further matches can be found.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            cursorMoveOnType: boolean(input.cursorMoveOnType, this.defaultValue.cursorMoveOnType),\n            seedSearchStringFromSelection: typeof _input.seedSearchStringFromSelection === 'boolean'\n                ? (_input.seedSearchStringFromSelection ? 'always' : 'never')\n                : stringSet(input.seedSearchStringFromSelection, this.defaultValue.seedSearchStringFromSelection, ['never', 'always', 'selection']),\n            autoFindInSelection: typeof _input.autoFindInSelection === 'boolean'\n                ? (_input.autoFindInSelection ? 'always' : 'never')\n                : stringSet(input.autoFindInSelection, this.defaultValue.autoFindInSelection, ['never', 'always', 'multiline']),\n            globalFindClipboard: boolean(input.globalFindClipboard, this.defaultValue.globalFindClipboard),\n            addExtraSpaceOnTop: boolean(input.addExtraSpaceOnTop, this.defaultValue.addExtraSpaceOnTop),\n            loop: boolean(input.loop, this.defaultValue.loop),\n        };\n    }\n}\n//#endregion\n//#region fontLigatures\n/**\n * @internal\n */\nexport class EditorFontLigatures extends BaseEditorOption {\n    constructor() {\n        super(49 /* EditorOption.fontLigatures */, 'fontLigatures', EditorFontLigatures.OFF, {\n            anyOf: [\n                {\n                    type: 'boolean',\n                    description: nls.localize('fontLigatures', \"Enables/Disables font ligatures ('calt' and 'liga' font features). Change this to a string for fine-grained control of the 'font-feature-settings' CSS property.\"),\n                },\n                {\n                    type: 'string',\n                    description: nls.localize('fontFeatureSettings', \"Explicit 'font-feature-settings' CSS property. A boolean can be passed instead if one only needs to turn on/off ligatures.\")\n                }\n            ],\n            description: nls.localize('fontLigaturesGeneral', \"Configures font ligatures or font features. Can be either a boolean to enable/disable ligatures or a string for the value of the CSS 'font-feature-settings' property.\"),\n            default: false\n        });\n    }\n    validate(input) {\n        if (typeof input === 'undefined') {\n            return this.defaultValue;\n        }\n        if (typeof input === 'string') {\n            if (input === 'false') {\n                return EditorFontLigatures.OFF;\n            }\n            if (input === 'true') {\n                return EditorFontLigatures.ON;\n            }\n            return input;\n        }\n        if (Boolean(input)) {\n            return EditorFontLigatures.ON;\n        }\n        return EditorFontLigatures.OFF;\n    }\n}\nEditorFontLigatures.OFF = '\"liga\" off, \"calt\" off';\nEditorFontLigatures.ON = '\"liga\" on, \"calt\" on';\n//#endregion\n//#region fontVariations\n/**\n * @internal\n */\nexport class EditorFontVariations extends BaseEditorOption {\n    constructor() {\n        super(52 /* EditorOption.fontVariations */, 'fontVariations', EditorFontVariations.OFF, {\n            anyOf: [\n                {\n                    type: 'boolean',\n                    description: nls.localize('fontVariations', \"Enables/Disables the translation from font-weight to font-variation-settings. Change this to a string for fine-grained control of the 'font-variation-settings' CSS property.\"),\n                },\n                {\n                    type: 'string',\n                    description: nls.localize('fontVariationSettings', \"Explicit 'font-variation-settings' CSS property. A boolean can be passed instead if one only needs to translate font-weight to font-variation-settings.\")\n                }\n            ],\n            description: nls.localize('fontVariationsGeneral', \"Configures font variations. Can be either a boolean to enable/disable the translation from font-weight to font-variation-settings or a string for the value of the CSS 'font-variation-settings' property.\"),\n            default: false\n        });\n    }\n    validate(input) {\n        if (typeof input === 'undefined') {\n            return this.defaultValue;\n        }\n        if (typeof input === 'string') {\n            if (input === 'false') {\n                return EditorFontVariations.OFF;\n            }\n            if (input === 'true') {\n                return EditorFontVariations.TRANSLATE;\n            }\n            return input;\n        }\n        if (Boolean(input)) {\n            return EditorFontVariations.TRANSLATE;\n        }\n        return EditorFontVariations.OFF;\n    }\n    compute(env, options, value) {\n        // The value is computed from the fontWeight if it is true.\n        // So take the result from env.fontInfo\n        return env.fontInfo.fontVariationSettings;\n    }\n}\n// Text is laid out using default settings.\nEditorFontVariations.OFF = 'normal';\n// Translate `fontWeight` config to the `font-variation-settings` CSS property.\nEditorFontVariations.TRANSLATE = 'translate';\n//#endregion\n//#region fontInfo\nclass EditorFontInfo extends ComputedEditorOption {\n    constructor() {\n        super(48 /* EditorOption.fontInfo */);\n    }\n    compute(env, options, _) {\n        return env.fontInfo;\n    }\n}\n//#endregion\n//#region fontSize\nclass EditorFontSize extends SimpleEditorOption {\n    constructor() {\n        super(50 /* EditorOption.fontSize */, 'fontSize', EDITOR_FONT_DEFAULTS.fontSize, {\n            type: 'number',\n            minimum: 6,\n            maximum: 100,\n            default: EDITOR_FONT_DEFAULTS.fontSize,\n            description: nls.localize('fontSize', \"Controls the font size in pixels.\")\n        });\n    }\n    validate(input) {\n        const r = EditorFloatOption.float(input, this.defaultValue);\n        if (r === 0) {\n            return EDITOR_FONT_DEFAULTS.fontSize;\n        }\n        return EditorFloatOption.clamp(r, 6, 100);\n    }\n    compute(env, options, value) {\n        // The final fontSize respects the editor zoom level.\n        // So take the result from env.fontInfo\n        return env.fontInfo.fontSize;\n    }\n}\n//#endregion\n//#region fontWeight\nclass EditorFontWeight extends BaseEditorOption {\n    constructor() {\n        super(51 /* EditorOption.fontWeight */, 'fontWeight', EDITOR_FONT_DEFAULTS.fontWeight, {\n            anyOf: [\n                {\n                    type: 'number',\n                    minimum: EditorFontWeight.MINIMUM_VALUE,\n                    maximum: EditorFontWeight.MAXIMUM_VALUE,\n                    errorMessage: nls.localize('fontWeightErrorMessage', \"Only \\\"normal\\\" and \\\"bold\\\" keywords or numbers between 1 and 1000 are allowed.\")\n                },\n                {\n                    type: 'string',\n                    pattern: '^(normal|bold|1000|[1-9][0-9]{0,2})$'\n                },\n                {\n                    enum: EditorFontWeight.SUGGESTION_VALUES\n                }\n            ],\n            default: EDITOR_FONT_DEFAULTS.fontWeight,\n            description: nls.localize('fontWeight', \"Controls the font weight. Accepts \\\"normal\\\" and \\\"bold\\\" keywords or numbers between 1 and 1000.\")\n        });\n    }\n    validate(input) {\n        if (input === 'normal' || input === 'bold') {\n            return input;\n        }\n        return String(EditorIntOption.clampedInt(input, EDITOR_FONT_DEFAULTS.fontWeight, EditorFontWeight.MINIMUM_VALUE, EditorFontWeight.MAXIMUM_VALUE));\n    }\n}\nEditorFontWeight.SUGGESTION_VALUES = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];\nEditorFontWeight.MINIMUM_VALUE = 1;\nEditorFontWeight.MAXIMUM_VALUE = 1000;\nclass EditorGoToLocation extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            multiple: 'peek',\n            multipleDefinitions: 'peek',\n            multipleTypeDefinitions: 'peek',\n            multipleDeclarations: 'peek',\n            multipleImplementations: 'peek',\n            multipleReferences: 'peek',\n            alternativeDefinitionCommand: 'editor.action.goToReferences',\n            alternativeTypeDefinitionCommand: 'editor.action.goToReferences',\n            alternativeDeclarationCommand: 'editor.action.goToReferences',\n            alternativeImplementationCommand: '',\n            alternativeReferenceCommand: '',\n        };\n        const jsonSubset = {\n            type: 'string',\n            enum: ['peek', 'gotoAndPeek', 'goto'],\n            default: defaults.multiple,\n            enumDescriptions: [\n                nls.localize('editor.gotoLocation.multiple.peek', 'Show Peek view of the results (default)'),\n                nls.localize('editor.gotoLocation.multiple.gotoAndPeek', 'Go to the primary result and show a Peek view'),\n                nls.localize('editor.gotoLocation.multiple.goto', 'Go to the primary result and enable Peek-less navigation to others')\n            ]\n        };\n        const alternativeCommandOptions = ['', 'editor.action.referenceSearch.trigger', 'editor.action.goToReferences', 'editor.action.peekImplementation', 'editor.action.goToImplementation', 'editor.action.peekTypeDefinition', 'editor.action.goToTypeDefinition', 'editor.action.peekDeclaration', 'editor.action.revealDeclaration', 'editor.action.peekDefinition', 'editor.action.revealDefinitionAside', 'editor.action.revealDefinition'];\n        super(56 /* EditorOption.gotoLocation */, 'gotoLocation', defaults, {\n            'editor.gotoLocation.multiple': {\n                deprecationMessage: nls.localize('editor.gotoLocation.multiple.deprecated', \"This setting is deprecated, please use separate settings like 'editor.editor.gotoLocation.multipleDefinitions' or 'editor.editor.gotoLocation.multipleImplementations' instead.\"),\n            },\n            'editor.gotoLocation.multipleDefinitions': Object.assign({ description: nls.localize('editor.editor.gotoLocation.multipleDefinitions', \"Controls the behavior the 'Go to Definition'-command when multiple target locations exist.\") }, jsonSubset),\n            'editor.gotoLocation.multipleTypeDefinitions': Object.assign({ description: nls.localize('editor.editor.gotoLocation.multipleTypeDefinitions', \"Controls the behavior the 'Go to Type Definition'-command when multiple target locations exist.\") }, jsonSubset),\n            'editor.gotoLocation.multipleDeclarations': Object.assign({ description: nls.localize('editor.editor.gotoLocation.multipleDeclarations', \"Controls the behavior the 'Go to Declaration'-command when multiple target locations exist.\") }, jsonSubset),\n            'editor.gotoLocation.multipleImplementations': Object.assign({ description: nls.localize('editor.editor.gotoLocation.multipleImplemenattions', \"Controls the behavior the 'Go to Implementations'-command when multiple target locations exist.\") }, jsonSubset),\n            'editor.gotoLocation.multipleReferences': Object.assign({ description: nls.localize('editor.editor.gotoLocation.multipleReferences', \"Controls the behavior the 'Go to References'-command when multiple target locations exist.\") }, jsonSubset),\n            'editor.gotoLocation.alternativeDefinitionCommand': {\n                type: 'string',\n                default: defaults.alternativeDefinitionCommand,\n                enum: alternativeCommandOptions,\n                description: nls.localize('alternativeDefinitionCommand', \"Alternative command id that is being executed when the result of 'Go to Definition' is the current location.\")\n            },\n            'editor.gotoLocation.alternativeTypeDefinitionCommand': {\n                type: 'string',\n                default: defaults.alternativeTypeDefinitionCommand,\n                enum: alternativeCommandOptions,\n                description: nls.localize('alternativeTypeDefinitionCommand', \"Alternative command id that is being executed when the result of 'Go to Type Definition' is the current location.\")\n            },\n            'editor.gotoLocation.alternativeDeclarationCommand': {\n                type: 'string',\n                default: defaults.alternativeDeclarationCommand,\n                enum: alternativeCommandOptions,\n                description: nls.localize('alternativeDeclarationCommand', \"Alternative command id that is being executed when the result of 'Go to Declaration' is the current location.\")\n            },\n            'editor.gotoLocation.alternativeImplementationCommand': {\n                type: 'string',\n                default: defaults.alternativeImplementationCommand,\n                enum: alternativeCommandOptions,\n                description: nls.localize('alternativeImplementationCommand', \"Alternative command id that is being executed when the result of 'Go to Implementation' is the current location.\")\n            },\n            'editor.gotoLocation.alternativeReferenceCommand': {\n                type: 'string',\n                default: defaults.alternativeReferenceCommand,\n                enum: alternativeCommandOptions,\n                description: nls.localize('alternativeReferenceCommand', \"Alternative command id that is being executed when the result of 'Go to Reference' is the current location.\")\n            },\n        });\n    }\n    validate(_input) {\n        var _a, _b, _c, _d, _e;\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            multiple: stringSet(input.multiple, this.defaultValue.multiple, ['peek', 'gotoAndPeek', 'goto']),\n            multipleDefinitions: (_a = input.multipleDefinitions) !== null && _a !== void 0 ? _a : stringSet(input.multipleDefinitions, 'peek', ['peek', 'gotoAndPeek', 'goto']),\n            multipleTypeDefinitions: (_b = input.multipleTypeDefinitions) !== null && _b !== void 0 ? _b : stringSet(input.multipleTypeDefinitions, 'peek', ['peek', 'gotoAndPeek', 'goto']),\n            multipleDeclarations: (_c = input.multipleDeclarations) !== null && _c !== void 0 ? _c : stringSet(input.multipleDeclarations, 'peek', ['peek', 'gotoAndPeek', 'goto']),\n            multipleImplementations: (_d = input.multipleImplementations) !== null && _d !== void 0 ? _d : stringSet(input.multipleImplementations, 'peek', ['peek', 'gotoAndPeek', 'goto']),\n            multipleReferences: (_e = input.multipleReferences) !== null && _e !== void 0 ? _e : stringSet(input.multipleReferences, 'peek', ['peek', 'gotoAndPeek', 'goto']),\n            alternativeDefinitionCommand: EditorStringOption.string(input.alternativeDefinitionCommand, this.defaultValue.alternativeDefinitionCommand),\n            alternativeTypeDefinitionCommand: EditorStringOption.string(input.alternativeTypeDefinitionCommand, this.defaultValue.alternativeTypeDefinitionCommand),\n            alternativeDeclarationCommand: EditorStringOption.string(input.alternativeDeclarationCommand, this.defaultValue.alternativeDeclarationCommand),\n            alternativeImplementationCommand: EditorStringOption.string(input.alternativeImplementationCommand, this.defaultValue.alternativeImplementationCommand),\n            alternativeReferenceCommand: EditorStringOption.string(input.alternativeReferenceCommand, this.defaultValue.alternativeReferenceCommand),\n        };\n    }\n}\nclass EditorHover extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            enabled: true,\n            delay: 300,\n            sticky: true,\n            above: true,\n        };\n        super(58 /* EditorOption.hover */, 'hover', defaults, {\n            'editor.hover.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                description: nls.localize('hover.enabled', \"Controls whether the hover is shown.\")\n            },\n            'editor.hover.delay': {\n                type: 'number',\n                default: defaults.delay,\n                minimum: 0,\n                maximum: 10000,\n                description: nls.localize('hover.delay', \"Controls the delay in milliseconds after which the hover is shown.\")\n            },\n            'editor.hover.sticky': {\n                type: 'boolean',\n                default: defaults.sticky,\n                description: nls.localize('hover.sticky', \"Controls whether the hover should remain visible when mouse is moved over it.\")\n            },\n            'editor.hover.above': {\n                type: 'boolean',\n                default: defaults.above,\n                description: nls.localize('hover.above', \"Prefer showing hovers above the line, if there's space.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            delay: EditorIntOption.clampedInt(input.delay, this.defaultValue.delay, 0, 10000),\n            sticky: boolean(input.sticky, this.defaultValue.sticky),\n            above: boolean(input.above, this.defaultValue.above),\n        };\n    }\n}\n/**\n * @internal\n */\nexport class EditorLayoutInfoComputer extends ComputedEditorOption {\n    constructor() {\n        super(141 /* EditorOption.layoutInfo */);\n    }\n    compute(env, options, _) {\n        return EditorLayoutInfoComputer.computeLayout(options, {\n            memory: env.memory,\n            outerWidth: env.outerWidth,\n            outerHeight: env.outerHeight,\n            isDominatedByLongLines: env.isDominatedByLongLines,\n            lineHeight: env.fontInfo.lineHeight,\n            viewLineCount: env.viewLineCount,\n            lineNumbersDigitCount: env.lineNumbersDigitCount,\n            typicalHalfwidthCharacterWidth: env.fontInfo.typicalHalfwidthCharacterWidth,\n            maxDigitWidth: env.fontInfo.maxDigitWidth,\n            pixelRatio: env.pixelRatio,\n            glyphMarginDecorationLaneCount: env.glyphMarginDecorationLaneCount\n        });\n    }\n    static computeContainedMinimapLineCount(input) {\n        const typicalViewportLineCount = input.height / input.lineHeight;\n        const extraLinesBeforeFirstLine = Math.floor(input.paddingTop / input.lineHeight);\n        let extraLinesBeyondLastLine = Math.floor(input.paddingBottom / input.lineHeight);\n        if (input.scrollBeyondLastLine) {\n            extraLinesBeyondLastLine = Math.max(extraLinesBeyondLastLine, typicalViewportLineCount - 1);\n        }\n        const desiredRatio = (extraLinesBeforeFirstLine + input.viewLineCount + extraLinesBeyondLastLine) / (input.pixelRatio * input.height);\n        const minimapLineCount = Math.floor(input.viewLineCount / desiredRatio);\n        return { typicalViewportLineCount, extraLinesBeforeFirstLine, extraLinesBeyondLastLine, desiredRatio, minimapLineCount };\n    }\n    static _computeMinimapLayout(input, memory) {\n        const outerWidth = input.outerWidth;\n        const outerHeight = input.outerHeight;\n        const pixelRatio = input.pixelRatio;\n        if (!input.minimap.enabled) {\n            return {\n                renderMinimap: 0 /* RenderMinimap.None */,\n                minimapLeft: 0,\n                minimapWidth: 0,\n                minimapHeightIsEditorHeight: false,\n                minimapIsSampling: false,\n                minimapScale: 1,\n                minimapLineHeight: 1,\n                minimapCanvasInnerWidth: 0,\n                minimapCanvasInnerHeight: Math.floor(pixelRatio * outerHeight),\n                minimapCanvasOuterWidth: 0,\n                minimapCanvasOuterHeight: outerHeight,\n            };\n        }\n        // Can use memory if only the `viewLineCount` and `remainingWidth` have changed\n        const stableMinimapLayoutInput = memory.stableMinimapLayoutInput;\n        const couldUseMemory = (stableMinimapLayoutInput\n            // && input.outerWidth === lastMinimapLayoutInput.outerWidth !!! INTENTIONAL OMITTED\n            && input.outerHeight === stableMinimapLayoutInput.outerHeight\n            && input.lineHeight === stableMinimapLayoutInput.lineHeight\n            && input.typicalHalfwidthCharacterWidth === stableMinimapLayoutInput.typicalHalfwidthCharacterWidth\n            && input.pixelRatio === stableMinimapLayoutInput.pixelRatio\n            && input.scrollBeyondLastLine === stableMinimapLayoutInput.scrollBeyondLastLine\n            && input.paddingTop === stableMinimapLayoutInput.paddingTop\n            && input.paddingBottom === stableMinimapLayoutInput.paddingBottom\n            && input.minimap.enabled === stableMinimapLayoutInput.minimap.enabled\n            && input.minimap.side === stableMinimapLayoutInput.minimap.side\n            && input.minimap.size === stableMinimapLayoutInput.minimap.size\n            && input.minimap.showSlider === stableMinimapLayoutInput.minimap.showSlider\n            && input.minimap.renderCharacters === stableMinimapLayoutInput.minimap.renderCharacters\n            && input.minimap.maxColumn === stableMinimapLayoutInput.minimap.maxColumn\n            && input.minimap.scale === stableMinimapLayoutInput.minimap.scale\n            && input.verticalScrollbarWidth === stableMinimapLayoutInput.verticalScrollbarWidth\n            // && input.viewLineCount === lastMinimapLayoutInput.viewLineCount !!! INTENTIONAL OMITTED\n            // && input.remainingWidth === lastMinimapLayoutInput.remainingWidth !!! INTENTIONAL OMITTED\n            && input.isViewportWrapping === stableMinimapLayoutInput.isViewportWrapping);\n        const lineHeight = input.lineHeight;\n        const typicalHalfwidthCharacterWidth = input.typicalHalfwidthCharacterWidth;\n        const scrollBeyondLastLine = input.scrollBeyondLastLine;\n        const minimapRenderCharacters = input.minimap.renderCharacters;\n        let minimapScale = (pixelRatio >= 2 ? Math.round(input.minimap.scale * 2) : input.minimap.scale);\n        const minimapMaxColumn = input.minimap.maxColumn;\n        const minimapSize = input.minimap.size;\n        const minimapSide = input.minimap.side;\n        const verticalScrollbarWidth = input.verticalScrollbarWidth;\n        const viewLineCount = input.viewLineCount;\n        const remainingWidth = input.remainingWidth;\n        const isViewportWrapping = input.isViewportWrapping;\n        const baseCharHeight = minimapRenderCharacters ? 2 : 3;\n        let minimapCanvasInnerHeight = Math.floor(pixelRatio * outerHeight);\n        const minimapCanvasOuterHeight = minimapCanvasInnerHeight / pixelRatio;\n        let minimapHeightIsEditorHeight = false;\n        let minimapIsSampling = false;\n        let minimapLineHeight = baseCharHeight * minimapScale;\n        let minimapCharWidth = minimapScale / pixelRatio;\n        let minimapWidthMultiplier = 1;\n        if (minimapSize === 'fill' || minimapSize === 'fit') {\n            const { typicalViewportLineCount, extraLinesBeforeFirstLine, extraLinesBeyondLastLine, desiredRatio, minimapLineCount } = EditorLayoutInfoComputer.computeContainedMinimapLineCount({\n                viewLineCount: viewLineCount,\n                scrollBeyondLastLine: scrollBeyondLastLine,\n                paddingTop: input.paddingTop,\n                paddingBottom: input.paddingBottom,\n                height: outerHeight,\n                lineHeight: lineHeight,\n                pixelRatio: pixelRatio\n            });\n            // ratio is intentionally not part of the layout to avoid the layout changing all the time\n            // when doing sampling\n            const ratio = viewLineCount / minimapLineCount;\n            if (ratio > 1) {\n                minimapHeightIsEditorHeight = true;\n                minimapIsSampling = true;\n                minimapScale = 1;\n                minimapLineHeight = 1;\n                minimapCharWidth = minimapScale / pixelRatio;\n            }\n            else {\n                let fitBecomesFill = false;\n                let maxMinimapScale = minimapScale + 1;\n                if (minimapSize === 'fit') {\n                    const effectiveMinimapHeight = Math.ceil((extraLinesBeforeFirstLine + viewLineCount + extraLinesBeyondLastLine) * minimapLineHeight);\n                    if (isViewportWrapping && couldUseMemory && remainingWidth <= memory.stableFitRemainingWidth) {\n                        // There is a loop when using `fit` and viewport wrapping:\n                        // - view line count impacts minimap layout\n                        // - minimap layout impacts viewport width\n                        // - viewport width impacts view line count\n                        // To break the loop, once we go to a smaller minimap scale, we try to stick with it.\n                        fitBecomesFill = true;\n                        maxMinimapScale = memory.stableFitMaxMinimapScale;\n                    }\n                    else {\n                        fitBecomesFill = (effectiveMinimapHeight > minimapCanvasInnerHeight);\n                    }\n                }\n                if (minimapSize === 'fill' || fitBecomesFill) {\n                    minimapHeightIsEditorHeight = true;\n                    const configuredMinimapScale = minimapScale;\n                    minimapLineHeight = Math.min(lineHeight * pixelRatio, Math.max(1, Math.floor(1 / desiredRatio)));\n                    if (isViewportWrapping && couldUseMemory && remainingWidth <= memory.stableFitRemainingWidth) {\n                        // There is a loop when using `fill` and viewport wrapping:\n                        // - view line count impacts minimap layout\n                        // - minimap layout impacts viewport width\n                        // - viewport width impacts view line count\n                        // To break the loop, once we go to a smaller minimap scale, we try to stick with it.\n                        maxMinimapScale = memory.stableFitMaxMinimapScale;\n                    }\n                    minimapScale = Math.min(maxMinimapScale, Math.max(1, Math.floor(minimapLineHeight / baseCharHeight)));\n                    if (minimapScale > configuredMinimapScale) {\n                        minimapWidthMultiplier = Math.min(2, minimapScale / configuredMinimapScale);\n                    }\n                    minimapCharWidth = minimapScale / pixelRatio / minimapWidthMultiplier;\n                    minimapCanvasInnerHeight = Math.ceil((Math.max(typicalViewportLineCount, extraLinesBeforeFirstLine + viewLineCount + extraLinesBeyondLastLine)) * minimapLineHeight);\n                    if (isViewportWrapping) {\n                        // remember for next time\n                        memory.stableMinimapLayoutInput = input;\n                        memory.stableFitRemainingWidth = remainingWidth;\n                        memory.stableFitMaxMinimapScale = minimapScale;\n                    }\n                    else {\n                        memory.stableMinimapLayoutInput = null;\n                        memory.stableFitRemainingWidth = 0;\n                    }\n                }\n            }\n        }\n        // Given:\n        // (leaving 2px for the cursor to have space after the last character)\n        // viewportColumn = (contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth\n        // minimapWidth = viewportColumn * minimapCharWidth\n        // contentWidth = remainingWidth - minimapWidth\n        // What are good values for contentWidth and minimapWidth ?\n        // minimapWidth = ((contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth) * minimapCharWidth\n        // typicalHalfwidthCharacterWidth * minimapWidth = (contentWidth - verticalScrollbarWidth - 2) * minimapCharWidth\n        // typicalHalfwidthCharacterWidth * minimapWidth = (remainingWidth - minimapWidth - verticalScrollbarWidth - 2) * minimapCharWidth\n        // (typicalHalfwidthCharacterWidth + minimapCharWidth) * minimapWidth = (remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth\n        // minimapWidth = ((remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth) / (typicalHalfwidthCharacterWidth + minimapCharWidth)\n        const minimapMaxWidth = Math.floor(minimapMaxColumn * minimapCharWidth);\n        const minimapWidth = Math.min(minimapMaxWidth, Math.max(0, Math.floor(((remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth) / (typicalHalfwidthCharacterWidth + minimapCharWidth))) + MINIMAP_GUTTER_WIDTH);\n        let minimapCanvasInnerWidth = Math.floor(pixelRatio * minimapWidth);\n        const minimapCanvasOuterWidth = minimapCanvasInnerWidth / pixelRatio;\n        minimapCanvasInnerWidth = Math.floor(minimapCanvasInnerWidth * minimapWidthMultiplier);\n        const renderMinimap = (minimapRenderCharacters ? 1 /* RenderMinimap.Text */ : 2 /* RenderMinimap.Blocks */);\n        const minimapLeft = (minimapSide === 'left' ? 0 : (outerWidth - minimapWidth - verticalScrollbarWidth));\n        return {\n            renderMinimap,\n            minimapLeft,\n            minimapWidth,\n            minimapHeightIsEditorHeight,\n            minimapIsSampling,\n            minimapScale,\n            minimapLineHeight,\n            minimapCanvasInnerWidth,\n            minimapCanvasInnerHeight,\n            minimapCanvasOuterWidth,\n            minimapCanvasOuterHeight,\n        };\n    }\n    static computeLayout(options, env) {\n        const outerWidth = env.outerWidth | 0;\n        const outerHeight = env.outerHeight | 0;\n        const lineHeight = env.lineHeight | 0;\n        const lineNumbersDigitCount = env.lineNumbersDigitCount | 0;\n        const typicalHalfwidthCharacterWidth = env.typicalHalfwidthCharacterWidth;\n        const maxDigitWidth = env.maxDigitWidth;\n        const pixelRatio = env.pixelRatio;\n        const viewLineCount = env.viewLineCount;\n        const wordWrapOverride2 = options.get(133 /* EditorOption.wordWrapOverride2 */);\n        const wordWrapOverride1 = (wordWrapOverride2 === 'inherit' ? options.get(132 /* EditorOption.wordWrapOverride1 */) : wordWrapOverride2);\n        const wordWrap = (wordWrapOverride1 === 'inherit' ? options.get(128 /* EditorOption.wordWrap */) : wordWrapOverride1);\n        const wordWrapColumn = options.get(131 /* EditorOption.wordWrapColumn */);\n        const isDominatedByLongLines = env.isDominatedByLongLines;\n        const showGlyphMargin = options.get(55 /* EditorOption.glyphMargin */);\n        const showLineNumbers = (options.get(65 /* EditorOption.lineNumbers */).renderType !== 0 /* RenderLineNumbersType.Off */);\n        const lineNumbersMinChars = options.get(66 /* EditorOption.lineNumbersMinChars */);\n        const scrollBeyondLastLine = options.get(102 /* EditorOption.scrollBeyondLastLine */);\n        const padding = options.get(81 /* EditorOption.padding */);\n        const minimap = options.get(70 /* EditorOption.minimap */);\n        const scrollbar = options.get(100 /* EditorOption.scrollbar */);\n        const verticalScrollbarWidth = scrollbar.verticalScrollbarSize;\n        const verticalScrollbarHasArrows = scrollbar.verticalHasArrows;\n        const scrollbarArrowSize = scrollbar.arrowSize;\n        const horizontalScrollbarHeight = scrollbar.horizontalScrollbarSize;\n        const folding = options.get(41 /* EditorOption.folding */);\n        const showFoldingDecoration = options.get(107 /* EditorOption.showFoldingControls */) !== 'never';\n        let lineDecorationsWidth = options.get(63 /* EditorOption.lineDecorationsWidth */);\n        if (folding && showFoldingDecoration) {\n            lineDecorationsWidth += 16;\n        }\n        let lineNumbersWidth = 0;\n        if (showLineNumbers) {\n            const digitCount = Math.max(lineNumbersDigitCount, lineNumbersMinChars);\n            lineNumbersWidth = Math.round(digitCount * maxDigitWidth);\n        }\n        let glyphMarginWidth = 0;\n        if (showGlyphMargin) {\n            glyphMarginWidth = lineHeight * env.glyphMarginDecorationLaneCount;\n        }\n        let glyphMarginLeft = 0;\n        let lineNumbersLeft = glyphMarginLeft + glyphMarginWidth;\n        let decorationsLeft = lineNumbersLeft + lineNumbersWidth;\n        let contentLeft = decorationsLeft + lineDecorationsWidth;\n        const remainingWidth = outerWidth - glyphMarginWidth - lineNumbersWidth - lineDecorationsWidth;\n        let isWordWrapMinified = false;\n        let isViewportWrapping = false;\n        let wrappingColumn = -1;\n        if (wordWrapOverride1 === 'inherit' && isDominatedByLongLines) {\n            // Force viewport width wrapping if model is dominated by long lines\n            isWordWrapMinified = true;\n            isViewportWrapping = true;\n        }\n        else if (wordWrap === 'on' || wordWrap === 'bounded') {\n            isViewportWrapping = true;\n        }\n        else if (wordWrap === 'wordWrapColumn') {\n            wrappingColumn = wordWrapColumn;\n        }\n        const minimapLayout = EditorLayoutInfoComputer._computeMinimapLayout({\n            outerWidth: outerWidth,\n            outerHeight: outerHeight,\n            lineHeight: lineHeight,\n            typicalHalfwidthCharacterWidth: typicalHalfwidthCharacterWidth,\n            pixelRatio: pixelRatio,\n            scrollBeyondLastLine: scrollBeyondLastLine,\n            paddingTop: padding.top,\n            paddingBottom: padding.bottom,\n            minimap: minimap,\n            verticalScrollbarWidth: verticalScrollbarWidth,\n            viewLineCount: viewLineCount,\n            remainingWidth: remainingWidth,\n            isViewportWrapping: isViewportWrapping,\n        }, env.memory || new ComputeOptionsMemory());\n        if (minimapLayout.renderMinimap !== 0 /* RenderMinimap.None */ && minimapLayout.minimapLeft === 0) {\n            // the minimap is rendered to the left, so move everything to the right\n            glyphMarginLeft += minimapLayout.minimapWidth;\n            lineNumbersLeft += minimapLayout.minimapWidth;\n            decorationsLeft += minimapLayout.minimapWidth;\n            contentLeft += minimapLayout.minimapWidth;\n        }\n        const contentWidth = remainingWidth - minimapLayout.minimapWidth;\n        // (leaving 2px for the cursor to have space after the last character)\n        const viewportColumn = Math.max(1, Math.floor((contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth));\n        const verticalArrowSize = (verticalScrollbarHasArrows ? scrollbarArrowSize : 0);\n        if (isViewportWrapping) {\n            // compute the actual wrappingColumn\n            wrappingColumn = Math.max(1, viewportColumn);\n            if (wordWrap === 'bounded') {\n                wrappingColumn = Math.min(wrappingColumn, wordWrapColumn);\n            }\n        }\n        return {\n            width: outerWidth,\n            height: outerHeight,\n            glyphMarginLeft: glyphMarginLeft,\n            glyphMarginWidth: glyphMarginWidth,\n            glyphMarginDecorationLaneCount: env.glyphMarginDecorationLaneCount,\n            lineNumbersLeft: lineNumbersLeft,\n            lineNumbersWidth: lineNumbersWidth,\n            decorationsLeft: decorationsLeft,\n            decorationsWidth: lineDecorationsWidth,\n            contentLeft: contentLeft,\n            contentWidth: contentWidth,\n            minimap: minimapLayout,\n            viewportColumn: viewportColumn,\n            isWordWrapMinified: isWordWrapMinified,\n            isViewportWrapping: isViewportWrapping,\n            wrappingColumn: wrappingColumn,\n            verticalScrollbarWidth: verticalScrollbarWidth,\n            horizontalScrollbarHeight: horizontalScrollbarHeight,\n            overviewRuler: {\n                top: verticalArrowSize,\n                width: verticalScrollbarWidth,\n                height: (outerHeight - 2 * verticalArrowSize),\n                right: 0\n            }\n        };\n    }\n}\n//#endregion\n//#region WrappingStrategy\nclass WrappingStrategy extends BaseEditorOption {\n    constructor() {\n        super(135 /* EditorOption.wrappingStrategy */, 'wrappingStrategy', 'simple', {\n            'editor.wrappingStrategy': {\n                enumDescriptions: [\n                    nls.localize('wrappingStrategy.simple', \"Assumes that all characters are of the same width. This is a fast algorithm that works correctly for monospace fonts and certain scripts (like Latin characters) where glyphs are of equal width.\"),\n                    nls.localize('wrappingStrategy.advanced', \"Delegates wrapping points computation to the browser. This is a slow algorithm, that might cause freezes for large files, but it works correctly in all cases.\")\n                ],\n                type: 'string',\n                enum: ['simple', 'advanced'],\n                default: 'simple',\n                description: nls.localize('wrappingStrategy', \"Controls the algorithm that computes wrapping points. Note that when in accessibility mode, advanced will be used for the best experience.\")\n            }\n        });\n    }\n    validate(input) {\n        return stringSet(input, 'simple', ['simple', 'advanced']);\n    }\n    compute(env, options, value) {\n        const accessibilitySupport = options.get(2 /* EditorOption.accessibilitySupport */);\n        if (accessibilitySupport === 2 /* AccessibilitySupport.Enabled */) {\n            // if we know for a fact that a screen reader is attached, we switch our strategy to advanced to\n            // help that the editor's wrapping points match the textarea's wrapping points\n            return 'advanced';\n        }\n        return value;\n    }\n}\nclass EditorLightbulb extends BaseEditorOption {\n    constructor() {\n        const defaults = { enabled: true };\n        super(62 /* EditorOption.lightbulb */, 'lightbulb', defaults, {\n            'editor.lightbulb.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                description: nls.localize('codeActions', \"Enables the Code Action lightbulb in the editor.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled)\n        };\n    }\n}\nclass EditorStickyScroll extends BaseEditorOption {\n    constructor() {\n        const defaults = { enabled: false, maxLineCount: 5, defaultModel: 'outlineModel' };\n        super(112 /* EditorOption.stickyScroll */, 'stickyScroll', defaults, {\n            'editor.stickyScroll.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                description: nls.localize('editor.stickyScroll.enabled', \"Shows the nested current scopes during the scroll at the top of the editor.\")\n            },\n            'editor.stickyScroll.maxLineCount': {\n                type: 'number',\n                default: defaults.maxLineCount,\n                minimum: 1,\n                maximum: 10,\n                description: nls.localize('editor.stickyScroll.maxLineCount', \"Defines the maximum number of sticky lines to show.\")\n            },\n            'editor.stickyScroll.defaultModel': {\n                type: 'string',\n                enum: ['outlineModel', 'foldingProviderModel', 'indentationModel'],\n                default: defaults.defaultModel,\n                description: nls.localize('editor.stickyScroll.defaultModel', \"Defines the model to use for determining which lines to stick. If the outline model does not exist, it will fall back on the folding provider model which falls back on the indentation model. This order is respected in all three cases.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            maxLineCount: EditorIntOption.clampedInt(input.maxLineCount, this.defaultValue.maxLineCount, 1, 10),\n            defaultModel: stringSet(input.defaultModel, this.defaultValue.defaultModel, ['outlineModel', 'foldingProviderModel', 'indentationModel']),\n        };\n    }\n}\nclass EditorInlayHints extends BaseEditorOption {\n    constructor() {\n        const defaults = { enabled: 'on', fontSize: 0, fontFamily: '', padding: false };\n        super(137 /* EditorOption.inlayHints */, 'inlayHints', defaults, {\n            'editor.inlayHints.enabled': {\n                type: 'string',\n                default: defaults.enabled,\n                description: nls.localize('inlayHints.enable', \"Enables the inlay hints in the editor.\"),\n                enum: ['on', 'onUnlessPressed', 'offUnlessPressed', 'off'],\n                markdownEnumDescriptions: [\n                    nls.localize('editor.inlayHints.on', \"Inlay hints are enabled\"),\n                    nls.localize('editor.inlayHints.onUnlessPressed', \"Inlay hints are showing by default and hide when holding {0}\", platform.isMacintosh ? `Ctrl+Option` : `Ctrl+Alt`),\n                    nls.localize('editor.inlayHints.offUnlessPressed', \"Inlay hints are hidden by default and show when holding {0}\", platform.isMacintosh ? `Ctrl+Option` : `Ctrl+Alt`),\n                    nls.localize('editor.inlayHints.off', \"Inlay hints are disabled\"),\n                ],\n            },\n            'editor.inlayHints.fontSize': {\n                type: 'number',\n                default: defaults.fontSize,\n                markdownDescription: nls.localize('inlayHints.fontSize', \"Controls font size of inlay hints in the editor. As default the {0} is used when the configured value is less than {1} or greater than the editor font size.\", '`#editor.fontSize#`', '`5`')\n            },\n            'editor.inlayHints.fontFamily': {\n                type: 'string',\n                default: defaults.fontFamily,\n                markdownDescription: nls.localize('inlayHints.fontFamily', \"Controls font family of inlay hints in the editor. When set to empty, the {0} is used.\", '`#editor.fontFamily#`')\n            },\n            'editor.inlayHints.padding': {\n                type: 'boolean',\n                default: defaults.padding,\n                description: nls.localize('inlayHints.padding', \"Enables the padding around the inlay hints in the editor.\")\n            }\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        if (typeof input.enabled === 'boolean') {\n            input.enabled = input.enabled ? 'on' : 'off';\n        }\n        return {\n            enabled: stringSet(input.enabled, this.defaultValue.enabled, ['on', 'off', 'offUnlessPressed', 'onUnlessPressed']),\n            fontSize: EditorIntOption.clampedInt(input.fontSize, this.defaultValue.fontSize, 0, 100),\n            fontFamily: EditorStringOption.string(input.fontFamily, this.defaultValue.fontFamily),\n            padding: boolean(input.padding, this.defaultValue.padding)\n        };\n    }\n}\n//#endregion\n//#region lineDecorationsWidth\nclass EditorLineDecorationsWidth extends BaseEditorOption {\n    constructor() {\n        super(63 /* EditorOption.lineDecorationsWidth */, 'lineDecorationsWidth', 10);\n    }\n    validate(input) {\n        if (typeof input === 'string' && /^\\d+(\\.\\d+)?ch$/.test(input)) {\n            const multiple = parseFloat(input.substring(0, input.length - 2));\n            return -multiple; // negative numbers signal a multiple\n        }\n        else {\n            return EditorIntOption.clampedInt(input, this.defaultValue, 0, 1000);\n        }\n    }\n    compute(env, options, value) {\n        if (value < 0) {\n            // negative numbers signal a multiple\n            return EditorIntOption.clampedInt(-value * env.fontInfo.typicalHalfwidthCharacterWidth, this.defaultValue, 0, 1000);\n        }\n        else {\n            return value;\n        }\n    }\n}\n//#endregion\n//#region lineHeight\nclass EditorLineHeight extends EditorFloatOption {\n    constructor() {\n        super(64 /* EditorOption.lineHeight */, 'lineHeight', EDITOR_FONT_DEFAULTS.lineHeight, x => EditorFloatOption.clamp(x, 0, 150), { markdownDescription: nls.localize('lineHeight', \"Controls the line height. \\n - Use 0 to automatically compute the line height from the font size.\\n - Values between 0 and 8 will be used as a multiplier with the font size.\\n - Values greater than or equal to 8 will be used as effective values.\") });\n    }\n    compute(env, options, value) {\n        // The lineHeight is computed from the fontSize if it is 0.\n        // Moreover, the final lineHeight respects the editor zoom level.\n        // So take the result from env.fontInfo\n        return env.fontInfo.lineHeight;\n    }\n}\nclass EditorMinimap extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            enabled: true,\n            size: 'proportional',\n            side: 'right',\n            showSlider: 'mouseover',\n            autohide: false,\n            renderCharacters: true,\n            maxColumn: 120,\n            scale: 1,\n        };\n        super(70 /* EditorOption.minimap */, 'minimap', defaults, {\n            'editor.minimap.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                description: nls.localize('minimap.enabled', \"Controls whether the minimap is shown.\")\n            },\n            'editor.minimap.autohide': {\n                type: 'boolean',\n                default: defaults.autohide,\n                description: nls.localize('minimap.autohide', \"Controls whether the minimap is hidden automatically.\")\n            },\n            'editor.minimap.size': {\n                type: 'string',\n                enum: ['proportional', 'fill', 'fit'],\n                enumDescriptions: [\n                    nls.localize('minimap.size.proportional', \"The minimap has the same size as the editor contents (and might scroll).\"),\n                    nls.localize('minimap.size.fill', \"The minimap will stretch or shrink as necessary to fill the height of the editor (no scrolling).\"),\n                    nls.localize('minimap.size.fit', \"The minimap will shrink as necessary to never be larger than the editor (no scrolling).\"),\n                ],\n                default: defaults.size,\n                description: nls.localize('minimap.size', \"Controls the size of the minimap.\")\n            },\n            'editor.minimap.side': {\n                type: 'string',\n                enum: ['left', 'right'],\n                default: defaults.side,\n                description: nls.localize('minimap.side', \"Controls the side where to render the minimap.\")\n            },\n            'editor.minimap.showSlider': {\n                type: 'string',\n                enum: ['always', 'mouseover'],\n                default: defaults.showSlider,\n                description: nls.localize('minimap.showSlider', \"Controls when the minimap slider is shown.\")\n            },\n            'editor.minimap.scale': {\n                type: 'number',\n                default: defaults.scale,\n                minimum: 1,\n                maximum: 3,\n                enum: [1, 2, 3],\n                description: nls.localize('minimap.scale', \"Scale of content drawn in the minimap: 1, 2 or 3.\")\n            },\n            'editor.minimap.renderCharacters': {\n                type: 'boolean',\n                default: defaults.renderCharacters,\n                description: nls.localize('minimap.renderCharacters', \"Render the actual characters on a line as opposed to color blocks.\")\n            },\n            'editor.minimap.maxColumn': {\n                type: 'number',\n                default: defaults.maxColumn,\n                description: nls.localize('minimap.maxColumn', \"Limit the width of the minimap to render at most a certain number of columns.\")\n            }\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            autohide: boolean(input.autohide, this.defaultValue.autohide),\n            size: stringSet(input.size, this.defaultValue.size, ['proportional', 'fill', 'fit']),\n            side: stringSet(input.side, this.defaultValue.side, ['right', 'left']),\n            showSlider: stringSet(input.showSlider, this.defaultValue.showSlider, ['always', 'mouseover']),\n            renderCharacters: boolean(input.renderCharacters, this.defaultValue.renderCharacters),\n            scale: EditorIntOption.clampedInt(input.scale, 1, 1, 3),\n            maxColumn: EditorIntOption.clampedInt(input.maxColumn, this.defaultValue.maxColumn, 1, 10000),\n        };\n    }\n}\n//#endregion\n//#region multiCursorModifier\nfunction _multiCursorModifierFromString(multiCursorModifier) {\n    if (multiCursorModifier === 'ctrlCmd') {\n        return (platform.isMacintosh ? 'metaKey' : 'ctrlKey');\n    }\n    return 'altKey';\n}\nclass EditorPadding extends BaseEditorOption {\n    constructor() {\n        super(81 /* EditorOption.padding */, 'padding', { top: 0, bottom: 0 }, {\n            'editor.padding.top': {\n                type: 'number',\n                default: 0,\n                minimum: 0,\n                maximum: 1000,\n                description: nls.localize('padding.top', \"Controls the amount of space between the top edge of the editor and the first line.\")\n            },\n            'editor.padding.bottom': {\n                type: 'number',\n                default: 0,\n                minimum: 0,\n                maximum: 1000,\n                description: nls.localize('padding.bottom', \"Controls the amount of space between the bottom edge of the editor and the last line.\")\n            }\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            top: EditorIntOption.clampedInt(input.top, 0, 0, 1000),\n            bottom: EditorIntOption.clampedInt(input.bottom, 0, 0, 1000)\n        };\n    }\n}\nclass EditorParameterHints extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            enabled: true,\n            cycle: true\n        };\n        super(83 /* EditorOption.parameterHints */, 'parameterHints', defaults, {\n            'editor.parameterHints.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                description: nls.localize('parameterHints.enabled', \"Enables a pop-up that shows parameter documentation and type information as you type.\")\n            },\n            'editor.parameterHints.cycle': {\n                type: 'boolean',\n                default: defaults.cycle,\n                description: nls.localize('parameterHints.cycle', \"Controls whether the parameter hints menu cycles or closes when reaching the end of the list.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            cycle: boolean(input.cycle, this.defaultValue.cycle)\n        };\n    }\n}\n//#endregion\n//#region pixelRatio\nclass EditorPixelRatio extends ComputedEditorOption {\n    constructor() {\n        super(139 /* EditorOption.pixelRatio */);\n    }\n    compute(env, options, _) {\n        return env.pixelRatio;\n    }\n}\nclass EditorQuickSuggestions extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            other: 'on',\n            comments: 'off',\n            strings: 'off'\n        };\n        const types = [\n            { type: 'boolean' },\n            {\n                type: 'string',\n                enum: ['on', 'inline', 'off'],\n                enumDescriptions: [nls.localize('on', \"Quick suggestions show inside the suggest widget\"), nls.localize('inline', \"Quick suggestions show as ghost text\"), nls.localize('off', \"Quick suggestions are disabled\")]\n            }\n        ];\n        super(86 /* EditorOption.quickSuggestions */, 'quickSuggestions', defaults, {\n            type: 'object',\n            additionalProperties: false,\n            properties: {\n                strings: {\n                    anyOf: types,\n                    default: defaults.strings,\n                    description: nls.localize('quickSuggestions.strings', \"Enable quick suggestions inside strings.\")\n                },\n                comments: {\n                    anyOf: types,\n                    default: defaults.comments,\n                    description: nls.localize('quickSuggestions.comments', \"Enable quick suggestions inside comments.\")\n                },\n                other: {\n                    anyOf: types,\n                    default: defaults.other,\n                    description: nls.localize('quickSuggestions.other', \"Enable quick suggestions outside of strings and comments.\")\n                },\n            },\n            default: defaults,\n            markdownDescription: nls.localize('quickSuggestions', \"Controls whether suggestions should automatically show up while typing. This can be controlled for typing in comments, strings, and other code. Quick suggestion can be configured to show as ghost text or with the suggest widget. Also be aware of the '{0}'-setting which controls if suggestions are triggered by special characters.\", `#editor.suggestOnTriggerCharacters#`)\n        });\n        this.defaultValue = defaults;\n    }\n    validate(input) {\n        if (typeof input === 'boolean') {\n            // boolean -> all on/off\n            const value = input ? 'on' : 'off';\n            return { comments: value, strings: value, other: value };\n        }\n        if (!input || typeof input !== 'object') {\n            // invalid object\n            return this.defaultValue;\n        }\n        const { other, comments, strings } = input;\n        const allowedValues = ['on', 'inline', 'off'];\n        let validatedOther;\n        let validatedComments;\n        let validatedStrings;\n        if (typeof other === 'boolean') {\n            validatedOther = other ? 'on' : 'off';\n        }\n        else {\n            validatedOther = stringSet(other, this.defaultValue.other, allowedValues);\n        }\n        if (typeof comments === 'boolean') {\n            validatedComments = comments ? 'on' : 'off';\n        }\n        else {\n            validatedComments = stringSet(comments, this.defaultValue.comments, allowedValues);\n        }\n        if (typeof strings === 'boolean') {\n            validatedStrings = strings ? 'on' : 'off';\n        }\n        else {\n            validatedStrings = stringSet(strings, this.defaultValue.strings, allowedValues);\n        }\n        return {\n            other: validatedOther,\n            comments: validatedComments,\n            strings: validatedStrings\n        };\n    }\n}\nclass EditorRenderLineNumbersOption extends BaseEditorOption {\n    constructor() {\n        super(65 /* EditorOption.lineNumbers */, 'lineNumbers', { renderType: 1 /* RenderLineNumbersType.On */, renderFn: null }, {\n            type: 'string',\n            enum: ['off', 'on', 'relative', 'interval'],\n            enumDescriptions: [\n                nls.localize('lineNumbers.off', \"Line numbers are not rendered.\"),\n                nls.localize('lineNumbers.on', \"Line numbers are rendered as absolute number.\"),\n                nls.localize('lineNumbers.relative', \"Line numbers are rendered as distance in lines to cursor position.\"),\n                nls.localize('lineNumbers.interval', \"Line numbers are rendered every 10 lines.\")\n            ],\n            default: 'on',\n            description: nls.localize('lineNumbers', \"Controls the display of line numbers.\")\n        });\n    }\n    validate(lineNumbers) {\n        let renderType = this.defaultValue.renderType;\n        let renderFn = this.defaultValue.renderFn;\n        if (typeof lineNumbers !== 'undefined') {\n            if (typeof lineNumbers === 'function') {\n                renderType = 4 /* RenderLineNumbersType.Custom */;\n                renderFn = lineNumbers;\n            }\n            else if (lineNumbers === 'interval') {\n                renderType = 3 /* RenderLineNumbersType.Interval */;\n            }\n            else if (lineNumbers === 'relative') {\n                renderType = 2 /* RenderLineNumbersType.Relative */;\n            }\n            else if (lineNumbers === 'on') {\n                renderType = 1 /* RenderLineNumbersType.On */;\n            }\n            else {\n                renderType = 0 /* RenderLineNumbersType.Off */;\n            }\n        }\n        return {\n            renderType,\n            renderFn\n        };\n    }\n}\n//#endregion\n//#region renderValidationDecorations\n/**\n * @internal\n */\nexport function filterValidationDecorations(options) {\n    const renderValidationDecorations = options.get(95 /* EditorOption.renderValidationDecorations */);\n    if (renderValidationDecorations === 'editable') {\n        return options.get(88 /* EditorOption.readOnly */);\n    }\n    return renderValidationDecorations === 'on' ? false : true;\n}\nclass EditorRulers extends BaseEditorOption {\n    constructor() {\n        const defaults = [];\n        const columnSchema = { type: 'number', description: nls.localize('rulers.size', \"Number of monospace characters at which this editor ruler will render.\") };\n        super(99 /* EditorOption.rulers */, 'rulers', defaults, {\n            type: 'array',\n            items: {\n                anyOf: [\n                    columnSchema,\n                    {\n                        type: [\n                            'object'\n                        ],\n                        properties: {\n                            column: columnSchema,\n                            color: {\n                                type: 'string',\n                                description: nls.localize('rulers.color', \"Color of this editor ruler.\"),\n                                format: 'color-hex'\n                            }\n                        }\n                    }\n                ]\n            },\n            default: defaults,\n            description: nls.localize('rulers', \"Render vertical rulers after a certain number of monospace characters. Use multiple values for multiple rulers. No rulers are drawn if array is empty.\")\n        });\n    }\n    validate(input) {\n        if (Array.isArray(input)) {\n            const rulers = [];\n            for (const _element of input) {\n                if (typeof _element === 'number') {\n                    rulers.push({\n                        column: EditorIntOption.clampedInt(_element, 0, 0, 10000),\n                        color: null\n                    });\n                }\n                else if (_element && typeof _element === 'object') {\n                    const element = _element;\n                    rulers.push({\n                        column: EditorIntOption.clampedInt(element.column, 0, 0, 10000),\n                        color: element.color\n                    });\n                }\n            }\n            rulers.sort((a, b) => a.column - b.column);\n            return rulers;\n        }\n        return this.defaultValue;\n    }\n}\n//#endregion\n//#region readonly\n/**\n * Configuration options for readonly message\n */\nclass ReadonlyMessage extends BaseEditorOption {\n    constructor() {\n        const defaults = undefined;\n        super(89 /* EditorOption.readOnlyMessage */, 'readOnlyMessage', defaults);\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        return _input;\n    }\n}\nfunction _scrollbarVisibilityFromString(visibility, defaultValue) {\n    if (typeof visibility !== 'string') {\n        return defaultValue;\n    }\n    switch (visibility) {\n        case 'hidden': return 2 /* ScrollbarVisibility.Hidden */;\n        case 'visible': return 3 /* ScrollbarVisibility.Visible */;\n        default: return 1 /* ScrollbarVisibility.Auto */;\n    }\n}\nclass EditorScrollbar extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            vertical: 1 /* ScrollbarVisibility.Auto */,\n            horizontal: 1 /* ScrollbarVisibility.Auto */,\n            arrowSize: 11,\n            useShadows: true,\n            verticalHasArrows: false,\n            horizontalHasArrows: false,\n            horizontalScrollbarSize: 12,\n            horizontalSliderSize: 12,\n            verticalScrollbarSize: 14,\n            verticalSliderSize: 14,\n            handleMouseWheel: true,\n            alwaysConsumeMouseWheel: true,\n            scrollByPage: false\n        };\n        super(100 /* EditorOption.scrollbar */, 'scrollbar', defaults, {\n            'editor.scrollbar.vertical': {\n                type: 'string',\n                enum: ['auto', 'visible', 'hidden'],\n                enumDescriptions: [\n                    nls.localize('scrollbar.vertical.auto', \"The vertical scrollbar will be visible only when necessary.\"),\n                    nls.localize('scrollbar.vertical.visible', \"The vertical scrollbar will always be visible.\"),\n                    nls.localize('scrollbar.vertical.fit', \"The vertical scrollbar will always be hidden.\"),\n                ],\n                default: 'auto',\n                description: nls.localize('scrollbar.vertical', \"Controls the visibility of the vertical scrollbar.\")\n            },\n            'editor.scrollbar.horizontal': {\n                type: 'string',\n                enum: ['auto', 'visible', 'hidden'],\n                enumDescriptions: [\n                    nls.localize('scrollbar.horizontal.auto', \"The horizontal scrollbar will be visible only when necessary.\"),\n                    nls.localize('scrollbar.horizontal.visible', \"The horizontal scrollbar will always be visible.\"),\n                    nls.localize('scrollbar.horizontal.fit', \"The horizontal scrollbar will always be hidden.\"),\n                ],\n                default: 'auto',\n                description: nls.localize('scrollbar.horizontal', \"Controls the visibility of the horizontal scrollbar.\")\n            },\n            'editor.scrollbar.verticalScrollbarSize': {\n                type: 'number',\n                default: defaults.verticalScrollbarSize,\n                description: nls.localize('scrollbar.verticalScrollbarSize', \"The width of the vertical scrollbar.\")\n            },\n            'editor.scrollbar.horizontalScrollbarSize': {\n                type: 'number',\n                default: defaults.horizontalScrollbarSize,\n                description: nls.localize('scrollbar.horizontalScrollbarSize', \"The height of the horizontal scrollbar.\")\n            },\n            'editor.scrollbar.scrollByPage': {\n                type: 'boolean',\n                default: defaults.scrollByPage,\n                description: nls.localize('scrollbar.scrollByPage', \"Controls whether clicks scroll by page or jump to click position.\")\n            }\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        const horizontalScrollbarSize = EditorIntOption.clampedInt(input.horizontalScrollbarSize, this.defaultValue.horizontalScrollbarSize, 0, 1000);\n        const verticalScrollbarSize = EditorIntOption.clampedInt(input.verticalScrollbarSize, this.defaultValue.verticalScrollbarSize, 0, 1000);\n        return {\n            arrowSize: EditorIntOption.clampedInt(input.arrowSize, this.defaultValue.arrowSize, 0, 1000),\n            vertical: _scrollbarVisibilityFromString(input.vertical, this.defaultValue.vertical),\n            horizontal: _scrollbarVisibilityFromString(input.horizontal, this.defaultValue.horizontal),\n            useShadows: boolean(input.useShadows, this.defaultValue.useShadows),\n            verticalHasArrows: boolean(input.verticalHasArrows, this.defaultValue.verticalHasArrows),\n            horizontalHasArrows: boolean(input.horizontalHasArrows, this.defaultValue.horizontalHasArrows),\n            handleMouseWheel: boolean(input.handleMouseWheel, this.defaultValue.handleMouseWheel),\n            alwaysConsumeMouseWheel: boolean(input.alwaysConsumeMouseWheel, this.defaultValue.alwaysConsumeMouseWheel),\n            horizontalScrollbarSize: horizontalScrollbarSize,\n            horizontalSliderSize: EditorIntOption.clampedInt(input.horizontalSliderSize, horizontalScrollbarSize, 0, 1000),\n            verticalScrollbarSize: verticalScrollbarSize,\n            verticalSliderSize: EditorIntOption.clampedInt(input.verticalSliderSize, verticalScrollbarSize, 0, 1000),\n            scrollByPage: boolean(input.scrollByPage, this.defaultValue.scrollByPage),\n        };\n    }\n}\n/**\n * @internal\n*/\nexport const inUntrustedWorkspace = 'inUntrustedWorkspace';\n/**\n * @internal\n */\nexport const unicodeHighlightConfigKeys = {\n    allowedCharacters: 'editor.unicodeHighlight.allowedCharacters',\n    invisibleCharacters: 'editor.unicodeHighlight.invisibleCharacters',\n    nonBasicASCII: 'editor.unicodeHighlight.nonBasicASCII',\n    ambiguousCharacters: 'editor.unicodeHighlight.ambiguousCharacters',\n    includeComments: 'editor.unicodeHighlight.includeComments',\n    includeStrings: 'editor.unicodeHighlight.includeStrings',\n    allowedLocales: 'editor.unicodeHighlight.allowedLocales',\n};\nclass UnicodeHighlight extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            nonBasicASCII: inUntrustedWorkspace,\n            invisibleCharacters: true,\n            ambiguousCharacters: true,\n            includeComments: inUntrustedWorkspace,\n            includeStrings: true,\n            allowedCharacters: {},\n            allowedLocales: { _os: true, _vscode: true },\n        };\n        super(122 /* EditorOption.unicodeHighlighting */, 'unicodeHighlight', defaults, {\n            [unicodeHighlightConfigKeys.nonBasicASCII]: {\n                restricted: true,\n                type: ['boolean', 'string'],\n                enum: [true, false, inUntrustedWorkspace],\n                default: defaults.nonBasicASCII,\n                description: nls.localize('unicodeHighlight.nonBasicASCII', \"Controls whether all non-basic ASCII characters are highlighted. Only characters between U+0020 and U+007E, tab, line-feed and carriage-return are considered basic ASCII.\")\n            },\n            [unicodeHighlightConfigKeys.invisibleCharacters]: {\n                restricted: true,\n                type: 'boolean',\n                default: defaults.invisibleCharacters,\n                description: nls.localize('unicodeHighlight.invisibleCharacters', \"Controls whether characters that just reserve space or have no width at all are highlighted.\")\n            },\n            [unicodeHighlightConfigKeys.ambiguousCharacters]: {\n                restricted: true,\n                type: 'boolean',\n                default: defaults.ambiguousCharacters,\n                description: nls.localize('unicodeHighlight.ambiguousCharacters', \"Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale.\")\n            },\n            [unicodeHighlightConfigKeys.includeComments]: {\n                restricted: true,\n                type: ['boolean', 'string'],\n                enum: [true, false, inUntrustedWorkspace],\n                default: defaults.includeComments,\n                description: nls.localize('unicodeHighlight.includeComments', \"Controls whether characters in comments should also be subject to Unicode highlighting.\")\n            },\n            [unicodeHighlightConfigKeys.includeStrings]: {\n                restricted: true,\n                type: ['boolean', 'string'],\n                enum: [true, false, inUntrustedWorkspace],\n                default: defaults.includeStrings,\n                description: nls.localize('unicodeHighlight.includeStrings', \"Controls whether characters in strings should also be subject to Unicode highlighting.\")\n            },\n            [unicodeHighlightConfigKeys.allowedCharacters]: {\n                restricted: true,\n                type: 'object',\n                default: defaults.allowedCharacters,\n                description: nls.localize('unicodeHighlight.allowedCharacters', \"Defines allowed characters that are not being highlighted.\"),\n                additionalProperties: {\n                    type: 'boolean'\n                }\n            },\n            [unicodeHighlightConfigKeys.allowedLocales]: {\n                restricted: true,\n                type: 'object',\n                additionalProperties: {\n                    type: 'boolean'\n                },\n                default: defaults.allowedLocales,\n                description: nls.localize('unicodeHighlight.allowedLocales', \"Unicode characters that are common in allowed locales are not being highlighted.\")\n            },\n        });\n    }\n    applyUpdate(value, update) {\n        let didChange = false;\n        if (update.allowedCharacters && value) {\n            // Treat allowedCharacters atomically\n            if (!objects.equals(value.allowedCharacters, update.allowedCharacters)) {\n                value = Object.assign(Object.assign({}, value), { allowedCharacters: update.allowedCharacters });\n                didChange = true;\n            }\n        }\n        if (update.allowedLocales && value) {\n            // Treat allowedLocales atomically\n            if (!objects.equals(value.allowedLocales, update.allowedLocales)) {\n                value = Object.assign(Object.assign({}, value), { allowedLocales: update.allowedLocales });\n                didChange = true;\n            }\n        }\n        const result = super.applyUpdate(value, update);\n        if (didChange) {\n            return new ApplyUpdateResult(result.newValue, true);\n        }\n        return result;\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            nonBasicASCII: primitiveSet(input.nonBasicASCII, inUntrustedWorkspace, [true, false, inUntrustedWorkspace]),\n            invisibleCharacters: boolean(input.invisibleCharacters, this.defaultValue.invisibleCharacters),\n            ambiguousCharacters: boolean(input.ambiguousCharacters, this.defaultValue.ambiguousCharacters),\n            includeComments: primitiveSet(input.includeComments, inUntrustedWorkspace, [true, false, inUntrustedWorkspace]),\n            includeStrings: primitiveSet(input.includeStrings, inUntrustedWorkspace, [true, false, inUntrustedWorkspace]),\n            allowedCharacters: this.validateBooleanMap(_input.allowedCharacters, this.defaultValue.allowedCharacters),\n            allowedLocales: this.validateBooleanMap(_input.allowedLocales, this.defaultValue.allowedLocales),\n        };\n    }\n    validateBooleanMap(map, defaultValue) {\n        if ((typeof map !== 'object') || !map) {\n            return defaultValue;\n        }\n        const result = {};\n        for (const [key, value] of Object.entries(map)) {\n            if (value === true) {\n                result[key] = true;\n            }\n        }\n        return result;\n    }\n}\n/**\n * Configuration options for inline suggestions\n */\nclass InlineEditorSuggest extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            enabled: true,\n            mode: 'subwordSmart',\n            showToolbar: 'onHover',\n            suppressSuggestions: false,\n            keepOnBlur: false,\n        };\n        super(60 /* EditorOption.inlineSuggest */, 'inlineSuggest', defaults, {\n            'editor.inlineSuggest.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                description: nls.localize('inlineSuggest.enabled', \"Controls whether to automatically show inline suggestions in the editor.\")\n            },\n            'editor.inlineSuggest.showToolbar': {\n                type: 'string',\n                default: defaults.showToolbar,\n                enum: ['always', 'onHover'],\n                enumDescriptions: [\n                    nls.localize('inlineSuggest.showToolbar.always', \"Show the inline suggestion toolbar whenever an inline suggestion is shown.\"),\n                    nls.localize('inlineSuggest.showToolbar.onHover', \"Show the inline suggestion toolbar when hovering over an inline suggestion.\"),\n                ],\n                description: nls.localize('inlineSuggest.showToolbar', \"Controls when to show the inline suggestion toolbar.\"),\n            },\n            'editor.inlineSuggest.suppressSuggestions': {\n                type: 'boolean',\n                default: defaults.suppressSuggestions,\n                description: nls.localize('inlineSuggest.suppressSuggestions', \"Controls how inline suggestions interact with the suggest widget. If enabled, the suggest widget is not shown automatically when inline suggestions are available.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            mode: stringSet(input.mode, this.defaultValue.mode, ['prefix', 'subword', 'subwordSmart']),\n            showToolbar: stringSet(input.showToolbar, this.defaultValue.showToolbar, ['always', 'onHover']),\n            suppressSuggestions: boolean(input.suppressSuggestions, this.defaultValue.suppressSuggestions),\n            keepOnBlur: boolean(input.keepOnBlur, this.defaultValue.keepOnBlur),\n        };\n    }\n}\n/**\n * Configuration options for inline suggestions\n */\nclass BracketPairColorization extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            enabled: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.enabled,\n            independentColorPoolPerBracketType: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.independentColorPoolPerBracketType,\n        };\n        super(13 /* EditorOption.bracketPairColorization */, 'bracketPairColorization', defaults, {\n            'editor.bracketPairColorization.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                markdownDescription: nls.localize('bracketPairColorization.enabled', \"Controls whether bracket pair colorization is enabled or not. Use {0} to override the bracket highlight colors.\", '`#workbench.colorCustomizations#`')\n            },\n            'editor.bracketPairColorization.independentColorPoolPerBracketType': {\n                type: 'boolean',\n                default: defaults.independentColorPoolPerBracketType,\n                description: nls.localize('bracketPairColorization.independentColorPoolPerBracketType', \"Controls whether each bracket type has its own independent color pool.\")\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            independentColorPoolPerBracketType: boolean(input.independentColorPoolPerBracketType, this.defaultValue.independentColorPoolPerBracketType),\n        };\n    }\n}\n/**\n * Configuration options for inline suggestions\n */\nclass GuideOptions extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            bracketPairs: false,\n            bracketPairsHorizontal: 'active',\n            highlightActiveBracketPair: true,\n            indentation: true,\n            highlightActiveIndentation: true\n        };\n        super(14 /* EditorOption.guides */, 'guides', defaults, {\n            'editor.guides.bracketPairs': {\n                type: ['boolean', 'string'],\n                enum: [true, 'active', false],\n                enumDescriptions: [\n                    nls.localize('editor.guides.bracketPairs.true', \"Enables bracket pair guides.\"),\n                    nls.localize('editor.guides.bracketPairs.active', \"Enables bracket pair guides only for the active bracket pair.\"),\n                    nls.localize('editor.guides.bracketPairs.false', \"Disables bracket pair guides.\"),\n                ],\n                default: defaults.bracketPairs,\n                description: nls.localize('editor.guides.bracketPairs', \"Controls whether bracket pair guides are enabled or not.\")\n            },\n            'editor.guides.bracketPairsHorizontal': {\n                type: ['boolean', 'string'],\n                enum: [true, 'active', false],\n                enumDescriptions: [\n                    nls.localize('editor.guides.bracketPairsHorizontal.true', \"Enables horizontal guides as addition to vertical bracket pair guides.\"),\n                    nls.localize('editor.guides.bracketPairsHorizontal.active', \"Enables horizontal guides only for the active bracket pair.\"),\n                    nls.localize('editor.guides.bracketPairsHorizontal.false', \"Disables horizontal bracket pair guides.\"),\n                ],\n                default: defaults.bracketPairsHorizontal,\n                description: nls.localize('editor.guides.bracketPairsHorizontal', \"Controls whether horizontal bracket pair guides are enabled or not.\")\n            },\n            'editor.guides.highlightActiveBracketPair': {\n                type: 'boolean',\n                default: defaults.highlightActiveBracketPair,\n                description: nls.localize('editor.guides.highlightActiveBracketPair', \"Controls whether the editor should highlight the active bracket pair.\")\n            },\n            'editor.guides.indentation': {\n                type: 'boolean',\n                default: defaults.indentation,\n                description: nls.localize('editor.guides.indentation', \"Controls whether the editor should render indent guides.\")\n            },\n            'editor.guides.highlightActiveIndentation': {\n                type: ['boolean', 'string'],\n                enum: [true, 'always', false],\n                enumDescriptions: [\n                    nls.localize('editor.guides.highlightActiveIndentation.true', \"Highlights the active indent guide.\"),\n                    nls.localize('editor.guides.highlightActiveIndentation.always', \"Highlights the active indent guide even if bracket guides are highlighted.\"),\n                    nls.localize('editor.guides.highlightActiveIndentation.false', \"Do not highlight the active indent guide.\"),\n                ],\n                default: defaults.highlightActiveIndentation,\n                description: nls.localize('editor.guides.highlightActiveIndentation', \"Controls whether the editor should highlight the active indent guide.\")\n            }\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            bracketPairs: primitiveSet(input.bracketPairs, this.defaultValue.bracketPairs, [true, false, 'active']),\n            bracketPairsHorizontal: primitiveSet(input.bracketPairsHorizontal, this.defaultValue.bracketPairsHorizontal, [true, false, 'active']),\n            highlightActiveBracketPair: boolean(input.highlightActiveBracketPair, this.defaultValue.highlightActiveBracketPair),\n            indentation: boolean(input.indentation, this.defaultValue.indentation),\n            highlightActiveIndentation: primitiveSet(input.highlightActiveIndentation, this.defaultValue.highlightActiveIndentation, [true, false, 'always']),\n        };\n    }\n}\nfunction primitiveSet(value, defaultValue, allowedValues) {\n    const idx = allowedValues.indexOf(value);\n    if (idx === -1) {\n        return defaultValue;\n    }\n    return allowedValues[idx];\n}\nclass EditorSuggest extends BaseEditorOption {\n    constructor() {\n        const defaults = {\n            insertMode: 'insert',\n            filterGraceful: true,\n            snippetsPreventQuickSuggestions: false,\n            localityBonus: false,\n            shareSuggestSelections: false,\n            selectionMode: 'always',\n            showIcons: true,\n            showStatusBar: false,\n            preview: false,\n            previewMode: 'subwordSmart',\n            showInlineDetails: true,\n            showMethods: true,\n            showFunctions: true,\n            showConstructors: true,\n            showDeprecated: true,\n            matchOnWordStartOnly: true,\n            showFields: true,\n            showVariables: true,\n            showClasses: true,\n            showStructs: true,\n            showInterfaces: true,\n            showModules: true,\n            showProperties: true,\n            showEvents: true,\n            showOperators: true,\n            showUnits: true,\n            showValues: true,\n            showConstants: true,\n            showEnums: true,\n            showEnumMembers: true,\n            showKeywords: true,\n            showWords: true,\n            showColors: true,\n            showFiles: true,\n            showReferences: true,\n            showFolders: true,\n            showTypeParameters: true,\n            showSnippets: true,\n            showUsers: true,\n            showIssues: true,\n        };\n        super(115 /* EditorOption.suggest */, 'suggest', defaults, {\n            'editor.suggest.insertMode': {\n                type: 'string',\n                enum: ['insert', 'replace'],\n                enumDescriptions: [\n                    nls.localize('suggest.insertMode.insert', \"Insert suggestion without overwriting text right of the cursor.\"),\n                    nls.localize('suggest.insertMode.replace', \"Insert suggestion and overwrite text right of the cursor.\"),\n                ],\n                default: defaults.insertMode,\n                description: nls.localize('suggest.insertMode', \"Controls whether words are overwritten when accepting completions. Note that this depends on extensions opting into this feature.\")\n            },\n            'editor.suggest.filterGraceful': {\n                type: 'boolean',\n                default: defaults.filterGraceful,\n                description: nls.localize('suggest.filterGraceful', \"Controls whether filtering and sorting suggestions accounts for small typos.\")\n            },\n            'editor.suggest.localityBonus': {\n                type: 'boolean',\n                default: defaults.localityBonus,\n                description: nls.localize('suggest.localityBonus', \"Controls whether sorting favors words that appear close to the cursor.\")\n            },\n            'editor.suggest.shareSuggestSelections': {\n                type: 'boolean',\n                default: defaults.shareSuggestSelections,\n                markdownDescription: nls.localize('suggest.shareSuggestSelections', \"Controls whether remembered suggestion selections are shared between multiple workspaces and windows (needs `#editor.suggestSelection#`).\")\n            },\n            'editor.suggest.selectionMode': {\n                type: 'string',\n                enum: ['always', 'never', 'whenTriggerCharacter', 'whenQuickSuggestion'],\n                enumDescriptions: [\n                    nls.localize('suggest.insertMode.always', \"Always select a suggestion when automatically triggering IntelliSense.\"),\n                    nls.localize('suggest.insertMode.never', \"Never select a suggestion when automatically triggering IntelliSense.\"),\n                    nls.localize('suggest.insertMode.whenTriggerCharacter', \"Select a suggestion only when triggering IntelliSense from a trigger character.\"),\n                    nls.localize('suggest.insertMode.whenQuickSuggestion', \"Select a suggestion only when triggering IntelliSense as you type.\"),\n                ],\n                default: defaults.selectionMode,\n                markdownDescription: nls.localize('suggest.selectionMode', \"Controls whether a suggestion is selected when the widget shows. Note that this only applies to automatically triggered suggestions (`#editor.quickSuggestions#` and `#editor.suggestOnTriggerCharacters#`) and that a suggestion is always selected when explicitly invoked, e.g via `Ctrl+Space`.\")\n            },\n            'editor.suggest.snippetsPreventQuickSuggestions': {\n                type: 'boolean',\n                default: defaults.snippetsPreventQuickSuggestions,\n                description: nls.localize('suggest.snippetsPreventQuickSuggestions', \"Controls whether an active snippet prevents quick suggestions.\")\n            },\n            'editor.suggest.showIcons': {\n                type: 'boolean',\n                default: defaults.showIcons,\n                description: nls.localize('suggest.showIcons', \"Controls whether to show or hide icons in suggestions.\")\n            },\n            'editor.suggest.showStatusBar': {\n                type: 'boolean',\n                default: defaults.showStatusBar,\n                description: nls.localize('suggest.showStatusBar', \"Controls the visibility of the status bar at the bottom of the suggest widget.\")\n            },\n            'editor.suggest.preview': {\n                type: 'boolean',\n                default: defaults.preview,\n                description: nls.localize('suggest.preview', \"Controls whether to preview the suggestion outcome in the editor.\")\n            },\n            'editor.suggest.showInlineDetails': {\n                type: 'boolean',\n                default: defaults.showInlineDetails,\n                description: nls.localize('suggest.showInlineDetails', \"Controls whether suggest details show inline with the label or only in the details widget.\")\n            },\n            'editor.suggest.maxVisibleSuggestions': {\n                type: 'number',\n                deprecationMessage: nls.localize('suggest.maxVisibleSuggestions.dep', \"This setting is deprecated. The suggest widget can now be resized.\"),\n            },\n            'editor.suggest.filteredTypes': {\n                type: 'object',\n                deprecationMessage: nls.localize('deprecated', \"This setting is deprecated, please use separate settings like 'editor.suggest.showKeywords' or 'editor.suggest.showSnippets' instead.\")\n            },\n            'editor.suggest.showMethods': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showMethods', \"When enabled IntelliSense shows `method`-suggestions.\")\n            },\n            'editor.suggest.showFunctions': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showFunctions', \"When enabled IntelliSense shows `function`-suggestions.\")\n            },\n            'editor.suggest.showConstructors': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showConstructors', \"When enabled IntelliSense shows `constructor`-suggestions.\")\n            },\n            'editor.suggest.showDeprecated': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showDeprecated', \"When enabled IntelliSense shows `deprecated`-suggestions.\")\n            },\n            'editor.suggest.matchOnWordStartOnly': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.matchOnWordStartOnly', \"When enabled IntelliSense filtering requires that the first character matches on a word start. For example, `c` on `Console` or `WebContext` but _not_ on `description`. When disabled IntelliSense will show more results but still sorts them by match quality.\")\n            },\n            'editor.suggest.showFields': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showFields', \"When enabled IntelliSense shows `field`-suggestions.\")\n            },\n            'editor.suggest.showVariables': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showVariables', \"When enabled IntelliSense shows `variable`-suggestions.\")\n            },\n            'editor.suggest.showClasses': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showClasss', \"When enabled IntelliSense shows `class`-suggestions.\")\n            },\n            'editor.suggest.showStructs': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showStructs', \"When enabled IntelliSense shows `struct`-suggestions.\")\n            },\n            'editor.suggest.showInterfaces': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showInterfaces', \"When enabled IntelliSense shows `interface`-suggestions.\")\n            },\n            'editor.suggest.showModules': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showModules', \"When enabled IntelliSense shows `module`-suggestions.\")\n            },\n            'editor.suggest.showProperties': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showPropertys', \"When enabled IntelliSense shows `property`-suggestions.\")\n            },\n            'editor.suggest.showEvents': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showEvents', \"When enabled IntelliSense shows `event`-suggestions.\")\n            },\n            'editor.suggest.showOperators': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showOperators', \"When enabled IntelliSense shows `operator`-suggestions.\")\n            },\n            'editor.suggest.showUnits': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showUnits', \"When enabled IntelliSense shows `unit`-suggestions.\")\n            },\n            'editor.suggest.showValues': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showValues', \"When enabled IntelliSense shows `value`-suggestions.\")\n            },\n            'editor.suggest.showConstants': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showConstants', \"When enabled IntelliSense shows `constant`-suggestions.\")\n            },\n            'editor.suggest.showEnums': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showEnums', \"When enabled IntelliSense shows `enum`-suggestions.\")\n            },\n            'editor.suggest.showEnumMembers': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showEnumMembers', \"When enabled IntelliSense shows `enumMember`-suggestions.\")\n            },\n            'editor.suggest.showKeywords': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showKeywords', \"When enabled IntelliSense shows `keyword`-suggestions.\")\n            },\n            'editor.suggest.showWords': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showTexts', \"When enabled IntelliSense shows `text`-suggestions.\")\n            },\n            'editor.suggest.showColors': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showColors', \"When enabled IntelliSense shows `color`-suggestions.\")\n            },\n            'editor.suggest.showFiles': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showFiles', \"When enabled IntelliSense shows `file`-suggestions.\")\n            },\n            'editor.suggest.showReferences': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showReferences', \"When enabled IntelliSense shows `reference`-suggestions.\")\n            },\n            'editor.suggest.showCustomcolors': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showCustomcolors', \"When enabled IntelliSense shows `customcolor`-suggestions.\")\n            },\n            'editor.suggest.showFolders': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showFolders', \"When enabled IntelliSense shows `folder`-suggestions.\")\n            },\n            'editor.suggest.showTypeParameters': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showTypeParameters', \"When enabled IntelliSense shows `typeParameter`-suggestions.\")\n            },\n            'editor.suggest.showSnippets': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showSnippets', \"When enabled IntelliSense shows `snippet`-suggestions.\")\n            },\n            'editor.suggest.showUsers': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showUsers', \"When enabled IntelliSense shows `user`-suggestions.\")\n            },\n            'editor.suggest.showIssues': {\n                type: 'boolean',\n                default: true,\n                markdownDescription: nls.localize('editor.suggest.showIssues', \"When enabled IntelliSense shows `issues`-suggestions.\")\n            }\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            insertMode: stringSet(input.insertMode, this.defaultValue.insertMode, ['insert', 'replace']),\n            filterGraceful: boolean(input.filterGraceful, this.defaultValue.filterGraceful),\n            snippetsPreventQuickSuggestions: boolean(input.snippetsPreventQuickSuggestions, this.defaultValue.filterGraceful),\n            localityBonus: boolean(input.localityBonus, this.defaultValue.localityBonus),\n            shareSuggestSelections: boolean(input.shareSuggestSelections, this.defaultValue.shareSuggestSelections),\n            selectionMode: stringSet(input.selectionMode, this.defaultValue.selectionMode, ['always', 'never', 'whenQuickSuggestion', 'whenTriggerCharacter']),\n            showIcons: boolean(input.showIcons, this.defaultValue.showIcons),\n            showStatusBar: boolean(input.showStatusBar, this.defaultValue.showStatusBar),\n            preview: boolean(input.preview, this.defaultValue.preview),\n            previewMode: stringSet(input.previewMode, this.defaultValue.previewMode, ['prefix', 'subword', 'subwordSmart']),\n            showInlineDetails: boolean(input.showInlineDetails, this.defaultValue.showInlineDetails),\n            showMethods: boolean(input.showMethods, this.defaultValue.showMethods),\n            showFunctions: boolean(input.showFunctions, this.defaultValue.showFunctions),\n            showConstructors: boolean(input.showConstructors, this.defaultValue.showConstructors),\n            showDeprecated: boolean(input.showDeprecated, this.defaultValue.showDeprecated),\n            matchOnWordStartOnly: boolean(input.matchOnWordStartOnly, this.defaultValue.matchOnWordStartOnly),\n            showFields: boolean(input.showFields, this.defaultValue.showFields),\n            showVariables: boolean(input.showVariables, this.defaultValue.showVariables),\n            showClasses: boolean(input.showClasses, this.defaultValue.showClasses),\n            showStructs: boolean(input.showStructs, this.defaultValue.showStructs),\n            showInterfaces: boolean(input.showInterfaces, this.defaultValue.showInterfaces),\n            showModules: boolean(input.showModules, this.defaultValue.showModules),\n            showProperties: boolean(input.showProperties, this.defaultValue.showProperties),\n            showEvents: boolean(input.showEvents, this.defaultValue.showEvents),\n            showOperators: boolean(input.showOperators, this.defaultValue.showOperators),\n            showUnits: boolean(input.showUnits, this.defaultValue.showUnits),\n            showValues: boolean(input.showValues, this.defaultValue.showValues),\n            showConstants: boolean(input.showConstants, this.defaultValue.showConstants),\n            showEnums: boolean(input.showEnums, this.defaultValue.showEnums),\n            showEnumMembers: boolean(input.showEnumMembers, this.defaultValue.showEnumMembers),\n            showKeywords: boolean(input.showKeywords, this.defaultValue.showKeywords),\n            showWords: boolean(input.showWords, this.defaultValue.showWords),\n            showColors: boolean(input.showColors, this.defaultValue.showColors),\n            showFiles: boolean(input.showFiles, this.defaultValue.showFiles),\n            showReferences: boolean(input.showReferences, this.defaultValue.showReferences),\n            showFolders: boolean(input.showFolders, this.defaultValue.showFolders),\n            showTypeParameters: boolean(input.showTypeParameters, this.defaultValue.showTypeParameters),\n            showSnippets: boolean(input.showSnippets, this.defaultValue.showSnippets),\n            showUsers: boolean(input.showUsers, this.defaultValue.showUsers),\n            showIssues: boolean(input.showIssues, this.defaultValue.showIssues),\n        };\n    }\n}\nclass SmartSelect extends BaseEditorOption {\n    constructor() {\n        super(110 /* EditorOption.smartSelect */, 'smartSelect', {\n            selectLeadingAndTrailingWhitespace: true,\n            selectSubwords: true,\n        }, {\n            'editor.smartSelect.selectLeadingAndTrailingWhitespace': {\n                description: nls.localize('selectLeadingAndTrailingWhitespace', \"Whether leading and trailing whitespace should always be selected.\"),\n                default: true,\n                type: 'boolean'\n            },\n            'editor.smartSelect.selectSubwords': {\n                description: nls.localize('selectSubwords', \"Whether subwords (like 'foo' in 'fooBar' or 'foo_bar') should be selected.\"),\n                default: true,\n                type: 'boolean'\n            }\n        });\n    }\n    validate(input) {\n        if (!input || typeof input !== 'object') {\n            return this.defaultValue;\n        }\n        return {\n            selectLeadingAndTrailingWhitespace: boolean(input.selectLeadingAndTrailingWhitespace, this.defaultValue.selectLeadingAndTrailingWhitespace),\n            selectSubwords: boolean(input.selectSubwords, this.defaultValue.selectSubwords),\n        };\n    }\n}\nclass WrappingIndentOption extends BaseEditorOption {\n    constructor() {\n        super(134 /* EditorOption.wrappingIndent */, 'wrappingIndent', 1 /* WrappingIndent.Same */, {\n            'editor.wrappingIndent': {\n                type: 'string',\n                enum: ['none', 'same', 'indent', 'deepIndent'],\n                enumDescriptions: [\n                    nls.localize('wrappingIndent.none', \"No indentation. Wrapped lines begin at column 1.\"),\n                    nls.localize('wrappingIndent.same', \"Wrapped lines get the same indentation as the parent.\"),\n                    nls.localize('wrappingIndent.indent', \"Wrapped lines get +1 indentation toward the parent.\"),\n                    nls.localize('wrappingIndent.deepIndent', \"Wrapped lines get +2 indentation toward the parent.\"),\n                ],\n                description: nls.localize('wrappingIndent', \"Controls the indentation of wrapped lines.\"),\n                default: 'same'\n            }\n        });\n    }\n    validate(input) {\n        switch (input) {\n            case 'none': return 0 /* WrappingIndent.None */;\n            case 'same': return 1 /* WrappingIndent.Same */;\n            case 'indent': return 2 /* WrappingIndent.Indent */;\n            case 'deepIndent': return 3 /* WrappingIndent.DeepIndent */;\n        }\n        return 1 /* WrappingIndent.Same */;\n    }\n    compute(env, options, value) {\n        const accessibilitySupport = options.get(2 /* EditorOption.accessibilitySupport */);\n        if (accessibilitySupport === 2 /* AccessibilitySupport.Enabled */) {\n            // if we know for a fact that a screen reader is attached, we use no indent wrapping to\n            // help that the editor's wrapping points match the textarea's wrapping points\n            return 0 /* WrappingIndent.None */;\n        }\n        return value;\n    }\n}\nclass EditorWrappingInfoComputer extends ComputedEditorOption {\n    constructor() {\n        super(142 /* EditorOption.wrappingInfo */);\n    }\n    compute(env, options, _) {\n        const layoutInfo = options.get(141 /* EditorOption.layoutInfo */);\n        return {\n            isDominatedByLongLines: env.isDominatedByLongLines,\n            isWordWrapMinified: layoutInfo.isWordWrapMinified,\n            isViewportWrapping: layoutInfo.isViewportWrapping,\n            wrappingColumn: layoutInfo.wrappingColumn,\n        };\n    }\n}\nclass EditorDropIntoEditor extends BaseEditorOption {\n    constructor() {\n        const defaults = { enabled: true, showDropSelector: 'afterDrop' };\n        super(34 /* EditorOption.dropIntoEditor */, 'dropIntoEditor', defaults, {\n            'editor.dropIntoEditor.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                markdownDescription: nls.localize('dropIntoEditor.enabled', \"Controls whether you can drag and drop a file into a text editor by holding down `shift` (instead of opening the file in an editor).\"),\n            },\n            'editor.dropIntoEditor.showDropSelector': {\n                type: 'string',\n                markdownDescription: nls.localize('dropIntoEditor.showDropSelector', \"Controls if a widget is shown when dropping files into the editor. This widget lets you control how the file is dropped.\"),\n                enum: [\n                    'afterDrop',\n                    'never'\n                ],\n                enumDescriptions: [\n                    nls.localize('dropIntoEditor.showDropSelector.afterDrop', \"Show the drop selector widget after a file is dropped into the editor.\"),\n                    nls.localize('dropIntoEditor.showDropSelector.never', \"Never show the drop selector widget. Instead the default drop provider is always used.\"),\n                ],\n                default: 'afterDrop',\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            showDropSelector: stringSet(input.showDropSelector, this.defaultValue.showDropSelector, ['afterDrop', 'never']),\n        };\n    }\n}\nclass EditorPasteAs extends BaseEditorOption {\n    constructor() {\n        const defaults = { enabled: true, showPasteSelector: 'afterPaste' };\n        super(82 /* EditorOption.pasteAs */, 'pasteAs', defaults, {\n            'editor.pasteAs.enabled': {\n                type: 'boolean',\n                default: defaults.enabled,\n                markdownDescription: nls.localize('pasteAs.enabled', \"Controls whether you can paste content in different ways.\"),\n            },\n            'editor.pasteAs.showPasteSelector': {\n                type: 'string',\n                markdownDescription: nls.localize('pasteAs.showPasteSelector', \"Controls if a widget is shown when pasting content in to the editor. This widget lets you control how the file is pasted.\"),\n                enum: [\n                    'afterPaste',\n                    'never'\n                ],\n                enumDescriptions: [\n                    nls.localize('pasteAs.showPasteSelector.afterPaste', \"Show the paste selector widget after content is pasted into the editor.\"),\n                    nls.localize('pasteAs.showPasteSelector.never', \"Never show the paste selector widget. Instead the default pasting behavior is always used.\"),\n                ],\n                default: 'afterPaste',\n            },\n        });\n    }\n    validate(_input) {\n        if (!_input || typeof _input !== 'object') {\n            return this.defaultValue;\n        }\n        const input = _input;\n        return {\n            enabled: boolean(input.enabled, this.defaultValue.enabled),\n            showPasteSelector: stringSet(input.showPasteSelector, this.defaultValue.showPasteSelector, ['afterPaste', 'never']),\n        };\n    }\n}\n//#endregion\nconst DEFAULT_WINDOWS_FONT_FAMILY = 'Consolas, \\'Courier New\\', monospace';\nconst DEFAULT_MAC_FONT_FAMILY = 'Menlo, Monaco, \\'Courier New\\', monospace';\nconst DEFAULT_LINUX_FONT_FAMILY = '\\'Droid Sans Mono\\', \\'monospace\\', monospace';\n/**\n * @internal\n */\nexport const EDITOR_FONT_DEFAULTS = {\n    fontFamily: (platform.isMacintosh ? DEFAULT_MAC_FONT_FAMILY : (platform.isLinux ? DEFAULT_LINUX_FONT_FAMILY : DEFAULT_WINDOWS_FONT_FAMILY)),\n    fontWeight: 'normal',\n    fontSize: (platform.isMacintosh ? 12 : 14),\n    lineHeight: 0,\n    letterSpacing: 0,\n};\n/**\n * @internal\n */\nexport const editorOptionsRegistry = [];\nfunction register(option) {\n    editorOptionsRegistry[option.id] = option;\n    return option;\n}\nexport const EditorOptions = {\n    acceptSuggestionOnCommitCharacter: register(new EditorBooleanOption(0 /* EditorOption.acceptSuggestionOnCommitCharacter */, 'acceptSuggestionOnCommitCharacter', true, { markdownDescription: nls.localize('acceptSuggestionOnCommitCharacter', \"Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character.\") })),\n    acceptSuggestionOnEnter: register(new EditorStringEnumOption(1 /* EditorOption.acceptSuggestionOnEnter */, 'acceptSuggestionOnEnter', 'on', ['on', 'smart', 'off'], {\n        markdownEnumDescriptions: [\n            '',\n            nls.localize('acceptSuggestionOnEnterSmart', \"Only accept a suggestion with `Enter` when it makes a textual change.\"),\n            ''\n        ],\n        markdownDescription: nls.localize('acceptSuggestionOnEnter', \"Controls whether suggestions should be accepted on `Enter`, in addition to `Tab`. Helps to avoid ambiguity between inserting new lines or accepting suggestions.\")\n    })),\n    accessibilitySupport: register(new EditorAccessibilitySupport()),\n    accessibilityPageSize: register(new EditorIntOption(3 /* EditorOption.accessibilityPageSize */, 'accessibilityPageSize', 10, 1, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, {\n        description: nls.localize('accessibilityPageSize', \"Controls the number of lines in the editor that can be read out by a screen reader at once. When we detect a screen reader we automatically set the default to be 500. Warning: this has a performance implication for numbers larger than the default.\"),\n        tags: ['accessibility']\n    })),\n    ariaLabel: register(new EditorStringOption(4 /* EditorOption.ariaLabel */, 'ariaLabel', nls.localize('editorViewAccessibleLabel', \"Editor content\"))),\n    screenReaderAnnounceInlineSuggestion: register(new EditorBooleanOption(6 /* EditorOption.screenReaderAnnounceInlineSuggestion */, 'screenReaderAnnounceInlineSuggestion', true, {\n        description: nls.localize('screenReaderAnnounceInlineSuggestion', \"Control whether inline suggestions are announced by a screen reader.\"),\n        tags: ['accessibility']\n    })),\n    autoClosingBrackets: register(new EditorStringEnumOption(5 /* EditorOption.autoClosingBrackets */, 'autoClosingBrackets', 'languageDefined', ['always', 'languageDefined', 'beforeWhitespace', 'never'], {\n        enumDescriptions: [\n            '',\n            nls.localize('editor.autoClosingBrackets.languageDefined', \"Use language configurations to determine when to autoclose brackets.\"),\n            nls.localize('editor.autoClosingBrackets.beforeWhitespace', \"Autoclose brackets only when the cursor is to the left of whitespace.\"),\n            '',\n        ],\n        description: nls.localize('autoClosingBrackets', \"Controls whether the editor should automatically close brackets after the user adds an opening bracket.\")\n    })),\n    autoClosingDelete: register(new EditorStringEnumOption(7 /* EditorOption.autoClosingDelete */, 'autoClosingDelete', 'auto', ['always', 'auto', 'never'], {\n        enumDescriptions: [\n            '',\n            nls.localize('editor.autoClosingDelete.auto', \"Remove adjacent closing quotes or brackets only if they were automatically inserted.\"),\n            '',\n        ],\n        description: nls.localize('autoClosingDelete', \"Controls whether the editor should remove adjacent closing quotes or brackets when deleting.\")\n    })),\n    autoClosingOvertype: register(new EditorStringEnumOption(8 /* EditorOption.autoClosingOvertype */, 'autoClosingOvertype', 'auto', ['always', 'auto', 'never'], {\n        enumDescriptions: [\n            '',\n            nls.localize('editor.autoClosingOvertype.auto', \"Type over closing quotes or brackets only if they were automatically inserted.\"),\n            '',\n        ],\n        description: nls.localize('autoClosingOvertype', \"Controls whether the editor should type over closing quotes or brackets.\")\n    })),\n    autoClosingQuotes: register(new EditorStringEnumOption(9 /* EditorOption.autoClosingQuotes */, 'autoClosingQuotes', 'languageDefined', ['always', 'languageDefined', 'beforeWhitespace', 'never'], {\n        enumDescriptions: [\n            '',\n            nls.localize('editor.autoClosingQuotes.languageDefined', \"Use language configurations to determine when to autoclose quotes.\"),\n            nls.localize('editor.autoClosingQuotes.beforeWhitespace', \"Autoclose quotes only when the cursor is to the left of whitespace.\"),\n            '',\n        ],\n        description: nls.localize('autoClosingQuotes', \"Controls whether the editor should automatically close quotes after the user adds an opening quote.\")\n    })),\n    autoIndent: register(new EditorEnumOption(10 /* EditorOption.autoIndent */, 'autoIndent', 4 /* EditorAutoIndentStrategy.Full */, 'full', ['none', 'keep', 'brackets', 'advanced', 'full'], _autoIndentFromString, {\n        enumDescriptions: [\n            nls.localize('editor.autoIndent.none', \"The editor will not insert indentation automatically.\"),\n            nls.localize('editor.autoIndent.keep', \"The editor will keep the current line's indentation.\"),\n            nls.localize('editor.autoIndent.brackets', \"The editor will keep the current line's indentation and honor language defined brackets.\"),\n            nls.localize('editor.autoIndent.advanced', \"The editor will keep the current line's indentation, honor language defined brackets and invoke special onEnterRules defined by languages.\"),\n            nls.localize('editor.autoIndent.full', \"The editor will keep the current line's indentation, honor language defined brackets, invoke special onEnterRules defined by languages, and honor indentationRules defined by languages.\"),\n        ],\n        description: nls.localize('autoIndent', \"Controls whether the editor should automatically adjust the indentation when users type, paste, move or indent lines.\")\n    })),\n    automaticLayout: register(new EditorBooleanOption(11 /* EditorOption.automaticLayout */, 'automaticLayout', false)),\n    autoSurround: register(new EditorStringEnumOption(12 /* EditorOption.autoSurround */, 'autoSurround', 'languageDefined', ['languageDefined', 'quotes', 'brackets', 'never'], {\n        enumDescriptions: [\n            nls.localize('editor.autoSurround.languageDefined', \"Use language configurations to determine when to automatically surround selections.\"),\n            nls.localize('editor.autoSurround.quotes', \"Surround with quotes but not brackets.\"),\n            nls.localize('editor.autoSurround.brackets', \"Surround with brackets but not quotes.\"),\n            ''\n        ],\n        description: nls.localize('autoSurround', \"Controls whether the editor should automatically surround selections when typing quotes or brackets.\")\n    })),\n    bracketPairColorization: register(new BracketPairColorization()),\n    bracketPairGuides: register(new GuideOptions()),\n    stickyTabStops: register(new EditorBooleanOption(113 /* EditorOption.stickyTabStops */, 'stickyTabStops', false, { description: nls.localize('stickyTabStops', \"Emulate selection behavior of tab characters when using spaces for indentation. Selection will stick to tab stops.\") })),\n    codeLens: register(new EditorBooleanOption(15 /* EditorOption.codeLens */, 'codeLens', true, { description: nls.localize('codeLens', \"Controls whether the editor shows CodeLens.\") })),\n    codeLensFontFamily: register(new EditorStringOption(16 /* EditorOption.codeLensFontFamily */, 'codeLensFontFamily', '', { description: nls.localize('codeLensFontFamily', \"Controls the font family for CodeLens.\") })),\n    codeLensFontSize: register(new EditorIntOption(17 /* EditorOption.codeLensFontSize */, 'codeLensFontSize', 0, 0, 100, {\n        type: 'number',\n        default: 0,\n        minimum: 0,\n        maximum: 100,\n        markdownDescription: nls.localize('codeLensFontSize', \"Controls the font size in pixels for CodeLens. When set to 0, 90% of `#editor.fontSize#` is used.\")\n    })),\n    colorDecorators: register(new EditorBooleanOption(18 /* EditorOption.colorDecorators */, 'colorDecorators', true, { description: nls.localize('colorDecorators', \"Controls whether the editor should render the inline color decorators and color picker.\") })),\n    colorDecoratorActivatedOn: register(new EditorStringEnumOption(144 /* EditorOption.colorDecoratorsActivatedOn */, 'colorDecoratorsActivatedOn', 'clickAndHover', ['clickAndHover', 'hover', 'click'], {\n        enumDescriptions: [\n            nls.localize('editor.colorDecoratorActivatedOn.clickAndHover', \"Make the color picker appear both on click and hover of the color decorator\"),\n            nls.localize('editor.colorDecoratorActivatedOn.hover', \"Make the color picker appear on hover of the color decorator\"),\n            nls.localize('editor.colorDecoratorActivatedOn.click', \"Make the color picker appear on click of the color decorator\")\n        ],\n        description: nls.localize('colorDecoratorActivatedOn', \"Controls the condition to make a color picker appear from a color decorator\")\n    })),\n    colorDecoratorsLimit: register(new EditorIntOption(19 /* EditorOption.colorDecoratorsLimit */, 'colorDecoratorsLimit', 500, 1, 1000000, {\n        markdownDescription: nls.localize('colorDecoratorsLimit', \"Controls the max number of color decorators that can be rendered in an editor at once.\")\n    })),\n    columnSelection: register(new EditorBooleanOption(20 /* EditorOption.columnSelection */, 'columnSelection', false, { description: nls.localize('columnSelection', \"Enable that the selection with the mouse and keys is doing column selection.\") })),\n    comments: register(new EditorComments()),\n    contextmenu: register(new EditorBooleanOption(22 /* EditorOption.contextmenu */, 'contextmenu', true)),\n    copyWithSyntaxHighlighting: register(new EditorBooleanOption(23 /* EditorOption.copyWithSyntaxHighlighting */, 'copyWithSyntaxHighlighting', true, { description: nls.localize('copyWithSyntaxHighlighting', \"Controls whether syntax highlighting should be copied into the clipboard.\") })),\n    cursorBlinking: register(new EditorEnumOption(24 /* EditorOption.cursorBlinking */, 'cursorBlinking', 1 /* TextEditorCursorBlinkingStyle.Blink */, 'blink', ['blink', 'smooth', 'phase', 'expand', 'solid'], _cursorBlinkingStyleFromString, { description: nls.localize('cursorBlinking', \"Control the cursor animation style.\") })),\n    cursorSmoothCaretAnimation: register(new EditorStringEnumOption(25 /* EditorOption.cursorSmoothCaretAnimation */, 'cursorSmoothCaretAnimation', 'off', ['off', 'explicit', 'on'], {\n        enumDescriptions: [\n            nls.localize('cursorSmoothCaretAnimation.off', \"Smooth caret animation is disabled.\"),\n            nls.localize('cursorSmoothCaretAnimation.explicit', \"Smooth caret animation is enabled only when the user moves the cursor with an explicit gesture.\"),\n            nls.localize('cursorSmoothCaretAnimation.on', \"Smooth caret animation is always enabled.\")\n        ],\n        description: nls.localize('cursorSmoothCaretAnimation', \"Controls whether the smooth caret animation should be enabled.\")\n    })),\n    cursorStyle: register(new EditorEnumOption(26 /* EditorOption.cursorStyle */, 'cursorStyle', TextEditorCursorStyle.Line, 'line', ['line', 'block', 'underline', 'line-thin', 'block-outline', 'underline-thin'], _cursorStyleFromString, { description: nls.localize('cursorStyle', \"Controls the cursor style.\") })),\n    cursorSurroundingLines: register(new EditorIntOption(27 /* EditorOption.cursorSurroundingLines */, 'cursorSurroundingLines', 0, 0, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, { description: nls.localize('cursorSurroundingLines', \"Controls the minimal number of visible leading lines (minimum 0) and trailing lines (minimum 1) surrounding the cursor. Known as 'scrollOff' or 'scrollOffset' in some other editors.\") })),\n    cursorSurroundingLinesStyle: register(new EditorStringEnumOption(28 /* EditorOption.cursorSurroundingLinesStyle */, 'cursorSurroundingLinesStyle', 'default', ['default', 'all'], {\n        enumDescriptions: [\n            nls.localize('cursorSurroundingLinesStyle.default', \"`cursorSurroundingLines` is enforced only when triggered via the keyboard or API.\"),\n            nls.localize('cursorSurroundingLinesStyle.all', \"`cursorSurroundingLines` is enforced always.\")\n        ],\n        description: nls.localize('cursorSurroundingLinesStyle', \"Controls when `cursorSurroundingLines` should be enforced.\")\n    })),\n    cursorWidth: register(new EditorIntOption(29 /* EditorOption.cursorWidth */, 'cursorWidth', 0, 0, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, { markdownDescription: nls.localize('cursorWidth', \"Controls the width of the cursor when `#editor.cursorStyle#` is set to `line`.\") })),\n    disableLayerHinting: register(new EditorBooleanOption(30 /* EditorOption.disableLayerHinting */, 'disableLayerHinting', false)),\n    disableMonospaceOptimizations: register(new EditorBooleanOption(31 /* EditorOption.disableMonospaceOptimizations */, 'disableMonospaceOptimizations', false)),\n    domReadOnly: register(new EditorBooleanOption(32 /* EditorOption.domReadOnly */, 'domReadOnly', false)),\n    dragAndDrop: register(new EditorBooleanOption(33 /* EditorOption.dragAndDrop */, 'dragAndDrop', true, { description: nls.localize('dragAndDrop', \"Controls whether the editor should allow moving selections via drag and drop.\") })),\n    emptySelectionClipboard: register(new EditorEmptySelectionClipboard()),\n    dropIntoEditor: register(new EditorDropIntoEditor()),\n    stickyScroll: register(new EditorStickyScroll()),\n    experimentalWhitespaceRendering: register(new EditorStringEnumOption(36 /* EditorOption.experimentalWhitespaceRendering */, 'experimentalWhitespaceRendering', 'svg', ['svg', 'font', 'off'], {\n        enumDescriptions: [\n            nls.localize('experimentalWhitespaceRendering.svg', \"Use a new rendering method with svgs.\"),\n            nls.localize('experimentalWhitespaceRendering.font', \"Use a new rendering method with font characters.\"),\n            nls.localize('experimentalWhitespaceRendering.off', \"Use the stable rendering method.\"),\n        ],\n        description: nls.localize('experimentalWhitespaceRendering', \"Controls whether whitespace is rendered with a new, experimental method.\")\n    })),\n    extraEditorClassName: register(new EditorStringOption(37 /* EditorOption.extraEditorClassName */, 'extraEditorClassName', '')),\n    fastScrollSensitivity: register(new EditorFloatOption(38 /* EditorOption.fastScrollSensitivity */, 'fastScrollSensitivity', 5, x => (x <= 0 ? 5 : x), { markdownDescription: nls.localize('fastScrollSensitivity', \"Scrolling speed multiplier when pressing `Alt`.\") })),\n    find: register(new EditorFind()),\n    fixedOverflowWidgets: register(new EditorBooleanOption(40 /* EditorOption.fixedOverflowWidgets */, 'fixedOverflowWidgets', false)),\n    folding: register(new EditorBooleanOption(41 /* EditorOption.folding */, 'folding', true, { description: nls.localize('folding', \"Controls whether the editor has code folding enabled.\") })),\n    foldingStrategy: register(new EditorStringEnumOption(42 /* EditorOption.foldingStrategy */, 'foldingStrategy', 'auto', ['auto', 'indentation'], {\n        enumDescriptions: [\n            nls.localize('foldingStrategy.auto', \"Use a language-specific folding strategy if available, else the indentation-based one.\"),\n            nls.localize('foldingStrategy.indentation', \"Use the indentation-based folding strategy.\"),\n        ],\n        description: nls.localize('foldingStrategy', \"Controls the strategy for computing folding ranges.\")\n    })),\n    foldingHighlight: register(new EditorBooleanOption(43 /* EditorOption.foldingHighlight */, 'foldingHighlight', true, { description: nls.localize('foldingHighlight', \"Controls whether the editor should highlight folded ranges.\") })),\n    foldingImportsByDefault: register(new EditorBooleanOption(44 /* EditorOption.foldingImportsByDefault */, 'foldingImportsByDefault', false, { description: nls.localize('foldingImportsByDefault', \"Controls whether the editor automatically collapses import ranges.\") })),\n    foldingMaximumRegions: register(new EditorIntOption(45 /* EditorOption.foldingMaximumRegions */, 'foldingMaximumRegions', 5000, 10, 65000, // limit must be less than foldingRanges MAX_FOLDING_REGIONS\n    { description: nls.localize('foldingMaximumRegions', \"The maximum number of foldable regions. Increasing this value may result in the editor becoming less responsive when the current source has a large number of foldable regions.\") })),\n    unfoldOnClickAfterEndOfLine: register(new EditorBooleanOption(46 /* EditorOption.unfoldOnClickAfterEndOfLine */, 'unfoldOnClickAfterEndOfLine', false, { description: nls.localize('unfoldOnClickAfterEndOfLine', \"Controls whether clicking on the empty content after a folded line will unfold the line.\") })),\n    fontFamily: register(new EditorStringOption(47 /* EditorOption.fontFamily */, 'fontFamily', EDITOR_FONT_DEFAULTS.fontFamily, { description: nls.localize('fontFamily', \"Controls the font family.\") })),\n    fontInfo: register(new EditorFontInfo()),\n    fontLigatures2: register(new EditorFontLigatures()),\n    fontSize: register(new EditorFontSize()),\n    fontWeight: register(new EditorFontWeight()),\n    fontVariations: register(new EditorFontVariations()),\n    formatOnPaste: register(new EditorBooleanOption(53 /* EditorOption.formatOnPaste */, 'formatOnPaste', false, { description: nls.localize('formatOnPaste', \"Controls whether the editor should automatically format the pasted content. A formatter must be available and the formatter should be able to format a range in a document.\") })),\n    formatOnType: register(new EditorBooleanOption(54 /* EditorOption.formatOnType */, 'formatOnType', false, { description: nls.localize('formatOnType', \"Controls whether the editor should automatically format the line after typing.\") })),\n    glyphMargin: register(new EditorBooleanOption(55 /* EditorOption.glyphMargin */, 'glyphMargin', true, { description: nls.localize('glyphMargin', \"Controls whether the editor should render the vertical glyph margin. Glyph margin is mostly used for debugging.\") })),\n    gotoLocation: register(new EditorGoToLocation()),\n    hideCursorInOverviewRuler: register(new EditorBooleanOption(57 /* EditorOption.hideCursorInOverviewRuler */, 'hideCursorInOverviewRuler', false, { description: nls.localize('hideCursorInOverviewRuler', \"Controls whether the cursor should be hidden in the overview ruler.\") })),\n    hover: register(new EditorHover()),\n    inDiffEditor: register(new EditorBooleanOption(59 /* EditorOption.inDiffEditor */, 'inDiffEditor', false)),\n    letterSpacing: register(new EditorFloatOption(61 /* EditorOption.letterSpacing */, 'letterSpacing', EDITOR_FONT_DEFAULTS.letterSpacing, x => EditorFloatOption.clamp(x, -5, 20), { description: nls.localize('letterSpacing', \"Controls the letter spacing in pixels.\") })),\n    lightbulb: register(new EditorLightbulb()),\n    lineDecorationsWidth: register(new EditorLineDecorationsWidth()),\n    lineHeight: register(new EditorLineHeight()),\n    lineNumbers: register(new EditorRenderLineNumbersOption()),\n    lineNumbersMinChars: register(new EditorIntOption(66 /* EditorOption.lineNumbersMinChars */, 'lineNumbersMinChars', 5, 1, 300)),\n    linkedEditing: register(new EditorBooleanOption(67 /* EditorOption.linkedEditing */, 'linkedEditing', false, { description: nls.localize('linkedEditing', \"Controls whether the editor has linked editing enabled. Depending on the language, related symbols such as HTML tags, are updated while editing.\") })),\n    links: register(new EditorBooleanOption(68 /* EditorOption.links */, 'links', true, { description: nls.localize('links', \"Controls whether the editor should detect links and make them clickable.\") })),\n    matchBrackets: register(new EditorStringEnumOption(69 /* EditorOption.matchBrackets */, 'matchBrackets', 'always', ['always', 'near', 'never'], { description: nls.localize('matchBrackets', \"Highlight matching brackets.\") })),\n    minimap: register(new EditorMinimap()),\n    mouseStyle: register(new EditorStringEnumOption(71 /* EditorOption.mouseStyle */, 'mouseStyle', 'text', ['text', 'default', 'copy'])),\n    mouseWheelScrollSensitivity: register(new EditorFloatOption(72 /* EditorOption.mouseWheelScrollSensitivity */, 'mouseWheelScrollSensitivity', 1, x => (x === 0 ? 1 : x), { markdownDescription: nls.localize('mouseWheelScrollSensitivity', \"A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.\") })),\n    mouseWheelZoom: register(new EditorBooleanOption(73 /* EditorOption.mouseWheelZoom */, 'mouseWheelZoom', false, { markdownDescription: nls.localize('mouseWheelZoom', \"Zoom the font of the editor when using mouse wheel and holding `Ctrl`.\") })),\n    multiCursorMergeOverlapping: register(new EditorBooleanOption(74 /* EditorOption.multiCursorMergeOverlapping */, 'multiCursorMergeOverlapping', true, { description: nls.localize('multiCursorMergeOverlapping', \"Merge multiple cursors when they are overlapping.\") })),\n    multiCursorModifier: register(new EditorEnumOption(75 /* EditorOption.multiCursorModifier */, 'multiCursorModifier', 'altKey', 'alt', ['ctrlCmd', 'alt'], _multiCursorModifierFromString, {\n        markdownEnumDescriptions: [\n            nls.localize('multiCursorModifier.ctrlCmd', \"Maps to `Control` on Windows and Linux and to `Command` on macOS.\"),\n            nls.localize('multiCursorModifier.alt', \"Maps to `Alt` on Windows and Linux and to `Option` on macOS.\")\n        ],\n        markdownDescription: nls.localize({\n            key: 'multiCursorModifier',\n            comment: [\n                '- `ctrlCmd` refers to a value the setting can take and should not be localized.',\n                '- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.'\n            ]\n        }, \"The modifier to be used to add multiple cursors with the mouse. The Go to Definition and Open Link mouse gestures will adapt such that they do not conflict with the [multicursor modifier](https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier).\")\n    })),\n    multiCursorPaste: register(new EditorStringEnumOption(76 /* EditorOption.multiCursorPaste */, 'multiCursorPaste', 'spread', ['spread', 'full'], {\n        markdownEnumDescriptions: [\n            nls.localize('multiCursorPaste.spread', \"Each cursor pastes a single line of the text.\"),\n            nls.localize('multiCursorPaste.full', \"Each cursor pastes the full text.\")\n        ],\n        markdownDescription: nls.localize('multiCursorPaste', \"Controls pasting when the line count of the pasted text matches the cursor count.\")\n    })),\n    multiCursorLimit: register(new EditorIntOption(77 /* EditorOption.multiCursorLimit */, 'multiCursorLimit', 10000, 1, 100000, {\n        markdownDescription: nls.localize('multiCursorLimit', \"Controls the max number of cursors that can be in an active editor at once.\")\n    })),\n    occurrencesHighlight: register(new EditorBooleanOption(78 /* EditorOption.occurrencesHighlight */, 'occurrencesHighlight', true, { description: nls.localize('occurrencesHighlight', \"Controls whether the editor should highlight semantic symbol occurrences.\") })),\n    overviewRulerBorder: register(new EditorBooleanOption(79 /* EditorOption.overviewRulerBorder */, 'overviewRulerBorder', true, { description: nls.localize('overviewRulerBorder', \"Controls whether a border should be drawn around the overview ruler.\") })),\n    overviewRulerLanes: register(new EditorIntOption(80 /* EditorOption.overviewRulerLanes */, 'overviewRulerLanes', 3, 0, 3)),\n    padding: register(new EditorPadding()),\n    pasteAs: register(new EditorPasteAs()),\n    parameterHints: register(new EditorParameterHints()),\n    peekWidgetDefaultFocus: register(new EditorStringEnumOption(84 /* EditorOption.peekWidgetDefaultFocus */, 'peekWidgetDefaultFocus', 'tree', ['tree', 'editor'], {\n        enumDescriptions: [\n            nls.localize('peekWidgetDefaultFocus.tree', \"Focus the tree when opening peek\"),\n            nls.localize('peekWidgetDefaultFocus.editor', \"Focus the editor when opening peek\")\n        ],\n        description: nls.localize('peekWidgetDefaultFocus', \"Controls whether to focus the inline editor or the tree in the peek widget.\")\n    })),\n    definitionLinkOpensInPeek: register(new EditorBooleanOption(85 /* EditorOption.definitionLinkOpensInPeek */, 'definitionLinkOpensInPeek', false, { description: nls.localize('definitionLinkOpensInPeek', \"Controls whether the Go to Definition mouse gesture always opens the peek widget.\") })),\n    quickSuggestions: register(new EditorQuickSuggestions()),\n    quickSuggestionsDelay: register(new EditorIntOption(87 /* EditorOption.quickSuggestionsDelay */, 'quickSuggestionsDelay', 10, 0, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, { description: nls.localize('quickSuggestionsDelay', \"Controls the delay in milliseconds after which quick suggestions will show up.\") })),\n    readOnly: register(new EditorBooleanOption(88 /* EditorOption.readOnly */, 'readOnly', false)),\n    readOnlyMessage: register(new ReadonlyMessage()),\n    renameOnType: register(new EditorBooleanOption(90 /* EditorOption.renameOnType */, 'renameOnType', false, { description: nls.localize('renameOnType', \"Controls whether the editor auto renames on type.\"), markdownDeprecationMessage: nls.localize('renameOnTypeDeprecate', \"Deprecated, use `editor.linkedEditing` instead.\") })),\n    renderControlCharacters: register(new EditorBooleanOption(91 /* EditorOption.renderControlCharacters */, 'renderControlCharacters', true, { description: nls.localize('renderControlCharacters', \"Controls whether the editor should render control characters.\"), restricted: true })),\n    renderFinalNewline: register(new EditorStringEnumOption(92 /* EditorOption.renderFinalNewline */, 'renderFinalNewline', (platform.isLinux ? 'dimmed' : 'on'), ['off', 'on', 'dimmed'], { description: nls.localize('renderFinalNewline', \"Render last line number when the file ends with a newline.\") })),\n    renderLineHighlight: register(new EditorStringEnumOption(93 /* EditorOption.renderLineHighlight */, 'renderLineHighlight', 'line', ['none', 'gutter', 'line', 'all'], {\n        enumDescriptions: [\n            '',\n            '',\n            '',\n            nls.localize('renderLineHighlight.all', \"Highlights both the gutter and the current line.\"),\n        ],\n        description: nls.localize('renderLineHighlight', \"Controls how the editor should render the current line highlight.\")\n    })),\n    renderLineHighlightOnlyWhenFocus: register(new EditorBooleanOption(94 /* EditorOption.renderLineHighlightOnlyWhenFocus */, 'renderLineHighlightOnlyWhenFocus', false, { description: nls.localize('renderLineHighlightOnlyWhenFocus', \"Controls if the editor should render the current line highlight only when the editor is focused.\") })),\n    renderValidationDecorations: register(new EditorStringEnumOption(95 /* EditorOption.renderValidationDecorations */, 'renderValidationDecorations', 'editable', ['editable', 'on', 'off'])),\n    renderWhitespace: register(new EditorStringEnumOption(96 /* EditorOption.renderWhitespace */, 'renderWhitespace', 'selection', ['none', 'boundary', 'selection', 'trailing', 'all'], {\n        enumDescriptions: [\n            '',\n            nls.localize('renderWhitespace.boundary', \"Render whitespace characters except for single spaces between words.\"),\n            nls.localize('renderWhitespace.selection', \"Render whitespace characters only on selected text.\"),\n            nls.localize('renderWhitespace.trailing', \"Render only trailing whitespace characters.\"),\n            ''\n        ],\n        description: nls.localize('renderWhitespace', \"Controls how the editor should render whitespace characters.\")\n    })),\n    revealHorizontalRightPadding: register(new EditorIntOption(97 /* EditorOption.revealHorizontalRightPadding */, 'revealHorizontalRightPadding', 15, 0, 1000)),\n    roundedSelection: register(new EditorBooleanOption(98 /* EditorOption.roundedSelection */, 'roundedSelection', true, { description: nls.localize('roundedSelection', \"Controls whether selections should have rounded corners.\") })),\n    rulers: register(new EditorRulers()),\n    scrollbar: register(new EditorScrollbar()),\n    scrollBeyondLastColumn: register(new EditorIntOption(101 /* EditorOption.scrollBeyondLastColumn */, 'scrollBeyondLastColumn', 4, 0, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, { description: nls.localize('scrollBeyondLastColumn', \"Controls the number of extra characters beyond which the editor will scroll horizontally.\") })),\n    scrollBeyondLastLine: register(new EditorBooleanOption(102 /* EditorOption.scrollBeyondLastLine */, 'scrollBeyondLastLine', true, { description: nls.localize('scrollBeyondLastLine', \"Controls whether the editor will scroll beyond the last line.\") })),\n    scrollPredominantAxis: register(new EditorBooleanOption(103 /* EditorOption.scrollPredominantAxis */, 'scrollPredominantAxis', true, { description: nls.localize('scrollPredominantAxis', \"Scroll only along the predominant axis when scrolling both vertically and horizontally at the same time. Prevents horizontal drift when scrolling vertically on a trackpad.\") })),\n    selectionClipboard: register(new EditorBooleanOption(104 /* EditorOption.selectionClipboard */, 'selectionClipboard', true, {\n        description: nls.localize('selectionClipboard', \"Controls whether the Linux primary clipboard should be supported.\"),\n        included: platform.isLinux\n    })),\n    selectionHighlight: register(new EditorBooleanOption(105 /* EditorOption.selectionHighlight */, 'selectionHighlight', true, { description: nls.localize('selectionHighlight', \"Controls whether the editor should highlight matches similar to the selection.\") })),\n    selectOnLineNumbers: register(new EditorBooleanOption(106 /* EditorOption.selectOnLineNumbers */, 'selectOnLineNumbers', true)),\n    showFoldingControls: register(new EditorStringEnumOption(107 /* EditorOption.showFoldingControls */, 'showFoldingControls', 'mouseover', ['always', 'never', 'mouseover'], {\n        enumDescriptions: [\n            nls.localize('showFoldingControls.always', \"Always show the folding controls.\"),\n            nls.localize('showFoldingControls.never', \"Never show the folding controls and reduce the gutter size.\"),\n            nls.localize('showFoldingControls.mouseover', \"Only show the folding controls when the mouse is over the gutter.\"),\n        ],\n        description: nls.localize('showFoldingControls', \"Controls when the folding controls on the gutter are shown.\")\n    })),\n    showUnused: register(new EditorBooleanOption(108 /* EditorOption.showUnused */, 'showUnused', true, { description: nls.localize('showUnused', \"Controls fading out of unused code.\") })),\n    showDeprecated: register(new EditorBooleanOption(136 /* EditorOption.showDeprecated */, 'showDeprecated', true, { description: nls.localize('showDeprecated', \"Controls strikethrough deprecated variables.\") })),\n    inlayHints: register(new EditorInlayHints()),\n    snippetSuggestions: register(new EditorStringEnumOption(109 /* EditorOption.snippetSuggestions */, 'snippetSuggestions', 'inline', ['top', 'bottom', 'inline', 'none'], {\n        enumDescriptions: [\n            nls.localize('snippetSuggestions.top', \"Show snippet suggestions on top of other suggestions.\"),\n            nls.localize('snippetSuggestions.bottom', \"Show snippet suggestions below other suggestions.\"),\n            nls.localize('snippetSuggestions.inline', \"Show snippets suggestions with other suggestions.\"),\n            nls.localize('snippetSuggestions.none', \"Do not show snippet suggestions.\"),\n        ],\n        description: nls.localize('snippetSuggestions', \"Controls whether snippets are shown with other suggestions and how they are sorted.\")\n    })),\n    smartSelect: register(new SmartSelect()),\n    smoothScrolling: register(new EditorBooleanOption(111 /* EditorOption.smoothScrolling */, 'smoothScrolling', false, { description: nls.localize('smoothScrolling', \"Controls whether the editor will scroll using an animation.\") })),\n    stopRenderingLineAfter: register(new EditorIntOption(114 /* EditorOption.stopRenderingLineAfter */, 'stopRenderingLineAfter', 10000, -1, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */)),\n    suggest: register(new EditorSuggest()),\n    inlineSuggest: register(new InlineEditorSuggest()),\n    suggestFontSize: register(new EditorIntOption(116 /* EditorOption.suggestFontSize */, 'suggestFontSize', 0, 0, 1000, { markdownDescription: nls.localize('suggestFontSize', \"Font size for the suggest widget. When set to {0}, the value of {1} is used.\", '`0`', '`#editor.fontSize#`') })),\n    suggestLineHeight: register(new EditorIntOption(117 /* EditorOption.suggestLineHeight */, 'suggestLineHeight', 0, 0, 1000, { markdownDescription: nls.localize('suggestLineHeight', \"Line height for the suggest widget. When set to {0}, the value of {1} is used. The minimum value is 8.\", '`0`', '`#editor.lineHeight#`') })),\n    suggestOnTriggerCharacters: register(new EditorBooleanOption(118 /* EditorOption.suggestOnTriggerCharacters */, 'suggestOnTriggerCharacters', true, { description: nls.localize('suggestOnTriggerCharacters', \"Controls whether suggestions should automatically show up when typing trigger characters.\") })),\n    suggestSelection: register(new EditorStringEnumOption(119 /* EditorOption.suggestSelection */, 'suggestSelection', 'first', ['first', 'recentlyUsed', 'recentlyUsedByPrefix'], {\n        markdownEnumDescriptions: [\n            nls.localize('suggestSelection.first', \"Always select the first suggestion.\"),\n            nls.localize('suggestSelection.recentlyUsed', \"Select recent suggestions unless further typing selects one, e.g. `console.| -> console.log` because `log` has been completed recently.\"),\n            nls.localize('suggestSelection.recentlyUsedByPrefix', \"Select suggestions based on previous prefixes that have completed those suggestions, e.g. `co -> console` and `con -> const`.\"),\n        ],\n        description: nls.localize('suggestSelection', \"Controls how suggestions are pre-selected when showing the suggest list.\")\n    })),\n    tabCompletion: register(new EditorStringEnumOption(120 /* EditorOption.tabCompletion */, 'tabCompletion', 'off', ['on', 'off', 'onlySnippets'], {\n        enumDescriptions: [\n            nls.localize('tabCompletion.on', \"Tab complete will insert the best matching suggestion when pressing tab.\"),\n            nls.localize('tabCompletion.off', \"Disable tab completions.\"),\n            nls.localize('tabCompletion.onlySnippets', \"Tab complete snippets when their prefix match. Works best when 'quickSuggestions' aren't enabled.\"),\n        ],\n        description: nls.localize('tabCompletion', \"Enables tab completions.\")\n    })),\n    tabIndex: register(new EditorIntOption(121 /* EditorOption.tabIndex */, 'tabIndex', 0, -1, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */)),\n    unicodeHighlight: register(new UnicodeHighlight()),\n    unusualLineTerminators: register(new EditorStringEnumOption(123 /* EditorOption.unusualLineTerminators */, 'unusualLineTerminators', 'prompt', ['auto', 'off', 'prompt'], {\n        enumDescriptions: [\n            nls.localize('unusualLineTerminators.auto', \"Unusual line terminators are automatically removed.\"),\n            nls.localize('unusualLineTerminators.off', \"Unusual line terminators are ignored.\"),\n            nls.localize('unusualLineTerminators.prompt', \"Unusual line terminators prompt to be removed.\"),\n        ],\n        description: nls.localize('unusualLineTerminators', \"Remove unusual line terminators that might cause problems.\")\n    })),\n    useShadowDOM: register(new EditorBooleanOption(124 /* EditorOption.useShadowDOM */, 'useShadowDOM', true)),\n    useTabStops: register(new EditorBooleanOption(125 /* EditorOption.useTabStops */, 'useTabStops', true, { description: nls.localize('useTabStops', \"Inserting and deleting whitespace follows tab stops.\") })),\n    wordBreak: register(new EditorStringEnumOption(126 /* EditorOption.wordBreak */, 'wordBreak', 'normal', ['normal', 'keepAll'], {\n        markdownEnumDescriptions: [\n            nls.localize('wordBreak.normal', \"Use the default line break rule.\"),\n            nls.localize('wordBreak.keepAll', \"Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal.\"),\n        ],\n        description: nls.localize('wordBreak', \"Controls the word break rules used for Chinese/Japanese/Korean (CJK) text.\")\n    })),\n    wordSeparators: register(new EditorStringOption(127 /* EditorOption.wordSeparators */, 'wordSeparators', USUAL_WORD_SEPARATORS, { description: nls.localize('wordSeparators', \"Characters that will be used as word separators when doing word related navigations or operations.\") })),\n    wordWrap: register(new EditorStringEnumOption(128 /* EditorOption.wordWrap */, 'wordWrap', 'off', ['off', 'on', 'wordWrapColumn', 'bounded'], {\n        markdownEnumDescriptions: [\n            nls.localize('wordWrap.off', \"Lines will never wrap.\"),\n            nls.localize('wordWrap.on', \"Lines will wrap at the viewport width.\"),\n            nls.localize({\n                key: 'wordWrap.wordWrapColumn',\n                comment: [\n                    '- `editor.wordWrapColumn` refers to a different setting and should not be localized.'\n                ]\n            }, \"Lines will wrap at `#editor.wordWrapColumn#`.\"),\n            nls.localize({\n                key: 'wordWrap.bounded',\n                comment: [\n                    '- viewport means the edge of the visible window size.',\n                    '- `editor.wordWrapColumn` refers to a different setting and should not be localized.'\n                ]\n            }, \"Lines will wrap at the minimum of viewport and `#editor.wordWrapColumn#`.\"),\n        ],\n        description: nls.localize({\n            key: 'wordWrap',\n            comment: [\n                '- \\'off\\', \\'on\\', \\'wordWrapColumn\\' and \\'bounded\\' refer to values the setting can take and should not be localized.',\n                '- `editor.wordWrapColumn` refers to a different setting and should not be localized.'\n            ]\n        }, \"Controls how lines should wrap.\")\n    })),\n    wordWrapBreakAfterCharacters: register(new EditorStringOption(129 /* EditorOption.wordWrapBreakAfterCharacters */, 'wordWrapBreakAfterCharacters', \n    // allow-any-unicode-next-line\n    ' \\t})]?|/&.,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」')),\n    wordWrapBreakBeforeCharacters: register(new EditorStringOption(130 /* EditorOption.wordWrapBreakBeforeCharacters */, 'wordWrapBreakBeforeCharacters', \n    // allow-any-unicode-next-line\n    '([{‘“〈《「『【〔([{「£¥$£¥++')),\n    wordWrapColumn: register(new EditorIntOption(131 /* EditorOption.wordWrapColumn */, 'wordWrapColumn', 80, 1, 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, {\n        markdownDescription: nls.localize({\n            key: 'wordWrapColumn',\n            comment: [\n                '- `editor.wordWrap` refers to a different setting and should not be localized.',\n                '- \\'wordWrapColumn\\' and \\'bounded\\' refer to values the different setting can take and should not be localized.'\n            ]\n        }, \"Controls the wrapping column of the editor when `#editor.wordWrap#` is `wordWrapColumn` or `bounded`.\")\n    })),\n    wordWrapOverride1: register(new EditorStringEnumOption(132 /* EditorOption.wordWrapOverride1 */, 'wordWrapOverride1', 'inherit', ['off', 'on', 'inherit'])),\n    wordWrapOverride2: register(new EditorStringEnumOption(133 /* EditorOption.wordWrapOverride2 */, 'wordWrapOverride2', 'inherit', ['off', 'on', 'inherit'])),\n    // Leave these at the end (because they have dependencies!)\n    editorClassName: register(new EditorClassName()),\n    defaultColorDecorators: register(new EditorBooleanOption(143 /* EditorOption.defaultColorDecorators */, 'defaultColorDecorators', false, { markdownDescription: nls.localize('defaultColorDecorators', \"Controls whether inline color decorations should be shown using the default document color provider\") })),\n    pixelRatio: register(new EditorPixelRatio()),\n    tabFocusMode: register(new EditorBooleanOption(140 /* EditorOption.tabFocusMode */, 'tabFocusMode', false, { markdownDescription: nls.localize('tabFocusMode', \"Controls whether the editor receives tabs or defers them to the workbench for navigation.\") })),\n    layoutInfo: register(new EditorLayoutInfoComputer()),\n    wrappingInfo: register(new EditorWrappingInfoComputer()),\n    wrappingIndent: register(new WrappingIndentOption()),\n    wrappingStrategy: register(new WrappingStrategy())\n};\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n// Avoid circular dependency on EventEmitter by implementing a subset of the interface.\nexport class ErrorHandler {\n    constructor() {\n        this.listeners = [];\n        this.unexpectedErrorHandler = function (e) {\n            setTimeout(() => {\n                if (e.stack) {\n                    if (ErrorNoTelemetry.isErrorNoTelemetry(e)) {\n                        throw new ErrorNoTelemetry(e.message + '\\n\\n' + e.stack);\n                    }\n                    throw new Error(e.message + '\\n\\n' + e.stack);\n                }\n                throw e;\n            }, 0);\n        };\n    }\n    emit(e) {\n        this.listeners.forEach((listener) => {\n            listener(e);\n        });\n    }\n    onUnexpectedError(e) {\n        this.unexpectedErrorHandler(e);\n        this.emit(e);\n    }\n    // For external errors, we don't want the listeners to be called\n    onUnexpectedExternalError(e) {\n        this.unexpectedErrorHandler(e);\n    }\n}\nexport const errorHandler = new ErrorHandler();\nexport function onUnexpectedError(e) {\n    // ignore errors from cancelled promises\n    if (!isCancellationError(e)) {\n        errorHandler.onUnexpectedError(e);\n    }\n    return undefined;\n}\nexport function onUnexpectedExternalError(e) {\n    // ignore errors from cancelled promises\n    if (!isCancellationError(e)) {\n        errorHandler.onUnexpectedExternalError(e);\n    }\n    return undefined;\n}\nexport function transformErrorForSerialization(error) {\n    if (error instanceof Error) {\n        const { name, message } = error;\n        const stack = error.stacktrace || error.stack;\n        return {\n            $isError: true,\n            name,\n            message,\n            stack,\n            noTelemetry: ErrorNoTelemetry.isErrorNoTelemetry(error)\n        };\n    }\n    // return as is\n    return error;\n}\nconst canceledName = 'Canceled';\n/**\n * Checks if the given error is a promise in canceled state\n */\nexport function isCancellationError(error) {\n    if (error instanceof CancellationError) {\n        return true;\n    }\n    return error instanceof Error && error.name === canceledName && error.message === canceledName;\n}\n// !!!IMPORTANT!!!\n// Do NOT change this class because it is also used as an API-type.\nexport class CancellationError extends Error {\n    constructor() {\n        super(canceledName);\n        this.name = this.message;\n    }\n}\n/**\n * @deprecated use {@link CancellationError `new CancellationError()`} instead\n */\nexport function canceled() {\n    const error = new Error(canceledName);\n    error.name = error.message;\n    return error;\n}\nexport function illegalArgument(name) {\n    if (name) {\n        return new Error(`Illegal argument: ${name}`);\n    }\n    else {\n        return new Error('Illegal argument');\n    }\n}\nexport function illegalState(name) {\n    if (name) {\n        return new Error(`Illegal state: ${name}`);\n    }\n    else {\n        return new Error('Illegal state');\n    }\n}\nexport class NotSupportedError extends Error {\n    constructor(message) {\n        super('NotSupported');\n        if (message) {\n            this.message = message;\n        }\n    }\n}\n/**\n * Error that when thrown won't be logged in telemetry as an unhandled error.\n */\nexport class ErrorNoTelemetry extends Error {\n    constructor(msg) {\n        super(msg);\n        this.name = 'CodeExpectedError';\n    }\n    static fromError(err) {\n        if (err instanceof ErrorNoTelemetry) {\n            return err;\n        }\n        const result = new ErrorNoTelemetry();\n        result.message = err.message;\n        result.stack = err.stack;\n        return result;\n    }\n    static isErrorNoTelemetry(err) {\n        return err.name === 'CodeExpectedError';\n    }\n}\n/**\n * This error indicates a bug.\n * Do not throw this for invalid user input.\n * Only catch this error to recover gracefully from bugs.\n */\nexport class BugIndicatingError extends Error {\n    constructor(message) {\n        super(message || 'An unexpected bug occurred.');\n        Object.setPrototypeOf(this, BugIndicatingError.prototype);\n        // Because we know for sure only buggy code throws this,\n        // we definitely want to break here and fix the bug.\n        // eslint-disable-next-line no-debugger\n        // debugger;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport function once(fn) {\n    const _this = this;\n    let didCall = false;\n    let result;\n    return function () {\n        if (didCall) {\n            return result;\n        }\n        didCall = true;\n        result = fn.apply(_this, arguments);\n        return result;\n    };\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { once } from './functional.js';\nimport { Iterable } from './iterator.js';\n// #region Disposable Tracking\n/**\n * Enables logging of potentially leaked disposables.\n *\n * A disposable is considered leaked if it is not disposed or not registered as the child of\n * another disposable. This tracking is very simple an only works for classes that either\n * extend Disposable or use a DisposableStore. This means there are a lot of false positives.\n */\nconst TRACK_DISPOSABLES = false;\nlet disposableTracker = null;\nexport function setDisposableTracker(tracker) {\n    disposableTracker = tracker;\n}\nif (TRACK_DISPOSABLES) {\n    const __is_disposable_tracked__ = '__is_disposable_tracked__';\n    setDisposableTracker(new class {\n        trackDisposable(x) {\n            const stack = new Error('Potentially leaked disposable').stack;\n            setTimeout(() => {\n                if (!x[__is_disposable_tracked__]) {\n                    console.log(stack);\n                }\n            }, 3000);\n        }\n        setParent(child, parent) {\n            if (child && child !== Disposable.None) {\n                try {\n                    child[__is_disposable_tracked__] = true;\n                }\n                catch (_a) {\n                    // noop\n                }\n            }\n        }\n        markAsDisposed(disposable) {\n            if (disposable && disposable !== Disposable.None) {\n                try {\n                    disposable[__is_disposable_tracked__] = true;\n                }\n                catch (_a) {\n                    // noop\n                }\n            }\n        }\n        markAsSingleton(disposable) { }\n    });\n}\nfunction trackDisposable(x) {\n    disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.trackDisposable(x);\n    return x;\n}\nfunction markAsDisposed(disposable) {\n    disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.markAsDisposed(disposable);\n}\nfunction setParentOfDisposable(child, parent) {\n    disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.setParent(child, parent);\n}\nfunction setParentOfDisposables(children, parent) {\n    if (!disposableTracker) {\n        return;\n    }\n    for (const child of children) {\n        disposableTracker.setParent(child, parent);\n    }\n}\n/**\n * Indicates that the given object is a singleton which does not need to be disposed.\n*/\nexport function markAsSingleton(singleton) {\n    disposableTracker === null || disposableTracker === void 0 ? void 0 : disposableTracker.markAsSingleton(singleton);\n    return singleton;\n}\n/**\n * Check if `thing` is {@link IDisposable disposable}.\n */\nexport function isDisposable(thing) {\n    return typeof thing.dispose === 'function' && thing.dispose.length === 0;\n}\nexport function dispose(arg) {\n    if (Iterable.is(arg)) {\n        const errors = [];\n        for (const d of arg) {\n            if (d) {\n                try {\n                    d.dispose();\n                }\n                catch (e) {\n                    errors.push(e);\n                }\n            }\n        }\n        if (errors.length === 1) {\n            throw errors[0];\n        }\n        else if (errors.length > 1) {\n            throw new AggregateError(errors, 'Encountered errors while disposing of store');\n        }\n        return Array.isArray(arg) ? [] : arg;\n    }\n    else if (arg) {\n        arg.dispose();\n        return arg;\n    }\n}\n/**\n * Combine multiple disposable values into a single {@link IDisposable}.\n */\nexport function combinedDisposable(...disposables) {\n    const parent = toDisposable(() => dispose(disposables));\n    setParentOfDisposables(disposables, parent);\n    return parent;\n}\n/**\n * Turn a function that implements dispose into an {@link IDisposable}.\n *\n * @param fn Clean up function, guaranteed to be called only **once**.\n */\nexport function toDisposable(fn) {\n    const self = trackDisposable({\n        dispose: once(() => {\n            markAsDisposed(self);\n            fn();\n        })\n    });\n    return self;\n}\n/**\n * Manages a collection of disposable values.\n *\n * This is the preferred way to manage multiple disposables. A `DisposableStore` is safer to work with than an\n * `IDisposable[]` as it considers edge cases, such as registering the same value multiple times or adding an item to a\n * store that has already been disposed of.\n */\nexport class DisposableStore {\n    constructor() {\n        this._toDispose = new Set();\n        this._isDisposed = false;\n        trackDisposable(this);\n    }\n    /**\n     * Dispose of all registered disposables and mark this object as disposed.\n     *\n     * Any future disposables added to this object will be disposed of on `add`.\n     */\n    dispose() {\n        if (this._isDisposed) {\n            return;\n        }\n        markAsDisposed(this);\n        this._isDisposed = true;\n        this.clear();\n    }\n    /**\n     * @return `true` if this object has been disposed of.\n     */\n    get isDisposed() {\n        return this._isDisposed;\n    }\n    /**\n     * Dispose of all registered disposables but do not mark this object as disposed.\n     */\n    clear() {\n        if (this._toDispose.size === 0) {\n            return;\n        }\n        try {\n            dispose(this._toDispose);\n        }\n        finally {\n            this._toDispose.clear();\n        }\n    }\n    /**\n     * Add a new {@link IDisposable disposable} to the collection.\n     */\n    add(o) {\n        if (!o) {\n            return o;\n        }\n        if (o === this) {\n            throw new Error('Cannot register a disposable on itself!');\n        }\n        setParentOfDisposable(o, this);\n        if (this._isDisposed) {\n            if (!DisposableStore.DISABLE_DISPOSED_WARNING) {\n                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);\n            }\n        }\n        else {\n            this._toDispose.add(o);\n        }\n        return o;\n    }\n}\nDisposableStore.DISABLE_DISPOSED_WARNING = false;\n/**\n * Abstract base class for a {@link IDisposable disposable} object.\n *\n * Subclasses can {@linkcode _register} disposables that will be automatically cleaned up when this object is disposed of.\n */\nexport class Disposable {\n    constructor() {\n        this._store = new DisposableStore();\n        trackDisposable(this);\n        setParentOfDisposable(this._store, this);\n    }\n    dispose() {\n        markAsDisposed(this);\n        this._store.dispose();\n    }\n    /**\n     * Adds `o` to the collection of disposables managed by this object.\n     */\n    _register(o) {\n        if (o === this) {\n            throw new Error('Cannot register a disposable on itself!');\n        }\n        return this._store.add(o);\n    }\n}\n/**\n * A disposable that does nothing when it is disposed of.\n *\n * TODO: This should not be a static property.\n */\nDisposable.None = Object.freeze({ dispose() { } });\n/**\n * Manages the lifecycle of a disposable value that may be changed.\n *\n * This ensures that when the disposable value is changed, the previously held disposable is disposed of. You can\n * also register a `MutableDisposable` on a `Disposable` to ensure it is automatically cleaned up.\n */\nexport class MutableDisposable {\n    constructor() {\n        this._isDisposed = false;\n        trackDisposable(this);\n    }\n    get value() {\n        return this._isDisposed ? undefined : this._value;\n    }\n    set value(value) {\n        var _a;\n        if (this._isDisposed || value === this._value) {\n            return;\n        }\n        (_a = this._value) === null || _a === void 0 ? void 0 : _a.dispose();\n        if (value) {\n            setParentOfDisposable(value, this);\n        }\n        this._value = value;\n    }\n    /**\n     * Resets the stored value and disposed of the previously stored value.\n     */\n    clear() {\n        this.value = undefined;\n    }\n    dispose() {\n        var _a;\n        this._isDisposed = true;\n        markAsDisposed(this);\n        (_a = this._value) === null || _a === void 0 ? void 0 : _a.dispose();\n        this._value = undefined;\n    }\n}\nexport class RefCountedDisposable {\n    constructor(_disposable) {\n        this._disposable = _disposable;\n        this._counter = 1;\n    }\n    acquire() {\n        this._counter++;\n        return this;\n    }\n    release() {\n        if (--this._counter === 0) {\n            this._disposable.dispose();\n        }\n        return this;\n    }\n}\nexport class ImmortalReference {\n    constructor(object) {\n        this.object = object;\n    }\n    dispose() { }\n}\n/**\n * A map the manages the lifecycle of the values that it stores.\n */\nexport class DisposableMap {\n    constructor() {\n        this._store = new Map();\n        this._isDisposed = false;\n        trackDisposable(this);\n    }\n    /**\n     * Disposes of all stored values and mark this object as disposed.\n     *\n     * Trying to use this object after it has been disposed of is an error.\n     */\n    dispose() {\n        markAsDisposed(this);\n        this._isDisposed = true;\n        this.clearAndDisposeAll();\n    }\n    /**\n     * Disposes of all stored values and clear the map, but DO NOT mark this object as disposed.\n     */\n    clearAndDisposeAll() {\n        if (!this._store.size) {\n            return;\n        }\n        try {\n            dispose(this._store.values());\n        }\n        finally {\n            this._store.clear();\n        }\n    }\n    get(key) {\n        return this._store.get(key);\n    }\n    set(key, value, skipDisposeOnOverwrite = false) {\n        var _a;\n        if (this._isDisposed) {\n            console.warn(new Error('Trying to add a disposable to a DisposableMap that has already been disposed of. The added object will be leaked!').stack);\n        }\n        if (!skipDisposeOnOverwrite) {\n            (_a = this._store.get(key)) === null || _a === void 0 ? void 0 : _a.dispose();\n        }\n        this._store.set(key, value);\n    }\n    /**\n     * Delete the value stored for `key` from this map and also dispose of it.\n     */\n    deleteAndDispose(key) {\n        var _a;\n        (_a = this._store.get(key)) === null || _a === void 0 ? void 0 : _a.dispose();\n        this._store.delete(key);\n    }\n    [Symbol.iterator]() {\n        return this._store[Symbol.iterator]();\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nconst hasPerformanceNow = (globalThis.performance && typeof globalThis.performance.now === 'function');\nexport class StopWatch {\n    static create(highResolution) {\n        return new StopWatch(highResolution);\n    }\n    constructor(highResolution) {\n        this._now = hasPerformanceNow && highResolution === false ? Date.now : globalThis.performance.now.bind(globalThis.performance);\n        this._startTime = this._now();\n        this._stopTime = -1;\n    }\n    stop() {\n        this._stopTime = this._now();\n    }\n    elapsed() {\n        if (this._stopTime !== -1) {\n            return this._stopTime - this._startTime;\n        }\n        return this._now() - this._startTime;\n    }\n}\n","import { onUnexpectedError } from './errors.js';\nimport { once as onceFn } from './functional.js';\nimport { combinedDisposable, Disposable, DisposableStore, toDisposable } from './lifecycle.js';\nimport { LinkedList } from './linkedList.js';\nimport { StopWatch } from './stopwatch.js';\n// -----------------------------------------------------------------------------------------------------------------------\n// Uncomment the next line to print warnings whenever an emitter with listeners is disposed. That is a sign of code smell.\n// -----------------------------------------------------------------------------------------------------------------------\nconst _enableDisposeWithListenerWarning = false;\n// _enableDisposeWithListenerWarning = Boolean(\"TRUE\"); // causes a linter warning so that it cannot be pushed\n// -----------------------------------------------------------------------------------------------------------------------\n// Uncomment the next line to print warnings whenever a snapshotted event is used repeatedly without cleanup.\n// See https://github.com/microsoft/vscode/issues/142851\n// -----------------------------------------------------------------------------------------------------------------------\nconst _enableSnapshotPotentialLeakWarning = false;\nexport var Event;\n(function (Event) {\n    Event.None = () => Disposable.None;\n    function _addLeakageTraceLogic(options) {\n        if (_enableSnapshotPotentialLeakWarning) {\n            const { onDidAddListener: origListenerDidAdd } = options;\n            const stack = Stacktrace.create();\n            let count = 0;\n            options.onDidAddListener = () => {\n                if (++count === 2) {\n                    console.warn('snapshotted emitter LIKELY used public and SHOULD HAVE BEEN created with DisposableStore. snapshotted here');\n                    stack.print();\n                }\n                origListenerDidAdd === null || origListenerDidAdd === void 0 ? void 0 : origListenerDidAdd();\n            };\n        }\n    }\n    /**\n     * Given an event, returns another event which debounces calls and defers the listeners to a later task via a shared\n     * `setTimeout`. The event is converted into a signal (`Event`) to avoid additional object creation as a\n     * result of merging events and to try prevent race conditions that could arise when using related deferred and\n     * non-deferred events.\n     *\n     * This is useful for deferring non-critical work (eg. general UI updates) to ensure it does not block critical work\n     * (eg. latency of keypress to text rendered).\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     *\n     * @param event The event source for the new event.\n     * @param disposable A disposable store to add the new EventEmitter to.\n     */\n    function defer(event, disposable) {\n        return debounce(event, () => void 0, 0, undefined, true, undefined, disposable);\n    }\n    Event.defer = defer;\n    /**\n     * Given an event, returns another event which only fires once.\n     *\n     * @param event The event source for the new event.\n     */\n    function once(event) {\n        return (listener, thisArgs = null, disposables) => {\n            // we need this, in case the event fires during the listener call\n            let didFire = false;\n            let result = undefined;\n            result = event(e => {\n                if (didFire) {\n                    return;\n                }\n                else if (result) {\n                    result.dispose();\n                }\n                else {\n                    didFire = true;\n                }\n                return listener.call(thisArgs, e);\n            }, null, disposables);\n            if (didFire) {\n                result.dispose();\n            }\n            return result;\n        };\n    }\n    Event.once = once;\n    /**\n     * Maps an event of one type into an event of another type using a mapping function, similar to how\n     * `Array.prototype.map` works.\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     *\n     * @param event The event source for the new event.\n     * @param map The mapping function.\n     * @param disposable A disposable store to add the new EventEmitter to.\n     */\n    function map(event, map, disposable) {\n        return snapshot((listener, thisArgs = null, disposables) => event(i => listener.call(thisArgs, map(i)), null, disposables), disposable);\n    }\n    Event.map = map;\n    /**\n     * Wraps an event in another event that performs some function on the event object before firing.\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     *\n     * @param event The event source for the new event.\n     * @param each The function to perform on the event object.\n     * @param disposable A disposable store to add the new EventEmitter to.\n     */\n    function forEach(event, each, disposable) {\n        return snapshot((listener, thisArgs = null, disposables) => event(i => { each(i); listener.call(thisArgs, i); }, null, disposables), disposable);\n    }\n    Event.forEach = forEach;\n    function filter(event, filter, disposable) {\n        return snapshot((listener, thisArgs = null, disposables) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables), disposable);\n    }\n    Event.filter = filter;\n    /**\n     * Given an event, returns the same event but typed as `Event`.\n     */\n    function signal(event) {\n        return event;\n    }\n    Event.signal = signal;\n    function any(...events) {\n        return (listener, thisArgs = null, disposables) => combinedDisposable(...events.map(event => event(e => listener.call(thisArgs, e), null, disposables)));\n    }\n    Event.any = any;\n    /**\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     */\n    function reduce(event, merge, initial, disposable) {\n        let output = initial;\n        return map(event, e => {\n            output = merge(output, e);\n            return output;\n        }, disposable);\n    }\n    Event.reduce = reduce;\n    function snapshot(event, disposable) {\n        let listener;\n        const options = {\n            onWillAddFirstListener() {\n                listener = event(emitter.fire, emitter);\n            },\n            onDidRemoveLastListener() {\n                listener === null || listener === void 0 ? void 0 : listener.dispose();\n            }\n        };\n        if (!disposable) {\n            _addLeakageTraceLogic(options);\n        }\n        const emitter = new Emitter(options);\n        disposable === null || disposable === void 0 ? void 0 : disposable.add(emitter);\n        return emitter.event;\n    }\n    function debounce(event, merge, delay = 100, leading = false, flushOnListenerRemove = false, leakWarningThreshold, disposable) {\n        let subscription;\n        let output = undefined;\n        let handle = undefined;\n        let numDebouncedCalls = 0;\n        let doFire;\n        const options = {\n            leakWarningThreshold,\n            onWillAddFirstListener() {\n                subscription = event(cur => {\n                    numDebouncedCalls++;\n                    output = merge(output, cur);\n                    if (leading && !handle) {\n                        emitter.fire(output);\n                        output = undefined;\n                    }\n                    doFire = () => {\n                        const _output = output;\n                        output = undefined;\n                        handle = undefined;\n                        if (!leading || numDebouncedCalls > 1) {\n                            emitter.fire(_output);\n                        }\n                        numDebouncedCalls = 0;\n                    };\n                    if (typeof delay === 'number') {\n                        clearTimeout(handle);\n                        handle = setTimeout(doFire, delay);\n                    }\n                    else {\n                        if (handle === undefined) {\n                            handle = 0;\n                            queueMicrotask(doFire);\n                        }\n                    }\n                });\n            },\n            onWillRemoveListener() {\n                if (flushOnListenerRemove && numDebouncedCalls > 0) {\n                    doFire === null || doFire === void 0 ? void 0 : doFire();\n                }\n            },\n            onDidRemoveLastListener() {\n                doFire = undefined;\n                subscription.dispose();\n            }\n        };\n        if (!disposable) {\n            _addLeakageTraceLogic(options);\n        }\n        const emitter = new Emitter(options);\n        disposable === null || disposable === void 0 ? void 0 : disposable.add(emitter);\n        return emitter.event;\n    }\n    Event.debounce = debounce;\n    /**\n     * Debounces an event, firing after some delay (default=0) with an array of all event original objects.\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     */\n    function accumulate(event, delay = 0, disposable) {\n        return Event.debounce(event, (last, e) => {\n            if (!last) {\n                return [e];\n            }\n            last.push(e);\n            return last;\n        }, delay, undefined, true, undefined, disposable);\n    }\n    Event.accumulate = accumulate;\n    /**\n     * Filters an event such that some condition is _not_ met more than once in a row, effectively ensuring duplicate\n     * event objects from different sources do not fire the same event object.\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     *\n     * @param event The event source for the new event.\n     * @param equals The equality condition.\n     * @param disposable A disposable store to add the new EventEmitter to.\n     *\n     * @example\n     * ```\n     * // Fire only one time when a single window is opened or focused\n     * Event.latch(Event.any(onDidOpenWindow, onDidFocusWindow))\n     * ```\n     */\n    function latch(event, equals = (a, b) => a === b, disposable) {\n        let firstCall = true;\n        let cache;\n        return filter(event, value => {\n            const shouldEmit = firstCall || !equals(value, cache);\n            firstCall = false;\n            cache = value;\n            return shouldEmit;\n        }, disposable);\n    }\n    Event.latch = latch;\n    /**\n     * Splits an event whose parameter is a union type into 2 separate events for each type in the union.\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     *\n     * @example\n     * ```\n     * const event = new EventEmitter().event;\n     * const [numberEvent, undefinedEvent] = Event.split(event, isUndefined);\n     * ```\n     *\n     * @param event The event source for the new event.\n     * @param isT A function that determines what event is of the first type.\n     * @param disposable A disposable store to add the new EventEmitter to.\n     */\n    function split(event, isT, disposable) {\n        return [\n            Event.filter(event, isT, disposable),\n            Event.filter(event, e => !isT(e), disposable),\n        ];\n    }\n    Event.split = split;\n    /**\n     * Buffers an event until it has a listener attached.\n     *\n     * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned\n     * event is accessible to \"third parties\", e.g the event is a public property. Otherwise a leaked listener on the\n     * returned event causes this utility to leak a listener on the original event.\n     *\n     * @param event The event source for the new event.\n     * @param flushAfterTimeout Determines whether to flush the buffer after a timeout immediately or after a\n     * `setTimeout` when the first event listener is added.\n     * @param _buffer Internal: A source event array used for tests.\n     *\n     * @example\n     * ```\n     * // Start accumulating events, when the first listener is attached, flush\n     * // the event after a timeout such that multiple listeners attached before\n     * // the timeout would receive the event\n     * this.onInstallExtension = Event.buffer(service.onInstallExtension, true);\n     * ```\n     */\n    function buffer(event, flushAfterTimeout = false, _buffer = []) {\n        let buffer = _buffer.slice();\n        let listener = event(e => {\n            if (buffer) {\n                buffer.push(e);\n            }\n            else {\n                emitter.fire(e);\n            }\n        });\n        const flush = () => {\n            buffer === null || buffer === void 0 ? void 0 : buffer.forEach(e => emitter.fire(e));\n            buffer = null;\n        };\n        const emitter = new Emitter({\n            onWillAddFirstListener() {\n                if (!listener) {\n                    listener = event(e => emitter.fire(e));\n                }\n            },\n            onDidAddFirstListener() {\n                if (buffer) {\n                    if (flushAfterTimeout) {\n                        setTimeout(flush);\n                    }\n                    else {\n                        flush();\n                    }\n                }\n            },\n            onDidRemoveLastListener() {\n                if (listener) {\n                    listener.dispose();\n                }\n                listener = null;\n            }\n        });\n        return emitter.event;\n    }\n    Event.buffer = buffer;\n    class ChainableEvent {\n        constructor(event) {\n            this.event = event;\n            this.disposables = new DisposableStore();\n        }\n        /** @see {@link Event.map} */\n        map(fn) {\n            return new ChainableEvent(map(this.event, fn, this.disposables));\n        }\n        /** @see {@link Event.forEach} */\n        forEach(fn) {\n            return new ChainableEvent(forEach(this.event, fn, this.disposables));\n        }\n        filter(fn) {\n            return new ChainableEvent(filter(this.event, fn, this.disposables));\n        }\n        /** @see {@link Event.reduce} */\n        reduce(merge, initial) {\n            return new ChainableEvent(reduce(this.event, merge, initial, this.disposables));\n        }\n        /** @see {@link Event.reduce} */\n        latch() {\n            return new ChainableEvent(latch(this.event, undefined, this.disposables));\n        }\n        debounce(merge, delay = 100, leading = false, flushOnListenerRemove = false, leakWarningThreshold) {\n            return new ChainableEvent(debounce(this.event, merge, delay, leading, flushOnListenerRemove, leakWarningThreshold, this.disposables));\n        }\n        /**\n         * Attach a listener to the event.\n         */\n        on(listener, thisArgs, disposables) {\n            return this.event(listener, thisArgs, disposables);\n        }\n        /** @see {@link Event.once} */\n        once(listener, thisArgs, disposables) {\n            return once(this.event)(listener, thisArgs, disposables);\n        }\n        dispose() {\n            this.disposables.dispose();\n        }\n    }\n    /**\n     * Wraps the event in an {@link IChainableEvent}, allowing a more functional programming style.\n     *\n     * @example\n     * ```\n     * // Normal\n     * const onEnterPressNormal = Event.filter(\n     *   Event.map(onKeyPress.event, e => new StandardKeyboardEvent(e)),\n     *   e.keyCode === KeyCode.Enter\n     * ).event;\n     *\n     * // Using chain\n     * const onEnterPressChain = Event.chain(onKeyPress.event)\n     *   .map(e => new StandardKeyboardEvent(e))\n     *   .filter(e => e.keyCode === KeyCode.Enter)\n     *   .event;\n     * ```\n     */\n    function chain(event) {\n        return new ChainableEvent(event);\n    }\n    Event.chain = chain;\n    /**\n     * Creates an {@link Event} from a node event emitter.\n     */\n    function fromNodeEventEmitter(emitter, eventName, map = id => id) {\n        const fn = (...args) => result.fire(map(...args));\n        const onFirstListenerAdd = () => emitter.on(eventName, fn);\n        const onLastListenerRemove = () => emitter.removeListener(eventName, fn);\n        const result = new Emitter({ onWillAddFirstListener: onFirstListenerAdd, onDidRemoveLastListener: onLastListenerRemove });\n        return result.event;\n    }\n    Event.fromNodeEventEmitter = fromNodeEventEmitter;\n    /**\n     * Creates an {@link Event} from a DOM event emitter.\n     */\n    function fromDOMEventEmitter(emitter, eventName, map = id => id) {\n        const fn = (...args) => result.fire(map(...args));\n        const onFirstListenerAdd = () => emitter.addEventListener(eventName, fn);\n        const onLastListenerRemove = () => emitter.removeEventListener(eventName, fn);\n        const result = new Emitter({ onWillAddFirstListener: onFirstListenerAdd, onDidRemoveLastListener: onLastListenerRemove });\n        return result.event;\n    }\n    Event.fromDOMEventEmitter = fromDOMEventEmitter;\n    /**\n     * Creates a promise out of an event, using the {@link Event.once} helper.\n     */\n    function toPromise(event) {\n        return new Promise(resolve => once(event)(resolve));\n    }\n    Event.toPromise = toPromise;\n    /**\n     * Adds a listener to an event and calls the listener immediately with undefined as the event object.\n     *\n     * @example\n     * ```\n     * // Initialize the UI and update it when dataChangeEvent fires\n     * runAndSubscribe(dataChangeEvent, () => this._updateUI());\n     * ```\n     */\n    function runAndSubscribe(event, handler) {\n        handler(undefined);\n        return event(e => handler(e));\n    }\n    Event.runAndSubscribe = runAndSubscribe;\n    /**\n     * Adds a listener to an event and calls the listener immediately with undefined as the event object. A new\n     * {@link DisposableStore} is passed to the listener which is disposed when the returned disposable is disposed.\n     */\n    function runAndSubscribeWithStore(event, handler) {\n        let store = null;\n        function run(e) {\n            store === null || store === void 0 ? void 0 : store.dispose();\n            store = new DisposableStore();\n            handler(e, store);\n        }\n        run(undefined);\n        const disposable = event(e => run(e));\n        return toDisposable(() => {\n            disposable.dispose();\n            store === null || store === void 0 ? void 0 : store.dispose();\n        });\n    }\n    Event.runAndSubscribeWithStore = runAndSubscribeWithStore;\n    class EmitterObserver {\n        constructor(_observable, store) {\n            this._observable = _observable;\n            this._counter = 0;\n            this._hasChanged = false;\n            const options = {\n                onWillAddFirstListener: () => {\n                    _observable.addObserver(this);\n                },\n                onDidRemoveLastListener: () => {\n                    _observable.removeObserver(this);\n                }\n            };\n            if (!store) {\n                _addLeakageTraceLogic(options);\n            }\n            this.emitter = new Emitter(options);\n            if (store) {\n                store.add(this.emitter);\n            }\n        }\n        beginUpdate(_observable) {\n            // assert(_observable === this.obs);\n            this._counter++;\n        }\n        handlePossibleChange(_observable) {\n            // assert(_observable === this.obs);\n        }\n        handleChange(_observable, _change) {\n            // assert(_observable === this.obs);\n            this._hasChanged = true;\n        }\n        endUpdate(_observable) {\n            // assert(_observable === this.obs);\n            this._counter--;\n            if (this._counter === 0) {\n                this._observable.reportChanges();\n                if (this._hasChanged) {\n                    this._hasChanged = false;\n                    this.emitter.fire(this._observable.get());\n                }\n            }\n        }\n    }\n    /**\n     * Creates an event emitter that is fired when the observable changes.\n     * Each listeners subscribes to the emitter.\n     */\n    function fromObservable(obs, store) {\n        const observer = new EmitterObserver(obs, store);\n        return observer.emitter.event;\n    }\n    Event.fromObservable = fromObservable;\n    /**\n     * Each listener is attached to the observable directly.\n     */\n    function fromObservableLight(observable) {\n        return (listener) => {\n            let count = 0;\n            let didChange = false;\n            const observer = {\n                beginUpdate() {\n                    count++;\n                },\n                endUpdate() {\n                    count--;\n                    if (count === 0) {\n                        observable.reportChanges();\n                        if (didChange) {\n                            didChange = false;\n                            listener();\n                        }\n                    }\n                },\n                handlePossibleChange() {\n                    // noop\n                },\n                handleChange() {\n                    didChange = true;\n                }\n            };\n            observable.addObserver(observer);\n            return {\n                dispose() {\n                    observable.removeObserver(observer);\n                }\n            };\n        };\n    }\n    Event.fromObservableLight = fromObservableLight;\n})(Event || (Event = {}));\nexport class EventProfiling {\n    constructor(name) {\n        this.listenerCount = 0;\n        this.invocationCount = 0;\n        this.elapsedOverall = 0;\n        this.durations = [];\n        this.name = `${name}_${EventProfiling._idPool++}`;\n        EventProfiling.all.add(this);\n    }\n    start(listenerCount) {\n        this._stopWatch = new StopWatch();\n        this.listenerCount = listenerCount;\n    }\n    stop() {\n        if (this._stopWatch) {\n            const elapsed = this._stopWatch.elapsed();\n            this.durations.push(elapsed);\n            this.elapsedOverall += elapsed;\n            this.invocationCount += 1;\n            this._stopWatch = undefined;\n        }\n    }\n}\nEventProfiling.all = new Set();\nEventProfiling._idPool = 0;\nlet _globalLeakWarningThreshold = -1;\nclass LeakageMonitor {\n    constructor(threshold, name = Math.random().toString(18).slice(2, 5)) {\n        this.threshold = threshold;\n        this.name = name;\n        this._warnCountdown = 0;\n    }\n    dispose() {\n        var _a;\n        (_a = this._stacks) === null || _a === void 0 ? void 0 : _a.clear();\n    }\n    check(stack, listenerCount) {\n        const threshold = this.threshold;\n        if (threshold <= 0 || listenerCount < threshold) {\n            return undefined;\n        }\n        if (!this._stacks) {\n            this._stacks = new Map();\n        }\n        const count = (this._stacks.get(stack.value) || 0);\n        this._stacks.set(stack.value, count + 1);\n        this._warnCountdown -= 1;\n        if (this._warnCountdown <= 0) {\n            // only warn on first exceed and then every time the limit\n            // is exceeded by 50% again\n            this._warnCountdown = threshold * 0.5;\n            // find most frequent listener and print warning\n            let topStack;\n            let topCount = 0;\n            for (const [stack, count] of this._stacks) {\n                if (!topStack || topCount < count) {\n                    topStack = stack;\n                    topCount = count;\n                }\n            }\n            console.warn(`[${this.name}] potential listener LEAK detected, having ${listenerCount} listeners already. MOST frequent listener (${topCount}):`);\n            console.warn(topStack);\n        }\n        return () => {\n            const count = (this._stacks.get(stack.value) || 0);\n            this._stacks.set(stack.value, count - 1);\n        };\n    }\n}\nclass Stacktrace {\n    static create() {\n        var _a;\n        return new Stacktrace((_a = new Error().stack) !== null && _a !== void 0 ? _a : '');\n    }\n    constructor(value) {\n        this.value = value;\n    }\n    print() {\n        console.warn(this.value.split('\\n').slice(2).join('\\n'));\n    }\n}\nclass UniqueContainer {\n    constructor(value) {\n        this.value = value;\n    }\n}\nconst compactionThreshold = 2;\nconst forEachListener = (listeners, fn) => {\n    if (listeners instanceof UniqueContainer) {\n        fn(listeners);\n    }\n    else {\n        for (let i = 0; i < listeners.length; i++) {\n            const l = listeners[i];\n            if (l) {\n                fn(l);\n            }\n        }\n    }\n};\n/**\n * The Emitter can be used to expose an Event to the public\n * to fire it from the insides.\n * Sample:\n    class Document {\n\n        private readonly _onDidChange = new Emitter<(value:string)=>any>();\n\n        public onDidChange = this._onDidChange.event;\n\n        // getter-style\n        // get onDidChange(): Event<(value:string)=>any> {\n        // \treturn this._onDidChange.event;\n        // }\n\n        private _doIt() {\n            //...\n            this._onDidChange.fire(value);\n        }\n    }\n */\nexport class Emitter {\n    constructor(options) {\n        var _a, _b, _c, _d, _e;\n        this._size = 0;\n        this._options = options;\n        this._leakageMon = _globalLeakWarningThreshold > 0 || ((_a = this._options) === null || _a === void 0 ? void 0 : _a.leakWarningThreshold) ? new LeakageMonitor((_c = (_b = this._options) === null || _b === void 0 ? void 0 : _b.leakWarningThreshold) !== null && _c !== void 0 ? _c : _globalLeakWarningThreshold) : undefined;\n        this._perfMon = ((_d = this._options) === null || _d === void 0 ? void 0 : _d._profName) ? new EventProfiling(this._options._profName) : undefined;\n        this._deliveryQueue = (_e = this._options) === null || _e === void 0 ? void 0 : _e.deliveryQueue;\n    }\n    dispose() {\n        var _a, _b, _c, _d;\n        if (!this._disposed) {\n            this._disposed = true;\n            // It is bad to have listeners at the time of disposing an emitter, it is worst to have listeners keep the emitter\n            // alive via the reference that's embedded in their disposables. Therefore we loop over all remaining listeners and\n            // unset their subscriptions/disposables. Looping and blaming remaining listeners is done on next tick because the\n            // the following programming pattern is very popular:\n            //\n            // const someModel = this._disposables.add(new ModelObject()); // (1) create and register model\n            // this._disposables.add(someModel.onDidChange(() => { ... }); // (2) subscribe and register model-event listener\n            // ...later...\n            // this._disposables.dispose(); disposes (1) then (2): don't warn after (1) but after the \"overall dispose\" is done\n            if (((_a = this._deliveryQueue) === null || _a === void 0 ? void 0 : _a.current) === this) {\n                this._deliveryQueue.reset();\n            }\n            if (this._listeners) {\n                if (_enableDisposeWithListenerWarning) {\n                    const listeners = this._listeners;\n                    queueMicrotask(() => {\n                        forEachListener(listeners, l => { var _a; return (_a = l.stack) === null || _a === void 0 ? void 0 : _a.print(); });\n                    });\n                }\n                this._listeners = undefined;\n                this._size = 0;\n            }\n            (_c = (_b = this._options) === null || _b === void 0 ? void 0 : _b.onDidRemoveLastListener) === null || _c === void 0 ? void 0 : _c.call(_b);\n            (_d = this._leakageMon) === null || _d === void 0 ? void 0 : _d.dispose();\n        }\n    }\n    /**\n     * For the public to allow to subscribe\n     * to events from this Emitter\n     */\n    get event() {\n        var _a;\n        (_a = this._event) !== null && _a !== void 0 ? _a : (this._event = (callback, thisArgs, disposables) => {\n            var _a, _b, _c, _d, _e;\n            if (this._leakageMon && this._size > this._leakageMon.threshold * 3) {\n                console.warn(`[${this._leakageMon.name}] REFUSES to accept new listeners because it exceeded its threshold by far`);\n                return Disposable.None;\n            }\n            if (this._disposed) {\n                // todo: should we warn if a listener is added to a disposed emitter? This happens often\n                return Disposable.None;\n            }\n            if (thisArgs) {\n                callback = callback.bind(thisArgs);\n            }\n            const contained = new UniqueContainer(callback);\n            let removeMonitor;\n            let stack;\n            if (this._leakageMon && this._size >= Math.ceil(this._leakageMon.threshold * 0.2)) {\n                // check and record this emitter for potential leakage\n                contained.stack = Stacktrace.create();\n                removeMonitor = this._leakageMon.check(contained.stack, this._size + 1);\n            }\n            if (_enableDisposeWithListenerWarning) {\n                contained.stack = stack !== null && stack !== void 0 ? stack : Stacktrace.create();\n            }\n            if (!this._listeners) {\n                (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.onWillAddFirstListener) === null || _b === void 0 ? void 0 : _b.call(_a, this);\n                this._listeners = contained;\n                (_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.onDidAddFirstListener) === null || _d === void 0 ? void 0 : _d.call(_c, this);\n            }\n            else if (this._listeners instanceof UniqueContainer) {\n                (_e = this._deliveryQueue) !== null && _e !== void 0 ? _e : (this._deliveryQueue = new EventDeliveryQueuePrivate());\n                this._listeners = [this._listeners, contained];\n            }\n            else {\n                this._listeners.push(contained);\n            }\n            this._size++;\n            const result = toDisposable(() => { removeMonitor === null || removeMonitor === void 0 ? void 0 : removeMonitor(); this._removeListener(contained); });\n            if (disposables instanceof DisposableStore) {\n                disposables.add(result);\n            }\n            else if (Array.isArray(disposables)) {\n                disposables.push(result);\n            }\n            return result;\n        });\n        return this._event;\n    }\n    _removeListener(listener) {\n        var _a, _b, _c, _d;\n        (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.onWillRemoveListener) === null || _b === void 0 ? void 0 : _b.call(_a, this);\n        if (!this._listeners) {\n            return; // expected if a listener gets disposed\n        }\n        if (this._size === 1) {\n            this._listeners = undefined;\n            (_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.onDidRemoveLastListener) === null || _d === void 0 ? void 0 : _d.call(_c, this);\n            this._size = 0;\n            return;\n        }\n        // size > 1 which requires that listeners be a list:\n        const listeners = this._listeners;\n        const index = listeners.indexOf(listener);\n        if (index === -1) {\n            console.log('disposed?', this._disposed);\n            console.log('size?', this._size);\n            console.log('arr?', JSON.stringify(this._listeners));\n            throw new Error('Attempted to dispose unknown listener');\n        }\n        this._size--;\n        listeners[index] = undefined;\n        const adjustDeliveryQueue = this._deliveryQueue.current === this;\n        if (this._size * compactionThreshold <= listeners.length) {\n            let n = 0;\n            for (let i = 0; i < listeners.length; i++) {\n                if (listeners[i]) {\n                    listeners[n++] = listeners[i];\n                }\n                else if (adjustDeliveryQueue) {\n                    this._deliveryQueue.end--;\n                    if (n < this._deliveryQueue.i) {\n                        this._deliveryQueue.i--;\n                    }\n                }\n            }\n            listeners.length = n;\n        }\n    }\n    _deliver(listener, value) {\n        var _a;\n        if (!listener) {\n            return;\n        }\n        const errorHandler = ((_a = this._options) === null || _a === void 0 ? void 0 : _a.onListenerError) || onUnexpectedError;\n        if (!errorHandler) {\n            listener.value(value);\n            return;\n        }\n        try {\n            listener.value(value);\n        }\n        catch (e) {\n            errorHandler(e);\n        }\n    }\n    /** Delivers items in the queue. Assumes the queue is ready to go. */\n    _deliverQueue(dq) {\n        const listeners = dq.current._listeners;\n        while (dq.i < dq.end) {\n            // important: dq.i is incremented before calling deliver() because it might reenter deliverQueue()\n            this._deliver(listeners[dq.i++], dq.value);\n        }\n        dq.reset();\n    }\n    /**\n     * To be kept private to fire an event to\n     * subscribers\n     */\n    fire(event) {\n        var _a, _b, _c, _d;\n        if ((_a = this._deliveryQueue) === null || _a === void 0 ? void 0 : _a.current) {\n            this._deliverQueue(this._deliveryQueue);\n            (_b = this._perfMon) === null || _b === void 0 ? void 0 : _b.stop(); // last fire() will have starting perfmon, stop it before starting the next dispatch\n        }\n        (_c = this._perfMon) === null || _c === void 0 ? void 0 : _c.start(this._size);\n        if (!this._listeners) {\n            // no-op\n        }\n        else if (this._listeners instanceof UniqueContainer) {\n            this._deliver(this._listeners, event);\n        }\n        else {\n            const dq = this._deliveryQueue;\n            dq.enqueue(this, event, this._listeners.length);\n            this._deliverQueue(dq);\n        }\n        (_d = this._perfMon) === null || _d === void 0 ? void 0 : _d.stop();\n    }\n    hasListeners() {\n        return this._size > 0;\n    }\n}\nexport const createEventDeliveryQueue = () => new EventDeliveryQueuePrivate();\nclass EventDeliveryQueuePrivate {\n    constructor() {\n        /**\n         * Index in current's listener list.\n         */\n        this.i = -1;\n        /**\n         * The last index in the listener's list to deliver.\n         */\n        this.end = 0;\n    }\n    enqueue(emitter, value, end) {\n        this.i = 0;\n        this.end = end;\n        this.current = emitter;\n        this.value = value;\n    }\n    reset() {\n        this.i = this.end; // force any current emission loop to stop, mainly for during dispose\n        this.current = undefined;\n        this.value = undefined;\n    }\n}\nexport class PauseableEmitter extends Emitter {\n    constructor(options) {\n        super(options);\n        this._isPaused = 0;\n        this._eventQueue = new LinkedList();\n        this._mergeFn = options === null || options === void 0 ? void 0 : options.merge;\n    }\n    pause() {\n        this._isPaused++;\n    }\n    resume() {\n        if (this._isPaused !== 0 && --this._isPaused === 0) {\n            if (this._mergeFn) {\n                // use the merge function to create a single composite\n                // event. make a copy in case firing pauses this emitter\n                if (this._eventQueue.size > 0) {\n                    const events = Array.from(this._eventQueue);\n                    this._eventQueue.clear();\n                    super.fire(this._mergeFn(events));\n                }\n            }\n            else {\n                // no merging, fire each event individually and test\n                // that this emitter isn't paused halfway through\n                while (!this._isPaused && this._eventQueue.size !== 0) {\n                    super.fire(this._eventQueue.shift());\n                }\n            }\n        }\n    }\n    fire(event) {\n        if (this._size) {\n            if (this._isPaused !== 0) {\n                this._eventQueue.push(event);\n            }\n            else {\n                super.fire(event);\n            }\n        }\n    }\n}\nexport class DebounceEmitter extends PauseableEmitter {\n    constructor(options) {\n        var _a;\n        super(options);\n        this._delay = (_a = options.delay) !== null && _a !== void 0 ? _a : 100;\n    }\n    fire(event) {\n        if (!this._handle) {\n            this.pause();\n            this._handle = setTimeout(() => {\n                this._handle = undefined;\n                this.resume();\n            }, this._delay);\n        }\n        super.fire(event);\n    }\n}\n/**\n * An emitter which queue all events and then process them at the\n * end of the event loop.\n */\nexport class MicrotaskEmitter extends Emitter {\n    constructor(options) {\n        super(options);\n        this._queuedEvents = [];\n        this._mergeFn = options === null || options === void 0 ? void 0 : options.merge;\n    }\n    fire(event) {\n        if (!this.hasListeners()) {\n            return;\n        }\n        this._queuedEvents.push(event);\n        if (this._queuedEvents.length === 1) {\n            queueMicrotask(() => {\n                if (this._mergeFn) {\n                    super.fire(this._mergeFn(this._queuedEvents));\n                }\n                else {\n                    this._queuedEvents.forEach(e => super.fire(e));\n                }\n                this._queuedEvents = [];\n            });\n        }\n    }\n}\nexport class EventMultiplexer {\n    constructor() {\n        this.hasListeners = false;\n        this.events = [];\n        this.emitter = new Emitter({\n            onWillAddFirstListener: () => this.onFirstListenerAdd(),\n            onDidRemoveLastListener: () => this.onLastListenerRemove()\n        });\n    }\n    get event() {\n        return this.emitter.event;\n    }\n    add(event) {\n        const e = { event: event, listener: null };\n        this.events.push(e);\n        if (this.hasListeners) {\n            this.hook(e);\n        }\n        const dispose = () => {\n            if (this.hasListeners) {\n                this.unhook(e);\n            }\n            const idx = this.events.indexOf(e);\n            this.events.splice(idx, 1);\n        };\n        return toDisposable(onceFn(dispose));\n    }\n    onFirstListenerAdd() {\n        this.hasListeners = true;\n        this.events.forEach(e => this.hook(e));\n    }\n    onLastListenerRemove() {\n        this.hasListeners = false;\n        this.events.forEach(e => this.unhook(e));\n    }\n    hook(e) {\n        e.listener = e.event(r => this.emitter.fire(r));\n    }\n    unhook(e) {\n        if (e.listener) {\n            e.listener.dispose();\n        }\n        e.listener = null;\n    }\n    dispose() {\n        this.emitter.dispose();\n    }\n}\n/**\n * The EventBufferer is useful in situations in which you want\n * to delay firing your events during some code.\n * You can wrap that code and be sure that the event will not\n * be fired during that wrap.\n *\n * ```\n * const emitter: Emitter;\n * const delayer = new EventDelayer();\n * const delayedEvent = delayer.wrapEvent(emitter.event);\n *\n * delayedEvent(console.log);\n *\n * delayer.bufferEvents(() => {\n *   emitter.fire(); // event will not be fired yet\n * });\n *\n * // event will only be fired at this point\n * ```\n */\nexport class EventBufferer {\n    constructor() {\n        this.buffers = [];\n    }\n    wrapEvent(event) {\n        return (listener, thisArgs, disposables) => {\n            return event(i => {\n                const buffer = this.buffers[this.buffers.length - 1];\n                if (buffer) {\n                    buffer.push(() => listener.call(thisArgs, i));\n                }\n                else {\n                    listener.call(thisArgs, i);\n                }\n            }, undefined, disposables);\n        };\n    }\n    bufferEvents(fn) {\n        const buffer = [];\n        this.buffers.push(buffer);\n        const r = fn();\n        this.buffers.pop();\n        buffer.forEach(flush => flush());\n        return r;\n    }\n}\n/**\n * A Relay is an event forwarder which functions as a replugabble event pipe.\n * Once created, you can connect an input event to it and it will simply forward\n * events from that input event through its own `event` property. The `input`\n * can be changed at any point in time.\n */\nexport class Relay {\n    constructor() {\n        this.listening = false;\n        this.inputEvent = Event.None;\n        this.inputEventListener = Disposable.None;\n        this.emitter = new Emitter({\n            onDidAddFirstListener: () => {\n                this.listening = true;\n                this.inputEventListener = this.inputEvent(this.emitter.fire, this.emitter);\n            },\n            onDidRemoveLastListener: () => {\n                this.listening = false;\n                this.inputEventListener.dispose();\n            }\n        });\n        this.event = this.emitter.event;\n    }\n    set input(event) {\n        this.inputEvent = event;\n        if (this.listening) {\n            this.inputEventListener.dispose();\n            this.inputEventListener = event(this.emitter.fire, this.emitter);\n        }\n    }\n    dispose() {\n        this.inputEventListener.dispose();\n        this.emitter.dispose();\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Emitter, Event } from './event.js';\nconst shortcutEvent = Object.freeze(function (callback, context) {\n    const handle = setTimeout(callback.bind(context), 0);\n    return { dispose() { clearTimeout(handle); } };\n});\nexport var CancellationToken;\n(function (CancellationToken) {\n    function isCancellationToken(thing) {\n        if (thing === CancellationToken.None || thing === CancellationToken.Cancelled) {\n            return true;\n        }\n        if (thing instanceof MutableToken) {\n            return true;\n        }\n        if (!thing || typeof thing !== 'object') {\n            return false;\n        }\n        return typeof thing.isCancellationRequested === 'boolean'\n            && typeof thing.onCancellationRequested === 'function';\n    }\n    CancellationToken.isCancellationToken = isCancellationToken;\n    CancellationToken.None = Object.freeze({\n        isCancellationRequested: false,\n        onCancellationRequested: Event.None\n    });\n    CancellationToken.Cancelled = Object.freeze({\n        isCancellationRequested: true,\n        onCancellationRequested: shortcutEvent\n    });\n})(CancellationToken || (CancellationToken = {}));\nclass MutableToken {\n    constructor() {\n        this._isCancelled = false;\n        this._emitter = null;\n    }\n    cancel() {\n        if (!this._isCancelled) {\n            this._isCancelled = true;\n            if (this._emitter) {\n                this._emitter.fire(undefined);\n                this.dispose();\n            }\n        }\n    }\n    get isCancellationRequested() {\n        return this._isCancelled;\n    }\n    get onCancellationRequested() {\n        if (this._isCancelled) {\n            return shortcutEvent;\n        }\n        if (!this._emitter) {\n            this._emitter = new Emitter();\n        }\n        return this._emitter.event;\n    }\n    dispose() {\n        if (this._emitter) {\n            this._emitter.dispose();\n            this._emitter = null;\n        }\n    }\n}\nexport class CancellationTokenSource {\n    constructor(parent) {\n        this._token = undefined;\n        this._parentListener = undefined;\n        this._parentListener = parent && parent.onCancellationRequested(this.cancel, this);\n    }\n    get token() {\n        if (!this._token) {\n            // be lazy and create the token only when\n            // actually needed\n            this._token = new MutableToken();\n        }\n        return this._token;\n    }\n    cancel() {\n        if (!this._token) {\n            // save an object by returning the default\n            // cancelled token when cancellation happens\n            // before someone asks for the token\n            this._token = CancellationToken.Cancelled;\n        }\n        else if (this._token instanceof MutableToken) {\n            // actually cancel\n            this._token.cancel();\n        }\n    }\n    dispose(cancel = false) {\n        var _a;\n        if (cancel) {\n            this.cancel();\n        }\n        (_a = this._parentListener) === null || _a === void 0 ? void 0 : _a.dispose();\n        if (!this._token) {\n            // ensure to initialize with an empty token if we had none\n            this._token = CancellationToken.None;\n        }\n        else if (this._token instanceof MutableToken) {\n            // actually dispose\n            this._token.dispose();\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nclass KeyCodeStrMap {\n    constructor() {\n        this._keyCodeToStr = [];\n        this._strToKeyCode = Object.create(null);\n    }\n    define(keyCode, str) {\n        this._keyCodeToStr[keyCode] = str;\n        this._strToKeyCode[str.toLowerCase()] = keyCode;\n    }\n    keyCodeToStr(keyCode) {\n        return this._keyCodeToStr[keyCode];\n    }\n    strToKeyCode(str) {\n        return this._strToKeyCode[str.toLowerCase()] || 0 /* KeyCode.Unknown */;\n    }\n}\nconst uiMap = new KeyCodeStrMap();\nconst userSettingsUSMap = new KeyCodeStrMap();\nconst userSettingsGeneralMap = new KeyCodeStrMap();\nexport const EVENT_KEY_CODE_MAP = new Array(230);\nexport const NATIVE_WINDOWS_KEY_CODE_TO_KEY_CODE = {};\nconst scanCodeIntToStr = [];\nconst scanCodeStrToInt = Object.create(null);\nconst scanCodeLowerCaseStrToInt = Object.create(null);\n/**\n * -1 if a ScanCode => KeyCode mapping depends on kb layout.\n */\nexport const IMMUTABLE_CODE_TO_KEY_CODE = [];\n/**\n * -1 if a KeyCode => ScanCode mapping depends on kb layout.\n */\nexport const IMMUTABLE_KEY_CODE_TO_CODE = [];\nfor (let i = 0; i <= 193 /* ScanCode.MAX_VALUE */; i++) {\n    IMMUTABLE_CODE_TO_KEY_CODE[i] = -1 /* KeyCode.DependsOnKbLayout */;\n}\nfor (let i = 0; i <= 132 /* KeyCode.MAX_VALUE */; i++) {\n    IMMUTABLE_KEY_CODE_TO_CODE[i] = -1 /* ScanCode.DependsOnKbLayout */;\n}\n(function () {\n    // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx\n    // See https://github.com/microsoft/node-native-keymap/blob/88c0b0e5/deps/chromium/keyboard_codes_win.h\n    const empty = '';\n    const mappings = [\n        // immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel\n        [1, 0 /* ScanCode.None */, 'None', 0 /* KeyCode.Unknown */, 'unknown', 0, 'VK_UNKNOWN', empty, empty],\n        [1, 1 /* ScanCode.Hyper */, 'Hyper', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 2 /* ScanCode.Super */, 'Super', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 3 /* ScanCode.Fn */, 'Fn', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 4 /* ScanCode.FnLock */, 'FnLock', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 5 /* ScanCode.Suspend */, 'Suspend', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 6 /* ScanCode.Resume */, 'Resume', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 7 /* ScanCode.Turbo */, 'Turbo', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 8 /* ScanCode.Sleep */, 'Sleep', 0 /* KeyCode.Unknown */, empty, 0, 'VK_SLEEP', empty, empty],\n        [1, 9 /* ScanCode.WakeUp */, 'WakeUp', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [0, 10 /* ScanCode.KeyA */, 'KeyA', 31 /* KeyCode.KeyA */, 'A', 65, 'VK_A', empty, empty],\n        [0, 11 /* ScanCode.KeyB */, 'KeyB', 32 /* KeyCode.KeyB */, 'B', 66, 'VK_B', empty, empty],\n        [0, 12 /* ScanCode.KeyC */, 'KeyC', 33 /* KeyCode.KeyC */, 'C', 67, 'VK_C', empty, empty],\n        [0, 13 /* ScanCode.KeyD */, 'KeyD', 34 /* KeyCode.KeyD */, 'D', 68, 'VK_D', empty, empty],\n        [0, 14 /* ScanCode.KeyE */, 'KeyE', 35 /* KeyCode.KeyE */, 'E', 69, 'VK_E', empty, empty],\n        [0, 15 /* ScanCode.KeyF */, 'KeyF', 36 /* KeyCode.KeyF */, 'F', 70, 'VK_F', empty, empty],\n        [0, 16 /* ScanCode.KeyG */, 'KeyG', 37 /* KeyCode.KeyG */, 'G', 71, 'VK_G', empty, empty],\n        [0, 17 /* ScanCode.KeyH */, 'KeyH', 38 /* KeyCode.KeyH */, 'H', 72, 'VK_H', empty, empty],\n        [0, 18 /* ScanCode.KeyI */, 'KeyI', 39 /* KeyCode.KeyI */, 'I', 73, 'VK_I', empty, empty],\n        [0, 19 /* ScanCode.KeyJ */, 'KeyJ', 40 /* KeyCode.KeyJ */, 'J', 74, 'VK_J', empty, empty],\n        [0, 20 /* ScanCode.KeyK */, 'KeyK', 41 /* KeyCode.KeyK */, 'K', 75, 'VK_K', empty, empty],\n        [0, 21 /* ScanCode.KeyL */, 'KeyL', 42 /* KeyCode.KeyL */, 'L', 76, 'VK_L', empty, empty],\n        [0, 22 /* ScanCode.KeyM */, 'KeyM', 43 /* KeyCode.KeyM */, 'M', 77, 'VK_M', empty, empty],\n        [0, 23 /* ScanCode.KeyN */, 'KeyN', 44 /* KeyCode.KeyN */, 'N', 78, 'VK_N', empty, empty],\n        [0, 24 /* ScanCode.KeyO */, 'KeyO', 45 /* KeyCode.KeyO */, 'O', 79, 'VK_O', empty, empty],\n        [0, 25 /* ScanCode.KeyP */, 'KeyP', 46 /* KeyCode.KeyP */, 'P', 80, 'VK_P', empty, empty],\n        [0, 26 /* ScanCode.KeyQ */, 'KeyQ', 47 /* KeyCode.KeyQ */, 'Q', 81, 'VK_Q', empty, empty],\n        [0, 27 /* ScanCode.KeyR */, 'KeyR', 48 /* KeyCode.KeyR */, 'R', 82, 'VK_R', empty, empty],\n        [0, 28 /* ScanCode.KeyS */, 'KeyS', 49 /* KeyCode.KeyS */, 'S', 83, 'VK_S', empty, empty],\n        [0, 29 /* ScanCode.KeyT */, 'KeyT', 50 /* KeyCode.KeyT */, 'T', 84, 'VK_T', empty, empty],\n        [0, 30 /* ScanCode.KeyU */, 'KeyU', 51 /* KeyCode.KeyU */, 'U', 85, 'VK_U', empty, empty],\n        [0, 31 /* ScanCode.KeyV */, 'KeyV', 52 /* KeyCode.KeyV */, 'V', 86, 'VK_V', empty, empty],\n        [0, 32 /* ScanCode.KeyW */, 'KeyW', 53 /* KeyCode.KeyW */, 'W', 87, 'VK_W', empty, empty],\n        [0, 33 /* ScanCode.KeyX */, 'KeyX', 54 /* KeyCode.KeyX */, 'X', 88, 'VK_X', empty, empty],\n        [0, 34 /* ScanCode.KeyY */, 'KeyY', 55 /* KeyCode.KeyY */, 'Y', 89, 'VK_Y', empty, empty],\n        [0, 35 /* ScanCode.KeyZ */, 'KeyZ', 56 /* KeyCode.KeyZ */, 'Z', 90, 'VK_Z', empty, empty],\n        [0, 36 /* ScanCode.Digit1 */, 'Digit1', 22 /* KeyCode.Digit1 */, '1', 49, 'VK_1', empty, empty],\n        [0, 37 /* ScanCode.Digit2 */, 'Digit2', 23 /* KeyCode.Digit2 */, '2', 50, 'VK_2', empty, empty],\n        [0, 38 /* ScanCode.Digit3 */, 'Digit3', 24 /* KeyCode.Digit3 */, '3', 51, 'VK_3', empty, empty],\n        [0, 39 /* ScanCode.Digit4 */, 'Digit4', 25 /* KeyCode.Digit4 */, '4', 52, 'VK_4', empty, empty],\n        [0, 40 /* ScanCode.Digit5 */, 'Digit5', 26 /* KeyCode.Digit5 */, '5', 53, 'VK_5', empty, empty],\n        [0, 41 /* ScanCode.Digit6 */, 'Digit6', 27 /* KeyCode.Digit6 */, '6', 54, 'VK_6', empty, empty],\n        [0, 42 /* ScanCode.Digit7 */, 'Digit7', 28 /* KeyCode.Digit7 */, '7', 55, 'VK_7', empty, empty],\n        [0, 43 /* ScanCode.Digit8 */, 'Digit8', 29 /* KeyCode.Digit8 */, '8', 56, 'VK_8', empty, empty],\n        [0, 44 /* ScanCode.Digit9 */, 'Digit9', 30 /* KeyCode.Digit9 */, '9', 57, 'VK_9', empty, empty],\n        [0, 45 /* ScanCode.Digit0 */, 'Digit0', 21 /* KeyCode.Digit0 */, '0', 48, 'VK_0', empty, empty],\n        [1, 46 /* ScanCode.Enter */, 'Enter', 3 /* KeyCode.Enter */, 'Enter', 13, 'VK_RETURN', empty, empty],\n        [1, 47 /* ScanCode.Escape */, 'Escape', 9 /* KeyCode.Escape */, 'Escape', 27, 'VK_ESCAPE', empty, empty],\n        [1, 48 /* ScanCode.Backspace */, 'Backspace', 1 /* KeyCode.Backspace */, 'Backspace', 8, 'VK_BACK', empty, empty],\n        [1, 49 /* ScanCode.Tab */, 'Tab', 2 /* KeyCode.Tab */, 'Tab', 9, 'VK_TAB', empty, empty],\n        [1, 50 /* ScanCode.Space */, 'Space', 10 /* KeyCode.Space */, 'Space', 32, 'VK_SPACE', empty, empty],\n        [0, 51 /* ScanCode.Minus */, 'Minus', 88 /* KeyCode.Minus */, '-', 189, 'VK_OEM_MINUS', '-', 'OEM_MINUS'],\n        [0, 52 /* ScanCode.Equal */, 'Equal', 86 /* KeyCode.Equal */, '=', 187, 'VK_OEM_PLUS', '=', 'OEM_PLUS'],\n        [0, 53 /* ScanCode.BracketLeft */, 'BracketLeft', 92 /* KeyCode.BracketLeft */, '[', 219, 'VK_OEM_4', '[', 'OEM_4'],\n        [0, 54 /* ScanCode.BracketRight */, 'BracketRight', 94 /* KeyCode.BracketRight */, ']', 221, 'VK_OEM_6', ']', 'OEM_6'],\n        [0, 55 /* ScanCode.Backslash */, 'Backslash', 93 /* KeyCode.Backslash */, '\\\\', 220, 'VK_OEM_5', '\\\\', 'OEM_5'],\n        [0, 56 /* ScanCode.IntlHash */, 'IntlHash', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [0, 57 /* ScanCode.Semicolon */, 'Semicolon', 85 /* KeyCode.Semicolon */, ';', 186, 'VK_OEM_1', ';', 'OEM_1'],\n        [0, 58 /* ScanCode.Quote */, 'Quote', 95 /* KeyCode.Quote */, '\\'', 222, 'VK_OEM_7', '\\'', 'OEM_7'],\n        [0, 59 /* ScanCode.Backquote */, 'Backquote', 91 /* KeyCode.Backquote */, '`', 192, 'VK_OEM_3', '`', 'OEM_3'],\n        [0, 60 /* ScanCode.Comma */, 'Comma', 87 /* KeyCode.Comma */, ',', 188, 'VK_OEM_COMMA', ',', 'OEM_COMMA'],\n        [0, 61 /* ScanCode.Period */, 'Period', 89 /* KeyCode.Period */, '.', 190, 'VK_OEM_PERIOD', '.', 'OEM_PERIOD'],\n        [0, 62 /* ScanCode.Slash */, 'Slash', 90 /* KeyCode.Slash */, '/', 191, 'VK_OEM_2', '/', 'OEM_2'],\n        [1, 63 /* ScanCode.CapsLock */, 'CapsLock', 8 /* KeyCode.CapsLock */, 'CapsLock', 20, 'VK_CAPITAL', empty, empty],\n        [1, 64 /* ScanCode.F1 */, 'F1', 59 /* KeyCode.F1 */, 'F1', 112, 'VK_F1', empty, empty],\n        [1, 65 /* ScanCode.F2 */, 'F2', 60 /* KeyCode.F2 */, 'F2', 113, 'VK_F2', empty, empty],\n        [1, 66 /* ScanCode.F3 */, 'F3', 61 /* KeyCode.F3 */, 'F3', 114, 'VK_F3', empty, empty],\n        [1, 67 /* ScanCode.F4 */, 'F4', 62 /* KeyCode.F4 */, 'F4', 115, 'VK_F4', empty, empty],\n        [1, 68 /* ScanCode.F5 */, 'F5', 63 /* KeyCode.F5 */, 'F5', 116, 'VK_F5', empty, empty],\n        [1, 69 /* ScanCode.F6 */, 'F6', 64 /* KeyCode.F6 */, 'F6', 117, 'VK_F6', empty, empty],\n        [1, 70 /* ScanCode.F7 */, 'F7', 65 /* KeyCode.F7 */, 'F7', 118, 'VK_F7', empty, empty],\n        [1, 71 /* ScanCode.F8 */, 'F8', 66 /* KeyCode.F8 */, 'F8', 119, 'VK_F8', empty, empty],\n        [1, 72 /* ScanCode.F9 */, 'F9', 67 /* KeyCode.F9 */, 'F9', 120, 'VK_F9', empty, empty],\n        [1, 73 /* ScanCode.F10 */, 'F10', 68 /* KeyCode.F10 */, 'F10', 121, 'VK_F10', empty, empty],\n        [1, 74 /* ScanCode.F11 */, 'F11', 69 /* KeyCode.F11 */, 'F11', 122, 'VK_F11', empty, empty],\n        [1, 75 /* ScanCode.F12 */, 'F12', 70 /* KeyCode.F12 */, 'F12', 123, 'VK_F12', empty, empty],\n        [1, 76 /* ScanCode.PrintScreen */, 'PrintScreen', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 77 /* ScanCode.ScrollLock */, 'ScrollLock', 84 /* KeyCode.ScrollLock */, 'ScrollLock', 145, 'VK_SCROLL', empty, empty],\n        [1, 78 /* ScanCode.Pause */, 'Pause', 7 /* KeyCode.PauseBreak */, 'PauseBreak', 19, 'VK_PAUSE', empty, empty],\n        [1, 79 /* ScanCode.Insert */, 'Insert', 19 /* KeyCode.Insert */, 'Insert', 45, 'VK_INSERT', empty, empty],\n        [1, 80 /* ScanCode.Home */, 'Home', 14 /* KeyCode.Home */, 'Home', 36, 'VK_HOME', empty, empty],\n        [1, 81 /* ScanCode.PageUp */, 'PageUp', 11 /* KeyCode.PageUp */, 'PageUp', 33, 'VK_PRIOR', empty, empty],\n        [1, 82 /* ScanCode.Delete */, 'Delete', 20 /* KeyCode.Delete */, 'Delete', 46, 'VK_DELETE', empty, empty],\n        [1, 83 /* ScanCode.End */, 'End', 13 /* KeyCode.End */, 'End', 35, 'VK_END', empty, empty],\n        [1, 84 /* ScanCode.PageDown */, 'PageDown', 12 /* KeyCode.PageDown */, 'PageDown', 34, 'VK_NEXT', empty, empty],\n        [1, 85 /* ScanCode.ArrowRight */, 'ArrowRight', 17 /* KeyCode.RightArrow */, 'RightArrow', 39, 'VK_RIGHT', 'Right', empty],\n        [1, 86 /* ScanCode.ArrowLeft */, 'ArrowLeft', 15 /* KeyCode.LeftArrow */, 'LeftArrow', 37, 'VK_LEFT', 'Left', empty],\n        [1, 87 /* ScanCode.ArrowDown */, 'ArrowDown', 18 /* KeyCode.DownArrow */, 'DownArrow', 40, 'VK_DOWN', 'Down', empty],\n        [1, 88 /* ScanCode.ArrowUp */, 'ArrowUp', 16 /* KeyCode.UpArrow */, 'UpArrow', 38, 'VK_UP', 'Up', empty],\n        [1, 89 /* ScanCode.NumLock */, 'NumLock', 83 /* KeyCode.NumLock */, 'NumLock', 144, 'VK_NUMLOCK', empty, empty],\n        [1, 90 /* ScanCode.NumpadDivide */, 'NumpadDivide', 113 /* KeyCode.NumpadDivide */, 'NumPad_Divide', 111, 'VK_DIVIDE', empty, empty],\n        [1, 91 /* ScanCode.NumpadMultiply */, 'NumpadMultiply', 108 /* KeyCode.NumpadMultiply */, 'NumPad_Multiply', 106, 'VK_MULTIPLY', empty, empty],\n        [1, 92 /* ScanCode.NumpadSubtract */, 'NumpadSubtract', 111 /* KeyCode.NumpadSubtract */, 'NumPad_Subtract', 109, 'VK_SUBTRACT', empty, empty],\n        [1, 93 /* ScanCode.NumpadAdd */, 'NumpadAdd', 109 /* KeyCode.NumpadAdd */, 'NumPad_Add', 107, 'VK_ADD', empty, empty],\n        [1, 94 /* ScanCode.NumpadEnter */, 'NumpadEnter', 3 /* KeyCode.Enter */, empty, 0, empty, empty, empty],\n        [1, 95 /* ScanCode.Numpad1 */, 'Numpad1', 99 /* KeyCode.Numpad1 */, 'NumPad1', 97, 'VK_NUMPAD1', empty, empty],\n        [1, 96 /* ScanCode.Numpad2 */, 'Numpad2', 100 /* KeyCode.Numpad2 */, 'NumPad2', 98, 'VK_NUMPAD2', empty, empty],\n        [1, 97 /* ScanCode.Numpad3 */, 'Numpad3', 101 /* KeyCode.Numpad3 */, 'NumPad3', 99, 'VK_NUMPAD3', empty, empty],\n        [1, 98 /* ScanCode.Numpad4 */, 'Numpad4', 102 /* KeyCode.Numpad4 */, 'NumPad4', 100, 'VK_NUMPAD4', empty, empty],\n        [1, 99 /* ScanCode.Numpad5 */, 'Numpad5', 103 /* KeyCode.Numpad5 */, 'NumPad5', 101, 'VK_NUMPAD5', empty, empty],\n        [1, 100 /* ScanCode.Numpad6 */, 'Numpad6', 104 /* KeyCode.Numpad6 */, 'NumPad6', 102, 'VK_NUMPAD6', empty, empty],\n        [1, 101 /* ScanCode.Numpad7 */, 'Numpad7', 105 /* KeyCode.Numpad7 */, 'NumPad7', 103, 'VK_NUMPAD7', empty, empty],\n        [1, 102 /* ScanCode.Numpad8 */, 'Numpad8', 106 /* KeyCode.Numpad8 */, 'NumPad8', 104, 'VK_NUMPAD8', empty, empty],\n        [1, 103 /* ScanCode.Numpad9 */, 'Numpad9', 107 /* KeyCode.Numpad9 */, 'NumPad9', 105, 'VK_NUMPAD9', empty, empty],\n        [1, 104 /* ScanCode.Numpad0 */, 'Numpad0', 98 /* KeyCode.Numpad0 */, 'NumPad0', 96, 'VK_NUMPAD0', empty, empty],\n        [1, 105 /* ScanCode.NumpadDecimal */, 'NumpadDecimal', 112 /* KeyCode.NumpadDecimal */, 'NumPad_Decimal', 110, 'VK_DECIMAL', empty, empty],\n        [0, 106 /* ScanCode.IntlBackslash */, 'IntlBackslash', 97 /* KeyCode.IntlBackslash */, 'OEM_102', 226, 'VK_OEM_102', empty, empty],\n        [1, 107 /* ScanCode.ContextMenu */, 'ContextMenu', 58 /* KeyCode.ContextMenu */, 'ContextMenu', 93, empty, empty, empty],\n        [1, 108 /* ScanCode.Power */, 'Power', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 109 /* ScanCode.NumpadEqual */, 'NumpadEqual', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 110 /* ScanCode.F13 */, 'F13', 71 /* KeyCode.F13 */, 'F13', 124, 'VK_F13', empty, empty],\n        [1, 111 /* ScanCode.F14 */, 'F14', 72 /* KeyCode.F14 */, 'F14', 125, 'VK_F14', empty, empty],\n        [1, 112 /* ScanCode.F15 */, 'F15', 73 /* KeyCode.F15 */, 'F15', 126, 'VK_F15', empty, empty],\n        [1, 113 /* ScanCode.F16 */, 'F16', 74 /* KeyCode.F16 */, 'F16', 127, 'VK_F16', empty, empty],\n        [1, 114 /* ScanCode.F17 */, 'F17', 75 /* KeyCode.F17 */, 'F17', 128, 'VK_F17', empty, empty],\n        [1, 115 /* ScanCode.F18 */, 'F18', 76 /* KeyCode.F18 */, 'F18', 129, 'VK_F18', empty, empty],\n        [1, 116 /* ScanCode.F19 */, 'F19', 77 /* KeyCode.F19 */, 'F19', 130, 'VK_F19', empty, empty],\n        [1, 117 /* ScanCode.F20 */, 'F20', 78 /* KeyCode.F20 */, 'F20', 131, 'VK_F20', empty, empty],\n        [1, 118 /* ScanCode.F21 */, 'F21', 79 /* KeyCode.F21 */, 'F21', 132, 'VK_F21', empty, empty],\n        [1, 119 /* ScanCode.F22 */, 'F22', 80 /* KeyCode.F22 */, 'F22', 133, 'VK_F22', empty, empty],\n        [1, 120 /* ScanCode.F23 */, 'F23', 81 /* KeyCode.F23 */, 'F23', 134, 'VK_F23', empty, empty],\n        [1, 121 /* ScanCode.F24 */, 'F24', 82 /* KeyCode.F24 */, 'F24', 135, 'VK_F24', empty, empty],\n        [1, 122 /* ScanCode.Open */, 'Open', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 123 /* ScanCode.Help */, 'Help', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 124 /* ScanCode.Select */, 'Select', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 125 /* ScanCode.Again */, 'Again', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 126 /* ScanCode.Undo */, 'Undo', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 127 /* ScanCode.Cut */, 'Cut', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 128 /* ScanCode.Copy */, 'Copy', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 129 /* ScanCode.Paste */, 'Paste', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 130 /* ScanCode.Find */, 'Find', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 131 /* ScanCode.AudioVolumeMute */, 'AudioVolumeMute', 117 /* KeyCode.AudioVolumeMute */, 'AudioVolumeMute', 173, 'VK_VOLUME_MUTE', empty, empty],\n        [1, 132 /* ScanCode.AudioVolumeUp */, 'AudioVolumeUp', 118 /* KeyCode.AudioVolumeUp */, 'AudioVolumeUp', 175, 'VK_VOLUME_UP', empty, empty],\n        [1, 133 /* ScanCode.AudioVolumeDown */, 'AudioVolumeDown', 119 /* KeyCode.AudioVolumeDown */, 'AudioVolumeDown', 174, 'VK_VOLUME_DOWN', empty, empty],\n        [1, 134 /* ScanCode.NumpadComma */, 'NumpadComma', 110 /* KeyCode.NUMPAD_SEPARATOR */, 'NumPad_Separator', 108, 'VK_SEPARATOR', empty, empty],\n        [0, 135 /* ScanCode.IntlRo */, 'IntlRo', 115 /* KeyCode.ABNT_C1 */, 'ABNT_C1', 193, 'VK_ABNT_C1', empty, empty],\n        [1, 136 /* ScanCode.KanaMode */, 'KanaMode', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [0, 137 /* ScanCode.IntlYen */, 'IntlYen', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 138 /* ScanCode.Convert */, 'Convert', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 139 /* ScanCode.NonConvert */, 'NonConvert', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 140 /* ScanCode.Lang1 */, 'Lang1', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 141 /* ScanCode.Lang2 */, 'Lang2', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 142 /* ScanCode.Lang3 */, 'Lang3', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 143 /* ScanCode.Lang4 */, 'Lang4', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 144 /* ScanCode.Lang5 */, 'Lang5', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 145 /* ScanCode.Abort */, 'Abort', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 146 /* ScanCode.Props */, 'Props', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 147 /* ScanCode.NumpadParenLeft */, 'NumpadParenLeft', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 148 /* ScanCode.NumpadParenRight */, 'NumpadParenRight', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 149 /* ScanCode.NumpadBackspace */, 'NumpadBackspace', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 150 /* ScanCode.NumpadMemoryStore */, 'NumpadMemoryStore', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 151 /* ScanCode.NumpadMemoryRecall */, 'NumpadMemoryRecall', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 152 /* ScanCode.NumpadMemoryClear */, 'NumpadMemoryClear', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 153 /* ScanCode.NumpadMemoryAdd */, 'NumpadMemoryAdd', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 154 /* ScanCode.NumpadMemorySubtract */, 'NumpadMemorySubtract', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 155 /* ScanCode.NumpadClear */, 'NumpadClear', 131 /* KeyCode.Clear */, 'Clear', 12, 'VK_CLEAR', empty, empty],\n        [1, 156 /* ScanCode.NumpadClearEntry */, 'NumpadClearEntry', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 5 /* KeyCode.Ctrl */, 'Ctrl', 17, 'VK_CONTROL', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 4 /* KeyCode.Shift */, 'Shift', 16, 'VK_SHIFT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 6 /* KeyCode.Alt */, 'Alt', 18, 'VK_MENU', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 57 /* KeyCode.Meta */, 'Meta', 91, 'VK_COMMAND', empty, empty],\n        [1, 157 /* ScanCode.ControlLeft */, 'ControlLeft', 5 /* KeyCode.Ctrl */, empty, 0, 'VK_LCONTROL', empty, empty],\n        [1, 158 /* ScanCode.ShiftLeft */, 'ShiftLeft', 4 /* KeyCode.Shift */, empty, 0, 'VK_LSHIFT', empty, empty],\n        [1, 159 /* ScanCode.AltLeft */, 'AltLeft', 6 /* KeyCode.Alt */, empty, 0, 'VK_LMENU', empty, empty],\n        [1, 160 /* ScanCode.MetaLeft */, 'MetaLeft', 57 /* KeyCode.Meta */, empty, 0, 'VK_LWIN', empty, empty],\n        [1, 161 /* ScanCode.ControlRight */, 'ControlRight', 5 /* KeyCode.Ctrl */, empty, 0, 'VK_RCONTROL', empty, empty],\n        [1, 162 /* ScanCode.ShiftRight */, 'ShiftRight', 4 /* KeyCode.Shift */, empty, 0, 'VK_RSHIFT', empty, empty],\n        [1, 163 /* ScanCode.AltRight */, 'AltRight', 6 /* KeyCode.Alt */, empty, 0, 'VK_RMENU', empty, empty],\n        [1, 164 /* ScanCode.MetaRight */, 'MetaRight', 57 /* KeyCode.Meta */, empty, 0, 'VK_RWIN', empty, empty],\n        [1, 165 /* ScanCode.BrightnessUp */, 'BrightnessUp', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 166 /* ScanCode.BrightnessDown */, 'BrightnessDown', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 167 /* ScanCode.MediaPlay */, 'MediaPlay', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 168 /* ScanCode.MediaRecord */, 'MediaRecord', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 169 /* ScanCode.MediaFastForward */, 'MediaFastForward', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 170 /* ScanCode.MediaRewind */, 'MediaRewind', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 171 /* ScanCode.MediaTrackNext */, 'MediaTrackNext', 124 /* KeyCode.MediaTrackNext */, 'MediaTrackNext', 176, 'VK_MEDIA_NEXT_TRACK', empty, empty],\n        [1, 172 /* ScanCode.MediaTrackPrevious */, 'MediaTrackPrevious', 125 /* KeyCode.MediaTrackPrevious */, 'MediaTrackPrevious', 177, 'VK_MEDIA_PREV_TRACK', empty, empty],\n        [1, 173 /* ScanCode.MediaStop */, 'MediaStop', 126 /* KeyCode.MediaStop */, 'MediaStop', 178, 'VK_MEDIA_STOP', empty, empty],\n        [1, 174 /* ScanCode.Eject */, 'Eject', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 175 /* ScanCode.MediaPlayPause */, 'MediaPlayPause', 127 /* KeyCode.MediaPlayPause */, 'MediaPlayPause', 179, 'VK_MEDIA_PLAY_PAUSE', empty, empty],\n        [1, 176 /* ScanCode.MediaSelect */, 'MediaSelect', 128 /* KeyCode.LaunchMediaPlayer */, 'LaunchMediaPlayer', 181, 'VK_MEDIA_LAUNCH_MEDIA_SELECT', empty, empty],\n        [1, 177 /* ScanCode.LaunchMail */, 'LaunchMail', 129 /* KeyCode.LaunchMail */, 'LaunchMail', 180, 'VK_MEDIA_LAUNCH_MAIL', empty, empty],\n        [1, 178 /* ScanCode.LaunchApp2 */, 'LaunchApp2', 130 /* KeyCode.LaunchApp2 */, 'LaunchApp2', 183, 'VK_MEDIA_LAUNCH_APP2', empty, empty],\n        [1, 179 /* ScanCode.LaunchApp1 */, 'LaunchApp1', 0 /* KeyCode.Unknown */, empty, 0, 'VK_MEDIA_LAUNCH_APP1', empty, empty],\n        [1, 180 /* ScanCode.SelectTask */, 'SelectTask', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 181 /* ScanCode.LaunchScreenSaver */, 'LaunchScreenSaver', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 182 /* ScanCode.BrowserSearch */, 'BrowserSearch', 120 /* KeyCode.BrowserSearch */, 'BrowserSearch', 170, 'VK_BROWSER_SEARCH', empty, empty],\n        [1, 183 /* ScanCode.BrowserHome */, 'BrowserHome', 121 /* KeyCode.BrowserHome */, 'BrowserHome', 172, 'VK_BROWSER_HOME', empty, empty],\n        [1, 184 /* ScanCode.BrowserBack */, 'BrowserBack', 122 /* KeyCode.BrowserBack */, 'BrowserBack', 166, 'VK_BROWSER_BACK', empty, empty],\n        [1, 185 /* ScanCode.BrowserForward */, 'BrowserForward', 123 /* KeyCode.BrowserForward */, 'BrowserForward', 167, 'VK_BROWSER_FORWARD', empty, empty],\n        [1, 186 /* ScanCode.BrowserStop */, 'BrowserStop', 0 /* KeyCode.Unknown */, empty, 0, 'VK_BROWSER_STOP', empty, empty],\n        [1, 187 /* ScanCode.BrowserRefresh */, 'BrowserRefresh', 0 /* KeyCode.Unknown */, empty, 0, 'VK_BROWSER_REFRESH', empty, empty],\n        [1, 188 /* ScanCode.BrowserFavorites */, 'BrowserFavorites', 0 /* KeyCode.Unknown */, empty, 0, 'VK_BROWSER_FAVORITES', empty, empty],\n        [1, 189 /* ScanCode.ZoomToggle */, 'ZoomToggle', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 190 /* ScanCode.MailReply */, 'MailReply', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 191 /* ScanCode.MailForward */, 'MailForward', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        [1, 192 /* ScanCode.MailSend */, 'MailSend', 0 /* KeyCode.Unknown */, empty, 0, empty, empty, empty],\n        // See https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html\n        // If an Input Method Editor is processing key input and the event is keydown, return 229.\n        [1, 0 /* ScanCode.None */, empty, 114 /* KeyCode.KEY_IN_COMPOSITION */, 'KeyInComposition', 229, empty, empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 116 /* KeyCode.ABNT_C2 */, 'ABNT_C2', 194, 'VK_ABNT_C2', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 96 /* KeyCode.OEM_8 */, 'OEM_8', 223, 'VK_OEM_8', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_KANA', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_HANGUL', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_JUNJA', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_FINAL', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_HANJA', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_KANJI', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_CONVERT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_NONCONVERT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_ACCEPT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_MODECHANGE', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_SELECT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PRINT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_EXECUTE', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_SNAPSHOT', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_HELP', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_APPS', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PROCESSKEY', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PACKET', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_DBE_SBCSCHAR', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_DBE_DBCSCHAR', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_ATTN', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_CRSEL', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_EXSEL', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_EREOF', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PLAY', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_ZOOM', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_NONAME', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_PA1', empty, empty],\n        [1, 0 /* ScanCode.None */, empty, 0 /* KeyCode.Unknown */, empty, 0, 'VK_OEM_CLEAR', empty, empty],\n    ];\n    const seenKeyCode = [];\n    const seenScanCode = [];\n    for (const mapping of mappings) {\n        const [immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel] = mapping;\n        if (!seenScanCode[scanCode]) {\n            seenScanCode[scanCode] = true;\n            scanCodeIntToStr[scanCode] = scanCodeStr;\n            scanCodeStrToInt[scanCodeStr] = scanCode;\n            scanCodeLowerCaseStrToInt[scanCodeStr.toLowerCase()] = scanCode;\n            if (immutable) {\n                IMMUTABLE_CODE_TO_KEY_CODE[scanCode] = keyCode;\n                if ((keyCode !== 0 /* KeyCode.Unknown */)\n                    && (keyCode !== 3 /* KeyCode.Enter */)\n                    && (keyCode !== 5 /* KeyCode.Ctrl */)\n                    && (keyCode !== 4 /* KeyCode.Shift */)\n                    && (keyCode !== 6 /* KeyCode.Alt */)\n                    && (keyCode !== 57 /* KeyCode.Meta */)) {\n                    IMMUTABLE_KEY_CODE_TO_CODE[keyCode] = scanCode;\n                }\n            }\n        }\n        if (!seenKeyCode[keyCode]) {\n            seenKeyCode[keyCode] = true;\n            if (!keyCodeStr) {\n                throw new Error(`String representation missing for key code ${keyCode} around scan code ${scanCodeStr}`);\n            }\n            uiMap.define(keyCode, keyCodeStr);\n            userSettingsUSMap.define(keyCode, usUserSettingsLabel || keyCodeStr);\n            userSettingsGeneralMap.define(keyCode, generalUserSettingsLabel || usUserSettingsLabel || keyCodeStr);\n        }\n        if (eventKeyCode) {\n            EVENT_KEY_CODE_MAP[eventKeyCode] = keyCode;\n        }\n        if (vkey) {\n            NATIVE_WINDOWS_KEY_CODE_TO_KEY_CODE[vkey] = keyCode;\n        }\n    }\n    // Manually added due to the exclusion above (due to duplication with NumpadEnter)\n    IMMUTABLE_KEY_CODE_TO_CODE[3 /* KeyCode.Enter */] = 46 /* ScanCode.Enter */;\n})();\nexport var KeyCodeUtils;\n(function (KeyCodeUtils) {\n    function toString(keyCode) {\n        return uiMap.keyCodeToStr(keyCode);\n    }\n    KeyCodeUtils.toString = toString;\n    function fromString(key) {\n        return uiMap.strToKeyCode(key);\n    }\n    KeyCodeUtils.fromString = fromString;\n    function toUserSettingsUS(keyCode) {\n        return userSettingsUSMap.keyCodeToStr(keyCode);\n    }\n    KeyCodeUtils.toUserSettingsUS = toUserSettingsUS;\n    function toUserSettingsGeneral(keyCode) {\n        return userSettingsGeneralMap.keyCodeToStr(keyCode);\n    }\n    KeyCodeUtils.toUserSettingsGeneral = toUserSettingsGeneral;\n    function fromUserSettings(key) {\n        return userSettingsUSMap.strToKeyCode(key) || userSettingsGeneralMap.strToKeyCode(key);\n    }\n    KeyCodeUtils.fromUserSettings = fromUserSettings;\n    function toElectronAccelerator(keyCode) {\n        if (keyCode >= 98 /* KeyCode.Numpad0 */ && keyCode <= 113 /* KeyCode.NumpadDivide */) {\n            // [Electron Accelerators] Electron is able to parse numpad keys, but unfortunately it\n            // renders them just as regular keys in menus. For example, num0 is rendered as \"0\",\n            // numdiv is rendered as \"/\", numsub is rendered as \"-\".\n            //\n            // This can lead to incredible confusion, as it makes numpad based keybindings indistinguishable\n            // from keybindings based on regular keys.\n            //\n            // We therefore need to fall back to custom rendering for numpad keys.\n            return null;\n        }\n        switch (keyCode) {\n            case 16 /* KeyCode.UpArrow */:\n                return 'Up';\n            case 18 /* KeyCode.DownArrow */:\n                return 'Down';\n            case 15 /* KeyCode.LeftArrow */:\n                return 'Left';\n            case 17 /* KeyCode.RightArrow */:\n                return 'Right';\n        }\n        return uiMap.keyCodeToStr(keyCode);\n    }\n    KeyCodeUtils.toElectronAccelerator = toElectronAccelerator;\n})(KeyCodeUtils || (KeyCodeUtils = {}));\nexport function KeyChord(firstPart, secondPart) {\n    const chordPart = ((secondPart & 0x0000FFFF) << 16) >>> 0;\n    return (firstPart | chordPart) >>> 0;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { globals, isMacintosh, isWindows } from './platform.js';\nlet safeProcess;\n// Native sandbox environment\nif (typeof globals.vscode !== 'undefined' && typeof globals.vscode.process !== 'undefined') {\n    const sandboxProcess = globals.vscode.process;\n    safeProcess = {\n        get platform() { return sandboxProcess.platform; },\n        get arch() { return sandboxProcess.arch; },\n        get env() { return sandboxProcess.env; },\n        cwd() { return sandboxProcess.cwd(); }\n    };\n}\n// Native node.js environment\nelse if (typeof process !== 'undefined') {\n    safeProcess = {\n        get platform() { return process.platform; },\n        get arch() { return process.arch; },\n        get env() { return process.env; },\n        cwd() { return process.env['VSCODE_CWD'] || process.cwd(); }\n    };\n}\n// Web environment\nelse {\n    safeProcess = {\n        // Supported\n        get platform() { return isWindows ? 'win32' : isMacintosh ? 'darwin' : 'linux'; },\n        get arch() { return undefined; /* arch is undefined in web */ },\n        // Unsupported\n        get env() { return {}; },\n        cwd() { return '/'; }\n    };\n}\n/**\n * Provides safe access to the `cwd` property in node.js, sandboxed or web\n * environments.\n *\n * Note: in web, this property is hardcoded to be `/`.\n *\n * @skipMangle\n */\nexport const cwd = safeProcess.cwd;\n/**\n * Provides safe access to the `env` property in node.js, sandboxed or web\n * environments.\n *\n * Note: in web, this property is hardcoded to be `{}`.\n */\nexport const env = safeProcess.env;\n/**\n * Provides safe access to the `platform` property in node.js, sandboxed or web\n * environments.\n */\nexport const platform = safeProcess.platform;\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n// NOTE: VSCode's copy of nodejs path library to be usable in common (non-node) namespace\n// Copied from: https://github.com/nodejs/node/blob/v16.14.2/lib/path.js\n/**\n * Copyright Joyent, Inc. and other Node contributors.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to permit\n * persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n * USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\nimport * as process from './process.js';\nconst CHAR_UPPERCASE_A = 65; /* A */\nconst CHAR_LOWERCASE_A = 97; /* a */\nconst CHAR_UPPERCASE_Z = 90; /* Z */\nconst CHAR_LOWERCASE_Z = 122; /* z */\nconst CHAR_DOT = 46; /* . */\nconst CHAR_FORWARD_SLASH = 47; /* / */\nconst CHAR_BACKWARD_SLASH = 92; /* \\ */\nconst CHAR_COLON = 58; /* : */\nconst CHAR_QUESTION_MARK = 63; /* ? */\nclass ErrorInvalidArgType extends Error {\n    constructor(name, expected, actual) {\n        // determiner: 'must be' or 'must not be'\n        let determiner;\n        if (typeof expected === 'string' && expected.indexOf('not ') === 0) {\n            determiner = 'must not be';\n            expected = expected.replace(/^not /, '');\n        }\n        else {\n            determiner = 'must be';\n        }\n        const type = name.indexOf('.') !== -1 ? 'property' : 'argument';\n        let msg = `The \"${name}\" ${type} ${determiner} of type ${expected}`;\n        msg += `. Received type ${typeof actual}`;\n        super(msg);\n        this.code = 'ERR_INVALID_ARG_TYPE';\n    }\n}\nfunction validateObject(pathObject, name) {\n    if (pathObject === null || typeof pathObject !== 'object') {\n        throw new ErrorInvalidArgType(name, 'Object', pathObject);\n    }\n}\nfunction validateString(value, name) {\n    if (typeof value !== 'string') {\n        throw new ErrorInvalidArgType(name, 'string', value);\n    }\n}\nconst platformIsWin32 = (process.platform === 'win32');\nfunction isPathSeparator(code) {\n    return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;\n}\nfunction isPosixPathSeparator(code) {\n    return code === CHAR_FORWARD_SLASH;\n}\nfunction isWindowsDeviceRoot(code) {\n    return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||\n        (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);\n}\n// Resolves . and .. elements in a path with directory names\nfunction normalizeString(path, allowAboveRoot, separator, isPathSeparator) {\n    let res = '';\n    let lastSegmentLength = 0;\n    let lastSlash = -1;\n    let dots = 0;\n    let code = 0;\n    for (let i = 0; i <= path.length; ++i) {\n        if (i < path.length) {\n            code = path.charCodeAt(i);\n        }\n        else if (isPathSeparator(code)) {\n            break;\n        }\n        else {\n            code = CHAR_FORWARD_SLASH;\n        }\n        if (isPathSeparator(code)) {\n            if (lastSlash === i - 1 || dots === 1) {\n                // NOOP\n            }\n            else if (dots === 2) {\n                if (res.length < 2 || lastSegmentLength !== 2 ||\n                    res.charCodeAt(res.length - 1) !== CHAR_DOT ||\n                    res.charCodeAt(res.length - 2) !== CHAR_DOT) {\n                    if (res.length > 2) {\n                        const lastSlashIndex = res.lastIndexOf(separator);\n                        if (lastSlashIndex === -1) {\n                            res = '';\n                            lastSegmentLength = 0;\n                        }\n                        else {\n                            res = res.slice(0, lastSlashIndex);\n                            lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);\n                        }\n                        lastSlash = i;\n                        dots = 0;\n                        continue;\n                    }\n                    else if (res.length !== 0) {\n                        res = '';\n                        lastSegmentLength = 0;\n                        lastSlash = i;\n                        dots = 0;\n                        continue;\n                    }\n                }\n                if (allowAboveRoot) {\n                    res += res.length > 0 ? `${separator}..` : '..';\n                    lastSegmentLength = 2;\n                }\n            }\n            else {\n                if (res.length > 0) {\n                    res += `${separator}${path.slice(lastSlash + 1, i)}`;\n                }\n                else {\n                    res = path.slice(lastSlash + 1, i);\n                }\n                lastSegmentLength = i - lastSlash - 1;\n            }\n            lastSlash = i;\n            dots = 0;\n        }\n        else if (code === CHAR_DOT && dots !== -1) {\n            ++dots;\n        }\n        else {\n            dots = -1;\n        }\n    }\n    return res;\n}\nfunction _format(sep, pathObject) {\n    validateObject(pathObject, 'pathObject');\n    const dir = pathObject.dir || pathObject.root;\n    const base = pathObject.base ||\n        `${pathObject.name || ''}${pathObject.ext || ''}`;\n    if (!dir) {\n        return base;\n    }\n    return dir === pathObject.root ? `${dir}${base}` : `${dir}${sep}${base}`;\n}\nexport const win32 = {\n    // path.resolve([from ...], to)\n    resolve(...pathSegments) {\n        let resolvedDevice = '';\n        let resolvedTail = '';\n        let resolvedAbsolute = false;\n        for (let i = pathSegments.length - 1; i >= -1; i--) {\n            let path;\n            if (i >= 0) {\n                path = pathSegments[i];\n                validateString(path, 'path');\n                // Skip empty entries\n                if (path.length === 0) {\n                    continue;\n                }\n            }\n            else if (resolvedDevice.length === 0) {\n                path = process.cwd();\n            }\n            else {\n                // Windows has the concept of drive-specific current working\n                // directories. If we've resolved a drive letter but not yet an\n                // absolute path, get cwd for that drive, or the process cwd if\n                // the drive cwd is not available. We're sure the device is not\n                // a UNC path at this points, because UNC paths are always absolute.\n                path = process.env[`=${resolvedDevice}`] || process.cwd();\n                // Verify that a cwd was found and that it actually points\n                // to our drive. If not, default to the drive's root.\n                if (path === undefined ||\n                    (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&\n                        path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {\n                    path = `${resolvedDevice}\\\\`;\n                }\n            }\n            const len = path.length;\n            let rootEnd = 0;\n            let device = '';\n            let isAbsolute = false;\n            const code = path.charCodeAt(0);\n            // Try to match a root\n            if (len === 1) {\n                if (isPathSeparator(code)) {\n                    // `path` contains just a path separator\n                    rootEnd = 1;\n                    isAbsolute = true;\n                }\n            }\n            else if (isPathSeparator(code)) {\n                // Possible UNC root\n                // If we started with a separator, we know we at least have an\n                // absolute path of some kind (UNC or otherwise)\n                isAbsolute = true;\n                if (isPathSeparator(path.charCodeAt(1))) {\n                    // Matched double path separator at beginning\n                    let j = 2;\n                    let last = j;\n                    // Match 1 or more non-path separators\n                    while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                        j++;\n                    }\n                    if (j < len && j !== last) {\n                        const firstPart = path.slice(last, j);\n                        // Matched!\n                        last = j;\n                        // Match 1 or more path separators\n                        while (j < len && isPathSeparator(path.charCodeAt(j))) {\n                            j++;\n                        }\n                        if (j < len && j !== last) {\n                            // Matched!\n                            last = j;\n                            // Match 1 or more non-path separators\n                            while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                                j++;\n                            }\n                            if (j === len || j !== last) {\n                                // We matched a UNC root\n                                device = `\\\\\\\\${firstPart}\\\\${path.slice(last, j)}`;\n                                rootEnd = j;\n                            }\n                        }\n                    }\n                }\n                else {\n                    rootEnd = 1;\n                }\n            }\n            else if (isWindowsDeviceRoot(code) &&\n                path.charCodeAt(1) === CHAR_COLON) {\n                // Possible device root\n                device = path.slice(0, 2);\n                rootEnd = 2;\n                if (len > 2 && isPathSeparator(path.charCodeAt(2))) {\n                    // Treat separator following drive name as an absolute path\n                    // indicator\n                    isAbsolute = true;\n                    rootEnd = 3;\n                }\n            }\n            if (device.length > 0) {\n                if (resolvedDevice.length > 0) {\n                    if (device.toLowerCase() !== resolvedDevice.toLowerCase()) {\n                        // This path points to another device so it is not applicable\n                        continue;\n                    }\n                }\n                else {\n                    resolvedDevice = device;\n                }\n            }\n            if (resolvedAbsolute) {\n                if (resolvedDevice.length > 0) {\n                    break;\n                }\n            }\n            else {\n                resolvedTail = `${path.slice(rootEnd)}\\\\${resolvedTail}`;\n                resolvedAbsolute = isAbsolute;\n                if (isAbsolute && resolvedDevice.length > 0) {\n                    break;\n                }\n            }\n        }\n        // At this point the path should be resolved to a full absolute path,\n        // but handle relative paths to be safe (might happen when process.cwd()\n        // fails)\n        // Normalize the tail path\n        resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\\\', isPathSeparator);\n        return resolvedAbsolute ?\n            `${resolvedDevice}\\\\${resolvedTail}` :\n            `${resolvedDevice}${resolvedTail}` || '.';\n    },\n    normalize(path) {\n        validateString(path, 'path');\n        const len = path.length;\n        if (len === 0) {\n            return '.';\n        }\n        let rootEnd = 0;\n        let device;\n        let isAbsolute = false;\n        const code = path.charCodeAt(0);\n        // Try to match a root\n        if (len === 1) {\n            // `path` contains just a single char, exit early to avoid\n            // unnecessary work\n            return isPosixPathSeparator(code) ? '\\\\' : path;\n        }\n        if (isPathSeparator(code)) {\n            // Possible UNC root\n            // If we started with a separator, we know we at least have an absolute\n            // path of some kind (UNC or otherwise)\n            isAbsolute = true;\n            if (isPathSeparator(path.charCodeAt(1))) {\n                // Matched double path separator at beginning\n                let j = 2;\n                let last = j;\n                // Match 1 or more non-path separators\n                while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                    j++;\n                }\n                if (j < len && j !== last) {\n                    const firstPart = path.slice(last, j);\n                    // Matched!\n                    last = j;\n                    // Match 1 or more path separators\n                    while (j < len && isPathSeparator(path.charCodeAt(j))) {\n                        j++;\n                    }\n                    if (j < len && j !== last) {\n                        // Matched!\n                        last = j;\n                        // Match 1 or more non-path separators\n                        while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                            j++;\n                        }\n                        if (j === len) {\n                            // We matched a UNC root only\n                            // Return the normalized version of the UNC root since there\n                            // is nothing left to process\n                            return `\\\\\\\\${firstPart}\\\\${path.slice(last)}\\\\`;\n                        }\n                        if (j !== last) {\n                            // We matched a UNC root with leftovers\n                            device = `\\\\\\\\${firstPart}\\\\${path.slice(last, j)}`;\n                            rootEnd = j;\n                        }\n                    }\n                }\n            }\n            else {\n                rootEnd = 1;\n            }\n        }\n        else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {\n            // Possible device root\n            device = path.slice(0, 2);\n            rootEnd = 2;\n            if (len > 2 && isPathSeparator(path.charCodeAt(2))) {\n                // Treat separator following drive name as an absolute path\n                // indicator\n                isAbsolute = true;\n                rootEnd = 3;\n            }\n        }\n        let tail = rootEnd < len ?\n            normalizeString(path.slice(rootEnd), !isAbsolute, '\\\\', isPathSeparator) :\n            '';\n        if (tail.length === 0 && !isAbsolute) {\n            tail = '.';\n        }\n        if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) {\n            tail += '\\\\';\n        }\n        if (device === undefined) {\n            return isAbsolute ? `\\\\${tail}` : tail;\n        }\n        return isAbsolute ? `${device}\\\\${tail}` : `${device}${tail}`;\n    },\n    isAbsolute(path) {\n        validateString(path, 'path');\n        const len = path.length;\n        if (len === 0) {\n            return false;\n        }\n        const code = path.charCodeAt(0);\n        return isPathSeparator(code) ||\n            // Possible device root\n            (len > 2 &&\n                isWindowsDeviceRoot(code) &&\n                path.charCodeAt(1) === CHAR_COLON &&\n                isPathSeparator(path.charCodeAt(2)));\n    },\n    join(...paths) {\n        if (paths.length === 0) {\n            return '.';\n        }\n        let joined;\n        let firstPart;\n        for (let i = 0; i < paths.length; ++i) {\n            const arg = paths[i];\n            validateString(arg, 'path');\n            if (arg.length > 0) {\n                if (joined === undefined) {\n                    joined = firstPart = arg;\n                }\n                else {\n                    joined += `\\\\${arg}`;\n                }\n            }\n        }\n        if (joined === undefined) {\n            return '.';\n        }\n        // Make sure that the joined path doesn't start with two slashes, because\n        // normalize() will mistake it for a UNC path then.\n        //\n        // This step is skipped when it is very clear that the user actually\n        // intended to point at a UNC path. This is assumed when the first\n        // non-empty string arguments starts with exactly two slashes followed by\n        // at least one more non-slash character.\n        //\n        // Note that for normalize() to treat a path as a UNC path it needs to\n        // have at least 2 components, so we don't filter for that here.\n        // This means that the user can use join to construct UNC paths from\n        // a server name and a share name; for example:\n        //   path.join('//server', 'share') -> '\\\\\\\\server\\\\share\\\\')\n        let needsReplace = true;\n        let slashCount = 0;\n        if (typeof firstPart === 'string' && isPathSeparator(firstPart.charCodeAt(0))) {\n            ++slashCount;\n            const firstLen = firstPart.length;\n            if (firstLen > 1 && isPathSeparator(firstPart.charCodeAt(1))) {\n                ++slashCount;\n                if (firstLen > 2) {\n                    if (isPathSeparator(firstPart.charCodeAt(2))) {\n                        ++slashCount;\n                    }\n                    else {\n                        // We matched a UNC path in the first part\n                        needsReplace = false;\n                    }\n                }\n            }\n        }\n        if (needsReplace) {\n            // Find any more consecutive slashes we need to replace\n            while (slashCount < joined.length &&\n                isPathSeparator(joined.charCodeAt(slashCount))) {\n                slashCount++;\n            }\n            // Replace the slashes if needed\n            if (slashCount >= 2) {\n                joined = `\\\\${joined.slice(slashCount)}`;\n            }\n        }\n        return win32.normalize(joined);\n    },\n    // It will solve the relative path from `from` to `to`, for instance:\n    //  from = 'C:\\\\orandea\\\\test\\\\aaa'\n    //  to = 'C:\\\\orandea\\\\impl\\\\bbb'\n    // The output of the function should be: '..\\\\..\\\\impl\\\\bbb'\n    relative(from, to) {\n        validateString(from, 'from');\n        validateString(to, 'to');\n        if (from === to) {\n            return '';\n        }\n        const fromOrig = win32.resolve(from);\n        const toOrig = win32.resolve(to);\n        if (fromOrig === toOrig) {\n            return '';\n        }\n        from = fromOrig.toLowerCase();\n        to = toOrig.toLowerCase();\n        if (from === to) {\n            return '';\n        }\n        // Trim any leading backslashes\n        let fromStart = 0;\n        while (fromStart < from.length &&\n            from.charCodeAt(fromStart) === CHAR_BACKWARD_SLASH) {\n            fromStart++;\n        }\n        // Trim trailing backslashes (applicable to UNC paths only)\n        let fromEnd = from.length;\n        while (fromEnd - 1 > fromStart &&\n            from.charCodeAt(fromEnd - 1) === CHAR_BACKWARD_SLASH) {\n            fromEnd--;\n        }\n        const fromLen = fromEnd - fromStart;\n        // Trim any leading backslashes\n        let toStart = 0;\n        while (toStart < to.length &&\n            to.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {\n            toStart++;\n        }\n        // Trim trailing backslashes (applicable to UNC paths only)\n        let toEnd = to.length;\n        while (toEnd - 1 > toStart &&\n            to.charCodeAt(toEnd - 1) === CHAR_BACKWARD_SLASH) {\n            toEnd--;\n        }\n        const toLen = toEnd - toStart;\n        // Compare paths to find the longest common path from root\n        const length = fromLen < toLen ? fromLen : toLen;\n        let lastCommonSep = -1;\n        let i = 0;\n        for (; i < length; i++) {\n            const fromCode = from.charCodeAt(fromStart + i);\n            if (fromCode !== to.charCodeAt(toStart + i)) {\n                break;\n            }\n            else if (fromCode === CHAR_BACKWARD_SLASH) {\n                lastCommonSep = i;\n            }\n        }\n        // We found a mismatch before the first common path separator was seen, so\n        // return the original `to`.\n        if (i !== length) {\n            if (lastCommonSep === -1) {\n                return toOrig;\n            }\n        }\n        else {\n            if (toLen > length) {\n                if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) {\n                    // We get here if `from` is the exact base path for `to`.\n                    // For example: from='C:\\\\foo\\\\bar'; to='C:\\\\foo\\\\bar\\\\baz'\n                    return toOrig.slice(toStart + i + 1);\n                }\n                if (i === 2) {\n                    // We get here if `from` is the device root.\n                    // For example: from='C:\\\\'; to='C:\\\\foo'\n                    return toOrig.slice(toStart + i);\n                }\n            }\n            if (fromLen > length) {\n                if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) {\n                    // We get here if `to` is the exact base path for `from`.\n                    // For example: from='C:\\\\foo\\\\bar'; to='C:\\\\foo'\n                    lastCommonSep = i;\n                }\n                else if (i === 2) {\n                    // We get here if `to` is the device root.\n                    // For example: from='C:\\\\foo\\\\bar'; to='C:\\\\'\n                    lastCommonSep = 3;\n                }\n            }\n            if (lastCommonSep === -1) {\n                lastCommonSep = 0;\n            }\n        }\n        let out = '';\n        // Generate the relative path based on the path difference between `to` and\n        // `from`\n        for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n            if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) {\n                out += out.length === 0 ? '..' : '\\\\..';\n            }\n        }\n        toStart += lastCommonSep;\n        // Lastly, append the rest of the destination (`to`) path that comes after\n        // the common path parts\n        if (out.length > 0) {\n            return `${out}${toOrig.slice(toStart, toEnd)}`;\n        }\n        if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {\n            ++toStart;\n        }\n        return toOrig.slice(toStart, toEnd);\n    },\n    toNamespacedPath(path) {\n        // Note: this will *probably* throw somewhere.\n        if (typeof path !== 'string' || path.length === 0) {\n            return path;\n        }\n        const resolvedPath = win32.resolve(path);\n        if (resolvedPath.length <= 2) {\n            return path;\n        }\n        if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) {\n            // Possible UNC root\n            if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) {\n                const code = resolvedPath.charCodeAt(2);\n                if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) {\n                    // Matched non-long UNC root, convert the path to a long UNC path\n                    return `\\\\\\\\?\\\\UNC\\\\${resolvedPath.slice(2)}`;\n                }\n            }\n        }\n        else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0)) &&\n            resolvedPath.charCodeAt(1) === CHAR_COLON &&\n            resolvedPath.charCodeAt(2) === CHAR_BACKWARD_SLASH) {\n            // Matched device root, convert the path to a long UNC path\n            return `\\\\\\\\?\\\\${resolvedPath}`;\n        }\n        return path;\n    },\n    dirname(path) {\n        validateString(path, 'path');\n        const len = path.length;\n        if (len === 0) {\n            return '.';\n        }\n        let rootEnd = -1;\n        let offset = 0;\n        const code = path.charCodeAt(0);\n        if (len === 1) {\n            // `path` contains just a path separator, exit early to avoid\n            // unnecessary work or a dot.\n            return isPathSeparator(code) ? path : '.';\n        }\n        // Try to match a root\n        if (isPathSeparator(code)) {\n            // Possible UNC root\n            rootEnd = offset = 1;\n            if (isPathSeparator(path.charCodeAt(1))) {\n                // Matched double path separator at beginning\n                let j = 2;\n                let last = j;\n                // Match 1 or more non-path separators\n                while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                    j++;\n                }\n                if (j < len && j !== last) {\n                    // Matched!\n                    last = j;\n                    // Match 1 or more path separators\n                    while (j < len && isPathSeparator(path.charCodeAt(j))) {\n                        j++;\n                    }\n                    if (j < len && j !== last) {\n                        // Matched!\n                        last = j;\n                        // Match 1 or more non-path separators\n                        while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                            j++;\n                        }\n                        if (j === len) {\n                            // We matched a UNC root only\n                            return path;\n                        }\n                        if (j !== last) {\n                            // We matched a UNC root with leftovers\n                            // Offset by 1 to include the separator after the UNC root to\n                            // treat it as a \"normal root\" on top of a (UNC) root\n                            rootEnd = offset = j + 1;\n                        }\n                    }\n                }\n            }\n            // Possible device root\n        }\n        else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {\n            rootEnd = len > 2 && isPathSeparator(path.charCodeAt(2)) ? 3 : 2;\n            offset = rootEnd;\n        }\n        let end = -1;\n        let matchedSlash = true;\n        for (let i = len - 1; i >= offset; --i) {\n            if (isPathSeparator(path.charCodeAt(i))) {\n                if (!matchedSlash) {\n                    end = i;\n                    break;\n                }\n            }\n            else {\n                // We saw the first non-path separator\n                matchedSlash = false;\n            }\n        }\n        if (end === -1) {\n            if (rootEnd === -1) {\n                return '.';\n            }\n            end = rootEnd;\n        }\n        return path.slice(0, end);\n    },\n    basename(path, ext) {\n        if (ext !== undefined) {\n            validateString(ext, 'ext');\n        }\n        validateString(path, 'path');\n        let start = 0;\n        let end = -1;\n        let matchedSlash = true;\n        let i;\n        // Check for a drive letter prefix so as not to mistake the following\n        // path separator as an extra separator at the end of the path that can be\n        // disregarded\n        if (path.length >= 2 &&\n            isWindowsDeviceRoot(path.charCodeAt(0)) &&\n            path.charCodeAt(1) === CHAR_COLON) {\n            start = 2;\n        }\n        if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {\n            if (ext === path) {\n                return '';\n            }\n            let extIdx = ext.length - 1;\n            let firstNonSlashEnd = -1;\n            for (i = path.length - 1; i >= start; --i) {\n                const code = path.charCodeAt(i);\n                if (isPathSeparator(code)) {\n                    // If we reached a path separator that was not part of a set of path\n                    // separators at the end of the string, stop now\n                    if (!matchedSlash) {\n                        start = i + 1;\n                        break;\n                    }\n                }\n                else {\n                    if (firstNonSlashEnd === -1) {\n                        // We saw the first non-path separator, remember this index in case\n                        // we need it if the extension ends up not matching\n                        matchedSlash = false;\n                        firstNonSlashEnd = i + 1;\n                    }\n                    if (extIdx >= 0) {\n                        // Try to match the explicit extension\n                        if (code === ext.charCodeAt(extIdx)) {\n                            if (--extIdx === -1) {\n                                // We matched the extension, so mark this as the end of our path\n                                // component\n                                end = i;\n                            }\n                        }\n                        else {\n                            // Extension does not match, so our result is the entire path\n                            // component\n                            extIdx = -1;\n                            end = firstNonSlashEnd;\n                        }\n                    }\n                }\n            }\n            if (start === end) {\n                end = firstNonSlashEnd;\n            }\n            else if (end === -1) {\n                end = path.length;\n            }\n            return path.slice(start, end);\n        }\n        for (i = path.length - 1; i >= start; --i) {\n            if (isPathSeparator(path.charCodeAt(i))) {\n                // If we reached a path separator that was not part of a set of path\n                // separators at the end of the string, stop now\n                if (!matchedSlash) {\n                    start = i + 1;\n                    break;\n                }\n            }\n            else if (end === -1) {\n                // We saw the first non-path separator, mark this as the end of our\n                // path component\n                matchedSlash = false;\n                end = i + 1;\n            }\n        }\n        if (end === -1) {\n            return '';\n        }\n        return path.slice(start, end);\n    },\n    extname(path) {\n        validateString(path, 'path');\n        let start = 0;\n        let startDot = -1;\n        let startPart = 0;\n        let end = -1;\n        let matchedSlash = true;\n        // Track the state of characters (if any) we see before our first dot and\n        // after any path separator we find\n        let preDotState = 0;\n        // Check for a drive letter prefix so as not to mistake the following\n        // path separator as an extra separator at the end of the path that can be\n        // disregarded\n        if (path.length >= 2 &&\n            path.charCodeAt(1) === CHAR_COLON &&\n            isWindowsDeviceRoot(path.charCodeAt(0))) {\n            start = startPart = 2;\n        }\n        for (let i = path.length - 1; i >= start; --i) {\n            const code = path.charCodeAt(i);\n            if (isPathSeparator(code)) {\n                // If we reached a path separator that was not part of a set of path\n                // separators at the end of the string, stop now\n                if (!matchedSlash) {\n                    startPart = i + 1;\n                    break;\n                }\n                continue;\n            }\n            if (end === -1) {\n                // We saw the first non-path separator, mark this as the end of our\n                // extension\n                matchedSlash = false;\n                end = i + 1;\n            }\n            if (code === CHAR_DOT) {\n                // If this is our first dot, mark it as the start of our extension\n                if (startDot === -1) {\n                    startDot = i;\n                }\n                else if (preDotState !== 1) {\n                    preDotState = 1;\n                }\n            }\n            else if (startDot !== -1) {\n                // We saw a non-dot and non-path separator before our dot, so we should\n                // have a good chance at having a non-empty extension\n                preDotState = -1;\n            }\n        }\n        if (startDot === -1 ||\n            end === -1 ||\n            // We saw a non-dot character immediately before the dot\n            preDotState === 0 ||\n            // The (right-most) trimmed path component is exactly '..'\n            (preDotState === 1 &&\n                startDot === end - 1 &&\n                startDot === startPart + 1)) {\n            return '';\n        }\n        return path.slice(startDot, end);\n    },\n    format: _format.bind(null, '\\\\'),\n    parse(path) {\n        validateString(path, 'path');\n        const ret = { root: '', dir: '', base: '', ext: '', name: '' };\n        if (path.length === 0) {\n            return ret;\n        }\n        const len = path.length;\n        let rootEnd = 0;\n        let code = path.charCodeAt(0);\n        if (len === 1) {\n            if (isPathSeparator(code)) {\n                // `path` contains just a path separator, exit early to avoid\n                // unnecessary work\n                ret.root = ret.dir = path;\n                return ret;\n            }\n            ret.base = ret.name = path;\n            return ret;\n        }\n        // Try to match a root\n        if (isPathSeparator(code)) {\n            // Possible UNC root\n            rootEnd = 1;\n            if (isPathSeparator(path.charCodeAt(1))) {\n                // Matched double path separator at beginning\n                let j = 2;\n                let last = j;\n                // Match 1 or more non-path separators\n                while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                    j++;\n                }\n                if (j < len && j !== last) {\n                    // Matched!\n                    last = j;\n                    // Match 1 or more path separators\n                    while (j < len && isPathSeparator(path.charCodeAt(j))) {\n                        j++;\n                    }\n                    if (j < len && j !== last) {\n                        // Matched!\n                        last = j;\n                        // Match 1 or more non-path separators\n                        while (j < len && !isPathSeparator(path.charCodeAt(j))) {\n                            j++;\n                        }\n                        if (j === len) {\n                            // We matched a UNC root only\n                            rootEnd = j;\n                        }\n                        else if (j !== last) {\n                            // We matched a UNC root with leftovers\n                            rootEnd = j + 1;\n                        }\n                    }\n                }\n            }\n        }\n        else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {\n            // Possible device root\n            if (len <= 2) {\n                // `path` contains just a drive root, exit early to avoid\n                // unnecessary work\n                ret.root = ret.dir = path;\n                return ret;\n            }\n            rootEnd = 2;\n            if (isPathSeparator(path.charCodeAt(2))) {\n                if (len === 3) {\n                    // `path` contains just a drive root, exit early to avoid\n                    // unnecessary work\n                    ret.root = ret.dir = path;\n                    return ret;\n                }\n                rootEnd = 3;\n            }\n        }\n        if (rootEnd > 0) {\n            ret.root = path.slice(0, rootEnd);\n        }\n        let startDot = -1;\n        let startPart = rootEnd;\n        let end = -1;\n        let matchedSlash = true;\n        let i = path.length - 1;\n        // Track the state of characters (if any) we see before our first dot and\n        // after any path separator we find\n        let preDotState = 0;\n        // Get non-dir info\n        for (; i >= rootEnd; --i) {\n            code = path.charCodeAt(i);\n            if (isPathSeparator(code)) {\n                // If we reached a path separator that was not part of a set of path\n                // separators at the end of the string, stop now\n                if (!matchedSlash) {\n                    startPart = i + 1;\n                    break;\n                }\n                continue;\n            }\n            if (end === -1) {\n                // We saw the first non-path separator, mark this as the end of our\n                // extension\n                matchedSlash = false;\n                end = i + 1;\n            }\n            if (code === CHAR_DOT) {\n                // If this is our first dot, mark it as the start of our extension\n                if (startDot === -1) {\n                    startDot = i;\n                }\n                else if (preDotState !== 1) {\n                    preDotState = 1;\n                }\n            }\n            else if (startDot !== -1) {\n                // We saw a non-dot and non-path separator before our dot, so we should\n                // have a good chance at having a non-empty extension\n                preDotState = -1;\n            }\n        }\n        if (end !== -1) {\n            if (startDot === -1 ||\n                // We saw a non-dot character immediately before the dot\n                preDotState === 0 ||\n                // The (right-most) trimmed path component is exactly '..'\n                (preDotState === 1 &&\n                    startDot === end - 1 &&\n                    startDot === startPart + 1)) {\n                ret.base = ret.name = path.slice(startPart, end);\n            }\n            else {\n                ret.name = path.slice(startPart, startDot);\n                ret.base = path.slice(startPart, end);\n                ret.ext = path.slice(startDot, end);\n            }\n        }\n        // If the directory is the root, use the entire root as the `dir` including\n        // the trailing slash if any (`C:\\abc` -> `C:\\`). Otherwise, strip out the\n        // trailing slash (`C:\\abc\\def` -> `C:\\abc`).\n        if (startPart > 0 && startPart !== rootEnd) {\n            ret.dir = path.slice(0, startPart - 1);\n        }\n        else {\n            ret.dir = ret.root;\n        }\n        return ret;\n    },\n    sep: '\\\\',\n    delimiter: ';',\n    win32: null,\n    posix: null\n};\nconst posixCwd = (() => {\n    if (platformIsWin32) {\n        // Converts Windows' backslash path separators to POSIX forward slashes\n        // and truncates any drive indicator\n        const regexp = /\\\\/g;\n        return () => {\n            const cwd = process.cwd().replace(regexp, '/');\n            return cwd.slice(cwd.indexOf('/'));\n        };\n    }\n    // We're already on POSIX, no need for any transformations\n    return () => process.cwd();\n})();\nexport const posix = {\n    // path.resolve([from ...], to)\n    resolve(...pathSegments) {\n        let resolvedPath = '';\n        let resolvedAbsolute = false;\n        for (let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n            const path = i >= 0 ? pathSegments[i] : posixCwd();\n            validateString(path, 'path');\n            // Skip empty entries\n            if (path.length === 0) {\n                continue;\n            }\n            resolvedPath = `${path}/${resolvedPath}`;\n            resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;\n        }\n        // At this point the path should be resolved to a full absolute path, but\n        // handle relative paths to be safe (might happen when process.cwd() fails)\n        // Normalize the path\n        resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', isPosixPathSeparator);\n        if (resolvedAbsolute) {\n            return `/${resolvedPath}`;\n        }\n        return resolvedPath.length > 0 ? resolvedPath : '.';\n    },\n    normalize(path) {\n        validateString(path, 'path');\n        if (path.length === 0) {\n            return '.';\n        }\n        const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;\n        const trailingSeparator = path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH;\n        // Normalize the path\n        path = normalizeString(path, !isAbsolute, '/', isPosixPathSeparator);\n        if (path.length === 0) {\n            if (isAbsolute) {\n                return '/';\n            }\n            return trailingSeparator ? './' : '.';\n        }\n        if (trailingSeparator) {\n            path += '/';\n        }\n        return isAbsolute ? `/${path}` : path;\n    },\n    isAbsolute(path) {\n        validateString(path, 'path');\n        return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH;\n    },\n    join(...paths) {\n        if (paths.length === 0) {\n            return '.';\n        }\n        let joined;\n        for (let i = 0; i < paths.length; ++i) {\n            const arg = paths[i];\n            validateString(arg, 'path');\n            if (arg.length > 0) {\n                if (joined === undefined) {\n                    joined = arg;\n                }\n                else {\n                    joined += `/${arg}`;\n                }\n            }\n        }\n        if (joined === undefined) {\n            return '.';\n        }\n        return posix.normalize(joined);\n    },\n    relative(from, to) {\n        validateString(from, 'from');\n        validateString(to, 'to');\n        if (from === to) {\n            return '';\n        }\n        // Trim leading forward slashes.\n        from = posix.resolve(from);\n        to = posix.resolve(to);\n        if (from === to) {\n            return '';\n        }\n        const fromStart = 1;\n        const fromEnd = from.length;\n        const fromLen = fromEnd - fromStart;\n        const toStart = 1;\n        const toLen = to.length - toStart;\n        // Compare paths to find the longest common path from root\n        const length = (fromLen < toLen ? fromLen : toLen);\n        let lastCommonSep = -1;\n        let i = 0;\n        for (; i < length; i++) {\n            const fromCode = from.charCodeAt(fromStart + i);\n            if (fromCode !== to.charCodeAt(toStart + i)) {\n                break;\n            }\n            else if (fromCode === CHAR_FORWARD_SLASH) {\n                lastCommonSep = i;\n            }\n        }\n        if (i === length) {\n            if (toLen > length) {\n                if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) {\n                    // We get here if `from` is the exact base path for `to`.\n                    // For example: from='/foo/bar'; to='/foo/bar/baz'\n                    return to.slice(toStart + i + 1);\n                }\n                if (i === 0) {\n                    // We get here if `from` is the root\n                    // For example: from='/'; to='/foo'\n                    return to.slice(toStart + i);\n                }\n            }\n            else if (fromLen > length) {\n                if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) {\n                    // We get here if `to` is the exact base path for `from`.\n                    // For example: from='/foo/bar/baz'; to='/foo/bar'\n                    lastCommonSep = i;\n                }\n                else if (i === 0) {\n                    // We get here if `to` is the root.\n                    // For example: from='/foo/bar'; to='/'\n                    lastCommonSep = 0;\n                }\n            }\n        }\n        let out = '';\n        // Generate the relative path based on the path difference between `to`\n        // and `from`.\n        for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n            if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) {\n                out += out.length === 0 ? '..' : '/..';\n            }\n        }\n        // Lastly, append the rest of the destination (`to`) path that comes after\n        // the common path parts.\n        return `${out}${to.slice(toStart + lastCommonSep)}`;\n    },\n    toNamespacedPath(path) {\n        // Non-op on posix systems\n        return path;\n    },\n    dirname(path) {\n        validateString(path, 'path');\n        if (path.length === 0) {\n            return '.';\n        }\n        const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH;\n        let end = -1;\n        let matchedSlash = true;\n        for (let i = path.length - 1; i >= 1; --i) {\n            if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) {\n                if (!matchedSlash) {\n                    end = i;\n                    break;\n                }\n            }\n            else {\n                // We saw the first non-path separator\n                matchedSlash = false;\n            }\n        }\n        if (end === -1) {\n            return hasRoot ? '/' : '.';\n        }\n        if (hasRoot && end === 1) {\n            return '//';\n        }\n        return path.slice(0, end);\n    },\n    basename(path, ext) {\n        if (ext !== undefined) {\n            validateString(ext, 'ext');\n        }\n        validateString(path, 'path');\n        let start = 0;\n        let end = -1;\n        let matchedSlash = true;\n        let i;\n        if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {\n            if (ext === path) {\n                return '';\n            }\n            let extIdx = ext.length - 1;\n            let firstNonSlashEnd = -1;\n            for (i = path.length - 1; i >= 0; --i) {\n                const code = path.charCodeAt(i);\n                if (code === CHAR_FORWARD_SLASH) {\n                    // If we reached a path separator that was not part of a set of path\n                    // separators at the end of the string, stop now\n                    if (!matchedSlash) {\n                        start = i + 1;\n                        break;\n                    }\n                }\n                else {\n                    if (firstNonSlashEnd === -1) {\n                        // We saw the first non-path separator, remember this index in case\n                        // we need it if the extension ends up not matching\n                        matchedSlash = false;\n                        firstNonSlashEnd = i + 1;\n                    }\n                    if (extIdx >= 0) {\n                        // Try to match the explicit extension\n                        if (code === ext.charCodeAt(extIdx)) {\n                            if (--extIdx === -1) {\n                                // We matched the extension, so mark this as the end of our path\n                                // component\n                                end = i;\n                            }\n                        }\n                        else {\n                            // Extension does not match, so our result is the entire path\n                            // component\n                            extIdx = -1;\n                            end = firstNonSlashEnd;\n                        }\n                    }\n                }\n            }\n            if (start === end) {\n                end = firstNonSlashEnd;\n            }\n            else if (end === -1) {\n                end = path.length;\n            }\n            return path.slice(start, end);\n        }\n        for (i = path.length - 1; i >= 0; --i) {\n            if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) {\n                // If we reached a path separator that was not part of a set of path\n                // separators at the end of the string, stop now\n                if (!matchedSlash) {\n                    start = i + 1;\n                    break;\n                }\n            }\n            else if (end === -1) {\n                // We saw the first non-path separator, mark this as the end of our\n                // path component\n                matchedSlash = false;\n                end = i + 1;\n            }\n        }\n        if (end === -1) {\n            return '';\n        }\n        return path.slice(start, end);\n    },\n    extname(path) {\n        validateString(path, 'path');\n        let startDot = -1;\n        let startPart = 0;\n        let end = -1;\n        let matchedSlash = true;\n        // Track the state of characters (if any) we see before our first dot and\n        // after any path separator we find\n        let preDotState = 0;\n        for (let i = path.length - 1; i >= 0; --i) {\n            const code = path.charCodeAt(i);\n            if (code === CHAR_FORWARD_SLASH) {\n                // If we reached a path separator that was not part of a set of path\n                // separators at the end of the string, stop now\n                if (!matchedSlash) {\n                    startPart = i + 1;\n                    break;\n                }\n                continue;\n            }\n            if (end === -1) {\n                // We saw the first non-path separator, mark this as the end of our\n                // extension\n                matchedSlash = false;\n                end = i + 1;\n            }\n            if (code === CHAR_DOT) {\n                // If this is our first dot, mark it as the start of our extension\n                if (startDot === -1) {\n                    startDot = i;\n                }\n                else if (preDotState !== 1) {\n                    preDotState = 1;\n                }\n            }\n            else if (startDot !== -1) {\n                // We saw a non-dot and non-path separator before our dot, so we should\n                // have a good chance at having a non-empty extension\n                preDotState = -1;\n            }\n        }\n        if (startDot === -1 ||\n            end === -1 ||\n            // We saw a non-dot character immediately before the dot\n            preDotState === 0 ||\n            // The (right-most) trimmed path component is exactly '..'\n            (preDotState === 1 &&\n                startDot === end - 1 &&\n                startDot === startPart + 1)) {\n            return '';\n        }\n        return path.slice(startDot, end);\n    },\n    format: _format.bind(null, '/'),\n    parse(path) {\n        validateString(path, 'path');\n        const ret = { root: '', dir: '', base: '', ext: '', name: '' };\n        if (path.length === 0) {\n            return ret;\n        }\n        const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;\n        let start;\n        if (isAbsolute) {\n            ret.root = '/';\n            start = 1;\n        }\n        else {\n            start = 0;\n        }\n        let startDot = -1;\n        let startPart = 0;\n        let end = -1;\n        let matchedSlash = true;\n        let i = path.length - 1;\n        // Track the state of characters (if any) we see before our first dot and\n        // after any path separator we find\n        let preDotState = 0;\n        // Get non-dir info\n        for (; i >= start; --i) {\n            const code = path.charCodeAt(i);\n            if (code === CHAR_FORWARD_SLASH) {\n                // If we reached a path separator that was not part of a set of path\n                // separators at the end of the string, stop now\n                if (!matchedSlash) {\n                    startPart = i + 1;\n                    break;\n                }\n                continue;\n            }\n            if (end === -1) {\n                // We saw the first non-path separator, mark this as the end of our\n                // extension\n                matchedSlash = false;\n                end = i + 1;\n            }\n            if (code === CHAR_DOT) {\n                // If this is our first dot, mark it as the start of our extension\n                if (startDot === -1) {\n                    startDot = i;\n                }\n                else if (preDotState !== 1) {\n                    preDotState = 1;\n                }\n            }\n            else if (startDot !== -1) {\n                // We saw a non-dot and non-path separator before our dot, so we should\n                // have a good chance at having a non-empty extension\n                preDotState = -1;\n            }\n        }\n        if (end !== -1) {\n            const start = startPart === 0 && isAbsolute ? 1 : startPart;\n            if (startDot === -1 ||\n                // We saw a non-dot character immediately before the dot\n                preDotState === 0 ||\n                // The (right-most) trimmed path component is exactly '..'\n                (preDotState === 1 &&\n                    startDot === end - 1 &&\n                    startDot === startPart + 1)) {\n                ret.base = ret.name = path.slice(start, end);\n            }\n            else {\n                ret.name = path.slice(start, startDot);\n                ret.base = path.slice(start, end);\n                ret.ext = path.slice(startDot, end);\n            }\n        }\n        if (startPart > 0) {\n            ret.dir = path.slice(0, startPart - 1);\n        }\n        else if (isAbsolute) {\n            ret.dir = '/';\n        }\n        return ret;\n    },\n    sep: '/',\n    delimiter: ':',\n    win32: null,\n    posix: null\n};\nposix.win32 = win32.win32 = win32;\nposix.posix = win32.posix = posix;\nexport const normalize = (platformIsWin32 ? win32.normalize : posix.normalize);\nexport const resolve = (platformIsWin32 ? win32.resolve : posix.resolve);\nexport const relative = (platformIsWin32 ? win32.relative : posix.relative);\nexport const dirname = (platformIsWin32 ? win32.dirname : posix.dirname);\nexport const basename = (platformIsWin32 ? win32.basename : posix.basename);\nexport const extname = (platformIsWin32 ? win32.extname : posix.extname);\nexport const sep = (platformIsWin32 ? win32.sep : posix.sep);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as paths from './path.js';\nimport { isWindows } from './platform.js';\nconst _schemePattern = /^\\w[\\w\\d+.-]*$/;\nconst _singleSlashStart = /^\\//;\nconst _doubleSlashStart = /^\\/\\//;\nfunction _validateUri(ret, _strict) {\n    // scheme, must be set\n    if (!ret.scheme && _strict) {\n        throw new Error(`[UriError]: Scheme is missing: {scheme: \"\", authority: \"${ret.authority}\", path: \"${ret.path}\", query: \"${ret.query}\", fragment: \"${ret.fragment}\"}`);\n    }\n    // scheme, https://tools.ietf.org/html/rfc3986#section-3.1\n    // ALPHA *( ALPHA / DIGIT / \"+\" / \"-\" / \".\" )\n    if (ret.scheme && !_schemePattern.test(ret.scheme)) {\n        throw new Error('[UriError]: Scheme contains illegal characters.');\n    }\n    // path, http://tools.ietf.org/html/rfc3986#section-3.3\n    // If a URI contains an authority component, then the path component\n    // must either be empty or begin with a slash (\"/\") character.  If a URI\n    // does not contain an authority component, then the path cannot begin\n    // with two slash characters (\"//\").\n    if (ret.path) {\n        if (ret.authority) {\n            if (!_singleSlashStart.test(ret.path)) {\n                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');\n            }\n        }\n        else {\n            if (_doubleSlashStart.test(ret.path)) {\n                throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters (\"//\")');\n            }\n        }\n    }\n}\n// for a while we allowed uris *without* schemes and this is the migration\n// for them, e.g. an uri without scheme and without strict-mode warns and falls\n// back to the file-scheme. that should cause the least carnage and still be a\n// clear warning\nfunction _schemeFix(scheme, _strict) {\n    if (!scheme && !_strict) {\n        return 'file';\n    }\n    return scheme;\n}\n// implements a bit of https://tools.ietf.org/html/rfc3986#section-5\nfunction _referenceResolution(scheme, path) {\n    // the slash-character is our 'default base' as we don't\n    // support constructing URIs relative to other URIs. This\n    // also means that we alter and potentially break paths.\n    // see https://tools.ietf.org/html/rfc3986#section-5.1.4\n    switch (scheme) {\n        case 'https':\n        case 'http':\n        case 'file':\n            if (!path) {\n                path = _slash;\n            }\n            else if (path[0] !== _slash) {\n                path = _slash + path;\n            }\n            break;\n    }\n    return path;\n}\nconst _empty = '';\nconst _slash = '/';\nconst _regexp = /^(([^:/?#]+?):)?(\\/\\/([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?/;\n/**\n * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.\n * This class is a simple parser which creates the basic component parts\n * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation\n * and encoding.\n *\n * ```txt\n *       foo://example.com:8042/over/there?name=ferret#nose\n *       \\_/   \\______________/\\_________/ \\_________/ \\__/\n *        |           |            |            |        |\n *     scheme     authority       path        query   fragment\n *        |   _____________________|__\n *       / \\ /                        \\\n *       urn:example:animal:ferret:nose\n * ```\n */\nexport class URI {\n    static isUri(thing) {\n        if (thing instanceof URI) {\n            return true;\n        }\n        if (!thing) {\n            return false;\n        }\n        return typeof thing.authority === 'string'\n            && typeof thing.fragment === 'string'\n            && typeof thing.path === 'string'\n            && typeof thing.query === 'string'\n            && typeof thing.scheme === 'string'\n            && typeof thing.fsPath === 'string'\n            && typeof thing.with === 'function'\n            && typeof thing.toString === 'function';\n    }\n    /**\n     * @internal\n     */\n    constructor(schemeOrData, authority, path, query, fragment, _strict = false) {\n        if (typeof schemeOrData === 'object') {\n            this.scheme = schemeOrData.scheme || _empty;\n            this.authority = schemeOrData.authority || _empty;\n            this.path = schemeOrData.path || _empty;\n            this.query = schemeOrData.query || _empty;\n            this.fragment = schemeOrData.fragment || _empty;\n            // no validation because it's this URI\n            // that creates uri components.\n            // _validateUri(this);\n        }\n        else {\n            this.scheme = _schemeFix(schemeOrData, _strict);\n            this.authority = authority || _empty;\n            this.path = _referenceResolution(this.scheme, path || _empty);\n            this.query = query || _empty;\n            this.fragment = fragment || _empty;\n            _validateUri(this, _strict);\n        }\n    }\n    // ---- filesystem path -----------------------\n    /**\n     * Returns a string representing the corresponding file system path of this URI.\n     * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the\n     * platform specific path separator.\n     *\n     * * Will *not* validate the path for invalid characters and semantics.\n     * * Will *not* look at the scheme of this URI.\n     * * The result shall *not* be used for display purposes but for accessing a file on disk.\n     *\n     *\n     * The *difference* to `URI#path` is the use of the platform specific separator and the handling\n     * of UNC paths. See the below sample of a file-uri with an authority (UNC path).\n     *\n     * ```ts\n        const u = URI.parse('file://server/c$/folder/file.txt')\n        u.authority === 'server'\n        u.path === '/shares/c$/file.txt'\n        u.fsPath === '\\\\server\\c$\\folder\\file.txt'\n    ```\n     *\n     * Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,\n     * namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working\n     * with URIs that represent files on disk (`file` scheme).\n     */\n    get fsPath() {\n        // if (this.scheme !== 'file') {\n        // \tconsole.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);\n        // }\n        return uriToFsPath(this, false);\n    }\n    // ---- modify to new -------------------------\n    with(change) {\n        if (!change) {\n            return this;\n        }\n        let { scheme, authority, path, query, fragment } = change;\n        if (scheme === undefined) {\n            scheme = this.scheme;\n        }\n        else if (scheme === null) {\n            scheme = _empty;\n        }\n        if (authority === undefined) {\n            authority = this.authority;\n        }\n        else if (authority === null) {\n            authority = _empty;\n        }\n        if (path === undefined) {\n            path = this.path;\n        }\n        else if (path === null) {\n            path = _empty;\n        }\n        if (query === undefined) {\n            query = this.query;\n        }\n        else if (query === null) {\n            query = _empty;\n        }\n        if (fragment === undefined) {\n            fragment = this.fragment;\n        }\n        else if (fragment === null) {\n            fragment = _empty;\n        }\n        if (scheme === this.scheme\n            && authority === this.authority\n            && path === this.path\n            && query === this.query\n            && fragment === this.fragment) {\n            return this;\n        }\n        return new Uri(scheme, authority, path, query, fragment);\n    }\n    // ---- parse & validate ------------------------\n    /**\n     * Creates a new URI from a string, e.g. `http://www.example.com/some/path`,\n     * `file:///usr/home`, or `scheme:with/path`.\n     *\n     * @param value A string which represents an URI (see `URI#toString`).\n     */\n    static parse(value, _strict = false) {\n        const match = _regexp.exec(value);\n        if (!match) {\n            return new Uri(_empty, _empty, _empty, _empty, _empty);\n        }\n        return new Uri(match[2] || _empty, percentDecode(match[4] || _empty), percentDecode(match[5] || _empty), percentDecode(match[7] || _empty), percentDecode(match[9] || _empty), _strict);\n    }\n    /**\n     * Creates a new URI from a file system path, e.g. `c:\\my\\files`,\n     * `/usr/home`, or `\\\\server\\share\\some\\path`.\n     *\n     * The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument\n     * as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**\n     * `URI.parse('file://' + path)` because the path might contain characters that are\n     * interpreted (# and ?). See the following sample:\n     * ```ts\n    const good = URI.file('/coding/c#/project1');\n    good.scheme === 'file';\n    good.path === '/coding/c#/project1';\n    good.fragment === '';\n    const bad = URI.parse('file://' + '/coding/c#/project1');\n    bad.scheme === 'file';\n    bad.path === '/coding/c'; // path is now broken\n    bad.fragment === '/project1';\n    ```\n     *\n     * @param path A file system path (see `URI#fsPath`)\n     */\n    static file(path) {\n        let authority = _empty;\n        // normalize to fwd-slashes on windows,\n        // on other systems bwd-slashes are valid\n        // filename character, eg /f\\oo/ba\\r.txt\n        if (isWindows) {\n            path = path.replace(/\\\\/g, _slash);\n        }\n        // check for authority as used in UNC shares\n        // or use the path as given\n        if (path[0] === _slash && path[1] === _slash) {\n            const idx = path.indexOf(_slash, 2);\n            if (idx === -1) {\n                authority = path.substring(2);\n                path = _slash;\n            }\n            else {\n                authority = path.substring(2, idx);\n                path = path.substring(idx) || _slash;\n            }\n        }\n        return new Uri('file', authority, path, _empty, _empty);\n    }\n    /**\n     * Creates new URI from uri components.\n     *\n     * Unless `strict` is `true` the scheme is defaults to be `file`. This function performs\n     * validation and should be used for untrusted uri components retrieved from storage,\n     * user input, command arguments etc\n     */\n    static from(components, strict) {\n        const result = new Uri(components.scheme, components.authority, components.path, components.query, components.fragment, strict);\n        return result;\n    }\n    /**\n     * Join a URI path with path fragments and normalizes the resulting path.\n     *\n     * @param uri The input URI.\n     * @param pathFragment The path fragment to add to the URI path.\n     * @returns The resulting URI.\n     */\n    static joinPath(uri, ...pathFragment) {\n        if (!uri.path) {\n            throw new Error(`[UriError]: cannot call joinPath on URI without path`);\n        }\n        let newPath;\n        if (isWindows && uri.scheme === 'file') {\n            newPath = URI.file(paths.win32.join(uriToFsPath(uri, true), ...pathFragment)).path;\n        }\n        else {\n            newPath = paths.posix.join(uri.path, ...pathFragment);\n        }\n        return uri.with({ path: newPath });\n    }\n    // ---- printing/externalize ---------------------------\n    /**\n     * Creates a string representation for this URI. It's guaranteed that calling\n     * `URI.parse` with the result of this function creates an URI which is equal\n     * to this URI.\n     *\n     * * The result shall *not* be used for display purposes but for externalization or transport.\n     * * The result will be encoded using the percentage encoding and encoding happens mostly\n     * ignore the scheme-specific encoding rules.\n     *\n     * @param skipEncoding Do not encode the result, default is `false`\n     */\n    toString(skipEncoding = false) {\n        return _asFormatted(this, skipEncoding);\n    }\n    toJSON() {\n        return this;\n    }\n    static revive(data) {\n        var _a, _b;\n        if (!data) {\n            return data;\n        }\n        else if (data instanceof URI) {\n            return data;\n        }\n        else {\n            const result = new Uri(data);\n            result._formatted = (_a = data.external) !== null && _a !== void 0 ? _a : null;\n            result._fsPath = data._sep === _pathSepMarker ? (_b = data.fsPath) !== null && _b !== void 0 ? _b : null : null;\n            return result;\n        }\n    }\n}\nconst _pathSepMarker = isWindows ? 1 : undefined;\n// This class exists so that URI is compatible with vscode.Uri (API).\nclass Uri extends URI {\n    constructor() {\n        super(...arguments);\n        this._formatted = null;\n        this._fsPath = null;\n    }\n    get fsPath() {\n        if (!this._fsPath) {\n            this._fsPath = uriToFsPath(this, false);\n        }\n        return this._fsPath;\n    }\n    toString(skipEncoding = false) {\n        if (!skipEncoding) {\n            if (!this._formatted) {\n                this._formatted = _asFormatted(this, false);\n            }\n            return this._formatted;\n        }\n        else {\n            // we don't cache that\n            return _asFormatted(this, true);\n        }\n    }\n    toJSON() {\n        const res = {\n            $mid: 1 /* MarshalledId.Uri */\n        };\n        // cached state\n        if (this._fsPath) {\n            res.fsPath = this._fsPath;\n            res._sep = _pathSepMarker;\n        }\n        if (this._formatted) {\n            res.external = this._formatted;\n        }\n        //--- uri components\n        if (this.path) {\n            res.path = this.path;\n        }\n        // TODO\n        // this isn't correct and can violate the UriComponents contract but\n        // this is part of the vscode.Uri API and we shouldn't change how that\n        // works anymore\n        if (this.scheme) {\n            res.scheme = this.scheme;\n        }\n        if (this.authority) {\n            res.authority = this.authority;\n        }\n        if (this.query) {\n            res.query = this.query;\n        }\n        if (this.fragment) {\n            res.fragment = this.fragment;\n        }\n        return res;\n    }\n}\n// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2\nconst encodeTable = {\n    [58 /* CharCode.Colon */]: '%3A',\n    [47 /* CharCode.Slash */]: '%2F',\n    [63 /* CharCode.QuestionMark */]: '%3F',\n    [35 /* CharCode.Hash */]: '%23',\n    [91 /* CharCode.OpenSquareBracket */]: '%5B',\n    [93 /* CharCode.CloseSquareBracket */]: '%5D',\n    [64 /* CharCode.AtSign */]: '%40',\n    [33 /* CharCode.ExclamationMark */]: '%21',\n    [36 /* CharCode.DollarSign */]: '%24',\n    [38 /* CharCode.Ampersand */]: '%26',\n    [39 /* CharCode.SingleQuote */]: '%27',\n    [40 /* CharCode.OpenParen */]: '%28',\n    [41 /* CharCode.CloseParen */]: '%29',\n    [42 /* CharCode.Asterisk */]: '%2A',\n    [43 /* CharCode.Plus */]: '%2B',\n    [44 /* CharCode.Comma */]: '%2C',\n    [59 /* CharCode.Semicolon */]: '%3B',\n    [61 /* CharCode.Equals */]: '%3D',\n    [32 /* CharCode.Space */]: '%20',\n};\nfunction encodeURIComponentFast(uriComponent, isPath, isAuthority) {\n    let res = undefined;\n    let nativeEncodePos = -1;\n    for (let pos = 0; pos < uriComponent.length; pos++) {\n        const code = uriComponent.charCodeAt(pos);\n        // unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3\n        if ((code >= 97 /* CharCode.a */ && code <= 122 /* CharCode.z */)\n            || (code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */)\n            || (code >= 48 /* CharCode.Digit0 */ && code <= 57 /* CharCode.Digit9 */)\n            || code === 45 /* CharCode.Dash */\n            || code === 46 /* CharCode.Period */\n            || code === 95 /* CharCode.Underline */\n            || code === 126 /* CharCode.Tilde */\n            || (isPath && code === 47 /* CharCode.Slash */)\n            || (isAuthority && code === 91 /* CharCode.OpenSquareBracket */)\n            || (isAuthority && code === 93 /* CharCode.CloseSquareBracket */)\n            || (isAuthority && code === 58 /* CharCode.Colon */)) {\n            // check if we are delaying native encode\n            if (nativeEncodePos !== -1) {\n                res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));\n                nativeEncodePos = -1;\n            }\n            // check if we write into a new string (by default we try to return the param)\n            if (res !== undefined) {\n                res += uriComponent.charAt(pos);\n            }\n        }\n        else {\n            // encoding needed, we need to allocate a new string\n            if (res === undefined) {\n                res = uriComponent.substr(0, pos);\n            }\n            // check with default table first\n            const escaped = encodeTable[code];\n            if (escaped !== undefined) {\n                // check if we are delaying native encode\n                if (nativeEncodePos !== -1) {\n                    res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));\n                    nativeEncodePos = -1;\n                }\n                // append escaped variant to result\n                res += escaped;\n            }\n            else if (nativeEncodePos === -1) {\n                // use native encode only when needed\n                nativeEncodePos = pos;\n            }\n        }\n    }\n    if (nativeEncodePos !== -1) {\n        res += encodeURIComponent(uriComponent.substring(nativeEncodePos));\n    }\n    return res !== undefined ? res : uriComponent;\n}\nfunction encodeURIComponentMinimal(path) {\n    let res = undefined;\n    for (let pos = 0; pos < path.length; pos++) {\n        const code = path.charCodeAt(pos);\n        if (code === 35 /* CharCode.Hash */ || code === 63 /* CharCode.QuestionMark */) {\n            if (res === undefined) {\n                res = path.substr(0, pos);\n            }\n            res += encodeTable[code];\n        }\n        else {\n            if (res !== undefined) {\n                res += path[pos];\n            }\n        }\n    }\n    return res !== undefined ? res : path;\n}\n/**\n * Compute `fsPath` for the given uri\n */\nexport function uriToFsPath(uri, keepDriveLetterCasing) {\n    let value;\n    if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {\n        // unc path: file://shares/c$/far/boo\n        value = `//${uri.authority}${uri.path}`;\n    }\n    else if (uri.path.charCodeAt(0) === 47 /* CharCode.Slash */\n        && (uri.path.charCodeAt(1) >= 65 /* CharCode.A */ && uri.path.charCodeAt(1) <= 90 /* CharCode.Z */ || uri.path.charCodeAt(1) >= 97 /* CharCode.a */ && uri.path.charCodeAt(1) <= 122 /* CharCode.z */)\n        && uri.path.charCodeAt(2) === 58 /* CharCode.Colon */) {\n        if (!keepDriveLetterCasing) {\n            // windows drive letter: file:///c:/far/boo\n            value = uri.path[1].toLowerCase() + uri.path.substr(2);\n        }\n        else {\n            value = uri.path.substr(1);\n        }\n    }\n    else {\n        // other path\n        value = uri.path;\n    }\n    if (isWindows) {\n        value = value.replace(/\\//g, '\\\\');\n    }\n    return value;\n}\n/**\n * Create the external version of a uri\n */\nfunction _asFormatted(uri, skipEncoding) {\n    const encoder = !skipEncoding\n        ? encodeURIComponentFast\n        : encodeURIComponentMinimal;\n    let res = '';\n    let { scheme, authority, path, query, fragment } = uri;\n    if (scheme) {\n        res += scheme;\n        res += ':';\n    }\n    if (authority || scheme === 'file') {\n        res += _slash;\n        res += _slash;\n    }\n    if (authority) {\n        let idx = authority.indexOf('@');\n        if (idx !== -1) {\n            // @\n            const userinfo = authority.substr(0, idx);\n            authority = authority.substr(idx + 1);\n            idx = userinfo.lastIndexOf(':');\n            if (idx === -1) {\n                res += encoder(userinfo, false, false);\n            }\n            else {\n                // :@\n                res += encoder(userinfo.substr(0, idx), false, false);\n                res += ':';\n                res += encoder(userinfo.substr(idx + 1), false, true);\n            }\n            res += '@';\n        }\n        authority = authority.toLowerCase();\n        idx = authority.lastIndexOf(':');\n        if (idx === -1) {\n            res += encoder(authority, false, true);\n        }\n        else {\n            // :\n            res += encoder(authority.substr(0, idx), false, true);\n            res += authority.substr(idx);\n        }\n    }\n    if (path) {\n        // lower-case windows drive letters in /C:/fff or C:/fff\n        if (path.length >= 3 && path.charCodeAt(0) === 47 /* CharCode.Slash */ && path.charCodeAt(2) === 58 /* CharCode.Colon */) {\n            const code = path.charCodeAt(1);\n            if (code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */) {\n                path = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // \"/c:\".length === 3\n            }\n        }\n        else if (path.length >= 2 && path.charCodeAt(1) === 58 /* CharCode.Colon */) {\n            const code = path.charCodeAt(0);\n            if (code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */) {\n                path = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // \"/c:\".length === 3\n            }\n        }\n        // encode the rest of the path\n        res += encoder(path, true, false);\n    }\n    if (query) {\n        res += '?';\n        res += encoder(query, false, false);\n    }\n    if (fragment) {\n        res += '#';\n        res += !skipEncoding ? encodeURIComponentFast(fragment, false, false) : fragment;\n    }\n    return res;\n}\n// --- decode\nfunction decodeURIComponentGraceful(str) {\n    try {\n        return decodeURIComponent(str);\n    }\n    catch (_a) {\n        if (str.length > 3) {\n            return str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));\n        }\n        else {\n            return str;\n        }\n    }\n}\nconst _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;\nfunction percentDecode(str) {\n    if (!str.match(_rEncodedAsHex)) {\n        return str;\n    }\n    return str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match));\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * A position in the editor.\n */\nexport class Position {\n    constructor(lineNumber, column) {\n        this.lineNumber = lineNumber;\n        this.column = column;\n    }\n    /**\n     * Create a new position from this position.\n     *\n     * @param newLineNumber new line number\n     * @param newColumn new column\n     */\n    with(newLineNumber = this.lineNumber, newColumn = this.column) {\n        if (newLineNumber === this.lineNumber && newColumn === this.column) {\n            return this;\n        }\n        else {\n            return new Position(newLineNumber, newColumn);\n        }\n    }\n    /**\n     * Derive a new position from this position.\n     *\n     * @param deltaLineNumber line number delta\n     * @param deltaColumn column delta\n     */\n    delta(deltaLineNumber = 0, deltaColumn = 0) {\n        return this.with(this.lineNumber + deltaLineNumber, this.column + deltaColumn);\n    }\n    /**\n     * Test if this position equals other position\n     */\n    equals(other) {\n        return Position.equals(this, other);\n    }\n    /**\n     * Test if position `a` equals position `b`\n     */\n    static equals(a, b) {\n        if (!a && !b) {\n            return true;\n        }\n        return (!!a &&\n            !!b &&\n            a.lineNumber === b.lineNumber &&\n            a.column === b.column);\n    }\n    /**\n     * Test if this position is before other position.\n     * If the two positions are equal, the result will be false.\n     */\n    isBefore(other) {\n        return Position.isBefore(this, other);\n    }\n    /**\n     * Test if position `a` is before position `b`.\n     * If the two positions are equal, the result will be false.\n     */\n    static isBefore(a, b) {\n        if (a.lineNumber < b.lineNumber) {\n            return true;\n        }\n        if (b.lineNumber < a.lineNumber) {\n            return false;\n        }\n        return a.column < b.column;\n    }\n    /**\n     * Test if this position is before other position.\n     * If the two positions are equal, the result will be true.\n     */\n    isBeforeOrEqual(other) {\n        return Position.isBeforeOrEqual(this, other);\n    }\n    /**\n     * Test if position `a` is before position `b`.\n     * If the two positions are equal, the result will be true.\n     */\n    static isBeforeOrEqual(a, b) {\n        if (a.lineNumber < b.lineNumber) {\n            return true;\n        }\n        if (b.lineNumber < a.lineNumber) {\n            return false;\n        }\n        return a.column <= b.column;\n    }\n    /**\n     * A function that compares positions, useful for sorting\n     */\n    static compare(a, b) {\n        const aLineNumber = a.lineNumber | 0;\n        const bLineNumber = b.lineNumber | 0;\n        if (aLineNumber === bLineNumber) {\n            const aColumn = a.column | 0;\n            const bColumn = b.column | 0;\n            return aColumn - bColumn;\n        }\n        return aLineNumber - bLineNumber;\n    }\n    /**\n     * Clone this position.\n     */\n    clone() {\n        return new Position(this.lineNumber, this.column);\n    }\n    /**\n     * Convert to a human-readable representation.\n     */\n    toString() {\n        return '(' + this.lineNumber + ',' + this.column + ')';\n    }\n    // ---\n    /**\n     * Create a `Position` from an `IPosition`.\n     */\n    static lift(pos) {\n        return new Position(pos.lineNumber, pos.column);\n    }\n    /**\n     * Test if `obj` is an `IPosition`.\n     */\n    static isIPosition(obj) {\n        return (obj\n            && (typeof obj.lineNumber === 'number')\n            && (typeof obj.column === 'number'));\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Position } from './position.js';\n/**\n * A range in the editor. (startLineNumber,startColumn) is <= (endLineNumber,endColumn)\n */\nexport class Range {\n    constructor(startLineNumber, startColumn, endLineNumber, endColumn) {\n        if ((startLineNumber > endLineNumber) || (startLineNumber === endLineNumber && startColumn > endColumn)) {\n            this.startLineNumber = endLineNumber;\n            this.startColumn = endColumn;\n            this.endLineNumber = startLineNumber;\n            this.endColumn = startColumn;\n        }\n        else {\n            this.startLineNumber = startLineNumber;\n            this.startColumn = startColumn;\n            this.endLineNumber = endLineNumber;\n            this.endColumn = endColumn;\n        }\n    }\n    /**\n     * Test if this range is empty.\n     */\n    isEmpty() {\n        return Range.isEmpty(this);\n    }\n    /**\n     * Test if `range` is empty.\n     */\n    static isEmpty(range) {\n        return (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn);\n    }\n    /**\n     * Test if position is in this range. If the position is at the edges, will return true.\n     */\n    containsPosition(position) {\n        return Range.containsPosition(this, position);\n    }\n    /**\n     * Test if `position` is in `range`. If the position is at the edges, will return true.\n     */\n    static containsPosition(range, position) {\n        if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {\n            return false;\n        }\n        if (position.lineNumber === range.startLineNumber && position.column < range.startColumn) {\n            return false;\n        }\n        if (position.lineNumber === range.endLineNumber && position.column > range.endColumn) {\n            return false;\n        }\n        return true;\n    }\n    /**\n     * Test if `position` is in `range`. If the position is at the edges, will return false.\n     * @internal\n     */\n    static strictContainsPosition(range, position) {\n        if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {\n            return false;\n        }\n        if (position.lineNumber === range.startLineNumber && position.column <= range.startColumn) {\n            return false;\n        }\n        if (position.lineNumber === range.endLineNumber && position.column >= range.endColumn) {\n            return false;\n        }\n        return true;\n    }\n    /**\n     * Test if range is in this range. If the range is equal to this range, will return true.\n     */\n    containsRange(range) {\n        return Range.containsRange(this, range);\n    }\n    /**\n     * Test if `otherRange` is in `range`. If the ranges are equal, will return true.\n     */\n    static containsRange(range, otherRange) {\n        if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {\n            return false;\n        }\n        if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {\n            return false;\n        }\n        if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn < range.startColumn) {\n            return false;\n        }\n        if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn > range.endColumn) {\n            return false;\n        }\n        return true;\n    }\n    /**\n     * Test if `range` is strictly in this range. `range` must start after and end before this range for the result to be true.\n     */\n    strictContainsRange(range) {\n        return Range.strictContainsRange(this, range);\n    }\n    /**\n     * Test if `otherRange` is strictly in `range` (must start after, and end before). If the ranges are equal, will return false.\n     */\n    static strictContainsRange(range, otherRange) {\n        if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {\n            return false;\n        }\n        if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {\n            return false;\n        }\n        if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn <= range.startColumn) {\n            return false;\n        }\n        if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn >= range.endColumn) {\n            return false;\n        }\n        return true;\n    }\n    /**\n     * A reunion of the two ranges.\n     * The smallest position will be used as the start point, and the largest one as the end point.\n     */\n    plusRange(range) {\n        return Range.plusRange(this, range);\n    }\n    /**\n     * A reunion of the two ranges.\n     * The smallest position will be used as the start point, and the largest one as the end point.\n     */\n    static plusRange(a, b) {\n        let startLineNumber;\n        let startColumn;\n        let endLineNumber;\n        let endColumn;\n        if (b.startLineNumber < a.startLineNumber) {\n            startLineNumber = b.startLineNumber;\n            startColumn = b.startColumn;\n        }\n        else if (b.startLineNumber === a.startLineNumber) {\n            startLineNumber = b.startLineNumber;\n            startColumn = Math.min(b.startColumn, a.startColumn);\n        }\n        else {\n            startLineNumber = a.startLineNumber;\n            startColumn = a.startColumn;\n        }\n        if (b.endLineNumber > a.endLineNumber) {\n            endLineNumber = b.endLineNumber;\n            endColumn = b.endColumn;\n        }\n        else if (b.endLineNumber === a.endLineNumber) {\n            endLineNumber = b.endLineNumber;\n            endColumn = Math.max(b.endColumn, a.endColumn);\n        }\n        else {\n            endLineNumber = a.endLineNumber;\n            endColumn = a.endColumn;\n        }\n        return new Range(startLineNumber, startColumn, endLineNumber, endColumn);\n    }\n    /**\n     * A intersection of the two ranges.\n     */\n    intersectRanges(range) {\n        return Range.intersectRanges(this, range);\n    }\n    /**\n     * A intersection of the two ranges.\n     */\n    static intersectRanges(a, b) {\n        let resultStartLineNumber = a.startLineNumber;\n        let resultStartColumn = a.startColumn;\n        let resultEndLineNumber = a.endLineNumber;\n        let resultEndColumn = a.endColumn;\n        const otherStartLineNumber = b.startLineNumber;\n        const otherStartColumn = b.startColumn;\n        const otherEndLineNumber = b.endLineNumber;\n        const otherEndColumn = b.endColumn;\n        if (resultStartLineNumber < otherStartLineNumber) {\n            resultStartLineNumber = otherStartLineNumber;\n            resultStartColumn = otherStartColumn;\n        }\n        else if (resultStartLineNumber === otherStartLineNumber) {\n            resultStartColumn = Math.max(resultStartColumn, otherStartColumn);\n        }\n        if (resultEndLineNumber > otherEndLineNumber) {\n            resultEndLineNumber = otherEndLineNumber;\n            resultEndColumn = otherEndColumn;\n        }\n        else if (resultEndLineNumber === otherEndLineNumber) {\n            resultEndColumn = Math.min(resultEndColumn, otherEndColumn);\n        }\n        // Check if selection is now empty\n        if (resultStartLineNumber > resultEndLineNumber) {\n            return null;\n        }\n        if (resultStartLineNumber === resultEndLineNumber && resultStartColumn > resultEndColumn) {\n            return null;\n        }\n        return new Range(resultStartLineNumber, resultStartColumn, resultEndLineNumber, resultEndColumn);\n    }\n    /**\n     * Test if this range equals other.\n     */\n    equalsRange(other) {\n        return Range.equalsRange(this, other);\n    }\n    /**\n     * Test if range `a` equals `b`.\n     */\n    static equalsRange(a, b) {\n        if (!a && !b) {\n            return true;\n        }\n        return (!!a &&\n            !!b &&\n            a.startLineNumber === b.startLineNumber &&\n            a.startColumn === b.startColumn &&\n            a.endLineNumber === b.endLineNumber &&\n            a.endColumn === b.endColumn);\n    }\n    /**\n     * Return the end position (which will be after or equal to the start position)\n     */\n    getEndPosition() {\n        return Range.getEndPosition(this);\n    }\n    /**\n     * Return the end position (which will be after or equal to the start position)\n     */\n    static getEndPosition(range) {\n        return new Position(range.endLineNumber, range.endColumn);\n    }\n    /**\n     * Return the start position (which will be before or equal to the end position)\n     */\n    getStartPosition() {\n        return Range.getStartPosition(this);\n    }\n    /**\n     * Return the start position (which will be before or equal to the end position)\n     */\n    static getStartPosition(range) {\n        return new Position(range.startLineNumber, range.startColumn);\n    }\n    /**\n     * Transform to a user presentable string representation.\n     */\n    toString() {\n        return '[' + this.startLineNumber + ',' + this.startColumn + ' -> ' + this.endLineNumber + ',' + this.endColumn + ']';\n    }\n    /**\n     * Create a new range using this range's start position, and using endLineNumber and endColumn as the end position.\n     */\n    setEndPosition(endLineNumber, endColumn) {\n        return new Range(this.startLineNumber, this.startColumn, endLineNumber, endColumn);\n    }\n    /**\n     * Create a new range using this range's end position, and using startLineNumber and startColumn as the start position.\n     */\n    setStartPosition(startLineNumber, startColumn) {\n        return new Range(startLineNumber, startColumn, this.endLineNumber, this.endColumn);\n    }\n    /**\n     * Create a new empty range using this range's start position.\n     */\n    collapseToStart() {\n        return Range.collapseToStart(this);\n    }\n    /**\n     * Create a new empty range using this range's start position.\n     */\n    static collapseToStart(range) {\n        return new Range(range.startLineNumber, range.startColumn, range.startLineNumber, range.startColumn);\n    }\n    /**\n     * Create a new empty range using this range's end position.\n     */\n    collapseToEnd() {\n        return Range.collapseToEnd(this);\n    }\n    /**\n     * Create a new empty range using this range's end position.\n     */\n    static collapseToEnd(range) {\n        return new Range(range.endLineNumber, range.endColumn, range.endLineNumber, range.endColumn);\n    }\n    /**\n     * Moves the range by the given amount of lines.\n     */\n    delta(lineCount) {\n        return new Range(this.startLineNumber + lineCount, this.startColumn, this.endLineNumber + lineCount, this.endColumn);\n    }\n    // ---\n    static fromPositions(start, end = start) {\n        return new Range(start.lineNumber, start.column, end.lineNumber, end.column);\n    }\n    static lift(range) {\n        if (!range) {\n            return null;\n        }\n        return new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);\n    }\n    /**\n     * Test if `obj` is an `IRange`.\n     */\n    static isIRange(obj) {\n        return (obj\n            && (typeof obj.startLineNumber === 'number')\n            && (typeof obj.startColumn === 'number')\n            && (typeof obj.endLineNumber === 'number')\n            && (typeof obj.endColumn === 'number'));\n    }\n    /**\n     * Test if the two ranges are touching in any way.\n     */\n    static areIntersectingOrTouching(a, b) {\n        // Check if `a` is before `b`\n        if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn < b.startColumn)) {\n            return false;\n        }\n        // Check if `b` is before `a`\n        if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn < a.startColumn)) {\n            return false;\n        }\n        // These ranges must intersect\n        return true;\n    }\n    /**\n     * Test if the two ranges are intersecting. If the ranges are touching it returns true.\n     */\n    static areIntersecting(a, b) {\n        // Check if `a` is before `b`\n        if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn <= b.startColumn)) {\n            return false;\n        }\n        // Check if `b` is before `a`\n        if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn <= a.startColumn)) {\n            return false;\n        }\n        // These ranges must intersect\n        return true;\n    }\n    /**\n     * A function that compares ranges, useful for sorting ranges\n     * It will first compare ranges on the startPosition and then on the endPosition\n     */\n    static compareRangesUsingStarts(a, b) {\n        if (a && b) {\n            const aStartLineNumber = a.startLineNumber | 0;\n            const bStartLineNumber = b.startLineNumber | 0;\n            if (aStartLineNumber === bStartLineNumber) {\n                const aStartColumn = a.startColumn | 0;\n                const bStartColumn = b.startColumn | 0;\n                if (aStartColumn === bStartColumn) {\n                    const aEndLineNumber = a.endLineNumber | 0;\n                    const bEndLineNumber = b.endLineNumber | 0;\n                    if (aEndLineNumber === bEndLineNumber) {\n                        const aEndColumn = a.endColumn | 0;\n                        const bEndColumn = b.endColumn | 0;\n                        return aEndColumn - bEndColumn;\n                    }\n                    return aEndLineNumber - bEndLineNumber;\n                }\n                return aStartColumn - bStartColumn;\n            }\n            return aStartLineNumber - bStartLineNumber;\n        }\n        const aExists = (a ? 1 : 0);\n        const bExists = (b ? 1 : 0);\n        return aExists - bExists;\n    }\n    /**\n     * A function that compares ranges, useful for sorting ranges\n     * It will first compare ranges on the endPosition and then on the startPosition\n     */\n    static compareRangesUsingEnds(a, b) {\n        if (a.endLineNumber === b.endLineNumber) {\n            if (a.endColumn === b.endColumn) {\n                if (a.startLineNumber === b.startLineNumber) {\n                    return a.startColumn - b.startColumn;\n                }\n                return a.startLineNumber - b.startLineNumber;\n            }\n            return a.endColumn - b.endColumn;\n        }\n        return a.endLineNumber - b.endLineNumber;\n    }\n    /**\n     * Test if the range spans multiple lines.\n     */\n    static spansMultipleLines(range) {\n        return range.endLineNumber > range.startLineNumber;\n    }\n    toJSON() {\n        return this;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Position } from './position.js';\nimport { Range } from './range.js';\n/**\n * A selection in the editor.\n * The selection is a range that has an orientation.\n */\nexport class Selection extends Range {\n    constructor(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn) {\n        super(selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn);\n        this.selectionStartLineNumber = selectionStartLineNumber;\n        this.selectionStartColumn = selectionStartColumn;\n        this.positionLineNumber = positionLineNumber;\n        this.positionColumn = positionColumn;\n    }\n    /**\n     * Transform to a human-readable representation.\n     */\n    toString() {\n        return '[' + this.selectionStartLineNumber + ',' + this.selectionStartColumn + ' -> ' + this.positionLineNumber + ',' + this.positionColumn + ']';\n    }\n    /**\n     * Test if equals other selection.\n     */\n    equalsSelection(other) {\n        return (Selection.selectionsEqual(this, other));\n    }\n    /**\n     * Test if the two selections are equal.\n     */\n    static selectionsEqual(a, b) {\n        return (a.selectionStartLineNumber === b.selectionStartLineNumber &&\n            a.selectionStartColumn === b.selectionStartColumn &&\n            a.positionLineNumber === b.positionLineNumber &&\n            a.positionColumn === b.positionColumn);\n    }\n    /**\n     * Get directions (LTR or RTL).\n     */\n    getDirection() {\n        if (this.selectionStartLineNumber === this.startLineNumber && this.selectionStartColumn === this.startColumn) {\n            return 0 /* SelectionDirection.LTR */;\n        }\n        return 1 /* SelectionDirection.RTL */;\n    }\n    /**\n     * Create a new selection with a different `positionLineNumber` and `positionColumn`.\n     */\n    setEndPosition(endLineNumber, endColumn) {\n        if (this.getDirection() === 0 /* SelectionDirection.LTR */) {\n            return new Selection(this.startLineNumber, this.startColumn, endLineNumber, endColumn);\n        }\n        return new Selection(endLineNumber, endColumn, this.startLineNumber, this.startColumn);\n    }\n    /**\n     * Get the position at `positionLineNumber` and `positionColumn`.\n     */\n    getPosition() {\n        return new Position(this.positionLineNumber, this.positionColumn);\n    }\n    /**\n     * Get the position at the start of the selection.\n    */\n    getSelectionStart() {\n        return new Position(this.selectionStartLineNumber, this.selectionStartColumn);\n    }\n    /**\n     * Create a new selection with a different `selectionStartLineNumber` and `selectionStartColumn`.\n     */\n    setStartPosition(startLineNumber, startColumn) {\n        if (this.getDirection() === 0 /* SelectionDirection.LTR */) {\n            return new Selection(startLineNumber, startColumn, this.endLineNumber, this.endColumn);\n        }\n        return new Selection(this.endLineNumber, this.endColumn, startLineNumber, startColumn);\n    }\n    // ----\n    /**\n     * Create a `Selection` from one or two positions\n     */\n    static fromPositions(start, end = start) {\n        return new Selection(start.lineNumber, start.column, end.lineNumber, end.column);\n    }\n    /**\n     * Creates a `Selection` from a range, given a direction.\n     */\n    static fromRange(range, direction) {\n        if (direction === 0 /* SelectionDirection.LTR */) {\n            return new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);\n        }\n        else {\n            return new Selection(range.endLineNumber, range.endColumn, range.startLineNumber, range.startColumn);\n        }\n    }\n    /**\n     * Create a `Selection` from an `ISelection`.\n     */\n    static liftSelection(sel) {\n        return new Selection(sel.selectionStartLineNumber, sel.selectionStartColumn, sel.positionLineNumber, sel.positionColumn);\n    }\n    /**\n     * `a` equals `b`.\n     */\n    static selectionsArrEqual(a, b) {\n        if (a && !b || !a && b) {\n            return false;\n        }\n        if (!a && !b) {\n            return true;\n        }\n        if (a.length !== b.length) {\n            return false;\n        }\n        for (let i = 0, len = a.length; i < len; i++) {\n            if (!this.selectionsEqual(a[i], b[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n     * Test if `obj` is an `ISelection`.\n     */\n    static isISelection(obj) {\n        return (obj\n            && (typeof obj.selectionStartLineNumber === 'number')\n            && (typeof obj.selectionStartColumn === 'number')\n            && (typeof obj.positionLineNumber === 'number')\n            && (typeof obj.positionColumn === 'number'));\n    }\n    /**\n     * Create with a direction.\n     */\n    static createWithDirection(startLineNumber, startColumn, endLineNumber, endColumn, direction) {\n        if (direction === 0 /* SelectionDirection.LTR */) {\n            return new Selection(startLineNumber, startColumn, endLineNumber, endColumn);\n        }\n        return new Selection(endLineNumber, endColumn, startLineNumber, startColumn);\n    }\n}\n","import { isString } from './types.js';\nconst _codiconFontCharacters = Object.create(null);\nfunction register(id, fontCharacter) {\n    if (isString(fontCharacter)) {\n        const val = _codiconFontCharacters[fontCharacter];\n        if (val === undefined) {\n            throw new Error(`${id} references an unknown codicon: ${fontCharacter}`);\n        }\n        fontCharacter = val;\n    }\n    _codiconFontCharacters[id] = fontCharacter;\n    return { id };\n}\n/**\n * Only to be used by the iconRegistry.\n */\nexport function getCodiconFontCharacters() {\n    return _codiconFontCharacters;\n}\n/**\n * The Codicon library is a set of default icons that are built-in in VS Code.\n *\n * In the product (outside of base) Codicons should only be used as defaults. In order to have all icons in VS Code\n * themeable, component should define new, UI component specific icons using `iconRegistry.registerIcon`.\n * In that call a Codicon can be named as default.\n */\nexport const Codicon = {\n    // built-in icons, with image name\n    add: register('add', 0xea60),\n    plus: register('plus', 0xea60),\n    gistNew: register('gist-new', 0xea60),\n    repoCreate: register('repo-create', 0xea60),\n    lightbulb: register('lightbulb', 0xea61),\n    lightBulb: register('light-bulb', 0xea61),\n    repo: register('repo', 0xea62),\n    repoDelete: register('repo-delete', 0xea62),\n    gistFork: register('gist-fork', 0xea63),\n    repoForked: register('repo-forked', 0xea63),\n    gitPullRequest: register('git-pull-request', 0xea64),\n    gitPullRequestAbandoned: register('git-pull-request-abandoned', 0xea64),\n    recordKeys: register('record-keys', 0xea65),\n    keyboard: register('keyboard', 0xea65),\n    tag: register('tag', 0xea66),\n    tagAdd: register('tag-add', 0xea66),\n    tagRemove: register('tag-remove', 0xea66),\n    person: register('person', 0xea67),\n    personFollow: register('person-follow', 0xea67),\n    personOutline: register('person-outline', 0xea67),\n    personFilled: register('person-filled', 0xea67),\n    gitBranch: register('git-branch', 0xea68),\n    gitBranchCreate: register('git-branch-create', 0xea68),\n    gitBranchDelete: register('git-branch-delete', 0xea68),\n    sourceControl: register('source-control', 0xea68),\n    mirror: register('mirror', 0xea69),\n    mirrorPublic: register('mirror-public', 0xea69),\n    star: register('star', 0xea6a),\n    starAdd: register('star-add', 0xea6a),\n    starDelete: register('star-delete', 0xea6a),\n    starEmpty: register('star-empty', 0xea6a),\n    comment: register('comment', 0xea6b),\n    commentAdd: register('comment-add', 0xea6b),\n    alert: register('alert', 0xea6c),\n    warning: register('warning', 0xea6c),\n    search: register('search', 0xea6d),\n    searchSave: register('search-save', 0xea6d),\n    logOut: register('log-out', 0xea6e),\n    signOut: register('sign-out', 0xea6e),\n    logIn: register('log-in', 0xea6f),\n    signIn: register('sign-in', 0xea6f),\n    eye: register('eye', 0xea70),\n    eyeUnwatch: register('eye-unwatch', 0xea70),\n    eyeWatch: register('eye-watch', 0xea70),\n    circleFilled: register('circle-filled', 0xea71),\n    primitiveDot: register('primitive-dot', 0xea71),\n    closeDirty: register('close-dirty', 0xea71),\n    debugBreakpoint: register('debug-breakpoint', 0xea71),\n    debugBreakpointDisabled: register('debug-breakpoint-disabled', 0xea71),\n    debugHint: register('debug-hint', 0xea71),\n    primitiveSquare: register('primitive-square', 0xea72),\n    edit: register('edit', 0xea73),\n    pencil: register('pencil', 0xea73),\n    info: register('info', 0xea74),\n    issueOpened: register('issue-opened', 0xea74),\n    gistPrivate: register('gist-private', 0xea75),\n    gitForkPrivate: register('git-fork-private', 0xea75),\n    lock: register('lock', 0xea75),\n    mirrorPrivate: register('mirror-private', 0xea75),\n    close: register('close', 0xea76),\n    removeClose: register('remove-close', 0xea76),\n    x: register('x', 0xea76),\n    repoSync: register('repo-sync', 0xea77),\n    sync: register('sync', 0xea77),\n    clone: register('clone', 0xea78),\n    desktopDownload: register('desktop-download', 0xea78),\n    beaker: register('beaker', 0xea79),\n    microscope: register('microscope', 0xea79),\n    vm: register('vm', 0xea7a),\n    deviceDesktop: register('device-desktop', 0xea7a),\n    file: register('file', 0xea7b),\n    fileText: register('file-text', 0xea7b),\n    more: register('more', 0xea7c),\n    ellipsis: register('ellipsis', 0xea7c),\n    kebabHorizontal: register('kebab-horizontal', 0xea7c),\n    mailReply: register('mail-reply', 0xea7d),\n    reply: register('reply', 0xea7d),\n    organization: register('organization', 0xea7e),\n    organizationFilled: register('organization-filled', 0xea7e),\n    organizationOutline: register('organization-outline', 0xea7e),\n    newFile: register('new-file', 0xea7f),\n    fileAdd: register('file-add', 0xea7f),\n    newFolder: register('new-folder', 0xea80),\n    fileDirectoryCreate: register('file-directory-create', 0xea80),\n    trash: register('trash', 0xea81),\n    trashcan: register('trashcan', 0xea81),\n    history: register('history', 0xea82),\n    clock: register('clock', 0xea82),\n    folder: register('folder', 0xea83),\n    fileDirectory: register('file-directory', 0xea83),\n    symbolFolder: register('symbol-folder', 0xea83),\n    logoGithub: register('logo-github', 0xea84),\n    markGithub: register('mark-github', 0xea84),\n    github: register('github', 0xea84),\n    terminal: register('terminal', 0xea85),\n    console: register('console', 0xea85),\n    repl: register('repl', 0xea85),\n    zap: register('zap', 0xea86),\n    symbolEvent: register('symbol-event', 0xea86),\n    error: register('error', 0xea87),\n    stop: register('stop', 0xea87),\n    variable: register('variable', 0xea88),\n    symbolVariable: register('symbol-variable', 0xea88),\n    array: register('array', 0xea8a),\n    symbolArray: register('symbol-array', 0xea8a),\n    symbolModule: register('symbol-module', 0xea8b),\n    symbolPackage: register('symbol-package', 0xea8b),\n    symbolNamespace: register('symbol-namespace', 0xea8b),\n    symbolObject: register('symbol-object', 0xea8b),\n    symbolMethod: register('symbol-method', 0xea8c),\n    symbolFunction: register('symbol-function', 0xea8c),\n    symbolConstructor: register('symbol-constructor', 0xea8c),\n    symbolBoolean: register('symbol-boolean', 0xea8f),\n    symbolNull: register('symbol-null', 0xea8f),\n    symbolNumeric: register('symbol-numeric', 0xea90),\n    symbolNumber: register('symbol-number', 0xea90),\n    symbolStructure: register('symbol-structure', 0xea91),\n    symbolStruct: register('symbol-struct', 0xea91),\n    symbolParameter: register('symbol-parameter', 0xea92),\n    symbolTypeParameter: register('symbol-type-parameter', 0xea92),\n    symbolKey: register('symbol-key', 0xea93),\n    symbolText: register('symbol-text', 0xea93),\n    symbolReference: register('symbol-reference', 0xea94),\n    goToFile: register('go-to-file', 0xea94),\n    symbolEnum: register('symbol-enum', 0xea95),\n    symbolValue: register('symbol-value', 0xea95),\n    symbolRuler: register('symbol-ruler', 0xea96),\n    symbolUnit: register('symbol-unit', 0xea96),\n    activateBreakpoints: register('activate-breakpoints', 0xea97),\n    archive: register('archive', 0xea98),\n    arrowBoth: register('arrow-both', 0xea99),\n    arrowDown: register('arrow-down', 0xea9a),\n    arrowLeft: register('arrow-left', 0xea9b),\n    arrowRight: register('arrow-right', 0xea9c),\n    arrowSmallDown: register('arrow-small-down', 0xea9d),\n    arrowSmallLeft: register('arrow-small-left', 0xea9e),\n    arrowSmallRight: register('arrow-small-right', 0xea9f),\n    arrowSmallUp: register('arrow-small-up', 0xeaa0),\n    arrowUp: register('arrow-up', 0xeaa1),\n    bell: register('bell', 0xeaa2),\n    bold: register('bold', 0xeaa3),\n    book: register('book', 0xeaa4),\n    bookmark: register('bookmark', 0xeaa5),\n    debugBreakpointConditionalUnverified: register('debug-breakpoint-conditional-unverified', 0xeaa6),\n    debugBreakpointConditional: register('debug-breakpoint-conditional', 0xeaa7),\n    debugBreakpointConditionalDisabled: register('debug-breakpoint-conditional-disabled', 0xeaa7),\n    debugBreakpointDataUnverified: register('debug-breakpoint-data-unverified', 0xeaa8),\n    debugBreakpointData: register('debug-breakpoint-data', 0xeaa9),\n    debugBreakpointDataDisabled: register('debug-breakpoint-data-disabled', 0xeaa9),\n    debugBreakpointLogUnverified: register('debug-breakpoint-log-unverified', 0xeaaa),\n    debugBreakpointLog: register('debug-breakpoint-log', 0xeaab),\n    debugBreakpointLogDisabled: register('debug-breakpoint-log-disabled', 0xeaab),\n    briefcase: register('briefcase', 0xeaac),\n    broadcast: register('broadcast', 0xeaad),\n    browser: register('browser', 0xeaae),\n    bug: register('bug', 0xeaaf),\n    calendar: register('calendar', 0xeab0),\n    caseSensitive: register('case-sensitive', 0xeab1),\n    check: register('check', 0xeab2),\n    checklist: register('checklist', 0xeab3),\n    chevronDown: register('chevron-down', 0xeab4),\n    dropDownButton: register('drop-down-button', 0xeab4),\n    chevronLeft: register('chevron-left', 0xeab5),\n    chevronRight: register('chevron-right', 0xeab6),\n    chevronUp: register('chevron-up', 0xeab7),\n    chromeClose: register('chrome-close', 0xeab8),\n    chromeMaximize: register('chrome-maximize', 0xeab9),\n    chromeMinimize: register('chrome-minimize', 0xeaba),\n    chromeRestore: register('chrome-restore', 0xeabb),\n    circle: register('circle', 0xeabc),\n    circleOutline: register('circle-outline', 0xeabc),\n    debugBreakpointUnverified: register('debug-breakpoint-unverified', 0xeabc),\n    circleSlash: register('circle-slash', 0xeabd),\n    circuitBoard: register('circuit-board', 0xeabe),\n    clearAll: register('clear-all', 0xeabf),\n    clippy: register('clippy', 0xeac0),\n    closeAll: register('close-all', 0xeac1),\n    cloudDownload: register('cloud-download', 0xeac2),\n    cloudUpload: register('cloud-upload', 0xeac3),\n    code: register('code', 0xeac4),\n    collapseAll: register('collapse-all', 0xeac5),\n    colorMode: register('color-mode', 0xeac6),\n    commentDiscussion: register('comment-discussion', 0xeac7),\n    compareChanges: register('compare-changes', 0xeafd),\n    creditCard: register('credit-card', 0xeac9),\n    dash: register('dash', 0xeacc),\n    dashboard: register('dashboard', 0xeacd),\n    database: register('database', 0xeace),\n    debugContinue: register('debug-continue', 0xeacf),\n    debugDisconnect: register('debug-disconnect', 0xead0),\n    debugPause: register('debug-pause', 0xead1),\n    debugRestart: register('debug-restart', 0xead2),\n    debugStart: register('debug-start', 0xead3),\n    debugStepInto: register('debug-step-into', 0xead4),\n    debugStepOut: register('debug-step-out', 0xead5),\n    debugStepOver: register('debug-step-over', 0xead6),\n    debugStop: register('debug-stop', 0xead7),\n    debug: register('debug', 0xead8),\n    deviceCameraVideo: register('device-camera-video', 0xead9),\n    deviceCamera: register('device-camera', 0xeada),\n    deviceMobile: register('device-mobile', 0xeadb),\n    diffAdded: register('diff-added', 0xeadc),\n    diffIgnored: register('diff-ignored', 0xeadd),\n    diffModified: register('diff-modified', 0xeade),\n    diffRemoved: register('diff-removed', 0xeadf),\n    diffRenamed: register('diff-renamed', 0xeae0),\n    diff: register('diff', 0xeae1),\n    discard: register('discard', 0xeae2),\n    editorLayout: register('editor-layout', 0xeae3),\n    emptyWindow: register('empty-window', 0xeae4),\n    exclude: register('exclude', 0xeae5),\n    extensions: register('extensions', 0xeae6),\n    eyeClosed: register('eye-closed', 0xeae7),\n    fileBinary: register('file-binary', 0xeae8),\n    fileCode: register('file-code', 0xeae9),\n    fileMedia: register('file-media', 0xeaea),\n    filePdf: register('file-pdf', 0xeaeb),\n    fileSubmodule: register('file-submodule', 0xeaec),\n    fileSymlinkDirectory: register('file-symlink-directory', 0xeaed),\n    fileSymlinkFile: register('file-symlink-file', 0xeaee),\n    fileZip: register('file-zip', 0xeaef),\n    files: register('files', 0xeaf0),\n    filter: register('filter', 0xeaf1),\n    flame: register('flame', 0xeaf2),\n    foldDown: register('fold-down', 0xeaf3),\n    foldUp: register('fold-up', 0xeaf4),\n    fold: register('fold', 0xeaf5),\n    folderActive: register('folder-active', 0xeaf6),\n    folderOpened: register('folder-opened', 0xeaf7),\n    gear: register('gear', 0xeaf8),\n    gift: register('gift', 0xeaf9),\n    gistSecret: register('gist-secret', 0xeafa),\n    gist: register('gist', 0xeafb),\n    gitCommit: register('git-commit', 0xeafc),\n    gitCompare: register('git-compare', 0xeafd),\n    gitMerge: register('git-merge', 0xeafe),\n    githubAction: register('github-action', 0xeaff),\n    githubAlt: register('github-alt', 0xeb00),\n    globe: register('globe', 0xeb01),\n    grabber: register('grabber', 0xeb02),\n    graph: register('graph', 0xeb03),\n    gripper: register('gripper', 0xeb04),\n    heart: register('heart', 0xeb05),\n    home: register('home', 0xeb06),\n    horizontalRule: register('horizontal-rule', 0xeb07),\n    hubot: register('hubot', 0xeb08),\n    inbox: register('inbox', 0xeb09),\n    issueClosed: register('issue-closed', 0xeba4),\n    issueReopened: register('issue-reopened', 0xeb0b),\n    issues: register('issues', 0xeb0c),\n    italic: register('italic', 0xeb0d),\n    jersey: register('jersey', 0xeb0e),\n    json: register('json', 0xeb0f),\n    bracket: register('bracket', 0xeb0f),\n    kebabVertical: register('kebab-vertical', 0xeb10),\n    key: register('key', 0xeb11),\n    law: register('law', 0xeb12),\n    lightbulbAutofix: register('lightbulb-autofix', 0xeb13),\n    linkExternal: register('link-external', 0xeb14),\n    link: register('link', 0xeb15),\n    listOrdered: register('list-ordered', 0xeb16),\n    listUnordered: register('list-unordered', 0xeb17),\n    liveShare: register('live-share', 0xeb18),\n    loading: register('loading', 0xeb19),\n    location: register('location', 0xeb1a),\n    mailRead: register('mail-read', 0xeb1b),\n    mail: register('mail', 0xeb1c),\n    markdown: register('markdown', 0xeb1d),\n    megaphone: register('megaphone', 0xeb1e),\n    mention: register('mention', 0xeb1f),\n    milestone: register('milestone', 0xeb20),\n    mortarBoard: register('mortar-board', 0xeb21),\n    move: register('move', 0xeb22),\n    multipleWindows: register('multiple-windows', 0xeb23),\n    mute: register('mute', 0xeb24),\n    noNewline: register('no-newline', 0xeb25),\n    note: register('note', 0xeb26),\n    octoface: register('octoface', 0xeb27),\n    openPreview: register('open-preview', 0xeb28),\n    package_: register('package', 0xeb29),\n    paintcan: register('paintcan', 0xeb2a),\n    pin: register('pin', 0xeb2b),\n    play: register('play', 0xeb2c),\n    run: register('run', 0xeb2c),\n    plug: register('plug', 0xeb2d),\n    preserveCase: register('preserve-case', 0xeb2e),\n    preview: register('preview', 0xeb2f),\n    project: register('project', 0xeb30),\n    pulse: register('pulse', 0xeb31),\n    question: register('question', 0xeb32),\n    quote: register('quote', 0xeb33),\n    radioTower: register('radio-tower', 0xeb34),\n    reactions: register('reactions', 0xeb35),\n    references: register('references', 0xeb36),\n    refresh: register('refresh', 0xeb37),\n    regex: register('regex', 0xeb38),\n    remoteExplorer: register('remote-explorer', 0xeb39),\n    remote: register('remote', 0xeb3a),\n    remove: register('remove', 0xeb3b),\n    replaceAll: register('replace-all', 0xeb3c),\n    replace: register('replace', 0xeb3d),\n    repoClone: register('repo-clone', 0xeb3e),\n    repoForcePush: register('repo-force-push', 0xeb3f),\n    repoPull: register('repo-pull', 0xeb40),\n    repoPush: register('repo-push', 0xeb41),\n    report: register('report', 0xeb42),\n    requestChanges: register('request-changes', 0xeb43),\n    rocket: register('rocket', 0xeb44),\n    rootFolderOpened: register('root-folder-opened', 0xeb45),\n    rootFolder: register('root-folder', 0xeb46),\n    rss: register('rss', 0xeb47),\n    ruby: register('ruby', 0xeb48),\n    saveAll: register('save-all', 0xeb49),\n    saveAs: register('save-as', 0xeb4a),\n    save: register('save', 0xeb4b),\n    screenFull: register('screen-full', 0xeb4c),\n    screenNormal: register('screen-normal', 0xeb4d),\n    searchStop: register('search-stop', 0xeb4e),\n    server: register('server', 0xeb50),\n    settingsGear: register('settings-gear', 0xeb51),\n    settings: register('settings', 0xeb52),\n    shield: register('shield', 0xeb53),\n    smiley: register('smiley', 0xeb54),\n    sortPrecedence: register('sort-precedence', 0xeb55),\n    splitHorizontal: register('split-horizontal', 0xeb56),\n    splitVertical: register('split-vertical', 0xeb57),\n    squirrel: register('squirrel', 0xeb58),\n    starFull: register('star-full', 0xeb59),\n    starHalf: register('star-half', 0xeb5a),\n    symbolClass: register('symbol-class', 0xeb5b),\n    symbolColor: register('symbol-color', 0xeb5c),\n    symbolCustomColor: register('symbol-customcolor', 0xeb5c),\n    symbolConstant: register('symbol-constant', 0xeb5d),\n    symbolEnumMember: register('symbol-enum-member', 0xeb5e),\n    symbolField: register('symbol-field', 0xeb5f),\n    symbolFile: register('symbol-file', 0xeb60),\n    symbolInterface: register('symbol-interface', 0xeb61),\n    symbolKeyword: register('symbol-keyword', 0xeb62),\n    symbolMisc: register('symbol-misc', 0xeb63),\n    symbolOperator: register('symbol-operator', 0xeb64),\n    symbolProperty: register('symbol-property', 0xeb65),\n    wrench: register('wrench', 0xeb65),\n    wrenchSubaction: register('wrench-subaction', 0xeb65),\n    symbolSnippet: register('symbol-snippet', 0xeb66),\n    tasklist: register('tasklist', 0xeb67),\n    telescope: register('telescope', 0xeb68),\n    textSize: register('text-size', 0xeb69),\n    threeBars: register('three-bars', 0xeb6a),\n    thumbsdown: register('thumbsdown', 0xeb6b),\n    thumbsup: register('thumbsup', 0xeb6c),\n    tools: register('tools', 0xeb6d),\n    triangleDown: register('triangle-down', 0xeb6e),\n    triangleLeft: register('triangle-left', 0xeb6f),\n    triangleRight: register('triangle-right', 0xeb70),\n    triangleUp: register('triangle-up', 0xeb71),\n    twitter: register('twitter', 0xeb72),\n    unfold: register('unfold', 0xeb73),\n    unlock: register('unlock', 0xeb74),\n    unmute: register('unmute', 0xeb75),\n    unverified: register('unverified', 0xeb76),\n    verified: register('verified', 0xeb77),\n    versions: register('versions', 0xeb78),\n    vmActive: register('vm-active', 0xeb79),\n    vmOutline: register('vm-outline', 0xeb7a),\n    vmRunning: register('vm-running', 0xeb7b),\n    watch: register('watch', 0xeb7c),\n    whitespace: register('whitespace', 0xeb7d),\n    wholeWord: register('whole-word', 0xeb7e),\n    window: register('window', 0xeb7f),\n    wordWrap: register('word-wrap', 0xeb80),\n    zoomIn: register('zoom-in', 0xeb81),\n    zoomOut: register('zoom-out', 0xeb82),\n    listFilter: register('list-filter', 0xeb83),\n    listFlat: register('list-flat', 0xeb84),\n    listSelection: register('list-selection', 0xeb85),\n    selection: register('selection', 0xeb85),\n    listTree: register('list-tree', 0xeb86),\n    debugBreakpointFunctionUnverified: register('debug-breakpoint-function-unverified', 0xeb87),\n    debugBreakpointFunction: register('debug-breakpoint-function', 0xeb88),\n    debugBreakpointFunctionDisabled: register('debug-breakpoint-function-disabled', 0xeb88),\n    debugStackframeActive: register('debug-stackframe-active', 0xeb89),\n    circleSmallFilled: register('circle-small-filled', 0xeb8a),\n    debugStackframeDot: register('debug-stackframe-dot', 0xeb8a),\n    debugStackframe: register('debug-stackframe', 0xeb8b),\n    debugStackframeFocused: register('debug-stackframe-focused', 0xeb8b),\n    debugBreakpointUnsupported: register('debug-breakpoint-unsupported', 0xeb8c),\n    symbolString: register('symbol-string', 0xeb8d),\n    debugReverseContinue: register('debug-reverse-continue', 0xeb8e),\n    debugStepBack: register('debug-step-back', 0xeb8f),\n    debugRestartFrame: register('debug-restart-frame', 0xeb90),\n    callIncoming: register('call-incoming', 0xeb92),\n    callOutgoing: register('call-outgoing', 0xeb93),\n    menu: register('menu', 0xeb94),\n    expandAll: register('expand-all', 0xeb95),\n    feedback: register('feedback', 0xeb96),\n    groupByRefType: register('group-by-ref-type', 0xeb97),\n    ungroupByRefType: register('ungroup-by-ref-type', 0xeb98),\n    account: register('account', 0xeb99),\n    bellDot: register('bell-dot', 0xeb9a),\n    debugConsole: register('debug-console', 0xeb9b),\n    library: register('library', 0xeb9c),\n    output: register('output', 0xeb9d),\n    runAll: register('run-all', 0xeb9e),\n    syncIgnored: register('sync-ignored', 0xeb9f),\n    pinned: register('pinned', 0xeba0),\n    githubInverted: register('github-inverted', 0xeba1),\n    debugAlt: register('debug-alt', 0xeb91),\n    serverProcess: register('server-process', 0xeba2),\n    serverEnvironment: register('server-environment', 0xeba3),\n    pass: register('pass', 0xeba4),\n    stopCircle: register('stop-circle', 0xeba5),\n    playCircle: register('play-circle', 0xeba6),\n    record: register('record', 0xeba7),\n    debugAltSmall: register('debug-alt-small', 0xeba8),\n    vmConnect: register('vm-connect', 0xeba9),\n    cloud: register('cloud', 0xebaa),\n    merge: register('merge', 0xebab),\n    exportIcon: register('export', 0xebac),\n    graphLeft: register('graph-left', 0xebad),\n    magnet: register('magnet', 0xebae),\n    notebook: register('notebook', 0xebaf),\n    redo: register('redo', 0xebb0),\n    checkAll: register('check-all', 0xebb1),\n    pinnedDirty: register('pinned-dirty', 0xebb2),\n    passFilled: register('pass-filled', 0xebb3),\n    circleLargeFilled: register('circle-large-filled', 0xebb4),\n    circleLarge: register('circle-large', 0xebb5),\n    circleLargeOutline: register('circle-large-outline', 0xebb5),\n    combine: register('combine', 0xebb6),\n    gather: register('gather', 0xebb6),\n    table: register('table', 0xebb7),\n    variableGroup: register('variable-group', 0xebb8),\n    typeHierarchy: register('type-hierarchy', 0xebb9),\n    typeHierarchySub: register('type-hierarchy-sub', 0xebba),\n    typeHierarchySuper: register('type-hierarchy-super', 0xebbb),\n    gitPullRequestCreate: register('git-pull-request-create', 0xebbc),\n    runAbove: register('run-above', 0xebbd),\n    runBelow: register('run-below', 0xebbe),\n    notebookTemplate: register('notebook-template', 0xebbf),\n    debugRerun: register('debug-rerun', 0xebc0),\n    workspaceTrusted: register('workspace-trusted', 0xebc1),\n    workspaceUntrusted: register('workspace-untrusted', 0xebc2),\n    workspaceUnspecified: register('workspace-unspecified', 0xebc3),\n    terminalCmd: register('terminal-cmd', 0xebc4),\n    terminalDebian: register('terminal-debian', 0xebc5),\n    terminalLinux: register('terminal-linux', 0xebc6),\n    terminalPowershell: register('terminal-powershell', 0xebc7),\n    terminalTmux: register('terminal-tmux', 0xebc8),\n    terminalUbuntu: register('terminal-ubuntu', 0xebc9),\n    terminalBash: register('terminal-bash', 0xebca),\n    arrowSwap: register('arrow-swap', 0xebcb),\n    copy: register('copy', 0xebcc),\n    personAdd: register('person-add', 0xebcd),\n    filterFilled: register('filter-filled', 0xebce),\n    wand: register('wand', 0xebcf),\n    debugLineByLine: register('debug-line-by-line', 0xebd0),\n    inspect: register('inspect', 0xebd1),\n    layers: register('layers', 0xebd2),\n    layersDot: register('layers-dot', 0xebd3),\n    layersActive: register('layers-active', 0xebd4),\n    compass: register('compass', 0xebd5),\n    compassDot: register('compass-dot', 0xebd6),\n    compassActive: register('compass-active', 0xebd7),\n    azure: register('azure', 0xebd8),\n    issueDraft: register('issue-draft', 0xebd9),\n    gitPullRequestClosed: register('git-pull-request-closed', 0xebda),\n    gitPullRequestDraft: register('git-pull-request-draft', 0xebdb),\n    debugAll: register('debug-all', 0xebdc),\n    debugCoverage: register('debug-coverage', 0xebdd),\n    runErrors: register('run-errors', 0xebde),\n    folderLibrary: register('folder-library', 0xebdf),\n    debugContinueSmall: register('debug-continue-small', 0xebe0),\n    beakerStop: register('beaker-stop', 0xebe1),\n    graphLine: register('graph-line', 0xebe2),\n    graphScatter: register('graph-scatter', 0xebe3),\n    pieChart: register('pie-chart', 0xebe4),\n    bracketDot: register('bracket-dot', 0xebe5),\n    bracketError: register('bracket-error', 0xebe6),\n    lockSmall: register('lock-small', 0xebe7),\n    azureDevops: register('azure-devops', 0xebe8),\n    verifiedFilled: register('verified-filled', 0xebe9),\n    newLine: register('newline', 0xebea),\n    layout: register('layout', 0xebeb),\n    layoutActivitybarLeft: register('layout-activitybar-left', 0xebec),\n    layoutActivitybarRight: register('layout-activitybar-right', 0xebed),\n    layoutPanelLeft: register('layout-panel-left', 0xebee),\n    layoutPanelCenter: register('layout-panel-center', 0xebef),\n    layoutPanelJustify: register('layout-panel-justify', 0xebf0),\n    layoutPanelRight: register('layout-panel-right', 0xebf1),\n    layoutPanel: register('layout-panel', 0xebf2),\n    layoutSidebarLeft: register('layout-sidebar-left', 0xebf3),\n    layoutSidebarRight: register('layout-sidebar-right', 0xebf4),\n    layoutStatusbar: register('layout-statusbar', 0xebf5),\n    layoutMenubar: register('layout-menubar', 0xebf6),\n    layoutCentered: register('layout-centered', 0xebf7),\n    layoutSidebarRightOff: register('layout-sidebar-right-off', 0xec00),\n    layoutPanelOff: register('layout-panel-off', 0xec01),\n    layoutSidebarLeftOff: register('layout-sidebar-left-off', 0xec02),\n    target: register('target', 0xebf8),\n    indent: register('indent', 0xebf9),\n    recordSmall: register('record-small', 0xebfa),\n    errorSmall: register('error-small', 0xebfb),\n    arrowCircleDown: register('arrow-circle-down', 0xebfc),\n    arrowCircleLeft: register('arrow-circle-left', 0xebfd),\n    arrowCircleRight: register('arrow-circle-right', 0xebfe),\n    arrowCircleUp: register('arrow-circle-up', 0xebff),\n    heartFilled: register('heart-filled', 0xec04),\n    map: register('map', 0xec05),\n    mapFilled: register('map-filled', 0xec06),\n    circleSmall: register('circle-small', 0xec07),\n    bellSlash: register('bell-slash', 0xec08),\n    bellSlashDot: register('bell-slash-dot', 0xec09),\n    commentUnresolved: register('comment-unresolved', 0xec0a),\n    gitPullRequestGoToChanges: register('git-pull-request-go-to-changes', 0xec0b),\n    gitPullRequestNewChanges: register('git-pull-request-new-changes', 0xec0c),\n    searchFuzzy: register('search-fuzzy', 0xec0d),\n    commentDraft: register('comment-draft', 0xec0e),\n    send: register('send', 0xec0f),\n    sparkle: register('sparkle', 0xec10),\n    insert: register('insert', 0xec11),\n    // derived icons, that could become separate icons\n    dialogError: register('dialog-error', 'error'),\n    dialogWarning: register('dialog-warning', 'warning'),\n    dialogInfo: register('dialog-info', 'info'),\n    dialogClose: register('dialog-close', 'close'),\n    treeItemExpanded: register('tree-item-expanded', 'chevron-down'),\n    treeFilterOnTypeOn: register('tree-filter-on-type-on', 'list-filter'),\n    treeFilterOnTypeOff: register('tree-filter-on-type-off', 'list-selection'),\n    treeFilterClear: register('tree-filter-clear', 'close'),\n    treeItemLoading: register('tree-item-loading', 'loading'),\n    menuSelection: register('menu-selection', 'check'),\n    menuSubmenu: register('menu-submenu', 'chevron-right'),\n    menuBarMore: register('menubar-more', 'more'),\n    scrollbarButtonLeft: register('scrollbar-button-left', 'triangle-left'),\n    scrollbarButtonRight: register('scrollbar-button-right', 'triangle-right'),\n    scrollbarButtonUp: register('scrollbar-button-up', 'triangle-up'),\n    scrollbarButtonDown: register('scrollbar-button-down', 'triangle-down'),\n    toolBarMore: register('toolbar-more', 'more'),\n    quickInputBack: register('quick-input-back', 'arrow-left')\n};\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nimport { Emitter } from '../../base/common/event.js';\nimport { Disposable, toDisposable } from '../../base/common/lifecycle.js';\nexport class TokenizationRegistry {\n    constructor() {\n        this._tokenizationSupports = new Map();\n        this._factories = new Map();\n        this._onDidChange = new Emitter();\n        this.onDidChange = this._onDidChange.event;\n        this._colorMap = null;\n    }\n    handleChange(languageIds) {\n        this._onDidChange.fire({\n            changedLanguages: languageIds,\n            changedColorMap: false\n        });\n    }\n    register(languageId, support) {\n        this._tokenizationSupports.set(languageId, support);\n        this.handleChange([languageId]);\n        return toDisposable(() => {\n            if (this._tokenizationSupports.get(languageId) !== support) {\n                return;\n            }\n            this._tokenizationSupports.delete(languageId);\n            this.handleChange([languageId]);\n        });\n    }\n    get(languageId) {\n        return this._tokenizationSupports.get(languageId) || null;\n    }\n    registerFactory(languageId, factory) {\n        var _a;\n        (_a = this._factories.get(languageId)) === null || _a === void 0 ? void 0 : _a.dispose();\n        const myData = new TokenizationSupportFactoryData(this, languageId, factory);\n        this._factories.set(languageId, myData);\n        return toDisposable(() => {\n            const v = this._factories.get(languageId);\n            if (!v || v !== myData) {\n                return;\n            }\n            this._factories.delete(languageId);\n            v.dispose();\n        });\n    }\n    getOrCreate(languageId) {\n        return __awaiter(this, void 0, void 0, function* () {\n            // check first if the support is already set\n            const tokenizationSupport = this.get(languageId);\n            if (tokenizationSupport) {\n                return tokenizationSupport;\n            }\n            const factory = this._factories.get(languageId);\n            if (!factory || factory.isResolved) {\n                // no factory or factory.resolve already finished\n                return null;\n            }\n            yield factory.resolve();\n            return this.get(languageId);\n        });\n    }\n    isResolved(languageId) {\n        const tokenizationSupport = this.get(languageId);\n        if (tokenizationSupport) {\n            return true;\n        }\n        const factory = this._factories.get(languageId);\n        if (!factory || factory.isResolved) {\n            return true;\n        }\n        return false;\n    }\n    setColorMap(colorMap) {\n        this._colorMap = colorMap;\n        this._onDidChange.fire({\n            changedLanguages: Array.from(this._tokenizationSupports.keys()),\n            changedColorMap: true\n        });\n    }\n    getColorMap() {\n        return this._colorMap;\n    }\n    getDefaultBackground() {\n        if (this._colorMap && this._colorMap.length > 2 /* ColorId.DefaultBackground */) {\n            return this._colorMap[2 /* ColorId.DefaultBackground */];\n        }\n        return null;\n    }\n}\nclass TokenizationSupportFactoryData extends Disposable {\n    get isResolved() {\n        return this._isResolved;\n    }\n    constructor(_registry, _languageId, _factory) {\n        super();\n        this._registry = _registry;\n        this._languageId = _languageId;\n        this._factory = _factory;\n        this._isDisposed = false;\n        this._resolvePromise = null;\n        this._isResolved = false;\n    }\n    dispose() {\n        this._isDisposed = true;\n        super.dispose();\n    }\n    resolve() {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!this._resolvePromise) {\n                this._resolvePromise = this._create();\n            }\n            return this._resolvePromise;\n        });\n    }\n    _create() {\n        return __awaiter(this, void 0, void 0, function* () {\n            const value = yield this._factory.tokenizationSupport;\n            this._isResolved = true;\n            if (value && !this._isDisposed) {\n                this._register(this._registry.register(this._languageId, value));\n            }\n        });\n    }\n}\n","import { Codicon } from '../../base/common/codicons.js';\nimport { URI } from '../../base/common/uri.js';\nimport { Range } from './core/range.js';\nimport { TokenizationRegistry as TokenizationRegistryImpl } from './tokenizationRegistry.js';\nexport class Token {\n    constructor(offset, type, language) {\n        this.offset = offset;\n        this.type = type;\n        this.language = language;\n        this._tokenBrand = undefined;\n    }\n    toString() {\n        return '(' + this.offset + ', ' + this.type + ')';\n    }\n}\n/**\n * @internal\n */\nexport class TokenizationResult {\n    constructor(tokens, endState) {\n        this.tokens = tokens;\n        this.endState = endState;\n        this._tokenizationResultBrand = undefined;\n    }\n}\n/**\n * @internal\n */\nexport class EncodedTokenizationResult {\n    constructor(\n    /**\n     * The tokens in binary format. Each token occupies two array indices. For token i:\n     *  - at offset 2*i => startIndex\n     *  - at offset 2*i + 1 => metadata\n     *\n     */\n    tokens, endState) {\n        this.tokens = tokens;\n        this.endState = endState;\n        this._encodedTokenizationResultBrand = undefined;\n    }\n}\n/**\n * @internal\n */\nexport var CompletionItemKinds;\n(function (CompletionItemKinds) {\n    const byKind = new Map();\n    byKind.set(0 /* CompletionItemKind.Method */, Codicon.symbolMethod);\n    byKind.set(1 /* CompletionItemKind.Function */, Codicon.symbolFunction);\n    byKind.set(2 /* CompletionItemKind.Constructor */, Codicon.symbolConstructor);\n    byKind.set(3 /* CompletionItemKind.Field */, Codicon.symbolField);\n    byKind.set(4 /* CompletionItemKind.Variable */, Codicon.symbolVariable);\n    byKind.set(5 /* CompletionItemKind.Class */, Codicon.symbolClass);\n    byKind.set(6 /* CompletionItemKind.Struct */, Codicon.symbolStruct);\n    byKind.set(7 /* CompletionItemKind.Interface */, Codicon.symbolInterface);\n    byKind.set(8 /* CompletionItemKind.Module */, Codicon.symbolModule);\n    byKind.set(9 /* CompletionItemKind.Property */, Codicon.symbolProperty);\n    byKind.set(10 /* CompletionItemKind.Event */, Codicon.symbolEvent);\n    byKind.set(11 /* CompletionItemKind.Operator */, Codicon.symbolOperator);\n    byKind.set(12 /* CompletionItemKind.Unit */, Codicon.symbolUnit);\n    byKind.set(13 /* CompletionItemKind.Value */, Codicon.symbolValue);\n    byKind.set(15 /* CompletionItemKind.Enum */, Codicon.symbolEnum);\n    byKind.set(14 /* CompletionItemKind.Constant */, Codicon.symbolConstant);\n    byKind.set(15 /* CompletionItemKind.Enum */, Codicon.symbolEnum);\n    byKind.set(16 /* CompletionItemKind.EnumMember */, Codicon.symbolEnumMember);\n    byKind.set(17 /* CompletionItemKind.Keyword */, Codicon.symbolKeyword);\n    byKind.set(27 /* CompletionItemKind.Snippet */, Codicon.symbolSnippet);\n    byKind.set(18 /* CompletionItemKind.Text */, Codicon.symbolText);\n    byKind.set(19 /* CompletionItemKind.Color */, Codicon.symbolColor);\n    byKind.set(20 /* CompletionItemKind.File */, Codicon.symbolFile);\n    byKind.set(21 /* CompletionItemKind.Reference */, Codicon.symbolReference);\n    byKind.set(22 /* CompletionItemKind.Customcolor */, Codicon.symbolCustomColor);\n    byKind.set(23 /* CompletionItemKind.Folder */, Codicon.symbolFolder);\n    byKind.set(24 /* CompletionItemKind.TypeParameter */, Codicon.symbolTypeParameter);\n    byKind.set(25 /* CompletionItemKind.User */, Codicon.account);\n    byKind.set(26 /* CompletionItemKind.Issue */, Codicon.issues);\n    /**\n     * @internal\n     */\n    function toIcon(kind) {\n        let codicon = byKind.get(kind);\n        if (!codicon) {\n            console.info('No codicon found for CompletionItemKind ' + kind);\n            codicon = Codicon.symbolProperty;\n        }\n        return codicon;\n    }\n    CompletionItemKinds.toIcon = toIcon;\n    const data = new Map();\n    data.set('method', 0 /* CompletionItemKind.Method */);\n    data.set('function', 1 /* CompletionItemKind.Function */);\n    data.set('constructor', 2 /* CompletionItemKind.Constructor */);\n    data.set('field', 3 /* CompletionItemKind.Field */);\n    data.set('variable', 4 /* CompletionItemKind.Variable */);\n    data.set('class', 5 /* CompletionItemKind.Class */);\n    data.set('struct', 6 /* CompletionItemKind.Struct */);\n    data.set('interface', 7 /* CompletionItemKind.Interface */);\n    data.set('module', 8 /* CompletionItemKind.Module */);\n    data.set('property', 9 /* CompletionItemKind.Property */);\n    data.set('event', 10 /* CompletionItemKind.Event */);\n    data.set('operator', 11 /* CompletionItemKind.Operator */);\n    data.set('unit', 12 /* CompletionItemKind.Unit */);\n    data.set('value', 13 /* CompletionItemKind.Value */);\n    data.set('constant', 14 /* CompletionItemKind.Constant */);\n    data.set('enum', 15 /* CompletionItemKind.Enum */);\n    data.set('enum-member', 16 /* CompletionItemKind.EnumMember */);\n    data.set('enumMember', 16 /* CompletionItemKind.EnumMember */);\n    data.set('keyword', 17 /* CompletionItemKind.Keyword */);\n    data.set('snippet', 27 /* CompletionItemKind.Snippet */);\n    data.set('text', 18 /* CompletionItemKind.Text */);\n    data.set('color', 19 /* CompletionItemKind.Color */);\n    data.set('file', 20 /* CompletionItemKind.File */);\n    data.set('reference', 21 /* CompletionItemKind.Reference */);\n    data.set('customcolor', 22 /* CompletionItemKind.Customcolor */);\n    data.set('folder', 23 /* CompletionItemKind.Folder */);\n    data.set('type-parameter', 24 /* CompletionItemKind.TypeParameter */);\n    data.set('typeParameter', 24 /* CompletionItemKind.TypeParameter */);\n    data.set('account', 25 /* CompletionItemKind.User */);\n    data.set('issue', 26 /* CompletionItemKind.Issue */);\n    /**\n     * @internal\n     */\n    function fromString(value, strict) {\n        let res = data.get(value);\n        if (typeof res === 'undefined' && !strict) {\n            res = 9 /* CompletionItemKind.Property */;\n        }\n        return res;\n    }\n    CompletionItemKinds.fromString = fromString;\n})(CompletionItemKinds || (CompletionItemKinds = {}));\n/**\n * How an {@link InlineCompletionsProvider inline completion provider} was triggered.\n */\nexport var InlineCompletionTriggerKind;\n(function (InlineCompletionTriggerKind) {\n    /**\n     * Completion was triggered automatically while editing.\n     * It is sufficient to return a single completion item in this case.\n     */\n    InlineCompletionTriggerKind[InlineCompletionTriggerKind[\"Automatic\"] = 0] = \"Automatic\";\n    /**\n     * Completion was triggered explicitly by a user gesture.\n     * Return multiple completion items to enable cycling through them.\n     */\n    InlineCompletionTriggerKind[InlineCompletionTriggerKind[\"Explicit\"] = 1] = \"Explicit\";\n})(InlineCompletionTriggerKind || (InlineCompletionTriggerKind = {}));\nexport class SelectedSuggestionInfo {\n    constructor(range, text, completionKind, isSnippetText) {\n        this.range = range;\n        this.text = text;\n        this.completionKind = completionKind;\n        this.isSnippetText = isSnippetText;\n    }\n    equals(other) {\n        return Range.lift(this.range).equalsRange(other.range)\n            && this.text === other.text\n            && this.completionKind === other.completionKind\n            && this.isSnippetText === other.isSnippetText;\n    }\n}\nexport var SignatureHelpTriggerKind;\n(function (SignatureHelpTriggerKind) {\n    SignatureHelpTriggerKind[SignatureHelpTriggerKind[\"Invoke\"] = 1] = \"Invoke\";\n    SignatureHelpTriggerKind[SignatureHelpTriggerKind[\"TriggerCharacter\"] = 2] = \"TriggerCharacter\";\n    SignatureHelpTriggerKind[SignatureHelpTriggerKind[\"ContentChange\"] = 3] = \"ContentChange\";\n})(SignatureHelpTriggerKind || (SignatureHelpTriggerKind = {}));\n/**\n * A document highlight kind.\n */\nexport var DocumentHighlightKind;\n(function (DocumentHighlightKind) {\n    /**\n     * A textual occurrence.\n     */\n    DocumentHighlightKind[DocumentHighlightKind[\"Text\"] = 0] = \"Text\";\n    /**\n     * Read-access of a symbol, like reading a variable.\n     */\n    DocumentHighlightKind[DocumentHighlightKind[\"Read\"] = 1] = \"Read\";\n    /**\n     * Write-access of a symbol, like writing to a variable.\n     */\n    DocumentHighlightKind[DocumentHighlightKind[\"Write\"] = 2] = \"Write\";\n})(DocumentHighlightKind || (DocumentHighlightKind = {}));\n/**\n * @internal\n */\nexport function isLocationLink(thing) {\n    return thing\n        && URI.isUri(thing.uri)\n        && Range.isIRange(thing.range)\n        && (Range.isIRange(thing.originSelectionRange) || Range.isIRange(thing.targetSelectionRange));\n}\n/**\n * @internal\n */\nexport var SymbolKinds;\n(function (SymbolKinds) {\n    const byKind = new Map();\n    byKind.set(0 /* SymbolKind.File */, Codicon.symbolFile);\n    byKind.set(1 /* SymbolKind.Module */, Codicon.symbolModule);\n    byKind.set(2 /* SymbolKind.Namespace */, Codicon.symbolNamespace);\n    byKind.set(3 /* SymbolKind.Package */, Codicon.symbolPackage);\n    byKind.set(4 /* SymbolKind.Class */, Codicon.symbolClass);\n    byKind.set(5 /* SymbolKind.Method */, Codicon.symbolMethod);\n    byKind.set(6 /* SymbolKind.Property */, Codicon.symbolProperty);\n    byKind.set(7 /* SymbolKind.Field */, Codicon.symbolField);\n    byKind.set(8 /* SymbolKind.Constructor */, Codicon.symbolConstructor);\n    byKind.set(9 /* SymbolKind.Enum */, Codicon.symbolEnum);\n    byKind.set(10 /* SymbolKind.Interface */, Codicon.symbolInterface);\n    byKind.set(11 /* SymbolKind.Function */, Codicon.symbolFunction);\n    byKind.set(12 /* SymbolKind.Variable */, Codicon.symbolVariable);\n    byKind.set(13 /* SymbolKind.Constant */, Codicon.symbolConstant);\n    byKind.set(14 /* SymbolKind.String */, Codicon.symbolString);\n    byKind.set(15 /* SymbolKind.Number */, Codicon.symbolNumber);\n    byKind.set(16 /* SymbolKind.Boolean */, Codicon.symbolBoolean);\n    byKind.set(17 /* SymbolKind.Array */, Codicon.symbolArray);\n    byKind.set(18 /* SymbolKind.Object */, Codicon.symbolObject);\n    byKind.set(19 /* SymbolKind.Key */, Codicon.symbolKey);\n    byKind.set(20 /* SymbolKind.Null */, Codicon.symbolNull);\n    byKind.set(21 /* SymbolKind.EnumMember */, Codicon.symbolEnumMember);\n    byKind.set(22 /* SymbolKind.Struct */, Codicon.symbolStruct);\n    byKind.set(23 /* SymbolKind.Event */, Codicon.symbolEvent);\n    byKind.set(24 /* SymbolKind.Operator */, Codicon.symbolOperator);\n    byKind.set(25 /* SymbolKind.TypeParameter */, Codicon.symbolTypeParameter);\n    /**\n     * @internal\n     */\n    function toIcon(kind) {\n        let icon = byKind.get(kind);\n        if (!icon) {\n            console.info('No codicon found for SymbolKind ' + kind);\n            icon = Codicon.symbolProperty;\n        }\n        return icon;\n    }\n    SymbolKinds.toIcon = toIcon;\n})(SymbolKinds || (SymbolKinds = {}));\nexport class FoldingRangeKind {\n    /**\n     * Returns a {@link FoldingRangeKind} for the given value.\n     *\n     * @param value of the kind.\n     */\n    static fromValue(value) {\n        switch (value) {\n            case 'comment': return FoldingRangeKind.Comment;\n            case 'imports': return FoldingRangeKind.Imports;\n            case 'region': return FoldingRangeKind.Region;\n        }\n        return new FoldingRangeKind(value);\n    }\n    /**\n     * Creates a new {@link FoldingRangeKind}.\n     *\n     * @param value of the kind.\n     */\n    constructor(value) {\n        this.value = value;\n    }\n}\n/**\n * Kind for folding range representing a comment. The value of the kind is 'comment'.\n */\nFoldingRangeKind.Comment = new FoldingRangeKind('comment');\n/**\n * Kind for folding range representing a import. The value of the kind is 'imports'.\n */\nFoldingRangeKind.Imports = new FoldingRangeKind('imports');\n/**\n * Kind for folding range representing regions (for example marked by `#region`, `#endregion`).\n * The value of the kind is 'region'.\n */\nFoldingRangeKind.Region = new FoldingRangeKind('region');\n/**\n * @internal\n */\nexport var Command;\n(function (Command) {\n    /**\n     * @internal\n     */\n    function is(obj) {\n        if (!obj || typeof obj !== 'object') {\n            return false;\n        }\n        return typeof obj.id === 'string' &&\n            typeof obj.title === 'string';\n    }\n    Command.is = is;\n})(Command || (Command = {}));\nexport var InlayHintKind;\n(function (InlayHintKind) {\n    InlayHintKind[InlayHintKind[\"Type\"] = 1] = \"Type\";\n    InlayHintKind[InlayHintKind[\"Parameter\"] = 2] = \"Parameter\";\n})(InlayHintKind || (InlayHintKind = {}));\n/**\n * @internal\n */\nexport class LazyTokenizationSupport {\n    constructor(createSupport) {\n        this.createSupport = createSupport;\n        this._tokenizationSupport = null;\n    }\n    dispose() {\n        if (this._tokenizationSupport) {\n            this._tokenizationSupport.then((support) => {\n                if (support) {\n                    support.dispose();\n                }\n            });\n        }\n    }\n    get tokenizationSupport() {\n        if (!this._tokenizationSupport) {\n            this._tokenizationSupport = this.createSupport();\n        }\n        return this._tokenizationSupport;\n    }\n}\n/**\n * @internal\n */\nexport const TokenizationRegistry = new TokenizationRegistryImpl();\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.\nexport var AccessibilitySupport;\n(function (AccessibilitySupport) {\n    /**\n     * This should be the browser case where it is not known if a screen reader is attached or no.\n     */\n    AccessibilitySupport[AccessibilitySupport[\"Unknown\"] = 0] = \"Unknown\";\n    AccessibilitySupport[AccessibilitySupport[\"Disabled\"] = 1] = \"Disabled\";\n    AccessibilitySupport[AccessibilitySupport[\"Enabled\"] = 2] = \"Enabled\";\n})(AccessibilitySupport || (AccessibilitySupport = {}));\nexport var CodeActionTriggerType;\n(function (CodeActionTriggerType) {\n    CodeActionTriggerType[CodeActionTriggerType[\"Invoke\"] = 1] = \"Invoke\";\n    CodeActionTriggerType[CodeActionTriggerType[\"Auto\"] = 2] = \"Auto\";\n})(CodeActionTriggerType || (CodeActionTriggerType = {}));\nexport var CompletionItemInsertTextRule;\n(function (CompletionItemInsertTextRule) {\n    CompletionItemInsertTextRule[CompletionItemInsertTextRule[\"None\"] = 0] = \"None\";\n    /**\n     * Adjust whitespace/indentation of multiline insert texts to\n     * match the current line indentation.\n     */\n    CompletionItemInsertTextRule[CompletionItemInsertTextRule[\"KeepWhitespace\"] = 1] = \"KeepWhitespace\";\n    /**\n     * `insertText` is a snippet.\n     */\n    CompletionItemInsertTextRule[CompletionItemInsertTextRule[\"InsertAsSnippet\"] = 4] = \"InsertAsSnippet\";\n})(CompletionItemInsertTextRule || (CompletionItemInsertTextRule = {}));\nexport var CompletionItemKind;\n(function (CompletionItemKind) {\n    CompletionItemKind[CompletionItemKind[\"Method\"] = 0] = \"Method\";\n    CompletionItemKind[CompletionItemKind[\"Function\"] = 1] = \"Function\";\n    CompletionItemKind[CompletionItemKind[\"Constructor\"] = 2] = \"Constructor\";\n    CompletionItemKind[CompletionItemKind[\"Field\"] = 3] = \"Field\";\n    CompletionItemKind[CompletionItemKind[\"Variable\"] = 4] = \"Variable\";\n    CompletionItemKind[CompletionItemKind[\"Class\"] = 5] = \"Class\";\n    CompletionItemKind[CompletionItemKind[\"Struct\"] = 6] = \"Struct\";\n    CompletionItemKind[CompletionItemKind[\"Interface\"] = 7] = \"Interface\";\n    CompletionItemKind[CompletionItemKind[\"Module\"] = 8] = \"Module\";\n    CompletionItemKind[CompletionItemKind[\"Property\"] = 9] = \"Property\";\n    CompletionItemKind[CompletionItemKind[\"Event\"] = 10] = \"Event\";\n    CompletionItemKind[CompletionItemKind[\"Operator\"] = 11] = \"Operator\";\n    CompletionItemKind[CompletionItemKind[\"Unit\"] = 12] = \"Unit\";\n    CompletionItemKind[CompletionItemKind[\"Value\"] = 13] = \"Value\";\n    CompletionItemKind[CompletionItemKind[\"Constant\"] = 14] = \"Constant\";\n    CompletionItemKind[CompletionItemKind[\"Enum\"] = 15] = \"Enum\";\n    CompletionItemKind[CompletionItemKind[\"EnumMember\"] = 16] = \"EnumMember\";\n    CompletionItemKind[CompletionItemKind[\"Keyword\"] = 17] = \"Keyword\";\n    CompletionItemKind[CompletionItemKind[\"Text\"] = 18] = \"Text\";\n    CompletionItemKind[CompletionItemKind[\"Color\"] = 19] = \"Color\";\n    CompletionItemKind[CompletionItemKind[\"File\"] = 20] = \"File\";\n    CompletionItemKind[CompletionItemKind[\"Reference\"] = 21] = \"Reference\";\n    CompletionItemKind[CompletionItemKind[\"Customcolor\"] = 22] = \"Customcolor\";\n    CompletionItemKind[CompletionItemKind[\"Folder\"] = 23] = \"Folder\";\n    CompletionItemKind[CompletionItemKind[\"TypeParameter\"] = 24] = \"TypeParameter\";\n    CompletionItemKind[CompletionItemKind[\"User\"] = 25] = \"User\";\n    CompletionItemKind[CompletionItemKind[\"Issue\"] = 26] = \"Issue\";\n    CompletionItemKind[CompletionItemKind[\"Snippet\"] = 27] = \"Snippet\";\n})(CompletionItemKind || (CompletionItemKind = {}));\nexport var CompletionItemTag;\n(function (CompletionItemTag) {\n    CompletionItemTag[CompletionItemTag[\"Deprecated\"] = 1] = \"Deprecated\";\n})(CompletionItemTag || (CompletionItemTag = {}));\n/**\n * How a suggest provider was triggered.\n */\nexport var CompletionTriggerKind;\n(function (CompletionTriggerKind) {\n    CompletionTriggerKind[CompletionTriggerKind[\"Invoke\"] = 0] = \"Invoke\";\n    CompletionTriggerKind[CompletionTriggerKind[\"TriggerCharacter\"] = 1] = \"TriggerCharacter\";\n    CompletionTriggerKind[CompletionTriggerKind[\"TriggerForIncompleteCompletions\"] = 2] = \"TriggerForIncompleteCompletions\";\n})(CompletionTriggerKind || (CompletionTriggerKind = {}));\n/**\n * A positioning preference for rendering content widgets.\n */\nexport var ContentWidgetPositionPreference;\n(function (ContentWidgetPositionPreference) {\n    /**\n     * Place the content widget exactly at a position\n     */\n    ContentWidgetPositionPreference[ContentWidgetPositionPreference[\"EXACT\"] = 0] = \"EXACT\";\n    /**\n     * Place the content widget above a position\n     */\n    ContentWidgetPositionPreference[ContentWidgetPositionPreference[\"ABOVE\"] = 1] = \"ABOVE\";\n    /**\n     * Place the content widget below a position\n     */\n    ContentWidgetPositionPreference[ContentWidgetPositionPreference[\"BELOW\"] = 2] = \"BELOW\";\n})(ContentWidgetPositionPreference || (ContentWidgetPositionPreference = {}));\n/**\n * Describes the reason the cursor has changed its position.\n */\nexport var CursorChangeReason;\n(function (CursorChangeReason) {\n    /**\n     * Unknown or not set.\n     */\n    CursorChangeReason[CursorChangeReason[\"NotSet\"] = 0] = \"NotSet\";\n    /**\n     * A `model.setValue()` was called.\n     */\n    CursorChangeReason[CursorChangeReason[\"ContentFlush\"] = 1] = \"ContentFlush\";\n    /**\n     * The `model` has been changed outside of this cursor and the cursor recovers its position from associated markers.\n     */\n    CursorChangeReason[CursorChangeReason[\"RecoverFromMarkers\"] = 2] = \"RecoverFromMarkers\";\n    /**\n     * There was an explicit user gesture.\n     */\n    CursorChangeReason[CursorChangeReason[\"Explicit\"] = 3] = \"Explicit\";\n    /**\n     * There was a Paste.\n     */\n    CursorChangeReason[CursorChangeReason[\"Paste\"] = 4] = \"Paste\";\n    /**\n     * There was an Undo.\n     */\n    CursorChangeReason[CursorChangeReason[\"Undo\"] = 5] = \"Undo\";\n    /**\n     * There was a Redo.\n     */\n    CursorChangeReason[CursorChangeReason[\"Redo\"] = 6] = \"Redo\";\n})(CursorChangeReason || (CursorChangeReason = {}));\n/**\n * The default end of line to use when instantiating models.\n */\nexport var DefaultEndOfLine;\n(function (DefaultEndOfLine) {\n    /**\n     * Use line feed (\\n) as the end of line character.\n     */\n    DefaultEndOfLine[DefaultEndOfLine[\"LF\"] = 1] = \"LF\";\n    /**\n     * Use carriage return and line feed (\\r\\n) as the end of line character.\n     */\n    DefaultEndOfLine[DefaultEndOfLine[\"CRLF\"] = 2] = \"CRLF\";\n})(DefaultEndOfLine || (DefaultEndOfLine = {}));\n/**\n * A document highlight kind.\n */\nexport var DocumentHighlightKind;\n(function (DocumentHighlightKind) {\n    /**\n     * A textual occurrence.\n     */\n    DocumentHighlightKind[DocumentHighlightKind[\"Text\"] = 0] = \"Text\";\n    /**\n     * Read-access of a symbol, like reading a variable.\n     */\n    DocumentHighlightKind[DocumentHighlightKind[\"Read\"] = 1] = \"Read\";\n    /**\n     * Write-access of a symbol, like writing to a variable.\n     */\n    DocumentHighlightKind[DocumentHighlightKind[\"Write\"] = 2] = \"Write\";\n})(DocumentHighlightKind || (DocumentHighlightKind = {}));\n/**\n * Configuration options for auto indentation in the editor\n */\nexport var EditorAutoIndentStrategy;\n(function (EditorAutoIndentStrategy) {\n    EditorAutoIndentStrategy[EditorAutoIndentStrategy[\"None\"] = 0] = \"None\";\n    EditorAutoIndentStrategy[EditorAutoIndentStrategy[\"Keep\"] = 1] = \"Keep\";\n    EditorAutoIndentStrategy[EditorAutoIndentStrategy[\"Brackets\"] = 2] = \"Brackets\";\n    EditorAutoIndentStrategy[EditorAutoIndentStrategy[\"Advanced\"] = 3] = \"Advanced\";\n    EditorAutoIndentStrategy[EditorAutoIndentStrategy[\"Full\"] = 4] = \"Full\";\n})(EditorAutoIndentStrategy || (EditorAutoIndentStrategy = {}));\nexport var EditorOption;\n(function (EditorOption) {\n    EditorOption[EditorOption[\"acceptSuggestionOnCommitCharacter\"] = 0] = \"acceptSuggestionOnCommitCharacter\";\n    EditorOption[EditorOption[\"acceptSuggestionOnEnter\"] = 1] = \"acceptSuggestionOnEnter\";\n    EditorOption[EditorOption[\"accessibilitySupport\"] = 2] = \"accessibilitySupport\";\n    EditorOption[EditorOption[\"accessibilityPageSize\"] = 3] = \"accessibilityPageSize\";\n    EditorOption[EditorOption[\"ariaLabel\"] = 4] = \"ariaLabel\";\n    EditorOption[EditorOption[\"autoClosingBrackets\"] = 5] = \"autoClosingBrackets\";\n    EditorOption[EditorOption[\"screenReaderAnnounceInlineSuggestion\"] = 6] = \"screenReaderAnnounceInlineSuggestion\";\n    EditorOption[EditorOption[\"autoClosingDelete\"] = 7] = \"autoClosingDelete\";\n    EditorOption[EditorOption[\"autoClosingOvertype\"] = 8] = \"autoClosingOvertype\";\n    EditorOption[EditorOption[\"autoClosingQuotes\"] = 9] = \"autoClosingQuotes\";\n    EditorOption[EditorOption[\"autoIndent\"] = 10] = \"autoIndent\";\n    EditorOption[EditorOption[\"automaticLayout\"] = 11] = \"automaticLayout\";\n    EditorOption[EditorOption[\"autoSurround\"] = 12] = \"autoSurround\";\n    EditorOption[EditorOption[\"bracketPairColorization\"] = 13] = \"bracketPairColorization\";\n    EditorOption[EditorOption[\"guides\"] = 14] = \"guides\";\n    EditorOption[EditorOption[\"codeLens\"] = 15] = \"codeLens\";\n    EditorOption[EditorOption[\"codeLensFontFamily\"] = 16] = \"codeLensFontFamily\";\n    EditorOption[EditorOption[\"codeLensFontSize\"] = 17] = \"codeLensFontSize\";\n    EditorOption[EditorOption[\"colorDecorators\"] = 18] = \"colorDecorators\";\n    EditorOption[EditorOption[\"colorDecoratorsLimit\"] = 19] = \"colorDecoratorsLimit\";\n    EditorOption[EditorOption[\"columnSelection\"] = 20] = \"columnSelection\";\n    EditorOption[EditorOption[\"comments\"] = 21] = \"comments\";\n    EditorOption[EditorOption[\"contextmenu\"] = 22] = \"contextmenu\";\n    EditorOption[EditorOption[\"copyWithSyntaxHighlighting\"] = 23] = \"copyWithSyntaxHighlighting\";\n    EditorOption[EditorOption[\"cursorBlinking\"] = 24] = \"cursorBlinking\";\n    EditorOption[EditorOption[\"cursorSmoothCaretAnimation\"] = 25] = \"cursorSmoothCaretAnimation\";\n    EditorOption[EditorOption[\"cursorStyle\"] = 26] = \"cursorStyle\";\n    EditorOption[EditorOption[\"cursorSurroundingLines\"] = 27] = \"cursorSurroundingLines\";\n    EditorOption[EditorOption[\"cursorSurroundingLinesStyle\"] = 28] = \"cursorSurroundingLinesStyle\";\n    EditorOption[EditorOption[\"cursorWidth\"] = 29] = \"cursorWidth\";\n    EditorOption[EditorOption[\"disableLayerHinting\"] = 30] = \"disableLayerHinting\";\n    EditorOption[EditorOption[\"disableMonospaceOptimizations\"] = 31] = \"disableMonospaceOptimizations\";\n    EditorOption[EditorOption[\"domReadOnly\"] = 32] = \"domReadOnly\";\n    EditorOption[EditorOption[\"dragAndDrop\"] = 33] = \"dragAndDrop\";\n    EditorOption[EditorOption[\"dropIntoEditor\"] = 34] = \"dropIntoEditor\";\n    EditorOption[EditorOption[\"emptySelectionClipboard\"] = 35] = \"emptySelectionClipboard\";\n    EditorOption[EditorOption[\"experimentalWhitespaceRendering\"] = 36] = \"experimentalWhitespaceRendering\";\n    EditorOption[EditorOption[\"extraEditorClassName\"] = 37] = \"extraEditorClassName\";\n    EditorOption[EditorOption[\"fastScrollSensitivity\"] = 38] = \"fastScrollSensitivity\";\n    EditorOption[EditorOption[\"find\"] = 39] = \"find\";\n    EditorOption[EditorOption[\"fixedOverflowWidgets\"] = 40] = \"fixedOverflowWidgets\";\n    EditorOption[EditorOption[\"folding\"] = 41] = \"folding\";\n    EditorOption[EditorOption[\"foldingStrategy\"] = 42] = \"foldingStrategy\";\n    EditorOption[EditorOption[\"foldingHighlight\"] = 43] = \"foldingHighlight\";\n    EditorOption[EditorOption[\"foldingImportsByDefault\"] = 44] = \"foldingImportsByDefault\";\n    EditorOption[EditorOption[\"foldingMaximumRegions\"] = 45] = \"foldingMaximumRegions\";\n    EditorOption[EditorOption[\"unfoldOnClickAfterEndOfLine\"] = 46] = \"unfoldOnClickAfterEndOfLine\";\n    EditorOption[EditorOption[\"fontFamily\"] = 47] = \"fontFamily\";\n    EditorOption[EditorOption[\"fontInfo\"] = 48] = \"fontInfo\";\n    EditorOption[EditorOption[\"fontLigatures\"] = 49] = \"fontLigatures\";\n    EditorOption[EditorOption[\"fontSize\"] = 50] = \"fontSize\";\n    EditorOption[EditorOption[\"fontWeight\"] = 51] = \"fontWeight\";\n    EditorOption[EditorOption[\"fontVariations\"] = 52] = \"fontVariations\";\n    EditorOption[EditorOption[\"formatOnPaste\"] = 53] = \"formatOnPaste\";\n    EditorOption[EditorOption[\"formatOnType\"] = 54] = \"formatOnType\";\n    EditorOption[EditorOption[\"glyphMargin\"] = 55] = \"glyphMargin\";\n    EditorOption[EditorOption[\"gotoLocation\"] = 56] = \"gotoLocation\";\n    EditorOption[EditorOption[\"hideCursorInOverviewRuler\"] = 57] = \"hideCursorInOverviewRuler\";\n    EditorOption[EditorOption[\"hover\"] = 58] = \"hover\";\n    EditorOption[EditorOption[\"inDiffEditor\"] = 59] = \"inDiffEditor\";\n    EditorOption[EditorOption[\"inlineSuggest\"] = 60] = \"inlineSuggest\";\n    EditorOption[EditorOption[\"letterSpacing\"] = 61] = \"letterSpacing\";\n    EditorOption[EditorOption[\"lightbulb\"] = 62] = \"lightbulb\";\n    EditorOption[EditorOption[\"lineDecorationsWidth\"] = 63] = \"lineDecorationsWidth\";\n    EditorOption[EditorOption[\"lineHeight\"] = 64] = \"lineHeight\";\n    EditorOption[EditorOption[\"lineNumbers\"] = 65] = \"lineNumbers\";\n    EditorOption[EditorOption[\"lineNumbersMinChars\"] = 66] = \"lineNumbersMinChars\";\n    EditorOption[EditorOption[\"linkedEditing\"] = 67] = \"linkedEditing\";\n    EditorOption[EditorOption[\"links\"] = 68] = \"links\";\n    EditorOption[EditorOption[\"matchBrackets\"] = 69] = \"matchBrackets\";\n    EditorOption[EditorOption[\"minimap\"] = 70] = \"minimap\";\n    EditorOption[EditorOption[\"mouseStyle\"] = 71] = \"mouseStyle\";\n    EditorOption[EditorOption[\"mouseWheelScrollSensitivity\"] = 72] = \"mouseWheelScrollSensitivity\";\n    EditorOption[EditorOption[\"mouseWheelZoom\"] = 73] = \"mouseWheelZoom\";\n    EditorOption[EditorOption[\"multiCursorMergeOverlapping\"] = 74] = \"multiCursorMergeOverlapping\";\n    EditorOption[EditorOption[\"multiCursorModifier\"] = 75] = \"multiCursorModifier\";\n    EditorOption[EditorOption[\"multiCursorPaste\"] = 76] = \"multiCursorPaste\";\n    EditorOption[EditorOption[\"multiCursorLimit\"] = 77] = \"multiCursorLimit\";\n    EditorOption[EditorOption[\"occurrencesHighlight\"] = 78] = \"occurrencesHighlight\";\n    EditorOption[EditorOption[\"overviewRulerBorder\"] = 79] = \"overviewRulerBorder\";\n    EditorOption[EditorOption[\"overviewRulerLanes\"] = 80] = \"overviewRulerLanes\";\n    EditorOption[EditorOption[\"padding\"] = 81] = \"padding\";\n    EditorOption[EditorOption[\"pasteAs\"] = 82] = \"pasteAs\";\n    EditorOption[EditorOption[\"parameterHints\"] = 83] = \"parameterHints\";\n    EditorOption[EditorOption[\"peekWidgetDefaultFocus\"] = 84] = \"peekWidgetDefaultFocus\";\n    EditorOption[EditorOption[\"definitionLinkOpensInPeek\"] = 85] = \"definitionLinkOpensInPeek\";\n    EditorOption[EditorOption[\"quickSuggestions\"] = 86] = \"quickSuggestions\";\n    EditorOption[EditorOption[\"quickSuggestionsDelay\"] = 87] = \"quickSuggestionsDelay\";\n    EditorOption[EditorOption[\"readOnly\"] = 88] = \"readOnly\";\n    EditorOption[EditorOption[\"readOnlyMessage\"] = 89] = \"readOnlyMessage\";\n    EditorOption[EditorOption[\"renameOnType\"] = 90] = \"renameOnType\";\n    EditorOption[EditorOption[\"renderControlCharacters\"] = 91] = \"renderControlCharacters\";\n    EditorOption[EditorOption[\"renderFinalNewline\"] = 92] = \"renderFinalNewline\";\n    EditorOption[EditorOption[\"renderLineHighlight\"] = 93] = \"renderLineHighlight\";\n    EditorOption[EditorOption[\"renderLineHighlightOnlyWhenFocus\"] = 94] = \"renderLineHighlightOnlyWhenFocus\";\n    EditorOption[EditorOption[\"renderValidationDecorations\"] = 95] = \"renderValidationDecorations\";\n    EditorOption[EditorOption[\"renderWhitespace\"] = 96] = \"renderWhitespace\";\n    EditorOption[EditorOption[\"revealHorizontalRightPadding\"] = 97] = \"revealHorizontalRightPadding\";\n    EditorOption[EditorOption[\"roundedSelection\"] = 98] = \"roundedSelection\";\n    EditorOption[EditorOption[\"rulers\"] = 99] = \"rulers\";\n    EditorOption[EditorOption[\"scrollbar\"] = 100] = \"scrollbar\";\n    EditorOption[EditorOption[\"scrollBeyondLastColumn\"] = 101] = \"scrollBeyondLastColumn\";\n    EditorOption[EditorOption[\"scrollBeyondLastLine\"] = 102] = \"scrollBeyondLastLine\";\n    EditorOption[EditorOption[\"scrollPredominantAxis\"] = 103] = \"scrollPredominantAxis\";\n    EditorOption[EditorOption[\"selectionClipboard\"] = 104] = \"selectionClipboard\";\n    EditorOption[EditorOption[\"selectionHighlight\"] = 105] = \"selectionHighlight\";\n    EditorOption[EditorOption[\"selectOnLineNumbers\"] = 106] = \"selectOnLineNumbers\";\n    EditorOption[EditorOption[\"showFoldingControls\"] = 107] = \"showFoldingControls\";\n    EditorOption[EditorOption[\"showUnused\"] = 108] = \"showUnused\";\n    EditorOption[EditorOption[\"snippetSuggestions\"] = 109] = \"snippetSuggestions\";\n    EditorOption[EditorOption[\"smartSelect\"] = 110] = \"smartSelect\";\n    EditorOption[EditorOption[\"smoothScrolling\"] = 111] = \"smoothScrolling\";\n    EditorOption[EditorOption[\"stickyScroll\"] = 112] = \"stickyScroll\";\n    EditorOption[EditorOption[\"stickyTabStops\"] = 113] = \"stickyTabStops\";\n    EditorOption[EditorOption[\"stopRenderingLineAfter\"] = 114] = \"stopRenderingLineAfter\";\n    EditorOption[EditorOption[\"suggest\"] = 115] = \"suggest\";\n    EditorOption[EditorOption[\"suggestFontSize\"] = 116] = \"suggestFontSize\";\n    EditorOption[EditorOption[\"suggestLineHeight\"] = 117] = \"suggestLineHeight\";\n    EditorOption[EditorOption[\"suggestOnTriggerCharacters\"] = 118] = \"suggestOnTriggerCharacters\";\n    EditorOption[EditorOption[\"suggestSelection\"] = 119] = \"suggestSelection\";\n    EditorOption[EditorOption[\"tabCompletion\"] = 120] = \"tabCompletion\";\n    EditorOption[EditorOption[\"tabIndex\"] = 121] = \"tabIndex\";\n    EditorOption[EditorOption[\"unicodeHighlighting\"] = 122] = \"unicodeHighlighting\";\n    EditorOption[EditorOption[\"unusualLineTerminators\"] = 123] = \"unusualLineTerminators\";\n    EditorOption[EditorOption[\"useShadowDOM\"] = 124] = \"useShadowDOM\";\n    EditorOption[EditorOption[\"useTabStops\"] = 125] = \"useTabStops\";\n    EditorOption[EditorOption[\"wordBreak\"] = 126] = \"wordBreak\";\n    EditorOption[EditorOption[\"wordSeparators\"] = 127] = \"wordSeparators\";\n    EditorOption[EditorOption[\"wordWrap\"] = 128] = \"wordWrap\";\n    EditorOption[EditorOption[\"wordWrapBreakAfterCharacters\"] = 129] = \"wordWrapBreakAfterCharacters\";\n    EditorOption[EditorOption[\"wordWrapBreakBeforeCharacters\"] = 130] = \"wordWrapBreakBeforeCharacters\";\n    EditorOption[EditorOption[\"wordWrapColumn\"] = 131] = \"wordWrapColumn\";\n    EditorOption[EditorOption[\"wordWrapOverride1\"] = 132] = \"wordWrapOverride1\";\n    EditorOption[EditorOption[\"wordWrapOverride2\"] = 133] = \"wordWrapOverride2\";\n    EditorOption[EditorOption[\"wrappingIndent\"] = 134] = \"wrappingIndent\";\n    EditorOption[EditorOption[\"wrappingStrategy\"] = 135] = \"wrappingStrategy\";\n    EditorOption[EditorOption[\"showDeprecated\"] = 136] = \"showDeprecated\";\n    EditorOption[EditorOption[\"inlayHints\"] = 137] = \"inlayHints\";\n    EditorOption[EditorOption[\"editorClassName\"] = 138] = \"editorClassName\";\n    EditorOption[EditorOption[\"pixelRatio\"] = 139] = \"pixelRatio\";\n    EditorOption[EditorOption[\"tabFocusMode\"] = 140] = \"tabFocusMode\";\n    EditorOption[EditorOption[\"layoutInfo\"] = 141] = \"layoutInfo\";\n    EditorOption[EditorOption[\"wrappingInfo\"] = 142] = \"wrappingInfo\";\n    EditorOption[EditorOption[\"defaultColorDecorators\"] = 143] = \"defaultColorDecorators\";\n    EditorOption[EditorOption[\"colorDecoratorsActivatedOn\"] = 144] = \"colorDecoratorsActivatedOn\";\n})(EditorOption || (EditorOption = {}));\n/**\n * End of line character preference.\n */\nexport var EndOfLinePreference;\n(function (EndOfLinePreference) {\n    /**\n     * Use the end of line character identified in the text buffer.\n     */\n    EndOfLinePreference[EndOfLinePreference[\"TextDefined\"] = 0] = \"TextDefined\";\n    /**\n     * Use line feed (\\n) as the end of line character.\n     */\n    EndOfLinePreference[EndOfLinePreference[\"LF\"] = 1] = \"LF\";\n    /**\n     * Use carriage return and line feed (\\r\\n) as the end of line character.\n     */\n    EndOfLinePreference[EndOfLinePreference[\"CRLF\"] = 2] = \"CRLF\";\n})(EndOfLinePreference || (EndOfLinePreference = {}));\n/**\n * End of line character preference.\n */\nexport var EndOfLineSequence;\n(function (EndOfLineSequence) {\n    /**\n     * Use line feed (\\n) as the end of line character.\n     */\n    EndOfLineSequence[EndOfLineSequence[\"LF\"] = 0] = \"LF\";\n    /**\n     * Use carriage return and line feed (\\r\\n) as the end of line character.\n     */\n    EndOfLineSequence[EndOfLineSequence[\"CRLF\"] = 1] = \"CRLF\";\n})(EndOfLineSequence || (EndOfLineSequence = {}));\n/**\n * Vertical Lane in the glyph margin of the editor.\n */\nexport var GlyphMarginLane;\n(function (GlyphMarginLane) {\n    GlyphMarginLane[GlyphMarginLane[\"Left\"] = 1] = \"Left\";\n    GlyphMarginLane[GlyphMarginLane[\"Right\"] = 2] = \"Right\";\n})(GlyphMarginLane || (GlyphMarginLane = {}));\n/**\n * Describes what to do with the indentation when pressing Enter.\n */\nexport var IndentAction;\n(function (IndentAction) {\n    /**\n     * Insert new line and copy the previous line's indentation.\n     */\n    IndentAction[IndentAction[\"None\"] = 0] = \"None\";\n    /**\n     * Insert new line and indent once (relative to the previous line's indentation).\n     */\n    IndentAction[IndentAction[\"Indent\"] = 1] = \"Indent\";\n    /**\n     * Insert two new lines:\n     *  - the first one indented which will hold the cursor\n     *  - the second one at the same indentation level\n     */\n    IndentAction[IndentAction[\"IndentOutdent\"] = 2] = \"IndentOutdent\";\n    /**\n     * Insert new line and outdent once (relative to the previous line's indentation).\n     */\n    IndentAction[IndentAction[\"Outdent\"] = 3] = \"Outdent\";\n})(IndentAction || (IndentAction = {}));\nexport var InjectedTextCursorStops;\n(function (InjectedTextCursorStops) {\n    InjectedTextCursorStops[InjectedTextCursorStops[\"Both\"] = 0] = \"Both\";\n    InjectedTextCursorStops[InjectedTextCursorStops[\"Right\"] = 1] = \"Right\";\n    InjectedTextCursorStops[InjectedTextCursorStops[\"Left\"] = 2] = \"Left\";\n    InjectedTextCursorStops[InjectedTextCursorStops[\"None\"] = 3] = \"None\";\n})(InjectedTextCursorStops || (InjectedTextCursorStops = {}));\nexport var InlayHintKind;\n(function (InlayHintKind) {\n    InlayHintKind[InlayHintKind[\"Type\"] = 1] = \"Type\";\n    InlayHintKind[InlayHintKind[\"Parameter\"] = 2] = \"Parameter\";\n})(InlayHintKind || (InlayHintKind = {}));\n/**\n * How an {@link InlineCompletionsProvider inline completion provider} was triggered.\n */\nexport var InlineCompletionTriggerKind;\n(function (InlineCompletionTriggerKind) {\n    /**\n     * Completion was triggered automatically while editing.\n     * It is sufficient to return a single completion item in this case.\n     */\n    InlineCompletionTriggerKind[InlineCompletionTriggerKind[\"Automatic\"] = 0] = \"Automatic\";\n    /**\n     * Completion was triggered explicitly by a user gesture.\n     * Return multiple completion items to enable cycling through them.\n     */\n    InlineCompletionTriggerKind[InlineCompletionTriggerKind[\"Explicit\"] = 1] = \"Explicit\";\n})(InlineCompletionTriggerKind || (InlineCompletionTriggerKind = {}));\n/**\n * Virtual Key Codes, the value does not hold any inherent meaning.\n * Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx\n * But these are \"more general\", as they should work across browsers & OS`s.\n */\nexport var KeyCode;\n(function (KeyCode) {\n    KeyCode[KeyCode[\"DependsOnKbLayout\"] = -1] = \"DependsOnKbLayout\";\n    /**\n     * Placed first to cover the 0 value of the enum.\n     */\n    KeyCode[KeyCode[\"Unknown\"] = 0] = \"Unknown\";\n    KeyCode[KeyCode[\"Backspace\"] = 1] = \"Backspace\";\n    KeyCode[KeyCode[\"Tab\"] = 2] = \"Tab\";\n    KeyCode[KeyCode[\"Enter\"] = 3] = \"Enter\";\n    KeyCode[KeyCode[\"Shift\"] = 4] = \"Shift\";\n    KeyCode[KeyCode[\"Ctrl\"] = 5] = \"Ctrl\";\n    KeyCode[KeyCode[\"Alt\"] = 6] = \"Alt\";\n    KeyCode[KeyCode[\"PauseBreak\"] = 7] = \"PauseBreak\";\n    KeyCode[KeyCode[\"CapsLock\"] = 8] = \"CapsLock\";\n    KeyCode[KeyCode[\"Escape\"] = 9] = \"Escape\";\n    KeyCode[KeyCode[\"Space\"] = 10] = \"Space\";\n    KeyCode[KeyCode[\"PageUp\"] = 11] = \"PageUp\";\n    KeyCode[KeyCode[\"PageDown\"] = 12] = \"PageDown\";\n    KeyCode[KeyCode[\"End\"] = 13] = \"End\";\n    KeyCode[KeyCode[\"Home\"] = 14] = \"Home\";\n    KeyCode[KeyCode[\"LeftArrow\"] = 15] = \"LeftArrow\";\n    KeyCode[KeyCode[\"UpArrow\"] = 16] = \"UpArrow\";\n    KeyCode[KeyCode[\"RightArrow\"] = 17] = \"RightArrow\";\n    KeyCode[KeyCode[\"DownArrow\"] = 18] = \"DownArrow\";\n    KeyCode[KeyCode[\"Insert\"] = 19] = \"Insert\";\n    KeyCode[KeyCode[\"Delete\"] = 20] = \"Delete\";\n    KeyCode[KeyCode[\"Digit0\"] = 21] = \"Digit0\";\n    KeyCode[KeyCode[\"Digit1\"] = 22] = \"Digit1\";\n    KeyCode[KeyCode[\"Digit2\"] = 23] = \"Digit2\";\n    KeyCode[KeyCode[\"Digit3\"] = 24] = \"Digit3\";\n    KeyCode[KeyCode[\"Digit4\"] = 25] = \"Digit4\";\n    KeyCode[KeyCode[\"Digit5\"] = 26] = \"Digit5\";\n    KeyCode[KeyCode[\"Digit6\"] = 27] = \"Digit6\";\n    KeyCode[KeyCode[\"Digit7\"] = 28] = \"Digit7\";\n    KeyCode[KeyCode[\"Digit8\"] = 29] = \"Digit8\";\n    KeyCode[KeyCode[\"Digit9\"] = 30] = \"Digit9\";\n    KeyCode[KeyCode[\"KeyA\"] = 31] = \"KeyA\";\n    KeyCode[KeyCode[\"KeyB\"] = 32] = \"KeyB\";\n    KeyCode[KeyCode[\"KeyC\"] = 33] = \"KeyC\";\n    KeyCode[KeyCode[\"KeyD\"] = 34] = \"KeyD\";\n    KeyCode[KeyCode[\"KeyE\"] = 35] = \"KeyE\";\n    KeyCode[KeyCode[\"KeyF\"] = 36] = \"KeyF\";\n    KeyCode[KeyCode[\"KeyG\"] = 37] = \"KeyG\";\n    KeyCode[KeyCode[\"KeyH\"] = 38] = \"KeyH\";\n    KeyCode[KeyCode[\"KeyI\"] = 39] = \"KeyI\";\n    KeyCode[KeyCode[\"KeyJ\"] = 40] = \"KeyJ\";\n    KeyCode[KeyCode[\"KeyK\"] = 41] = \"KeyK\";\n    KeyCode[KeyCode[\"KeyL\"] = 42] = \"KeyL\";\n    KeyCode[KeyCode[\"KeyM\"] = 43] = \"KeyM\";\n    KeyCode[KeyCode[\"KeyN\"] = 44] = \"KeyN\";\n    KeyCode[KeyCode[\"KeyO\"] = 45] = \"KeyO\";\n    KeyCode[KeyCode[\"KeyP\"] = 46] = \"KeyP\";\n    KeyCode[KeyCode[\"KeyQ\"] = 47] = \"KeyQ\";\n    KeyCode[KeyCode[\"KeyR\"] = 48] = \"KeyR\";\n    KeyCode[KeyCode[\"KeyS\"] = 49] = \"KeyS\";\n    KeyCode[KeyCode[\"KeyT\"] = 50] = \"KeyT\";\n    KeyCode[KeyCode[\"KeyU\"] = 51] = \"KeyU\";\n    KeyCode[KeyCode[\"KeyV\"] = 52] = \"KeyV\";\n    KeyCode[KeyCode[\"KeyW\"] = 53] = \"KeyW\";\n    KeyCode[KeyCode[\"KeyX\"] = 54] = \"KeyX\";\n    KeyCode[KeyCode[\"KeyY\"] = 55] = \"KeyY\";\n    KeyCode[KeyCode[\"KeyZ\"] = 56] = \"KeyZ\";\n    KeyCode[KeyCode[\"Meta\"] = 57] = \"Meta\";\n    KeyCode[KeyCode[\"ContextMenu\"] = 58] = \"ContextMenu\";\n    KeyCode[KeyCode[\"F1\"] = 59] = \"F1\";\n    KeyCode[KeyCode[\"F2\"] = 60] = \"F2\";\n    KeyCode[KeyCode[\"F3\"] = 61] = \"F3\";\n    KeyCode[KeyCode[\"F4\"] = 62] = \"F4\";\n    KeyCode[KeyCode[\"F5\"] = 63] = \"F5\";\n    KeyCode[KeyCode[\"F6\"] = 64] = \"F6\";\n    KeyCode[KeyCode[\"F7\"] = 65] = \"F7\";\n    KeyCode[KeyCode[\"F8\"] = 66] = \"F8\";\n    KeyCode[KeyCode[\"F9\"] = 67] = \"F9\";\n    KeyCode[KeyCode[\"F10\"] = 68] = \"F10\";\n    KeyCode[KeyCode[\"F11\"] = 69] = \"F11\";\n    KeyCode[KeyCode[\"F12\"] = 70] = \"F12\";\n    KeyCode[KeyCode[\"F13\"] = 71] = \"F13\";\n    KeyCode[KeyCode[\"F14\"] = 72] = \"F14\";\n    KeyCode[KeyCode[\"F15\"] = 73] = \"F15\";\n    KeyCode[KeyCode[\"F16\"] = 74] = \"F16\";\n    KeyCode[KeyCode[\"F17\"] = 75] = \"F17\";\n    KeyCode[KeyCode[\"F18\"] = 76] = \"F18\";\n    KeyCode[KeyCode[\"F19\"] = 77] = \"F19\";\n    KeyCode[KeyCode[\"F20\"] = 78] = \"F20\";\n    KeyCode[KeyCode[\"F21\"] = 79] = \"F21\";\n    KeyCode[KeyCode[\"F22\"] = 80] = \"F22\";\n    KeyCode[KeyCode[\"F23\"] = 81] = \"F23\";\n    KeyCode[KeyCode[\"F24\"] = 82] = \"F24\";\n    KeyCode[KeyCode[\"NumLock\"] = 83] = \"NumLock\";\n    KeyCode[KeyCode[\"ScrollLock\"] = 84] = \"ScrollLock\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the ';:' key\n     */\n    KeyCode[KeyCode[\"Semicolon\"] = 85] = \"Semicolon\";\n    /**\n     * For any country/region, the '+' key\n     * For the US standard keyboard, the '=+' key\n     */\n    KeyCode[KeyCode[\"Equal\"] = 86] = \"Equal\";\n    /**\n     * For any country/region, the ',' key\n     * For the US standard keyboard, the ',<' key\n     */\n    KeyCode[KeyCode[\"Comma\"] = 87] = \"Comma\";\n    /**\n     * For any country/region, the '-' key\n     * For the US standard keyboard, the '-_' key\n     */\n    KeyCode[KeyCode[\"Minus\"] = 88] = \"Minus\";\n    /**\n     * For any country/region, the '.' key\n     * For the US standard keyboard, the '.>' key\n     */\n    KeyCode[KeyCode[\"Period\"] = 89] = \"Period\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the '/?' key\n     */\n    KeyCode[KeyCode[\"Slash\"] = 90] = \"Slash\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the '`~' key\n     */\n    KeyCode[KeyCode[\"Backquote\"] = 91] = \"Backquote\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the '[{' key\n     */\n    KeyCode[KeyCode[\"BracketLeft\"] = 92] = \"BracketLeft\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the '\\|' key\n     */\n    KeyCode[KeyCode[\"Backslash\"] = 93] = \"Backslash\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the ']}' key\n     */\n    KeyCode[KeyCode[\"BracketRight\"] = 94] = \"BracketRight\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     * For the US standard keyboard, the ''\"' key\n     */\n    KeyCode[KeyCode[\"Quote\"] = 95] = \"Quote\";\n    /**\n     * Used for miscellaneous characters; it can vary by keyboard.\n     */\n    KeyCode[KeyCode[\"OEM_8\"] = 96] = \"OEM_8\";\n    /**\n     * Either the angle bracket key or the backslash key on the RT 102-key keyboard.\n     */\n    KeyCode[KeyCode[\"IntlBackslash\"] = 97] = \"IntlBackslash\";\n    KeyCode[KeyCode[\"Numpad0\"] = 98] = \"Numpad0\";\n    KeyCode[KeyCode[\"Numpad1\"] = 99] = \"Numpad1\";\n    KeyCode[KeyCode[\"Numpad2\"] = 100] = \"Numpad2\";\n    KeyCode[KeyCode[\"Numpad3\"] = 101] = \"Numpad3\";\n    KeyCode[KeyCode[\"Numpad4\"] = 102] = \"Numpad4\";\n    KeyCode[KeyCode[\"Numpad5\"] = 103] = \"Numpad5\";\n    KeyCode[KeyCode[\"Numpad6\"] = 104] = \"Numpad6\";\n    KeyCode[KeyCode[\"Numpad7\"] = 105] = \"Numpad7\";\n    KeyCode[KeyCode[\"Numpad8\"] = 106] = \"Numpad8\";\n    KeyCode[KeyCode[\"Numpad9\"] = 107] = \"Numpad9\";\n    KeyCode[KeyCode[\"NumpadMultiply\"] = 108] = \"NumpadMultiply\";\n    KeyCode[KeyCode[\"NumpadAdd\"] = 109] = \"NumpadAdd\";\n    KeyCode[KeyCode[\"NUMPAD_SEPARATOR\"] = 110] = \"NUMPAD_SEPARATOR\";\n    KeyCode[KeyCode[\"NumpadSubtract\"] = 111] = \"NumpadSubtract\";\n    KeyCode[KeyCode[\"NumpadDecimal\"] = 112] = \"NumpadDecimal\";\n    KeyCode[KeyCode[\"NumpadDivide\"] = 113] = \"NumpadDivide\";\n    /**\n     * Cover all key codes when IME is processing input.\n     */\n    KeyCode[KeyCode[\"KEY_IN_COMPOSITION\"] = 114] = \"KEY_IN_COMPOSITION\";\n    KeyCode[KeyCode[\"ABNT_C1\"] = 115] = \"ABNT_C1\";\n    KeyCode[KeyCode[\"ABNT_C2\"] = 116] = \"ABNT_C2\";\n    KeyCode[KeyCode[\"AudioVolumeMute\"] = 117] = \"AudioVolumeMute\";\n    KeyCode[KeyCode[\"AudioVolumeUp\"] = 118] = \"AudioVolumeUp\";\n    KeyCode[KeyCode[\"AudioVolumeDown\"] = 119] = \"AudioVolumeDown\";\n    KeyCode[KeyCode[\"BrowserSearch\"] = 120] = \"BrowserSearch\";\n    KeyCode[KeyCode[\"BrowserHome\"] = 121] = \"BrowserHome\";\n    KeyCode[KeyCode[\"BrowserBack\"] = 122] = \"BrowserBack\";\n    KeyCode[KeyCode[\"BrowserForward\"] = 123] = \"BrowserForward\";\n    KeyCode[KeyCode[\"MediaTrackNext\"] = 124] = \"MediaTrackNext\";\n    KeyCode[KeyCode[\"MediaTrackPrevious\"] = 125] = \"MediaTrackPrevious\";\n    KeyCode[KeyCode[\"MediaStop\"] = 126] = \"MediaStop\";\n    KeyCode[KeyCode[\"MediaPlayPause\"] = 127] = \"MediaPlayPause\";\n    KeyCode[KeyCode[\"LaunchMediaPlayer\"] = 128] = \"LaunchMediaPlayer\";\n    KeyCode[KeyCode[\"LaunchMail\"] = 129] = \"LaunchMail\";\n    KeyCode[KeyCode[\"LaunchApp2\"] = 130] = \"LaunchApp2\";\n    /**\n     * VK_CLEAR, 0x0C, CLEAR key\n     */\n    KeyCode[KeyCode[\"Clear\"] = 131] = \"Clear\";\n    /**\n     * Placed last to cover the length of the enum.\n     * Please do not depend on this value!\n     */\n    KeyCode[KeyCode[\"MAX_VALUE\"] = 132] = \"MAX_VALUE\";\n})(KeyCode || (KeyCode = {}));\nexport var MarkerSeverity;\n(function (MarkerSeverity) {\n    MarkerSeverity[MarkerSeverity[\"Hint\"] = 1] = \"Hint\";\n    MarkerSeverity[MarkerSeverity[\"Info\"] = 2] = \"Info\";\n    MarkerSeverity[MarkerSeverity[\"Warning\"] = 4] = \"Warning\";\n    MarkerSeverity[MarkerSeverity[\"Error\"] = 8] = \"Error\";\n})(MarkerSeverity || (MarkerSeverity = {}));\nexport var MarkerTag;\n(function (MarkerTag) {\n    MarkerTag[MarkerTag[\"Unnecessary\"] = 1] = \"Unnecessary\";\n    MarkerTag[MarkerTag[\"Deprecated\"] = 2] = \"Deprecated\";\n})(MarkerTag || (MarkerTag = {}));\n/**\n * Position in the minimap to render the decoration.\n */\nexport var MinimapPosition;\n(function (MinimapPosition) {\n    MinimapPosition[MinimapPosition[\"Inline\"] = 1] = \"Inline\";\n    MinimapPosition[MinimapPosition[\"Gutter\"] = 2] = \"Gutter\";\n})(MinimapPosition || (MinimapPosition = {}));\n/**\n * Type of hit element with the mouse in the editor.\n */\nexport var MouseTargetType;\n(function (MouseTargetType) {\n    /**\n     * Mouse is on top of an unknown element.\n     */\n    MouseTargetType[MouseTargetType[\"UNKNOWN\"] = 0] = \"UNKNOWN\";\n    /**\n     * Mouse is on top of the textarea used for input.\n     */\n    MouseTargetType[MouseTargetType[\"TEXTAREA\"] = 1] = \"TEXTAREA\";\n    /**\n     * Mouse is on top of the glyph margin\n     */\n    MouseTargetType[MouseTargetType[\"GUTTER_GLYPH_MARGIN\"] = 2] = \"GUTTER_GLYPH_MARGIN\";\n    /**\n     * Mouse is on top of the line numbers\n     */\n    MouseTargetType[MouseTargetType[\"GUTTER_LINE_NUMBERS\"] = 3] = \"GUTTER_LINE_NUMBERS\";\n    /**\n     * Mouse is on top of the line decorations\n     */\n    MouseTargetType[MouseTargetType[\"GUTTER_LINE_DECORATIONS\"] = 4] = \"GUTTER_LINE_DECORATIONS\";\n    /**\n     * Mouse is on top of the whitespace left in the gutter by a view zone.\n     */\n    MouseTargetType[MouseTargetType[\"GUTTER_VIEW_ZONE\"] = 5] = \"GUTTER_VIEW_ZONE\";\n    /**\n     * Mouse is on top of text in the content.\n     */\n    MouseTargetType[MouseTargetType[\"CONTENT_TEXT\"] = 6] = \"CONTENT_TEXT\";\n    /**\n     * Mouse is on top of empty space in the content (e.g. after line text or below last line)\n     */\n    MouseTargetType[MouseTargetType[\"CONTENT_EMPTY\"] = 7] = \"CONTENT_EMPTY\";\n    /**\n     * Mouse is on top of a view zone in the content.\n     */\n    MouseTargetType[MouseTargetType[\"CONTENT_VIEW_ZONE\"] = 8] = \"CONTENT_VIEW_ZONE\";\n    /**\n     * Mouse is on top of a content widget.\n     */\n    MouseTargetType[MouseTargetType[\"CONTENT_WIDGET\"] = 9] = \"CONTENT_WIDGET\";\n    /**\n     * Mouse is on top of the decorations overview ruler.\n     */\n    MouseTargetType[MouseTargetType[\"OVERVIEW_RULER\"] = 10] = \"OVERVIEW_RULER\";\n    /**\n     * Mouse is on top of a scrollbar.\n     */\n    MouseTargetType[MouseTargetType[\"SCROLLBAR\"] = 11] = \"SCROLLBAR\";\n    /**\n     * Mouse is on top of an overlay widget.\n     */\n    MouseTargetType[MouseTargetType[\"OVERLAY_WIDGET\"] = 12] = \"OVERLAY_WIDGET\";\n    /**\n     * Mouse is outside of the editor.\n     */\n    MouseTargetType[MouseTargetType[\"OUTSIDE_EDITOR\"] = 13] = \"OUTSIDE_EDITOR\";\n})(MouseTargetType || (MouseTargetType = {}));\n/**\n * A positioning preference for rendering overlay widgets.\n */\nexport var OverlayWidgetPositionPreference;\n(function (OverlayWidgetPositionPreference) {\n    /**\n     * Position the overlay widget in the top right corner\n     */\n    OverlayWidgetPositionPreference[OverlayWidgetPositionPreference[\"TOP_RIGHT_CORNER\"] = 0] = \"TOP_RIGHT_CORNER\";\n    /**\n     * Position the overlay widget in the bottom right corner\n     */\n    OverlayWidgetPositionPreference[OverlayWidgetPositionPreference[\"BOTTOM_RIGHT_CORNER\"] = 1] = \"BOTTOM_RIGHT_CORNER\";\n    /**\n     * Position the overlay widget in the top center\n     */\n    OverlayWidgetPositionPreference[OverlayWidgetPositionPreference[\"TOP_CENTER\"] = 2] = \"TOP_CENTER\";\n})(OverlayWidgetPositionPreference || (OverlayWidgetPositionPreference = {}));\n/**\n * Vertical Lane in the overview ruler of the editor.\n */\nexport var OverviewRulerLane;\n(function (OverviewRulerLane) {\n    OverviewRulerLane[OverviewRulerLane[\"Left\"] = 1] = \"Left\";\n    OverviewRulerLane[OverviewRulerLane[\"Center\"] = 2] = \"Center\";\n    OverviewRulerLane[OverviewRulerLane[\"Right\"] = 4] = \"Right\";\n    OverviewRulerLane[OverviewRulerLane[\"Full\"] = 7] = \"Full\";\n})(OverviewRulerLane || (OverviewRulerLane = {}));\nexport var PositionAffinity;\n(function (PositionAffinity) {\n    /**\n     * Prefers the left most position.\n    */\n    PositionAffinity[PositionAffinity[\"Left\"] = 0] = \"Left\";\n    /**\n     * Prefers the right most position.\n    */\n    PositionAffinity[PositionAffinity[\"Right\"] = 1] = \"Right\";\n    /**\n     * No preference.\n    */\n    PositionAffinity[PositionAffinity[\"None\"] = 2] = \"None\";\n    /**\n     * If the given position is on injected text, prefers the position left of it.\n    */\n    PositionAffinity[PositionAffinity[\"LeftOfInjectedText\"] = 3] = \"LeftOfInjectedText\";\n    /**\n     * If the given position is on injected text, prefers the position right of it.\n    */\n    PositionAffinity[PositionAffinity[\"RightOfInjectedText\"] = 4] = \"RightOfInjectedText\";\n})(PositionAffinity || (PositionAffinity = {}));\nexport var RenderLineNumbersType;\n(function (RenderLineNumbersType) {\n    RenderLineNumbersType[RenderLineNumbersType[\"Off\"] = 0] = \"Off\";\n    RenderLineNumbersType[RenderLineNumbersType[\"On\"] = 1] = \"On\";\n    RenderLineNumbersType[RenderLineNumbersType[\"Relative\"] = 2] = \"Relative\";\n    RenderLineNumbersType[RenderLineNumbersType[\"Interval\"] = 3] = \"Interval\";\n    RenderLineNumbersType[RenderLineNumbersType[\"Custom\"] = 4] = \"Custom\";\n})(RenderLineNumbersType || (RenderLineNumbersType = {}));\nexport var RenderMinimap;\n(function (RenderMinimap) {\n    RenderMinimap[RenderMinimap[\"None\"] = 0] = \"None\";\n    RenderMinimap[RenderMinimap[\"Text\"] = 1] = \"Text\";\n    RenderMinimap[RenderMinimap[\"Blocks\"] = 2] = \"Blocks\";\n})(RenderMinimap || (RenderMinimap = {}));\nexport var ScrollType;\n(function (ScrollType) {\n    ScrollType[ScrollType[\"Smooth\"] = 0] = \"Smooth\";\n    ScrollType[ScrollType[\"Immediate\"] = 1] = \"Immediate\";\n})(ScrollType || (ScrollType = {}));\nexport var ScrollbarVisibility;\n(function (ScrollbarVisibility) {\n    ScrollbarVisibility[ScrollbarVisibility[\"Auto\"] = 1] = \"Auto\";\n    ScrollbarVisibility[ScrollbarVisibility[\"Hidden\"] = 2] = \"Hidden\";\n    ScrollbarVisibility[ScrollbarVisibility[\"Visible\"] = 3] = \"Visible\";\n})(ScrollbarVisibility || (ScrollbarVisibility = {}));\n/**\n * The direction of a selection.\n */\nexport var SelectionDirection;\n(function (SelectionDirection) {\n    /**\n     * The selection starts above where it ends.\n     */\n    SelectionDirection[SelectionDirection[\"LTR\"] = 0] = \"LTR\";\n    /**\n     * The selection starts below where it ends.\n     */\n    SelectionDirection[SelectionDirection[\"RTL\"] = 1] = \"RTL\";\n})(SelectionDirection || (SelectionDirection = {}));\nexport var SignatureHelpTriggerKind;\n(function (SignatureHelpTriggerKind) {\n    SignatureHelpTriggerKind[SignatureHelpTriggerKind[\"Invoke\"] = 1] = \"Invoke\";\n    SignatureHelpTriggerKind[SignatureHelpTriggerKind[\"TriggerCharacter\"] = 2] = \"TriggerCharacter\";\n    SignatureHelpTriggerKind[SignatureHelpTriggerKind[\"ContentChange\"] = 3] = \"ContentChange\";\n})(SignatureHelpTriggerKind || (SignatureHelpTriggerKind = {}));\n/**\n * A symbol kind.\n */\nexport var SymbolKind;\n(function (SymbolKind) {\n    SymbolKind[SymbolKind[\"File\"] = 0] = \"File\";\n    SymbolKind[SymbolKind[\"Module\"] = 1] = \"Module\";\n    SymbolKind[SymbolKind[\"Namespace\"] = 2] = \"Namespace\";\n    SymbolKind[SymbolKind[\"Package\"] = 3] = \"Package\";\n    SymbolKind[SymbolKind[\"Class\"] = 4] = \"Class\";\n    SymbolKind[SymbolKind[\"Method\"] = 5] = \"Method\";\n    SymbolKind[SymbolKind[\"Property\"] = 6] = \"Property\";\n    SymbolKind[SymbolKind[\"Field\"] = 7] = \"Field\";\n    SymbolKind[SymbolKind[\"Constructor\"] = 8] = \"Constructor\";\n    SymbolKind[SymbolKind[\"Enum\"] = 9] = \"Enum\";\n    SymbolKind[SymbolKind[\"Interface\"] = 10] = \"Interface\";\n    SymbolKind[SymbolKind[\"Function\"] = 11] = \"Function\";\n    SymbolKind[SymbolKind[\"Variable\"] = 12] = \"Variable\";\n    SymbolKind[SymbolKind[\"Constant\"] = 13] = \"Constant\";\n    SymbolKind[SymbolKind[\"String\"] = 14] = \"String\";\n    SymbolKind[SymbolKind[\"Number\"] = 15] = \"Number\";\n    SymbolKind[SymbolKind[\"Boolean\"] = 16] = \"Boolean\";\n    SymbolKind[SymbolKind[\"Array\"] = 17] = \"Array\";\n    SymbolKind[SymbolKind[\"Object\"] = 18] = \"Object\";\n    SymbolKind[SymbolKind[\"Key\"] = 19] = \"Key\";\n    SymbolKind[SymbolKind[\"Null\"] = 20] = \"Null\";\n    SymbolKind[SymbolKind[\"EnumMember\"] = 21] = \"EnumMember\";\n    SymbolKind[SymbolKind[\"Struct\"] = 22] = \"Struct\";\n    SymbolKind[SymbolKind[\"Event\"] = 23] = \"Event\";\n    SymbolKind[SymbolKind[\"Operator\"] = 24] = \"Operator\";\n    SymbolKind[SymbolKind[\"TypeParameter\"] = 25] = \"TypeParameter\";\n})(SymbolKind || (SymbolKind = {}));\nexport var SymbolTag;\n(function (SymbolTag) {\n    SymbolTag[SymbolTag[\"Deprecated\"] = 1] = \"Deprecated\";\n})(SymbolTag || (SymbolTag = {}));\n/**\n * The kind of animation in which the editor's cursor should be rendered.\n */\nexport var TextEditorCursorBlinkingStyle;\n(function (TextEditorCursorBlinkingStyle) {\n    /**\n     * Hidden\n     */\n    TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle[\"Hidden\"] = 0] = \"Hidden\";\n    /**\n     * Blinking\n     */\n    TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle[\"Blink\"] = 1] = \"Blink\";\n    /**\n     * Blinking with smooth fading\n     */\n    TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle[\"Smooth\"] = 2] = \"Smooth\";\n    /**\n     * Blinking with prolonged filled state and smooth fading\n     */\n    TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle[\"Phase\"] = 3] = \"Phase\";\n    /**\n     * Expand collapse animation on the y axis\n     */\n    TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle[\"Expand\"] = 4] = \"Expand\";\n    /**\n     * No-Blinking\n     */\n    TextEditorCursorBlinkingStyle[TextEditorCursorBlinkingStyle[\"Solid\"] = 5] = \"Solid\";\n})(TextEditorCursorBlinkingStyle || (TextEditorCursorBlinkingStyle = {}));\n/**\n * The style in which the editor's cursor should be rendered.\n */\nexport var TextEditorCursorStyle;\n(function (TextEditorCursorStyle) {\n    /**\n     * As a vertical line (sitting between two characters).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"Line\"] = 1] = \"Line\";\n    /**\n     * As a block (sitting on top of a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"Block\"] = 2] = \"Block\";\n    /**\n     * As a horizontal line (sitting under a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"Underline\"] = 3] = \"Underline\";\n    /**\n     * As a thin vertical line (sitting between two characters).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"LineThin\"] = 4] = \"LineThin\";\n    /**\n     * As an outlined block (sitting on top of a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"BlockOutline\"] = 5] = \"BlockOutline\";\n    /**\n     * As a thin horizontal line (sitting under a character).\n     */\n    TextEditorCursorStyle[TextEditorCursorStyle[\"UnderlineThin\"] = 6] = \"UnderlineThin\";\n})(TextEditorCursorStyle || (TextEditorCursorStyle = {}));\n/**\n * Describes the behavior of decorations when typing/editing near their edges.\n * Note: Please do not edit the values, as they very carefully match `DecorationRangeBehavior`\n */\nexport var TrackedRangeStickiness;\n(function (TrackedRangeStickiness) {\n    TrackedRangeStickiness[TrackedRangeStickiness[\"AlwaysGrowsWhenTypingAtEdges\"] = 0] = \"AlwaysGrowsWhenTypingAtEdges\";\n    TrackedRangeStickiness[TrackedRangeStickiness[\"NeverGrowsWhenTypingAtEdges\"] = 1] = \"NeverGrowsWhenTypingAtEdges\";\n    TrackedRangeStickiness[TrackedRangeStickiness[\"GrowsOnlyWhenTypingBefore\"] = 2] = \"GrowsOnlyWhenTypingBefore\";\n    TrackedRangeStickiness[TrackedRangeStickiness[\"GrowsOnlyWhenTypingAfter\"] = 3] = \"GrowsOnlyWhenTypingAfter\";\n})(TrackedRangeStickiness || (TrackedRangeStickiness = {}));\n/**\n * Describes how to indent wrapped lines.\n */\nexport var WrappingIndent;\n(function (WrappingIndent) {\n    /**\n     * No indentation => wrapped lines begin at column 1.\n     */\n    WrappingIndent[WrappingIndent[\"None\"] = 0] = \"None\";\n    /**\n     * Same => wrapped lines get the same indentation as the parent.\n     */\n    WrappingIndent[WrappingIndent[\"Same\"] = 1] = \"Same\";\n    /**\n     * Indent => wrapped lines get +1 indentation toward the parent.\n     */\n    WrappingIndent[WrappingIndent[\"Indent\"] = 2] = \"Indent\";\n    /**\n     * DeepIndent => wrapped lines get +2 indentation toward the parent.\n     */\n    WrappingIndent[WrappingIndent[\"DeepIndent\"] = 3] = \"DeepIndent\";\n})(WrappingIndent || (WrappingIndent = {}));\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { CancellationTokenSource } from '../../../base/common/cancellation.js';\nimport { Emitter } from '../../../base/common/event.js';\nimport { KeyChord } from '../../../base/common/keyCodes.js';\nimport { URI } from '../../../base/common/uri.js';\nimport { Position } from '../core/position.js';\nimport { Range } from '../core/range.js';\nimport { Selection } from '../core/selection.js';\nimport { Token } from '../languages.js';\nimport * as standaloneEnums from '../standalone/standaloneEnums.js';\nexport class KeyMod {\n    static chord(firstPart, secondPart) {\n        return KeyChord(firstPart, secondPart);\n    }\n}\nKeyMod.CtrlCmd = 2048 /* ConstKeyMod.CtrlCmd */;\nKeyMod.Shift = 1024 /* ConstKeyMod.Shift */;\nKeyMod.Alt = 512 /* ConstKeyMod.Alt */;\nKeyMod.WinCtrl = 256 /* ConstKeyMod.WinCtrl */;\nexport function createMonacoBaseAPI() {\n    return {\n        editor: undefined,\n        languages: undefined,\n        CancellationTokenSource: CancellationTokenSource,\n        Emitter: Emitter,\n        KeyCode: standaloneEnums.KeyCode,\n        KeyMod: KeyMod,\n        Position: Position,\n        Range: Range,\n        Selection: Selection,\n        SelectionDirection: standaloneEnums.SelectionDirection,\n        MarkerSeverity: standaloneEnums.MarkerSeverity,\n        MarkerTag: standaloneEnums.MarkerTag,\n        Uri: URI,\n        Token: Token\n    };\n}\n","/**\n * Uses a LRU cache to make a given parametrized function cached.\n * Caches just the last value.\n * The key must be JSON serializable.\n*/\nexport class LRUCachedFunction {\n    constructor(fn) {\n        this.fn = fn;\n        this.lastCache = undefined;\n        this.lastArgKey = undefined;\n    }\n    get(arg) {\n        const key = JSON.stringify(arg);\n        if (this.lastArgKey !== key) {\n            this.lastArgKey = key;\n            this.lastCache = this.fn(arg);\n        }\n        return this.lastCache;\n    }\n}\n/**\n * Uses an unbounded cache (referential equality) to memoize the results of the given function.\n*/\nexport class CachedFunction {\n    get cachedValues() {\n        return this._map;\n    }\n    constructor(fn) {\n        this.fn = fn;\n        this._map = new Map();\n    }\n    get(arg) {\n        if (this._map.has(arg)) {\n            return this._map.get(arg);\n        }\n        const value = this.fn(arg);\n        this._map.set(arg, value);\n        return value;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport class Lazy {\n    constructor(executor) {\n        this.executor = executor;\n        this._didRun = false;\n    }\n    /**\n     * Get the wrapped value.\n     *\n     * This will force evaluation of the lazy value if it has not been resolved yet. Lazy values are only\n     * resolved once. `getValue` will re-throw exceptions that are hit while resolving the value\n     */\n    get value() {\n        if (!this._didRun) {\n            try {\n                this._value = this.executor();\n            }\n            catch (err) {\n                this._error = err;\n            }\n            finally {\n                this._didRun = true;\n            }\n        }\n        if (this._error) {\n            throw this._error;\n        }\n        return this._value;\n    }\n    /**\n     * Get the wrapped value without forcing evaluation.\n     */\n    get rawValue() { return this._value; }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar _a;\nimport { LRUCachedFunction } from './cache.js';\nimport { Lazy } from './lazy.js';\nexport function isFalsyOrWhitespace(str) {\n    if (!str || typeof str !== 'string') {\n        return true;\n    }\n    return str.trim().length === 0;\n}\nconst _formatRegexp = /{(\\d+)}/g;\n/**\n * Helper to produce a string with a variable number of arguments. Insert variable segments\n * into the string using the {n} notation where N is the index of the argument following the string.\n * @param value string to which formatting is applied\n * @param args replacements for {n}-entries\n */\nexport function format(value, ...args) {\n    if (args.length === 0) {\n        return value;\n    }\n    return value.replace(_formatRegexp, function (match, group) {\n        const idx = parseInt(group, 10);\n        return isNaN(idx) || idx < 0 || idx >= args.length ?\n            match :\n            args[idx];\n    });\n}\n/**\n * Converts HTML characters inside the string to use entities instead. Makes the string safe from\n * being used e.g. in HTMLElement.innerHTML.\n */\nexport function escape(html) {\n    return html.replace(/[<>&]/g, function (match) {\n        switch (match) {\n            case '<': return '<';\n            case '>': return '>';\n            case '&': return '&';\n            default: return match;\n        }\n    });\n}\n/**\n * Escapes regular expression characters in a given string\n */\nexport function escapeRegExpCharacters(value) {\n    return value.replace(/[\\\\\\{\\}\\*\\+\\?\\|\\^\\$\\.\\[\\]\\(\\)]/g, '\\\\$&');\n}\n/**\n * Removes all occurrences of needle from the beginning and end of haystack.\n * @param haystack string to trim\n * @param needle the thing to trim (default is a blank)\n */\nexport function trim(haystack, needle = ' ') {\n    const trimmed = ltrim(haystack, needle);\n    return rtrim(trimmed, needle);\n}\n/**\n * Removes all occurrences of needle from the beginning of haystack.\n * @param haystack string to trim\n * @param needle the thing to trim\n */\nexport function ltrim(haystack, needle) {\n    if (!haystack || !needle) {\n        return haystack;\n    }\n    const needleLen = needle.length;\n    if (needleLen === 0 || haystack.length === 0) {\n        return haystack;\n    }\n    let offset = 0;\n    while (haystack.indexOf(needle, offset) === offset) {\n        offset = offset + needleLen;\n    }\n    return haystack.substring(offset);\n}\n/**\n * Removes all occurrences of needle from the end of haystack.\n * @param haystack string to trim\n * @param needle the thing to trim\n */\nexport function rtrim(haystack, needle) {\n    if (!haystack || !needle) {\n        return haystack;\n    }\n    const needleLen = needle.length, haystackLen = haystack.length;\n    if (needleLen === 0 || haystackLen === 0) {\n        return haystack;\n    }\n    let offset = haystackLen, idx = -1;\n    while (true) {\n        idx = haystack.lastIndexOf(needle, offset - 1);\n        if (idx === -1 || idx + needleLen !== offset) {\n            break;\n        }\n        if (idx === 0) {\n            return '';\n        }\n        offset = idx;\n    }\n    return haystack.substring(0, offset);\n}\nexport function convertSimple2RegExpPattern(pattern) {\n    return pattern.replace(/[\\-\\\\\\{\\}\\+\\?\\|\\^\\$\\.\\,\\[\\]\\(\\)\\#\\s]/g, '\\\\$&').replace(/[\\*]/g, '.*');\n}\nexport function stripWildcards(pattern) {\n    return pattern.replace(/\\*/g, '');\n}\nexport function createRegExp(searchString, isRegex, options = {}) {\n    if (!searchString) {\n        throw new Error('Cannot create regex from empty string');\n    }\n    if (!isRegex) {\n        searchString = escapeRegExpCharacters(searchString);\n    }\n    if (options.wholeWord) {\n        if (!/\\B/.test(searchString.charAt(0))) {\n            searchString = '\\\\b' + searchString;\n        }\n        if (!/\\B/.test(searchString.charAt(searchString.length - 1))) {\n            searchString = searchString + '\\\\b';\n        }\n    }\n    let modifiers = '';\n    if (options.global) {\n        modifiers += 'g';\n    }\n    if (!options.matchCase) {\n        modifiers += 'i';\n    }\n    if (options.multiline) {\n        modifiers += 'm';\n    }\n    if (options.unicode) {\n        modifiers += 'u';\n    }\n    return new RegExp(searchString, modifiers);\n}\nexport function regExpLeadsToEndlessLoop(regexp) {\n    // Exit early if it's one of these special cases which are meant to match\n    // against an empty string\n    if (regexp.source === '^' || regexp.source === '^$' || regexp.source === '$' || regexp.source === '^\\\\s*$') {\n        return false;\n    }\n    // We check against an empty string. If the regular expression doesn't advance\n    // (e.g. ends in an endless loop) it will match an empty string.\n    const match = regexp.exec('');\n    return !!(match && regexp.lastIndex === 0);\n}\nexport function regExpFlags(regexp) {\n    return (regexp.global ? 'g' : '')\n        + (regexp.ignoreCase ? 'i' : '')\n        + (regexp.multiline ? 'm' : '')\n        + (regexp /* standalone editor compilation */.unicode ? 'u' : '');\n}\nexport function splitLines(str) {\n    return str.split(/\\r\\n|\\r|\\n/);\n}\n/**\n * Returns first index of the string that is not whitespace.\n * If string is empty or contains only whitespaces, returns -1\n */\nexport function firstNonWhitespaceIndex(str) {\n    for (let i = 0, len = str.length; i < len; i++) {\n        const chCode = str.charCodeAt(i);\n        if (chCode !== 32 /* CharCode.Space */ && chCode !== 9 /* CharCode.Tab */) {\n            return i;\n        }\n    }\n    return -1;\n}\n/**\n * Returns the leading whitespace of the string.\n * If the string contains only whitespaces, returns entire string\n */\nexport function getLeadingWhitespace(str, start = 0, end = str.length) {\n    for (let i = start; i < end; i++) {\n        const chCode = str.charCodeAt(i);\n        if (chCode !== 32 /* CharCode.Space */ && chCode !== 9 /* CharCode.Tab */) {\n            return str.substring(start, i);\n        }\n    }\n    return str.substring(start, end);\n}\n/**\n * Returns last index of the string that is not whitespace.\n * If string is empty or contains only whitespaces, returns -1\n */\nexport function lastNonWhitespaceIndex(str, startIndex = str.length - 1) {\n    for (let i = startIndex; i >= 0; i--) {\n        const chCode = str.charCodeAt(i);\n        if (chCode !== 32 /* CharCode.Space */ && chCode !== 9 /* CharCode.Tab */) {\n            return i;\n        }\n    }\n    return -1;\n}\nexport function compare(a, b) {\n    if (a < b) {\n        return -1;\n    }\n    else if (a > b) {\n        return 1;\n    }\n    else {\n        return 0;\n    }\n}\nexport function compareSubstring(a, b, aStart = 0, aEnd = a.length, bStart = 0, bEnd = b.length) {\n    for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) {\n        const codeA = a.charCodeAt(aStart);\n        const codeB = b.charCodeAt(bStart);\n        if (codeA < codeB) {\n            return -1;\n        }\n        else if (codeA > codeB) {\n            return 1;\n        }\n    }\n    const aLen = aEnd - aStart;\n    const bLen = bEnd - bStart;\n    if (aLen < bLen) {\n        return -1;\n    }\n    else if (aLen > bLen) {\n        return 1;\n    }\n    return 0;\n}\nexport function compareIgnoreCase(a, b) {\n    return compareSubstringIgnoreCase(a, b, 0, a.length, 0, b.length);\n}\nexport function compareSubstringIgnoreCase(a, b, aStart = 0, aEnd = a.length, bStart = 0, bEnd = b.length) {\n    for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) {\n        let codeA = a.charCodeAt(aStart);\n        let codeB = b.charCodeAt(bStart);\n        if (codeA === codeB) {\n            // equal\n            continue;\n        }\n        if (codeA >= 128 || codeB >= 128) {\n            // not ASCII letters -> fallback to lower-casing strings\n            return compareSubstring(a.toLowerCase(), b.toLowerCase(), aStart, aEnd, bStart, bEnd);\n        }\n        // mapper lower-case ascii letter onto upper-case varinats\n        // [97-122] (lower ascii) --> [65-90] (upper ascii)\n        if (isLowerAsciiLetter(codeA)) {\n            codeA -= 32;\n        }\n        if (isLowerAsciiLetter(codeB)) {\n            codeB -= 32;\n        }\n        // compare both code points\n        const diff = codeA - codeB;\n        if (diff === 0) {\n            continue;\n        }\n        return diff;\n    }\n    const aLen = aEnd - aStart;\n    const bLen = bEnd - bStart;\n    if (aLen < bLen) {\n        return -1;\n    }\n    else if (aLen > bLen) {\n        return 1;\n    }\n    return 0;\n}\nexport function isAsciiDigit(code) {\n    return code >= 48 /* CharCode.Digit0 */ && code <= 57 /* CharCode.Digit9 */;\n}\nexport function isLowerAsciiLetter(code) {\n    return code >= 97 /* CharCode.a */ && code <= 122 /* CharCode.z */;\n}\nexport function isUpperAsciiLetter(code) {\n    return code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */;\n}\nexport function equalsIgnoreCase(a, b) {\n    return a.length === b.length && compareSubstringIgnoreCase(a, b) === 0;\n}\nexport function startsWithIgnoreCase(str, candidate) {\n    const candidateLength = candidate.length;\n    if (candidate.length > str.length) {\n        return false;\n    }\n    return compareSubstringIgnoreCase(str, candidate, 0, candidateLength) === 0;\n}\n/**\n * @returns the length of the common prefix of the two strings.\n */\nexport function commonPrefixLength(a, b) {\n    const len = Math.min(a.length, b.length);\n    let i;\n    for (i = 0; i < len; i++) {\n        if (a.charCodeAt(i) !== b.charCodeAt(i)) {\n            return i;\n        }\n    }\n    return len;\n}\n/**\n * @returns the length of the common suffix of the two strings.\n */\nexport function commonSuffixLength(a, b) {\n    const len = Math.min(a.length, b.length);\n    let i;\n    const aLastIndex = a.length - 1;\n    const bLastIndex = b.length - 1;\n    for (i = 0; i < len; i++) {\n        if (a.charCodeAt(aLastIndex - i) !== b.charCodeAt(bLastIndex - i)) {\n            return i;\n        }\n    }\n    return len;\n}\n/**\n * See http://en.wikipedia.org/wiki/Surrogate_pair\n */\nexport function isHighSurrogate(charCode) {\n    return (0xD800 <= charCode && charCode <= 0xDBFF);\n}\n/**\n * See http://en.wikipedia.org/wiki/Surrogate_pair\n */\nexport function isLowSurrogate(charCode) {\n    return (0xDC00 <= charCode && charCode <= 0xDFFF);\n}\n/**\n * See http://en.wikipedia.org/wiki/Surrogate_pair\n */\nexport function computeCodePoint(highSurrogate, lowSurrogate) {\n    return ((highSurrogate - 0xD800) << 10) + (lowSurrogate - 0xDC00) + 0x10000;\n}\n/**\n * get the code point that begins at offset `offset`\n */\nexport function getNextCodePoint(str, len, offset) {\n    const charCode = str.charCodeAt(offset);\n    if (isHighSurrogate(charCode) && offset + 1 < len) {\n        const nextCharCode = str.charCodeAt(offset + 1);\n        if (isLowSurrogate(nextCharCode)) {\n            return computeCodePoint(charCode, nextCharCode);\n        }\n    }\n    return charCode;\n}\n/**\n * get the code point that ends right before offset `offset`\n */\nfunction getPrevCodePoint(str, offset) {\n    const charCode = str.charCodeAt(offset - 1);\n    if (isLowSurrogate(charCode) && offset > 1) {\n        const prevCharCode = str.charCodeAt(offset - 2);\n        if (isHighSurrogate(prevCharCode)) {\n            return computeCodePoint(prevCharCode, charCode);\n        }\n    }\n    return charCode;\n}\nexport class CodePointIterator {\n    get offset() {\n        return this._offset;\n    }\n    constructor(str, offset = 0) {\n        this._str = str;\n        this._len = str.length;\n        this._offset = offset;\n    }\n    setOffset(offset) {\n        this._offset = offset;\n    }\n    prevCodePoint() {\n        const codePoint = getPrevCodePoint(this._str, this._offset);\n        this._offset -= (codePoint >= 65536 /* Constants.UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1);\n        return codePoint;\n    }\n    nextCodePoint() {\n        const codePoint = getNextCodePoint(this._str, this._len, this._offset);\n        this._offset += (codePoint >= 65536 /* Constants.UNICODE_SUPPLEMENTARY_PLANE_BEGIN */ ? 2 : 1);\n        return codePoint;\n    }\n    eol() {\n        return (this._offset >= this._len);\n    }\n}\nexport class GraphemeIterator {\n    get offset() {\n        return this._iterator.offset;\n    }\n    constructor(str, offset = 0) {\n        this._iterator = new CodePointIterator(str, offset);\n    }\n    nextGraphemeLength() {\n        const graphemeBreakTree = GraphemeBreakTree.getInstance();\n        const iterator = this._iterator;\n        const initialOffset = iterator.offset;\n        let graphemeBreakType = graphemeBreakTree.getGraphemeBreakType(iterator.nextCodePoint());\n        while (!iterator.eol()) {\n            const offset = iterator.offset;\n            const nextGraphemeBreakType = graphemeBreakTree.getGraphemeBreakType(iterator.nextCodePoint());\n            if (breakBetweenGraphemeBreakType(graphemeBreakType, nextGraphemeBreakType)) {\n                // move iterator back\n                iterator.setOffset(offset);\n                break;\n            }\n            graphemeBreakType = nextGraphemeBreakType;\n        }\n        return (iterator.offset - initialOffset);\n    }\n    prevGraphemeLength() {\n        const graphemeBreakTree = GraphemeBreakTree.getInstance();\n        const iterator = this._iterator;\n        const initialOffset = iterator.offset;\n        let graphemeBreakType = graphemeBreakTree.getGraphemeBreakType(iterator.prevCodePoint());\n        while (iterator.offset > 0) {\n            const offset = iterator.offset;\n            const prevGraphemeBreakType = graphemeBreakTree.getGraphemeBreakType(iterator.prevCodePoint());\n            if (breakBetweenGraphemeBreakType(prevGraphemeBreakType, graphemeBreakType)) {\n                // move iterator back\n                iterator.setOffset(offset);\n                break;\n            }\n            graphemeBreakType = prevGraphemeBreakType;\n        }\n        return (initialOffset - iterator.offset);\n    }\n    eol() {\n        return this._iterator.eol();\n    }\n}\nexport function nextCharLength(str, initialOffset) {\n    const iterator = new GraphemeIterator(str, initialOffset);\n    return iterator.nextGraphemeLength();\n}\nexport function prevCharLength(str, initialOffset) {\n    const iterator = new GraphemeIterator(str, initialOffset);\n    return iterator.prevGraphemeLength();\n}\nexport function getCharContainingOffset(str, offset) {\n    if (offset > 0 && isLowSurrogate(str.charCodeAt(offset))) {\n        offset--;\n    }\n    const endOffset = offset + nextCharLength(str, offset);\n    const startOffset = endOffset - prevCharLength(str, endOffset);\n    return [startOffset, endOffset];\n}\nlet CONTAINS_RTL = undefined;\nfunction makeContainsRtl() {\n    // Generated using https://github.com/alexdima/unicode-utils/blob/main/rtl-test.js\n    return /(?:[\\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\\u07FE-\\u0815\\u081A\\u0824\\u0828\\u0830-\\u0858\\u085E-\\u088E\\u08A0-\\u08C9\\u200F\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFD3D\\uFD50-\\uFDC7\\uFDF0-\\uFDFC\\uFE70-\\uFEFC]|\\uD802[\\uDC00-\\uDD1B\\uDD20-\\uDE00\\uDE10-\\uDE35\\uDE40-\\uDEE4\\uDEEB-\\uDF35\\uDF40-\\uDFFF]|\\uD803[\\uDC00-\\uDD23\\uDE80-\\uDEA9\\uDEAD-\\uDF45\\uDF51-\\uDF81\\uDF86-\\uDFF6]|\\uD83A[\\uDC00-\\uDCCF\\uDD00-\\uDD43\\uDD4B-\\uDFFF]|\\uD83B[\\uDC00-\\uDEBB])/;\n}\n/**\n * Returns true if `str` contains any Unicode character that is classified as \"R\" or \"AL\".\n */\nexport function containsRTL(str) {\n    if (!CONTAINS_RTL) {\n        CONTAINS_RTL = makeContainsRtl();\n    }\n    return CONTAINS_RTL.test(str);\n}\nconst IS_BASIC_ASCII = /^[\\t\\n\\r\\x20-\\x7E]*$/;\n/**\n * Returns true if `str` contains only basic ASCII characters in the range 32 - 126 (including 32 and 126) or \\n, \\r, \\t\n */\nexport function isBasicASCII(str) {\n    return IS_BASIC_ASCII.test(str);\n}\nexport const UNUSUAL_LINE_TERMINATORS = /[\\u2028\\u2029]/; // LINE SEPARATOR (LS) or PARAGRAPH SEPARATOR (PS)\n/**\n * Returns true if `str` contains unusual line terminators, like LS or PS\n */\nexport function containsUnusualLineTerminators(str) {\n    return UNUSUAL_LINE_TERMINATORS.test(str);\n}\nexport function isFullWidthCharacter(charCode) {\n    // Do a cheap trick to better support wrapping of wide characters, treat them as 2 columns\n    // http://jrgraphix.net/research/unicode_blocks.php\n    //          2E80 - 2EFF   CJK Radicals Supplement\n    //          2F00 - 2FDF   Kangxi Radicals\n    //          2FF0 - 2FFF   Ideographic Description Characters\n    //          3000 - 303F   CJK Symbols and Punctuation\n    //          3040 - 309F   Hiragana\n    //          30A0 - 30FF   Katakana\n    //          3100 - 312F   Bopomofo\n    //          3130 - 318F   Hangul Compatibility Jamo\n    //          3190 - 319F   Kanbun\n    //          31A0 - 31BF   Bopomofo Extended\n    //          31F0 - 31FF   Katakana Phonetic Extensions\n    //          3200 - 32FF   Enclosed CJK Letters and Months\n    //          3300 - 33FF   CJK Compatibility\n    //          3400 - 4DBF   CJK Unified Ideographs Extension A\n    //          4DC0 - 4DFF   Yijing Hexagram Symbols\n    //          4E00 - 9FFF   CJK Unified Ideographs\n    //          A000 - A48F   Yi Syllables\n    //          A490 - A4CF   Yi Radicals\n    //          AC00 - D7AF   Hangul Syllables\n    // [IGNORE] D800 - DB7F   High Surrogates\n    // [IGNORE] DB80 - DBFF   High Private Use Surrogates\n    // [IGNORE] DC00 - DFFF   Low Surrogates\n    // [IGNORE] E000 - F8FF   Private Use Area\n    //          F900 - FAFF   CJK Compatibility Ideographs\n    // [IGNORE] FB00 - FB4F   Alphabetic Presentation Forms\n    // [IGNORE] FB50 - FDFF   Arabic Presentation Forms-A\n    // [IGNORE] FE00 - FE0F   Variation Selectors\n    // [IGNORE] FE20 - FE2F   Combining Half Marks\n    // [IGNORE] FE30 - FE4F   CJK Compatibility Forms\n    // [IGNORE] FE50 - FE6F   Small Form Variants\n    // [IGNORE] FE70 - FEFF   Arabic Presentation Forms-B\n    //          FF00 - FFEF   Halfwidth and Fullwidth Forms\n    //               [https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms]\n    //               of which FF01 - FF5E fullwidth ASCII of 21 to 7E\n    // [IGNORE]    and FF65 - FFDC halfwidth of Katakana and Hangul\n    // [IGNORE] FFF0 - FFFF   Specials\n    return ((charCode >= 0x2E80 && charCode <= 0xD7AF)\n        || (charCode >= 0xF900 && charCode <= 0xFAFF)\n        || (charCode >= 0xFF01 && charCode <= 0xFF5E));\n}\n/**\n * A fast function (therefore imprecise) to check if code points are emojis.\n * Generated using https://github.com/alexdima/unicode-utils/blob/main/emoji-test.js\n */\nexport function isEmojiImprecise(x) {\n    return ((x >= 0x1F1E6 && x <= 0x1F1FF) || (x === 8986) || (x === 8987) || (x === 9200)\n        || (x === 9203) || (x >= 9728 && x <= 10175) || (x === 11088) || (x === 11093)\n        || (x >= 127744 && x <= 128591) || (x >= 128640 && x <= 128764)\n        || (x >= 128992 && x <= 129008) || (x >= 129280 && x <= 129535)\n        || (x >= 129648 && x <= 129782));\n}\n// -- UTF-8 BOM\nexport const UTF8_BOM_CHARACTER = String.fromCharCode(65279 /* CharCode.UTF8_BOM */);\nexport function startsWithUTF8BOM(str) {\n    return !!(str && str.length > 0 && str.charCodeAt(0) === 65279 /* CharCode.UTF8_BOM */);\n}\nexport function containsUppercaseCharacter(target, ignoreEscapedChars = false) {\n    if (!target) {\n        return false;\n    }\n    if (ignoreEscapedChars) {\n        target = target.replace(/\\\\./g, '');\n    }\n    return target.toLowerCase() !== target;\n}\n/**\n * Produces 'a'-'z', followed by 'A'-'Z'... followed by 'a'-'z', etc.\n */\nexport function singleLetterHash(n) {\n    const LETTERS_CNT = (90 /* CharCode.Z */ - 65 /* CharCode.A */ + 1);\n    n = n % (2 * LETTERS_CNT);\n    if (n < LETTERS_CNT) {\n        return String.fromCharCode(97 /* CharCode.a */ + n);\n    }\n    return String.fromCharCode(65 /* CharCode.A */ + n - LETTERS_CNT);\n}\nfunction breakBetweenGraphemeBreakType(breakTypeA, breakTypeB) {\n    // http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules\n    // !!! Let's make the common case a bit faster\n    if (breakTypeA === 0 /* GraphemeBreakType.Other */) {\n        // see https://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakTest-13.0.0d10.html#table\n        return (breakTypeB !== 5 /* GraphemeBreakType.Extend */ && breakTypeB !== 7 /* GraphemeBreakType.SpacingMark */);\n    }\n    // Do not break between a CR and LF. Otherwise, break before and after controls.\n    // GB3                                        CR × LF\n    // GB4                       (Control | CR | LF) ÷\n    // GB5                                           ÷ (Control | CR | LF)\n    if (breakTypeA === 2 /* GraphemeBreakType.CR */) {\n        if (breakTypeB === 3 /* GraphemeBreakType.LF */) {\n            return false; // GB3\n        }\n    }\n    if (breakTypeA === 4 /* GraphemeBreakType.Control */ || breakTypeA === 2 /* GraphemeBreakType.CR */ || breakTypeA === 3 /* GraphemeBreakType.LF */) {\n        return true; // GB4\n    }\n    if (breakTypeB === 4 /* GraphemeBreakType.Control */ || breakTypeB === 2 /* GraphemeBreakType.CR */ || breakTypeB === 3 /* GraphemeBreakType.LF */) {\n        return true; // GB5\n    }\n    // Do not break Hangul syllable sequences.\n    // GB6                                         L × (L | V | LV | LVT)\n    // GB7                                  (LV | V) × (V | T)\n    // GB8                                 (LVT | T) × T\n    if (breakTypeA === 8 /* GraphemeBreakType.L */) {\n        if (breakTypeB === 8 /* GraphemeBreakType.L */ || breakTypeB === 9 /* GraphemeBreakType.V */ || breakTypeB === 11 /* GraphemeBreakType.LV */ || breakTypeB === 12 /* GraphemeBreakType.LVT */) {\n            return false; // GB6\n        }\n    }\n    if (breakTypeA === 11 /* GraphemeBreakType.LV */ || breakTypeA === 9 /* GraphemeBreakType.V */) {\n        if (breakTypeB === 9 /* GraphemeBreakType.V */ || breakTypeB === 10 /* GraphemeBreakType.T */) {\n            return false; // GB7\n        }\n    }\n    if (breakTypeA === 12 /* GraphemeBreakType.LVT */ || breakTypeA === 10 /* GraphemeBreakType.T */) {\n        if (breakTypeB === 10 /* GraphemeBreakType.T */) {\n            return false; // GB8\n        }\n    }\n    // Do not break before extending characters or ZWJ.\n    // GB9                                           × (Extend | ZWJ)\n    if (breakTypeB === 5 /* GraphemeBreakType.Extend */ || breakTypeB === 13 /* GraphemeBreakType.ZWJ */) {\n        return false; // GB9\n    }\n    // The GB9a and GB9b rules only apply to extended grapheme clusters:\n    // Do not break before SpacingMarks, or after Prepend characters.\n    // GB9a                                          × SpacingMark\n    // GB9b                                  Prepend ×\n    if (breakTypeB === 7 /* GraphemeBreakType.SpacingMark */) {\n        return false; // GB9a\n    }\n    if (breakTypeA === 1 /* GraphemeBreakType.Prepend */) {\n        return false; // GB9b\n    }\n    // Do not break within emoji modifier sequences or emoji zwj sequences.\n    // GB11    \\p{Extended_Pictographic} Extend* ZWJ × \\p{Extended_Pictographic}\n    if (breakTypeA === 13 /* GraphemeBreakType.ZWJ */ && breakTypeB === 14 /* GraphemeBreakType.Extended_Pictographic */) {\n        // Note: we are not implementing the rule entirely here to avoid introducing states\n        return false; // GB11\n    }\n    // GB12                          sot (RI RI)* RI × RI\n    // GB13                        [^RI] (RI RI)* RI × RI\n    if (breakTypeA === 6 /* GraphemeBreakType.Regional_Indicator */ && breakTypeB === 6 /* GraphemeBreakType.Regional_Indicator */) {\n        // Note: we are not implementing the rule entirely here to avoid introducing states\n        return false; // GB12 & GB13\n    }\n    // GB999                                     Any ÷ Any\n    return true;\n}\nclass GraphemeBreakTree {\n    static getInstance() {\n        if (!GraphemeBreakTree._INSTANCE) {\n            GraphemeBreakTree._INSTANCE = new GraphemeBreakTree();\n        }\n        return GraphemeBreakTree._INSTANCE;\n    }\n    constructor() {\n        this._data = getGraphemeBreakRawData();\n    }\n    getGraphemeBreakType(codePoint) {\n        // !!! Let's make 7bit ASCII a bit faster: 0..31\n        if (codePoint < 32) {\n            if (codePoint === 10 /* CharCode.LineFeed */) {\n                return 3 /* GraphemeBreakType.LF */;\n            }\n            if (codePoint === 13 /* CharCode.CarriageReturn */) {\n                return 2 /* GraphemeBreakType.CR */;\n            }\n            return 4 /* GraphemeBreakType.Control */;\n        }\n        // !!! Let's make 7bit ASCII a bit faster: 32..126\n        if (codePoint < 127) {\n            return 0 /* GraphemeBreakType.Other */;\n        }\n        const data = this._data;\n        const nodeCount = data.length / 3;\n        let nodeIndex = 1;\n        while (nodeIndex <= nodeCount) {\n            if (codePoint < data[3 * nodeIndex]) {\n                // go left\n                nodeIndex = 2 * nodeIndex;\n            }\n            else if (codePoint > data[3 * nodeIndex + 1]) {\n                // go right\n                nodeIndex = 2 * nodeIndex + 1;\n            }\n            else {\n                // hit\n                return data[3 * nodeIndex + 2];\n            }\n        }\n        return 0 /* GraphemeBreakType.Other */;\n    }\n}\nGraphemeBreakTree._INSTANCE = null;\nfunction getGraphemeBreakRawData() {\n    // generated using https://github.com/alexdima/unicode-utils/blob/main/grapheme-break.js\n    return JSON.parse('[0,0,0,51229,51255,12,44061,44087,12,127462,127487,6,7083,7085,5,47645,47671,12,54813,54839,12,128678,128678,14,3270,3270,5,9919,9923,14,45853,45879,12,49437,49463,12,53021,53047,12,71216,71218,7,128398,128399,14,129360,129374,14,2519,2519,5,4448,4519,9,9742,9742,14,12336,12336,14,44957,44983,12,46749,46775,12,48541,48567,12,50333,50359,12,52125,52151,12,53917,53943,12,69888,69890,5,73018,73018,5,127990,127990,14,128558,128559,14,128759,128760,14,129653,129655,14,2027,2035,5,2891,2892,7,3761,3761,5,6683,6683,5,8293,8293,4,9825,9826,14,9999,9999,14,43452,43453,5,44509,44535,12,45405,45431,12,46301,46327,12,47197,47223,12,48093,48119,12,48989,49015,12,49885,49911,12,50781,50807,12,51677,51703,12,52573,52599,12,53469,53495,12,54365,54391,12,65279,65279,4,70471,70472,7,72145,72147,7,119173,119179,5,127799,127818,14,128240,128244,14,128512,128512,14,128652,128652,14,128721,128722,14,129292,129292,14,129445,129450,14,129734,129743,14,1476,1477,5,2366,2368,7,2750,2752,7,3076,3076,5,3415,3415,5,4141,4144,5,6109,6109,5,6964,6964,5,7394,7400,5,9197,9198,14,9770,9770,14,9877,9877,14,9968,9969,14,10084,10084,14,43052,43052,5,43713,43713,5,44285,44311,12,44733,44759,12,45181,45207,12,45629,45655,12,46077,46103,12,46525,46551,12,46973,46999,12,47421,47447,12,47869,47895,12,48317,48343,12,48765,48791,12,49213,49239,12,49661,49687,12,50109,50135,12,50557,50583,12,51005,51031,12,51453,51479,12,51901,51927,12,52349,52375,12,52797,52823,12,53245,53271,12,53693,53719,12,54141,54167,12,54589,54615,12,55037,55063,12,69506,69509,5,70191,70193,5,70841,70841,7,71463,71467,5,72330,72342,5,94031,94031,5,123628,123631,5,127763,127765,14,127941,127941,14,128043,128062,14,128302,128317,14,128465,128467,14,128539,128539,14,128640,128640,14,128662,128662,14,128703,128703,14,128745,128745,14,129004,129007,14,129329,129330,14,129402,129402,14,129483,129483,14,129686,129704,14,130048,131069,14,173,173,4,1757,1757,1,2200,2207,5,2434,2435,7,2631,2632,5,2817,2817,5,3008,3008,5,3201,3201,5,3387,3388,5,3542,3542,5,3902,3903,7,4190,4192,5,6002,6003,5,6439,6440,5,6765,6770,7,7019,7027,5,7154,7155,7,8205,8205,13,8505,8505,14,9654,9654,14,9757,9757,14,9792,9792,14,9852,9853,14,9890,9894,14,9937,9937,14,9981,9981,14,10035,10036,14,11035,11036,14,42654,42655,5,43346,43347,7,43587,43587,5,44006,44007,7,44173,44199,12,44397,44423,12,44621,44647,12,44845,44871,12,45069,45095,12,45293,45319,12,45517,45543,12,45741,45767,12,45965,45991,12,46189,46215,12,46413,46439,12,46637,46663,12,46861,46887,12,47085,47111,12,47309,47335,12,47533,47559,12,47757,47783,12,47981,48007,12,48205,48231,12,48429,48455,12,48653,48679,12,48877,48903,12,49101,49127,12,49325,49351,12,49549,49575,12,49773,49799,12,49997,50023,12,50221,50247,12,50445,50471,12,50669,50695,12,50893,50919,12,51117,51143,12,51341,51367,12,51565,51591,12,51789,51815,12,52013,52039,12,52237,52263,12,52461,52487,12,52685,52711,12,52909,52935,12,53133,53159,12,53357,53383,12,53581,53607,12,53805,53831,12,54029,54055,12,54253,54279,12,54477,54503,12,54701,54727,12,54925,54951,12,55149,55175,12,68101,68102,5,69762,69762,7,70067,70069,7,70371,70378,5,70720,70721,7,71087,71087,5,71341,71341,5,71995,71996,5,72249,72249,7,72850,72871,5,73109,73109,5,118576,118598,5,121505,121519,5,127245,127247,14,127568,127569,14,127777,127777,14,127872,127891,14,127956,127967,14,128015,128016,14,128110,128172,14,128259,128259,14,128367,128368,14,128424,128424,14,128488,128488,14,128530,128532,14,128550,128551,14,128566,128566,14,128647,128647,14,128656,128656,14,128667,128673,14,128691,128693,14,128715,128715,14,128728,128732,14,128752,128752,14,128765,128767,14,129096,129103,14,129311,129311,14,129344,129349,14,129394,129394,14,129413,129425,14,129466,129471,14,129511,129535,14,129664,129666,14,129719,129722,14,129760,129767,14,917536,917631,5,13,13,2,1160,1161,5,1564,1564,4,1807,1807,1,2085,2087,5,2307,2307,7,2382,2383,7,2497,2500,5,2563,2563,7,2677,2677,5,2763,2764,7,2879,2879,5,2914,2915,5,3021,3021,5,3142,3144,5,3263,3263,5,3285,3286,5,3398,3400,7,3530,3530,5,3633,3633,5,3864,3865,5,3974,3975,5,4155,4156,7,4229,4230,5,5909,5909,7,6078,6085,7,6277,6278,5,6451,6456,7,6744,6750,5,6846,6846,5,6972,6972,5,7074,7077,5,7146,7148,7,7222,7223,5,7416,7417,5,8234,8238,4,8417,8417,5,9000,9000,14,9203,9203,14,9730,9731,14,9748,9749,14,9762,9763,14,9776,9783,14,9800,9811,14,9831,9831,14,9872,9873,14,9882,9882,14,9900,9903,14,9929,9933,14,9941,9960,14,9974,9974,14,9989,9989,14,10006,10006,14,10062,10062,14,10160,10160,14,11647,11647,5,12953,12953,14,43019,43019,5,43232,43249,5,43443,43443,5,43567,43568,7,43696,43696,5,43765,43765,7,44013,44013,5,44117,44143,12,44229,44255,12,44341,44367,12,44453,44479,12,44565,44591,12,44677,44703,12,44789,44815,12,44901,44927,12,45013,45039,12,45125,45151,12,45237,45263,12,45349,45375,12,45461,45487,12,45573,45599,12,45685,45711,12,45797,45823,12,45909,45935,12,46021,46047,12,46133,46159,12,46245,46271,12,46357,46383,12,46469,46495,12,46581,46607,12,46693,46719,12,46805,46831,12,46917,46943,12,47029,47055,12,47141,47167,12,47253,47279,12,47365,47391,12,47477,47503,12,47589,47615,12,47701,47727,12,47813,47839,12,47925,47951,12,48037,48063,12,48149,48175,12,48261,48287,12,48373,48399,12,48485,48511,12,48597,48623,12,48709,48735,12,48821,48847,12,48933,48959,12,49045,49071,12,49157,49183,12,49269,49295,12,49381,49407,12,49493,49519,12,49605,49631,12,49717,49743,12,49829,49855,12,49941,49967,12,50053,50079,12,50165,50191,12,50277,50303,12,50389,50415,12,50501,50527,12,50613,50639,12,50725,50751,12,50837,50863,12,50949,50975,12,51061,51087,12,51173,51199,12,51285,51311,12,51397,51423,12,51509,51535,12,51621,51647,12,51733,51759,12,51845,51871,12,51957,51983,12,52069,52095,12,52181,52207,12,52293,52319,12,52405,52431,12,52517,52543,12,52629,52655,12,52741,52767,12,52853,52879,12,52965,52991,12,53077,53103,12,53189,53215,12,53301,53327,12,53413,53439,12,53525,53551,12,53637,53663,12,53749,53775,12,53861,53887,12,53973,53999,12,54085,54111,12,54197,54223,12,54309,54335,12,54421,54447,12,54533,54559,12,54645,54671,12,54757,54783,12,54869,54895,12,54981,55007,12,55093,55119,12,55243,55291,10,66045,66045,5,68325,68326,5,69688,69702,5,69817,69818,5,69957,69958,7,70089,70092,5,70198,70199,5,70462,70462,5,70502,70508,5,70750,70750,5,70846,70846,7,71100,71101,5,71230,71230,7,71351,71351,5,71737,71738,5,72000,72000,7,72160,72160,5,72273,72278,5,72752,72758,5,72882,72883,5,73031,73031,5,73461,73462,7,94192,94193,7,119149,119149,7,121403,121452,5,122915,122916,5,126980,126980,14,127358,127359,14,127535,127535,14,127759,127759,14,127771,127771,14,127792,127793,14,127825,127867,14,127897,127899,14,127945,127945,14,127985,127986,14,128000,128007,14,128021,128021,14,128066,128100,14,128184,128235,14,128249,128252,14,128266,128276,14,128335,128335,14,128379,128390,14,128407,128419,14,128444,128444,14,128481,128481,14,128499,128499,14,128526,128526,14,128536,128536,14,128543,128543,14,128556,128556,14,128564,128564,14,128577,128580,14,128643,128645,14,128649,128649,14,128654,128654,14,128660,128660,14,128664,128664,14,128675,128675,14,128686,128689,14,128695,128696,14,128705,128709,14,128717,128719,14,128725,128725,14,128736,128741,14,128747,128748,14,128755,128755,14,128762,128762,14,128981,128991,14,129009,129023,14,129160,129167,14,129296,129304,14,129320,129327,14,129340,129342,14,129356,129356,14,129388,129392,14,129399,129400,14,129404,129407,14,129432,129442,14,129454,129455,14,129473,129474,14,129485,129487,14,129648,129651,14,129659,129660,14,129671,129679,14,129709,129711,14,129728,129730,14,129751,129753,14,129776,129782,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,2274,2274,1,2363,2363,7,2377,2380,7,2402,2403,5,2494,2494,5,2507,2508,7,2558,2558,5,2622,2624,7,2641,2641,5,2691,2691,7,2759,2760,5,2786,2787,5,2876,2876,5,2881,2884,5,2901,2902,5,3006,3006,5,3014,3016,7,3072,3072,5,3134,3136,5,3157,3158,5,3260,3260,5,3266,3266,5,3274,3275,7,3328,3329,5,3391,3392,7,3405,3405,5,3457,3457,5,3536,3537,7,3551,3551,5,3636,3642,5,3764,3772,5,3895,3895,5,3967,3967,7,3993,4028,5,4146,4151,5,4182,4183,7,4226,4226,5,4253,4253,5,4957,4959,5,5940,5940,7,6070,6070,7,6087,6088,7,6158,6158,4,6432,6434,5,6448,6449,7,6679,6680,5,6742,6742,5,6754,6754,5,6783,6783,5,6912,6915,5,6966,6970,5,6978,6978,5,7042,7042,7,7080,7081,5,7143,7143,7,7150,7150,7,7212,7219,5,7380,7392,5,7412,7412,5,8203,8203,4,8232,8232,4,8265,8265,14,8400,8412,5,8421,8432,5,8617,8618,14,9167,9167,14,9200,9200,14,9410,9410,14,9723,9726,14,9733,9733,14,9745,9745,14,9752,9752,14,9760,9760,14,9766,9766,14,9774,9774,14,9786,9786,14,9794,9794,14,9823,9823,14,9828,9828,14,9833,9850,14,9855,9855,14,9875,9875,14,9880,9880,14,9885,9887,14,9896,9897,14,9906,9916,14,9926,9927,14,9935,9935,14,9939,9939,14,9962,9962,14,9972,9972,14,9978,9978,14,9986,9986,14,9997,9997,14,10002,10002,14,10017,10017,14,10055,10055,14,10071,10071,14,10133,10135,14,10548,10549,14,11093,11093,14,12330,12333,5,12441,12442,5,42608,42610,5,43010,43010,5,43045,43046,5,43188,43203,7,43302,43309,5,43392,43394,5,43446,43449,5,43493,43493,5,43571,43572,7,43597,43597,7,43703,43704,5,43756,43757,5,44003,44004,7,44009,44010,7,44033,44059,12,44089,44115,12,44145,44171,12,44201,44227,12,44257,44283,12,44313,44339,12,44369,44395,12,44425,44451,12,44481,44507,12,44537,44563,12,44593,44619,12,44649,44675,12,44705,44731,12,44761,44787,12,44817,44843,12,44873,44899,12,44929,44955,12,44985,45011,12,45041,45067,12,45097,45123,12,45153,45179,12,45209,45235,12,45265,45291,12,45321,45347,12,45377,45403,12,45433,45459,12,45489,45515,12,45545,45571,12,45601,45627,12,45657,45683,12,45713,45739,12,45769,45795,12,45825,45851,12,45881,45907,12,45937,45963,12,45993,46019,12,46049,46075,12,46105,46131,12,46161,46187,12,46217,46243,12,46273,46299,12,46329,46355,12,46385,46411,12,46441,46467,12,46497,46523,12,46553,46579,12,46609,46635,12,46665,46691,12,46721,46747,12,46777,46803,12,46833,46859,12,46889,46915,12,46945,46971,12,47001,47027,12,47057,47083,12,47113,47139,12,47169,47195,12,47225,47251,12,47281,47307,12,47337,47363,12,47393,47419,12,47449,47475,12,47505,47531,12,47561,47587,12,47617,47643,12,47673,47699,12,47729,47755,12,47785,47811,12,47841,47867,12,47897,47923,12,47953,47979,12,48009,48035,12,48065,48091,12,48121,48147,12,48177,48203,12,48233,48259,12,48289,48315,12,48345,48371,12,48401,48427,12,48457,48483,12,48513,48539,12,48569,48595,12,48625,48651,12,48681,48707,12,48737,48763,12,48793,48819,12,48849,48875,12,48905,48931,12,48961,48987,12,49017,49043,12,49073,49099,12,49129,49155,12,49185,49211,12,49241,49267,12,49297,49323,12,49353,49379,12,49409,49435,12,49465,49491,12,49521,49547,12,49577,49603,12,49633,49659,12,49689,49715,12,49745,49771,12,49801,49827,12,49857,49883,12,49913,49939,12,49969,49995,12,50025,50051,12,50081,50107,12,50137,50163,12,50193,50219,12,50249,50275,12,50305,50331,12,50361,50387,12,50417,50443,12,50473,50499,12,50529,50555,12,50585,50611,12,50641,50667,12,50697,50723,12,50753,50779,12,50809,50835,12,50865,50891,12,50921,50947,12,50977,51003,12,51033,51059,12,51089,51115,12,51145,51171,12,51201,51227,12,51257,51283,12,51313,51339,12,51369,51395,12,51425,51451,12,51481,51507,12,51537,51563,12,51593,51619,12,51649,51675,12,51705,51731,12,51761,51787,12,51817,51843,12,51873,51899,12,51929,51955,12,51985,52011,12,52041,52067,12,52097,52123,12,52153,52179,12,52209,52235,12,52265,52291,12,52321,52347,12,52377,52403,12,52433,52459,12,52489,52515,12,52545,52571,12,52601,52627,12,52657,52683,12,52713,52739,12,52769,52795,12,52825,52851,12,52881,52907,12,52937,52963,12,52993,53019,12,53049,53075,12,53105,53131,12,53161,53187,12,53217,53243,12,53273,53299,12,53329,53355,12,53385,53411,12,53441,53467,12,53497,53523,12,53553,53579,12,53609,53635,12,53665,53691,12,53721,53747,12,53777,53803,12,53833,53859,12,53889,53915,12,53945,53971,12,54001,54027,12,54057,54083,12,54113,54139,12,54169,54195,12,54225,54251,12,54281,54307,12,54337,54363,12,54393,54419,12,54449,54475,12,54505,54531,12,54561,54587,12,54617,54643,12,54673,54699,12,54729,54755,12,54785,54811,12,54841,54867,12,54897,54923,12,54953,54979,12,55009,55035,12,55065,55091,12,55121,55147,12,55177,55203,12,65024,65039,5,65520,65528,4,66422,66426,5,68152,68154,5,69291,69292,5,69633,69633,5,69747,69748,5,69811,69814,5,69826,69826,5,69932,69932,7,70016,70017,5,70079,70080,7,70095,70095,5,70196,70196,5,70367,70367,5,70402,70403,7,70464,70464,5,70487,70487,5,70709,70711,7,70725,70725,7,70833,70834,7,70843,70844,7,70849,70849,7,71090,71093,5,71103,71104,5,71227,71228,7,71339,71339,5,71344,71349,5,71458,71461,5,71727,71735,5,71985,71989,7,71998,71998,5,72002,72002,7,72154,72155,5,72193,72202,5,72251,72254,5,72281,72283,5,72344,72345,5,72766,72766,7,72874,72880,5,72885,72886,5,73023,73029,5,73104,73105,5,73111,73111,5,92912,92916,5,94095,94098,5,113824,113827,4,119142,119142,7,119155,119162,4,119362,119364,5,121476,121476,5,122888,122904,5,123184,123190,5,125252,125258,5,127183,127183,14,127340,127343,14,127377,127386,14,127491,127503,14,127548,127551,14,127744,127756,14,127761,127761,14,127769,127769,14,127773,127774,14,127780,127788,14,127796,127797,14,127820,127823,14,127869,127869,14,127894,127895,14,127902,127903,14,127943,127943,14,127947,127950,14,127972,127972,14,127988,127988,14,127992,127994,14,128009,128011,14,128019,128019,14,128023,128041,14,128064,128064,14,128102,128107,14,128174,128181,14,128238,128238,14,128246,128247,14,128254,128254,14,128264,128264,14,128278,128299,14,128329,128330,14,128348,128359,14,128371,128377,14,128392,128393,14,128401,128404,14,128421,128421,14,128433,128434,14,128450,128452,14,128476,128478,14,128483,128483,14,128495,128495,14,128506,128506,14,128519,128520,14,128528,128528,14,128534,128534,14,128538,128538,14,128540,128542,14,128544,128549,14,128552,128555,14,128557,128557,14,128560,128563,14,128565,128565,14,128567,128576,14,128581,128591,14,128641,128642,14,128646,128646,14,128648,128648,14,128650,128651,14,128653,128653,14,128655,128655,14,128657,128659,14,128661,128661,14,128663,128663,14,128665,128666,14,128674,128674,14,128676,128677,14,128679,128685,14,128690,128690,14,128694,128694,14,128697,128702,14,128704,128704,14,128710,128714,14,128716,128716,14,128720,128720,14,128723,128724,14,128726,128727,14,128733,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,129008,129008,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,129661,129663,14,129667,129670,14,129680,129685,14,129705,129708,14,129712,129718,14,129723,129727,14,129731,129733,14,129744,129750,14,129754,129759,14,129768,129775,14,129783,129791,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,2192,2193,1,2250,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,3132,3132,5,3137,3140,7,3146,3149,5,3170,3171,5,3202,3203,7,3262,3262,7,3264,3265,7,3267,3268,7,3271,3272,7,3276,3277,5,3298,3299,5,3330,3331,7,3390,3390,5,3393,3396,5,3402,3404,7,3406,3406,1,3426,3427,5,3458,3459,7,3535,3535,5,3538,3540,5,3544,3550,7,3570,3571,7,3635,3635,7,3655,3662,5,3763,3763,7,3784,3789,5,3893,3893,5,3897,3897,5,3953,3966,5,3968,3972,5,3981,3991,5,4038,4038,5,4145,4145,7,4153,4154,5,4157,4158,5,4184,4185,5,4209,4212,5,4228,4228,7,4237,4237,5,4352,4447,8,4520,4607,10,5906,5908,5,5938,5939,5,5970,5971,5,6068,6069,5,6071,6077,5,6086,6086,5,6089,6099,5,6155,6157,5,6159,6159,5,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,6862,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,7679,5,8204,8204,5,8206,8207,4,8233,8233,4,8252,8252,14,8288,8292,4,8294,8303,4,8413,8416,5,8418,8420,5,8482,8482,14,8596,8601,14,8986,8987,14,9096,9096,14,9193,9196,14,9199,9199,14,9201,9202,14,9208,9210,14,9642,9643,14,9664,9664,14,9728,9729,14,9732,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,9775,9775,14,9784,9785,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,9874,14,9876,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,9934,14,9936,9936,14,9938,9938,14,9940,9940,14,9961,9961,14,9963,9967,14,9970,9971,14,9973,9973,14,9975,9977,14,9979,9980,14,9982,9985,14,9987,9988,14,9992,9996,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,10083,14,10085,10087,14,10145,10145,14,10175,10175,14,11013,11015,14,11088,11088,14,11503,11505,5,11744,11775,5,12334,12335,5,12349,12349,14,12951,12951,14,42607,42607,5,42612,42621,5,42736,42737,5,43014,43014,5,43043,43044,7,43047,43047,7,43136,43137,7,43204,43205,5,43263,43263,5,43335,43345,5,43360,43388,8,43395,43395,7,43444,43445,7,43450,43451,7,43454,43456,7,43561,43566,5,43569,43570,5,43573,43574,5,43596,43596,5,43644,43644,5,43698,43700,5,43710,43711,5,43755,43755,7,43758,43759,7,43766,43766,5,44005,44005,5,44008,44008,5,44012,44012,7,44032,44032,11,44060,44060,11,44088,44088,11,44116,44116,11,44144,44144,11,44172,44172,11,44200,44200,11,44228,44228,11,44256,44256,11,44284,44284,11,44312,44312,11,44340,44340,11,44368,44368,11,44396,44396,11,44424,44424,11,44452,44452,11,44480,44480,11,44508,44508,11,44536,44536,11,44564,44564,11,44592,44592,11,44620,44620,11,44648,44648,11,44676,44676,11,44704,44704,11,44732,44732,11,44760,44760,11,44788,44788,11,44816,44816,11,44844,44844,11,44872,44872,11,44900,44900,11,44928,44928,11,44956,44956,11,44984,44984,11,45012,45012,11,45040,45040,11,45068,45068,11,45096,45096,11,45124,45124,11,45152,45152,11,45180,45180,11,45208,45208,11,45236,45236,11,45264,45264,11,45292,45292,11,45320,45320,11,45348,45348,11,45376,45376,11,45404,45404,11,45432,45432,11,45460,45460,11,45488,45488,11,45516,45516,11,45544,45544,11,45572,45572,11,45600,45600,11,45628,45628,11,45656,45656,11,45684,45684,11,45712,45712,11,45740,45740,11,45768,45768,11,45796,45796,11,45824,45824,11,45852,45852,11,45880,45880,11,45908,45908,11,45936,45936,11,45964,45964,11,45992,45992,11,46020,46020,11,46048,46048,11,46076,46076,11,46104,46104,11,46132,46132,11,46160,46160,11,46188,46188,11,46216,46216,11,46244,46244,11,46272,46272,11,46300,46300,11,46328,46328,11,46356,46356,11,46384,46384,11,46412,46412,11,46440,46440,11,46468,46468,11,46496,46496,11,46524,46524,11,46552,46552,11,46580,46580,11,46608,46608,11,46636,46636,11,46664,46664,11,46692,46692,11,46720,46720,11,46748,46748,11,46776,46776,11,46804,46804,11,46832,46832,11,46860,46860,11,46888,46888,11,46916,46916,11,46944,46944,11,46972,46972,11,47000,47000,11,47028,47028,11,47056,47056,11,47084,47084,11,47112,47112,11,47140,47140,11,47168,47168,11,47196,47196,11,47224,47224,11,47252,47252,11,47280,47280,11,47308,47308,11,47336,47336,11,47364,47364,11,47392,47392,11,47420,47420,11,47448,47448,11,47476,47476,11,47504,47504,11,47532,47532,11,47560,47560,11,47588,47588,11,47616,47616,11,47644,47644,11,47672,47672,11,47700,47700,11,47728,47728,11,47756,47756,11,47784,47784,11,47812,47812,11,47840,47840,11,47868,47868,11,47896,47896,11,47924,47924,11,47952,47952,11,47980,47980,11,48008,48008,11,48036,48036,11,48064,48064,11,48092,48092,11,48120,48120,11,48148,48148,11,48176,48176,11,48204,48204,11,48232,48232,11,48260,48260,11,48288,48288,11,48316,48316,11,48344,48344,11,48372,48372,11,48400,48400,11,48428,48428,11,48456,48456,11,48484,48484,11,48512,48512,11,48540,48540,11,48568,48568,11,48596,48596,11,48624,48624,11,48652,48652,11,48680,48680,11,48708,48708,11,48736,48736,11,48764,48764,11,48792,48792,11,48820,48820,11,48848,48848,11,48876,48876,11,48904,48904,11,48932,48932,11,48960,48960,11,48988,48988,11,49016,49016,11,49044,49044,11,49072,49072,11,49100,49100,11,49128,49128,11,49156,49156,11,49184,49184,11,49212,49212,11,49240,49240,11,49268,49268,11,49296,49296,11,49324,49324,11,49352,49352,11,49380,49380,11,49408,49408,11,49436,49436,11,49464,49464,11,49492,49492,11,49520,49520,11,49548,49548,11,49576,49576,11,49604,49604,11,49632,49632,11,49660,49660,11,49688,49688,11,49716,49716,11,49744,49744,11,49772,49772,11,49800,49800,11,49828,49828,11,49856,49856,11,49884,49884,11,49912,49912,11,49940,49940,11,49968,49968,11,49996,49996,11,50024,50024,11,50052,50052,11,50080,50080,11,50108,50108,11,50136,50136,11,50164,50164,11,50192,50192,11,50220,50220,11,50248,50248,11,50276,50276,11,50304,50304,11,50332,50332,11,50360,50360,11,50388,50388,11,50416,50416,11,50444,50444,11,50472,50472,11,50500,50500,11,50528,50528,11,50556,50556,11,50584,50584,11,50612,50612,11,50640,50640,11,50668,50668,11,50696,50696,11,50724,50724,11,50752,50752,11,50780,50780,11,50808,50808,11,50836,50836,11,50864,50864,11,50892,50892,11,50920,50920,11,50948,50948,11,50976,50976,11,51004,51004,11,51032,51032,11,51060,51060,11,51088,51088,11,51116,51116,11,51144,51144,11,51172,51172,11,51200,51200,11,51228,51228,11,51256,51256,11,51284,51284,11,51312,51312,11,51340,51340,11,51368,51368,11,51396,51396,11,51424,51424,11,51452,51452,11,51480,51480,11,51508,51508,11,51536,51536,11,51564,51564,11,51592,51592,11,51620,51620,11,51648,51648,11,51676,51676,11,51704,51704,11,51732,51732,11,51760,51760,11,51788,51788,11,51816,51816,11,51844,51844,11,51872,51872,11,51900,51900,11,51928,51928,11,51956,51956,11,51984,51984,11,52012,52012,11,52040,52040,11,52068,52068,11,52096,52096,11,52124,52124,11,52152,52152,11,52180,52180,11,52208,52208,11,52236,52236,11,52264,52264,11,52292,52292,11,52320,52320,11,52348,52348,11,52376,52376,11,52404,52404,11,52432,52432,11,52460,52460,11,52488,52488,11,52516,52516,11,52544,52544,11,52572,52572,11,52600,52600,11,52628,52628,11,52656,52656,11,52684,52684,11,52712,52712,11,52740,52740,11,52768,52768,11,52796,52796,11,52824,52824,11,52852,52852,11,52880,52880,11,52908,52908,11,52936,52936,11,52964,52964,11,52992,52992,11,53020,53020,11,53048,53048,11,53076,53076,11,53104,53104,11,53132,53132,11,53160,53160,11,53188,53188,11,53216,53216,11,53244,53244,11,53272,53272,11,53300,53300,11,53328,53328,11,53356,53356,11,53384,53384,11,53412,53412,11,53440,53440,11,53468,53468,11,53496,53496,11,53524,53524,11,53552,53552,11,53580,53580,11,53608,53608,11,53636,53636,11,53664,53664,11,53692,53692,11,53720,53720,11,53748,53748,11,53776,53776,11,53804,53804,11,53832,53832,11,53860,53860,11,53888,53888,11,53916,53916,11,53944,53944,11,53972,53972,11,54000,54000,11,54028,54028,11,54056,54056,11,54084,54084,11,54112,54112,11,54140,54140,11,54168,54168,11,54196,54196,11,54224,54224,11,54252,54252,11,54280,54280,11,54308,54308,11,54336,54336,11,54364,54364,11,54392,54392,11,54420,54420,11,54448,54448,11,54476,54476,11,54504,54504,11,54532,54532,11,54560,54560,11,54588,54588,11,54616,54616,11,54644,54644,11,54672,54672,11,54700,54700,11,54728,54728,11,54756,54756,11,54784,54784,11,54812,54812,11,54840,54840,11,54868,54868,11,54896,54896,11,54924,54924,11,54952,54952,11,54980,54980,11,55008,55008,11,55036,55036,11,55064,55064,11,55092,55092,11,55120,55120,11,55148,55148,11,55176,55176,11,55216,55238,9,64286,64286,5,65056,65071,5,65438,65439,5,65529,65531,4,66272,66272,5,68097,68099,5,68108,68111,5,68159,68159,5,68900,68903,5,69446,69456,5,69632,69632,7,69634,69634,7,69744,69744,5,69759,69761,5,69808,69810,7,69815,69816,7,69821,69821,1,69837,69837,1,69927,69931,5,69933,69940,5,70003,70003,5,70018,70018,7,70070,70078,5,70082,70083,1,70094,70094,7,70188,70190,7,70194,70195,7,70197,70197,7,70206,70206,5,70368,70370,7,70400,70401,5,70459,70460,5,70463,70463,7,70465,70468,7,70475,70477,7,70498,70499,7,70512,70516,5,70712,70719,5,70722,70724,5,70726,70726,5,70832,70832,5,70835,70840,5,70842,70842,5,70845,70845,5,70847,70848,5,70850,70851,5,71088,71089,7,71096,71099,7,71102,71102,7,71132,71133,5,71219,71226,5,71229,71229,5,71231,71232,5,71340,71340,7,71342,71343,7,71350,71350,7,71453,71455,5,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,118528,118573,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,123566,123566,5,125136,125142,5,126976,126979,14,126981,127182,14,127184,127231,14,127279,127279,14,127344,127345,14,127374,127374,14,127405,127461,14,127489,127490,14,127514,127514,14,127538,127546,14,127561,127567,14,127570,127743,14,127757,127758,14,127760,127760,14,127762,127762,14,127766,127768,14,127770,127770,14,127772,127772,14,127775,127776,14,127778,127779,14,127789,127791,14,127794,127795,14,127798,127798,14,127819,127819,14,127824,127824,14,127868,127868,14,127870,127871,14,127892,127893,14,127896,127896,14,127900,127901,14,127904,127940,14,127942,127942,14,127944,127944,14,127946,127946,14,127951,127955,14,127968,127971,14,127973,127984,14,127987,127987,14,127989,127989,14,127991,127991,14,127995,127999,5,128008,128008,14,128012,128014,14,128017,128018,14,128020,128020,14,128022,128022,14,128042,128042,14,128063,128063,14,128065,128065,14,128101,128101,14,128108,128109,14,128173,128173,14,128182,128183,14,128236,128237,14,128239,128239,14,128245,128245,14,128248,128248,14,128253,128253,14,128255,128258,14,128260,128263,14,128265,128265,14,128277,128277,14,128300,128301,14,128326,128328,14,128331,128334,14,128336,128347,14,128360,128366,14,128369,128370,14,128378,128378,14,128391,128391,14,128394,128397,14,128400,128400,14,128405,128406,14,128420,128420,14,128422,128423,14,128425,128432,14,128435,128443,14,128445,128449,14,128453,128464,14,128468,128475,14,128479,128480,14,128482,128482,14,128484,128487,14,128489,128494,14,128496,128498,14,128500,128505,14,128507,128511,14,128513,128518,14,128521,128525,14,128527,128527,14,128529,128529,14,128533,128533,14,128535,128535,14,128537,128537,14]');\n}\n//#endregion\n/**\n * Computes the offset after performing a left delete on the given string,\n * while considering unicode grapheme/emoji rules.\n*/\nexport function getLeftDeleteOffset(offset, str) {\n    if (offset === 0) {\n        return 0;\n    }\n    // Try to delete emoji part.\n    const emojiOffset = getOffsetBeforeLastEmojiComponent(offset, str);\n    if (emojiOffset !== undefined) {\n        return emojiOffset;\n    }\n    // Otherwise, just skip a single code point.\n    const iterator = new CodePointIterator(str, offset);\n    iterator.prevCodePoint();\n    return iterator.offset;\n}\nfunction getOffsetBeforeLastEmojiComponent(initialOffset, str) {\n    // See https://www.unicode.org/reports/tr51/tr51-14.html#EBNF_and_Regex for the\n    // structure of emojis.\n    const iterator = new CodePointIterator(str, initialOffset);\n    let codePoint = iterator.prevCodePoint();\n    // Skip modifiers\n    while ((isEmojiModifier(codePoint) || codePoint === 65039 /* CodePoint.emojiVariantSelector */ || codePoint === 8419 /* CodePoint.enclosingKeyCap */)) {\n        if (iterator.offset === 0) {\n            // Cannot skip modifier, no preceding emoji base.\n            return undefined;\n        }\n        codePoint = iterator.prevCodePoint();\n    }\n    // Expect base emoji\n    if (!isEmojiImprecise(codePoint)) {\n        // Unexpected code point, not a valid emoji.\n        return undefined;\n    }\n    let resultOffset = iterator.offset;\n    if (resultOffset > 0) {\n        // Skip optional ZWJ code points that combine multiple emojis.\n        // In theory, we should check if that ZWJ actually combines multiple emojis\n        // to prevent deleting ZWJs in situations we didn't account for.\n        const optionalZwjCodePoint = iterator.prevCodePoint();\n        if (optionalZwjCodePoint === 8205 /* CodePoint.zwj */) {\n            resultOffset = iterator.offset;\n        }\n    }\n    return resultOffset;\n}\nfunction isEmojiModifier(codePoint) {\n    return 0x1F3FB <= codePoint && codePoint <= 0x1F3FF;\n}\nexport const noBreakWhitespace = '\\xa0';\nexport class AmbiguousCharacters {\n    static getInstance(locales) {\n        return AmbiguousCharacters.cache.get(Array.from(locales));\n    }\n    static getLocales() {\n        return AmbiguousCharacters._locales.value;\n    }\n    constructor(confusableDictionary) {\n        this.confusableDictionary = confusableDictionary;\n    }\n    isAmbiguous(codePoint) {\n        return this.confusableDictionary.has(codePoint);\n    }\n    /**\n     * Returns the non basic ASCII code point that the given code point can be confused,\n     * or undefined if such code point does note exist.\n     */\n    getPrimaryConfusable(codePoint) {\n        return this.confusableDictionary.get(codePoint);\n    }\n    getConfusableCodePoints() {\n        return new Set(this.confusableDictionary.keys());\n    }\n}\n_a = AmbiguousCharacters;\nAmbiguousCharacters.ambiguousCharacterData = new Lazy(() => {\n    // Generated using https://github.com/hediet/vscode-unicode-data\n    // Stored as key1, value1, key2, value2, ...\n    return JSON.parse('{\\\"_common\\\":[8232,32,8233,32,5760,32,8192,32,8193,32,8194,32,8195,32,8196,32,8197,32,8198,32,8200,32,8201,32,8202,32,8287,32,8199,32,8239,32,2042,95,65101,95,65102,95,65103,95,8208,45,8209,45,8210,45,65112,45,1748,45,8259,45,727,45,8722,45,10134,45,11450,45,1549,44,1643,44,8218,44,184,44,42233,44,894,59,2307,58,2691,58,1417,58,1795,58,1796,58,5868,58,65072,58,6147,58,6153,58,8282,58,1475,58,760,58,42889,58,8758,58,720,58,42237,58,451,33,11601,33,660,63,577,63,2429,63,5038,63,42731,63,119149,46,8228,46,1793,46,1794,46,42510,46,68176,46,1632,46,1776,46,42232,46,1373,96,65287,96,8219,96,8242,96,1370,96,1523,96,8175,96,65344,96,900,96,8189,96,8125,96,8127,96,8190,96,697,96,884,96,712,96,714,96,715,96,756,96,699,96,701,96,700,96,702,96,42892,96,1497,96,2036,96,2037,96,5194,96,5836,96,94033,96,94034,96,65339,91,10088,40,10098,40,12308,40,64830,40,65341,93,10089,41,10099,41,12309,41,64831,41,10100,123,119060,123,10101,125,65342,94,8270,42,1645,42,8727,42,66335,42,5941,47,8257,47,8725,47,8260,47,9585,47,10187,47,10744,47,119354,47,12755,47,12339,47,11462,47,20031,47,12035,47,65340,92,65128,92,8726,92,10189,92,10741,92,10745,92,119311,92,119355,92,12756,92,20022,92,12034,92,42872,38,708,94,710,94,5869,43,10133,43,66203,43,8249,60,10094,60,706,60,119350,60,5176,60,5810,60,5120,61,11840,61,12448,61,42239,61,8250,62,10095,62,707,62,119351,62,5171,62,94015,62,8275,126,732,126,8128,126,8764,126,65372,124,65293,45,120784,50,120794,50,120804,50,120814,50,120824,50,130034,50,42842,50,423,50,1000,50,42564,50,5311,50,42735,50,119302,51,120785,51,120795,51,120805,51,120815,51,120825,51,130035,51,42923,51,540,51,439,51,42858,51,11468,51,1248,51,94011,51,71882,51,120786,52,120796,52,120806,52,120816,52,120826,52,130036,52,5070,52,71855,52,120787,53,120797,53,120807,53,120817,53,120827,53,130037,53,444,53,71867,53,120788,54,120798,54,120808,54,120818,54,120828,54,130038,54,11474,54,5102,54,71893,54,119314,55,120789,55,120799,55,120809,55,120819,55,120829,55,130039,55,66770,55,71878,55,2819,56,2538,56,2666,56,125131,56,120790,56,120800,56,120810,56,120820,56,120830,56,130040,56,547,56,546,56,66330,56,2663,57,2920,57,2541,57,3437,57,120791,57,120801,57,120811,57,120821,57,120831,57,130041,57,42862,57,11466,57,71884,57,71852,57,71894,57,9082,97,65345,97,119834,97,119886,97,119938,97,119990,97,120042,97,120094,97,120146,97,120198,97,120250,97,120302,97,120354,97,120406,97,120458,97,593,97,945,97,120514,97,120572,97,120630,97,120688,97,120746,97,65313,65,119808,65,119860,65,119912,65,119964,65,120016,65,120068,65,120120,65,120172,65,120224,65,120276,65,120328,65,120380,65,120432,65,913,65,120488,65,120546,65,120604,65,120662,65,120720,65,5034,65,5573,65,42222,65,94016,65,66208,65,119835,98,119887,98,119939,98,119991,98,120043,98,120095,98,120147,98,120199,98,120251,98,120303,98,120355,98,120407,98,120459,98,388,98,5071,98,5234,98,5551,98,65314,66,8492,66,119809,66,119861,66,119913,66,120017,66,120069,66,120121,66,120173,66,120225,66,120277,66,120329,66,120381,66,120433,66,42932,66,914,66,120489,66,120547,66,120605,66,120663,66,120721,66,5108,66,5623,66,42192,66,66178,66,66209,66,66305,66,65347,99,8573,99,119836,99,119888,99,119940,99,119992,99,120044,99,120096,99,120148,99,120200,99,120252,99,120304,99,120356,99,120408,99,120460,99,7428,99,1010,99,11429,99,43951,99,66621,99,128844,67,71922,67,71913,67,65315,67,8557,67,8450,67,8493,67,119810,67,119862,67,119914,67,119966,67,120018,67,120174,67,120226,67,120278,67,120330,67,120382,67,120434,67,1017,67,11428,67,5087,67,42202,67,66210,67,66306,67,66581,67,66844,67,8574,100,8518,100,119837,100,119889,100,119941,100,119993,100,120045,100,120097,100,120149,100,120201,100,120253,100,120305,100,120357,100,120409,100,120461,100,1281,100,5095,100,5231,100,42194,100,8558,68,8517,68,119811,68,119863,68,119915,68,119967,68,120019,68,120071,68,120123,68,120175,68,120227,68,120279,68,120331,68,120383,68,120435,68,5024,68,5598,68,5610,68,42195,68,8494,101,65349,101,8495,101,8519,101,119838,101,119890,101,119942,101,120046,101,120098,101,120150,101,120202,101,120254,101,120306,101,120358,101,120410,101,120462,101,43826,101,1213,101,8959,69,65317,69,8496,69,119812,69,119864,69,119916,69,120020,69,120072,69,120124,69,120176,69,120228,69,120280,69,120332,69,120384,69,120436,69,917,69,120492,69,120550,69,120608,69,120666,69,120724,69,11577,69,5036,69,42224,69,71846,69,71854,69,66182,69,119839,102,119891,102,119943,102,119995,102,120047,102,120099,102,120151,102,120203,102,120255,102,120307,102,120359,102,120411,102,120463,102,43829,102,42905,102,383,102,7837,102,1412,102,119315,70,8497,70,119813,70,119865,70,119917,70,120021,70,120073,70,120125,70,120177,70,120229,70,120281,70,120333,70,120385,70,120437,70,42904,70,988,70,120778,70,5556,70,42205,70,71874,70,71842,70,66183,70,66213,70,66853,70,65351,103,8458,103,119840,103,119892,103,119944,103,120048,103,120100,103,120152,103,120204,103,120256,103,120308,103,120360,103,120412,103,120464,103,609,103,7555,103,397,103,1409,103,119814,71,119866,71,119918,71,119970,71,120022,71,120074,71,120126,71,120178,71,120230,71,120282,71,120334,71,120386,71,120438,71,1292,71,5056,71,5107,71,42198,71,65352,104,8462,104,119841,104,119945,104,119997,104,120049,104,120101,104,120153,104,120205,104,120257,104,120309,104,120361,104,120413,104,120465,104,1211,104,1392,104,5058,104,65320,72,8459,72,8460,72,8461,72,119815,72,119867,72,119919,72,120023,72,120179,72,120231,72,120283,72,120335,72,120387,72,120439,72,919,72,120494,72,120552,72,120610,72,120668,72,120726,72,11406,72,5051,72,5500,72,42215,72,66255,72,731,105,9075,105,65353,105,8560,105,8505,105,8520,105,119842,105,119894,105,119946,105,119998,105,120050,105,120102,105,120154,105,120206,105,120258,105,120310,105,120362,105,120414,105,120466,105,120484,105,618,105,617,105,953,105,8126,105,890,105,120522,105,120580,105,120638,105,120696,105,120754,105,1110,105,42567,105,1231,105,43893,105,5029,105,71875,105,65354,106,8521,106,119843,106,119895,106,119947,106,119999,106,120051,106,120103,106,120155,106,120207,106,120259,106,120311,106,120363,106,120415,106,120467,106,1011,106,1112,106,65322,74,119817,74,119869,74,119921,74,119973,74,120025,74,120077,74,120129,74,120181,74,120233,74,120285,74,120337,74,120389,74,120441,74,42930,74,895,74,1032,74,5035,74,5261,74,42201,74,119844,107,119896,107,119948,107,120000,107,120052,107,120104,107,120156,107,120208,107,120260,107,120312,107,120364,107,120416,107,120468,107,8490,75,65323,75,119818,75,119870,75,119922,75,119974,75,120026,75,120078,75,120130,75,120182,75,120234,75,120286,75,120338,75,120390,75,120442,75,922,75,120497,75,120555,75,120613,75,120671,75,120729,75,11412,75,5094,75,5845,75,42199,75,66840,75,1472,108,8739,73,9213,73,65512,73,1633,108,1777,73,66336,108,125127,108,120783,73,120793,73,120803,73,120813,73,120823,73,130033,73,65321,73,8544,73,8464,73,8465,73,119816,73,119868,73,119920,73,120024,73,120128,73,120180,73,120232,73,120284,73,120336,73,120388,73,120440,73,65356,108,8572,73,8467,108,119845,108,119897,108,119949,108,120001,108,120053,108,120105,73,120157,73,120209,73,120261,73,120313,73,120365,73,120417,73,120469,73,448,73,120496,73,120554,73,120612,73,120670,73,120728,73,11410,73,1030,73,1216,73,1493,108,1503,108,1575,108,126464,108,126592,108,65166,108,65165,108,1994,108,11599,73,5825,73,42226,73,93992,73,66186,124,66313,124,119338,76,8556,76,8466,76,119819,76,119871,76,119923,76,120027,76,120079,76,120131,76,120183,76,120235,76,120287,76,120339,76,120391,76,120443,76,11472,76,5086,76,5290,76,42209,76,93974,76,71843,76,71858,76,66587,76,66854,76,65325,77,8559,77,8499,77,119820,77,119872,77,119924,77,120028,77,120080,77,120132,77,120184,77,120236,77,120288,77,120340,77,120392,77,120444,77,924,77,120499,77,120557,77,120615,77,120673,77,120731,77,1018,77,11416,77,5047,77,5616,77,5846,77,42207,77,66224,77,66321,77,119847,110,119899,110,119951,110,120003,110,120055,110,120107,110,120159,110,120211,110,120263,110,120315,110,120367,110,120419,110,120471,110,1400,110,1404,110,65326,78,8469,78,119821,78,119873,78,119925,78,119977,78,120029,78,120081,78,120185,78,120237,78,120289,78,120341,78,120393,78,120445,78,925,78,120500,78,120558,78,120616,78,120674,78,120732,78,11418,78,42208,78,66835,78,3074,111,3202,111,3330,111,3458,111,2406,111,2662,111,2790,111,3046,111,3174,111,3302,111,3430,111,3664,111,3792,111,4160,111,1637,111,1781,111,65359,111,8500,111,119848,111,119900,111,119952,111,120056,111,120108,111,120160,111,120212,111,120264,111,120316,111,120368,111,120420,111,120472,111,7439,111,7441,111,43837,111,959,111,120528,111,120586,111,120644,111,120702,111,120760,111,963,111,120532,111,120590,111,120648,111,120706,111,120764,111,11423,111,4351,111,1413,111,1505,111,1607,111,126500,111,126564,111,126596,111,65259,111,65260,111,65258,111,65257,111,1726,111,64428,111,64429,111,64427,111,64426,111,1729,111,64424,111,64425,111,64423,111,64422,111,1749,111,3360,111,4125,111,66794,111,71880,111,71895,111,66604,111,1984,79,2534,79,2918,79,12295,79,70864,79,71904,79,120782,79,120792,79,120802,79,120812,79,120822,79,130032,79,65327,79,119822,79,119874,79,119926,79,119978,79,120030,79,120082,79,120134,79,120186,79,120238,79,120290,79,120342,79,120394,79,120446,79,927,79,120502,79,120560,79,120618,79,120676,79,120734,79,11422,79,1365,79,11604,79,4816,79,2848,79,66754,79,42227,79,71861,79,66194,79,66219,79,66564,79,66838,79,9076,112,65360,112,119849,112,119901,112,119953,112,120005,112,120057,112,120109,112,120161,112,120213,112,120265,112,120317,112,120369,112,120421,112,120473,112,961,112,120530,112,120544,112,120588,112,120602,112,120646,112,120660,112,120704,112,120718,112,120762,112,120776,112,11427,112,65328,80,8473,80,119823,80,119875,80,119927,80,119979,80,120031,80,120083,80,120187,80,120239,80,120291,80,120343,80,120395,80,120447,80,929,80,120504,80,120562,80,120620,80,120678,80,120736,80,11426,80,5090,80,5229,80,42193,80,66197,80,119850,113,119902,113,119954,113,120006,113,120058,113,120110,113,120162,113,120214,113,120266,113,120318,113,120370,113,120422,113,120474,113,1307,113,1379,113,1382,113,8474,81,119824,81,119876,81,119928,81,119980,81,120032,81,120084,81,120188,81,120240,81,120292,81,120344,81,120396,81,120448,81,11605,81,119851,114,119903,114,119955,114,120007,114,120059,114,120111,114,120163,114,120215,114,120267,114,120319,114,120371,114,120423,114,120475,114,43847,114,43848,114,7462,114,11397,114,43905,114,119318,82,8475,82,8476,82,8477,82,119825,82,119877,82,119929,82,120033,82,120189,82,120241,82,120293,82,120345,82,120397,82,120449,82,422,82,5025,82,5074,82,66740,82,5511,82,42211,82,94005,82,65363,115,119852,115,119904,115,119956,115,120008,115,120060,115,120112,115,120164,115,120216,115,120268,115,120320,115,120372,115,120424,115,120476,115,42801,115,445,115,1109,115,43946,115,71873,115,66632,115,65331,83,119826,83,119878,83,119930,83,119982,83,120034,83,120086,83,120138,83,120190,83,120242,83,120294,83,120346,83,120398,83,120450,83,1029,83,1359,83,5077,83,5082,83,42210,83,94010,83,66198,83,66592,83,119853,116,119905,116,119957,116,120009,116,120061,116,120113,116,120165,116,120217,116,120269,116,120321,116,120373,116,120425,116,120477,116,8868,84,10201,84,128872,84,65332,84,119827,84,119879,84,119931,84,119983,84,120035,84,120087,84,120139,84,120191,84,120243,84,120295,84,120347,84,120399,84,120451,84,932,84,120507,84,120565,84,120623,84,120681,84,120739,84,11430,84,5026,84,42196,84,93962,84,71868,84,66199,84,66225,84,66325,84,119854,117,119906,117,119958,117,120010,117,120062,117,120114,117,120166,117,120218,117,120270,117,120322,117,120374,117,120426,117,120478,117,42911,117,7452,117,43854,117,43858,117,651,117,965,117,120534,117,120592,117,120650,117,120708,117,120766,117,1405,117,66806,117,71896,117,8746,85,8899,85,119828,85,119880,85,119932,85,119984,85,120036,85,120088,85,120140,85,120192,85,120244,85,120296,85,120348,85,120400,85,120452,85,1357,85,4608,85,66766,85,5196,85,42228,85,94018,85,71864,85,8744,118,8897,118,65366,118,8564,118,119855,118,119907,118,119959,118,120011,118,120063,118,120115,118,120167,118,120219,118,120271,118,120323,118,120375,118,120427,118,120479,118,7456,118,957,118,120526,118,120584,118,120642,118,120700,118,120758,118,1141,118,1496,118,71430,118,43945,118,71872,118,119309,86,1639,86,1783,86,8548,86,119829,86,119881,86,119933,86,119985,86,120037,86,120089,86,120141,86,120193,86,120245,86,120297,86,120349,86,120401,86,120453,86,1140,86,11576,86,5081,86,5167,86,42719,86,42214,86,93960,86,71840,86,66845,86,623,119,119856,119,119908,119,119960,119,120012,119,120064,119,120116,119,120168,119,120220,119,120272,119,120324,119,120376,119,120428,119,120480,119,7457,119,1121,119,1309,119,1377,119,71434,119,71438,119,71439,119,43907,119,71919,87,71910,87,119830,87,119882,87,119934,87,119986,87,120038,87,120090,87,120142,87,120194,87,120246,87,120298,87,120350,87,120402,87,120454,87,1308,87,5043,87,5076,87,42218,87,5742,120,10539,120,10540,120,10799,120,65368,120,8569,120,119857,120,119909,120,119961,120,120013,120,120065,120,120117,120,120169,120,120221,120,120273,120,120325,120,120377,120,120429,120,120481,120,5441,120,5501,120,5741,88,9587,88,66338,88,71916,88,65336,88,8553,88,119831,88,119883,88,119935,88,119987,88,120039,88,120091,88,120143,88,120195,88,120247,88,120299,88,120351,88,120403,88,120455,88,42931,88,935,88,120510,88,120568,88,120626,88,120684,88,120742,88,11436,88,11613,88,5815,88,42219,88,66192,88,66228,88,66327,88,66855,88,611,121,7564,121,65369,121,119858,121,119910,121,119962,121,120014,121,120066,121,120118,121,120170,121,120222,121,120274,121,120326,121,120378,121,120430,121,120482,121,655,121,7935,121,43866,121,947,121,8509,121,120516,121,120574,121,120632,121,120690,121,120748,121,1199,121,4327,121,71900,121,65337,89,119832,89,119884,89,119936,89,119988,89,120040,89,120092,89,120144,89,120196,89,120248,89,120300,89,120352,89,120404,89,120456,89,933,89,978,89,120508,89,120566,89,120624,89,120682,89,120740,89,11432,89,1198,89,5033,89,5053,89,42220,89,94019,89,71844,89,66226,89,119859,122,119911,122,119963,122,120015,122,120067,122,120119,122,120171,122,120223,122,120275,122,120327,122,120379,122,120431,122,120483,122,7458,122,43923,122,71876,122,66293,90,71909,90,65338,90,8484,90,8488,90,119833,90,119885,90,119937,90,119989,90,120041,90,120197,90,120249,90,120301,90,120353,90,120405,90,120457,90,918,90,120493,90,120551,90,120609,90,120667,90,120725,90,5059,90,42204,90,71849,90,65282,34,65284,36,65285,37,65286,38,65290,42,65291,43,65294,46,65295,47,65296,48,65297,49,65298,50,65299,51,65300,52,65301,53,65302,54,65303,55,65304,56,65305,57,65308,60,65309,61,65310,62,65312,64,65316,68,65318,70,65319,71,65324,76,65329,81,65330,82,65333,85,65334,86,65335,87,65343,95,65346,98,65348,100,65350,102,65355,107,65357,109,65358,110,65361,113,65362,114,65364,116,65365,117,65367,119,65370,122,65371,123,65373,125,119846,109],\\\"_default\\\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"cs\\\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"de\\\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"es\\\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"fr\\\":[65374,126,65306,58,65281,33,8216,96,8245,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"it\\\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"ja\\\":[8211,45,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65292,44,65307,59],\\\"ko\\\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"pl\\\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"pt-BR\\\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"qps-ploc\\\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"ru\\\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,305,105,921,73,1009,112,215,120,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"tr\\\":[160,32,8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\\\"zh-hans\\\":[65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65288,40,65289,41],\\\"zh-hant\\\":[8211,45,65374,126,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65307,59]}');\n});\nAmbiguousCharacters.cache = new LRUCachedFunction((locales) => {\n    function arrayToMap(arr) {\n        const result = new Map();\n        for (let i = 0; i < arr.length; i += 2) {\n            result.set(arr[i], arr[i + 1]);\n        }\n        return result;\n    }\n    function mergeMaps(map1, map2) {\n        const result = new Map(map1);\n        for (const [key, value] of map2) {\n            result.set(key, value);\n        }\n        return result;\n    }\n    function intersectMaps(map1, map2) {\n        if (!map1) {\n            return map2;\n        }\n        const result = new Map();\n        for (const [key, value] of map1) {\n            if (map2.has(key)) {\n                result.set(key, value);\n            }\n        }\n        return result;\n    }\n    const data = _a.ambiguousCharacterData.value;\n    let filteredLocales = locales.filter((l) => !l.startsWith('_') && l in data);\n    if (filteredLocales.length === 0) {\n        filteredLocales = ['_default'];\n    }\n    let languageSpecificMap = undefined;\n    for (const locale of filteredLocales) {\n        const map = arrayToMap(data[locale]);\n        languageSpecificMap = intersectMaps(languageSpecificMap, map);\n    }\n    const commonMap = arrayToMap(data['_common']);\n    const map = mergeMaps(commonMap, languageSpecificMap);\n    return new AmbiguousCharacters(map);\n});\nAmbiguousCharacters._locales = new Lazy(() => Object.keys(AmbiguousCharacters.ambiguousCharacterData.value).filter((k) => !k.startsWith('_')));\nexport class InvisibleCharacters {\n    static getRawData() {\n        // Generated using https://github.com/hediet/vscode-unicode-data\n        return JSON.parse('[9,10,11,12,13,32,127,160,173,847,1564,4447,4448,6068,6069,6155,6156,6157,6158,7355,7356,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8234,8235,8236,8237,8238,8239,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,10240,12288,12644,65024,65025,65026,65027,65028,65029,65030,65031,65032,65033,65034,65035,65036,65037,65038,65039,65279,65440,65520,65521,65522,65523,65524,65525,65526,65527,65528,65532,78844,119155,119156,119157,119158,119159,119160,119161,119162,917504,917505,917506,917507,917508,917509,917510,917511,917512,917513,917514,917515,917516,917517,917518,917519,917520,917521,917522,917523,917524,917525,917526,917527,917528,917529,917530,917531,917532,917533,917534,917535,917536,917537,917538,917539,917540,917541,917542,917543,917544,917545,917546,917547,917548,917549,917550,917551,917552,917553,917554,917555,917556,917557,917558,917559,917560,917561,917562,917563,917564,917565,917566,917567,917568,917569,917570,917571,917572,917573,917574,917575,917576,917577,917578,917579,917580,917581,917582,917583,917584,917585,917586,917587,917588,917589,917590,917591,917592,917593,917594,917595,917596,917597,917598,917599,917600,917601,917602,917603,917604,917605,917606,917607,917608,917609,917610,917611,917612,917613,917614,917615,917616,917617,917618,917619,917620,917621,917622,917623,917624,917625,917626,917627,917628,917629,917630,917631,917760,917761,917762,917763,917764,917765,917766,917767,917768,917769,917770,917771,917772,917773,917774,917775,917776,917777,917778,917779,917780,917781,917782,917783,917784,917785,917786,917787,917788,917789,917790,917791,917792,917793,917794,917795,917796,917797,917798,917799,917800,917801,917802,917803,917804,917805,917806,917807,917808,917809,917810,917811,917812,917813,917814,917815,917816,917817,917818,917819,917820,917821,917822,917823,917824,917825,917826,917827,917828,917829,917830,917831,917832,917833,917834,917835,917836,917837,917838,917839,917840,917841,917842,917843,917844,917845,917846,917847,917848,917849,917850,917851,917852,917853,917854,917855,917856,917857,917858,917859,917860,917861,917862,917863,917864,917865,917866,917867,917868,917869,917870,917871,917872,917873,917874,917875,917876,917877,917878,917879,917880,917881,917882,917883,917884,917885,917886,917887,917888,917889,917890,917891,917892,917893,917894,917895,917896,917897,917898,917899,917900,917901,917902,917903,917904,917905,917906,917907,917908,917909,917910,917911,917912,917913,917914,917915,917916,917917,917918,917919,917920,917921,917922,917923,917924,917925,917926,917927,917928,917929,917930,917931,917932,917933,917934,917935,917936,917937,917938,917939,917940,917941,917942,917943,917944,917945,917946,917947,917948,917949,917950,917951,917952,917953,917954,917955,917956,917957,917958,917959,917960,917961,917962,917963,917964,917965,917966,917967,917968,917969,917970,917971,917972,917973,917974,917975,917976,917977,917978,917979,917980,917981,917982,917983,917984,917985,917986,917987,917988,917989,917990,917991,917992,917993,917994,917995,917996,917997,917998,917999]');\n    }\n    static getData() {\n        if (!this._data) {\n            this._data = new Set(InvisibleCharacters.getRawData());\n        }\n        return this._data;\n    }\n    static isInvisibleCharacter(codePoint) {\n        return InvisibleCharacters.getData().has(codePoint);\n    }\n    static get codePoints() {\n        return InvisibleCharacters.getData();\n    }\n}\nInvisibleCharacters._data = undefined;\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Emitter } from '../common/event.js';\nimport { Disposable, markAsSingleton } from '../common/lifecycle.js';\nclass WindowManager {\n    constructor() {\n        // --- Zoom Factor\n        this._zoomFactor = 1;\n    }\n    getZoomFactor() {\n        return this._zoomFactor;\n    }\n}\nWindowManager.INSTANCE = new WindowManager();\n/**\n * See https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n */\nclass DevicePixelRatioMonitor extends Disposable {\n    constructor() {\n        super();\n        this._onDidChange = this._register(new Emitter());\n        this.onDidChange = this._onDidChange.event;\n        this._listener = () => this._handleChange(true);\n        this._mediaQueryList = null;\n        this._handleChange(false);\n    }\n    _handleChange(fireEvent) {\n        var _a;\n        (_a = this._mediaQueryList) === null || _a === void 0 ? void 0 : _a.removeEventListener('change', this._listener);\n        this._mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\n        this._mediaQueryList.addEventListener('change', this._listener);\n        if (fireEvent) {\n            this._onDidChange.fire();\n        }\n    }\n}\nclass PixelRatioImpl extends Disposable {\n    get value() {\n        return this._value;\n    }\n    constructor() {\n        super();\n        this._onDidChange = this._register(new Emitter());\n        this.onDidChange = this._onDidChange.event;\n        this._value = this._getPixelRatio();\n        const dprMonitor = this._register(new DevicePixelRatioMonitor());\n        this._register(dprMonitor.onDidChange(() => {\n            this._value = this._getPixelRatio();\n            this._onDidChange.fire(this._value);\n        }));\n    }\n    _getPixelRatio() {\n        const ctx = document.createElement('canvas').getContext('2d');\n        const dpr = window.devicePixelRatio || 1;\n        const bsr = ctx.webkitBackingStorePixelRatio ||\n            ctx.mozBackingStorePixelRatio ||\n            ctx.msBackingStorePixelRatio ||\n            ctx.oBackingStorePixelRatio ||\n            ctx.backingStorePixelRatio || 1;\n        return dpr / bsr;\n    }\n}\nclass PixelRatioFacade {\n    constructor() {\n        this._pixelRatioMonitor = null;\n    }\n    _getOrCreatePixelRatioMonitor() {\n        if (!this._pixelRatioMonitor) {\n            this._pixelRatioMonitor = markAsSingleton(new PixelRatioImpl());\n        }\n        return this._pixelRatioMonitor;\n    }\n    /**\n     * Get the current value.\n     */\n    get value() {\n        return this._getOrCreatePixelRatioMonitor().value;\n    }\n    /**\n     * Listen for changes.\n     */\n    get onDidChange() {\n        return this._getOrCreatePixelRatioMonitor().onDidChange;\n    }\n}\nexport function addMatchMediaChangeListener(query, callback) {\n    if (typeof query === 'string') {\n        query = window.matchMedia(query);\n    }\n    query.addEventListener('change', callback);\n}\n/**\n * Returns the pixel ratio.\n *\n * This is useful for rendering  elements at native screen resolution or for being used as\n * a cache key when storing font measurements. Fonts might render differently depending on resolution\n * and any measurements need to be discarded for example when a window is moved from a monitor to another.\n */\nexport const PixelRatio = new PixelRatioFacade();\n/** The zoom scale for an index, e.g. 1, 1.2, 1.4 */\nexport function getZoomFactor() {\n    return WindowManager.INSTANCE.getZoomFactor();\n}\nconst userAgent = navigator.userAgent;\nexport const isFirefox = (userAgent.indexOf('Firefox') >= 0);\nexport const isWebKit = (userAgent.indexOf('AppleWebKit') >= 0);\nexport const isChrome = (userAgent.indexOf('Chrome') >= 0);\nexport const isSafari = (!isChrome && (userAgent.indexOf('Safari') >= 0));\nexport const isWebkitWebView = (!isChrome && !isSafari && isWebKit);\nexport const isElectron = (userAgent.indexOf('Electron/') >= 0);\nexport const isAndroid = (userAgent.indexOf('Android') >= 0);\nlet standalone = false;\nif (window.matchMedia) {\n    const standaloneMatchMedia = window.matchMedia('(display-mode: standalone) or (display-mode: window-controls-overlay)');\n    const fullScreenMatchMedia = window.matchMedia('(display-mode: fullscreen)');\n    standalone = standaloneMatchMedia.matches;\n    addMatchMediaChangeListener(standaloneMatchMedia, ({ matches }) => {\n        // entering fullscreen would change standaloneMatchMedia.matches to false\n        // if standalone is true (running as PWA) and entering fullscreen, skip this change\n        if (standalone && fullScreenMatchMedia.matches) {\n            return;\n        }\n        // otherwise update standalone (browser to PWA or PWA to browser)\n        standalone = matches;\n    });\n}\nexport function isStandalone() {\n    return standalone;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport class FastDomNode {\n    constructor(domNode) {\n        this.domNode = domNode;\n        this._maxWidth = '';\n        this._width = '';\n        this._height = '';\n        this._top = '';\n        this._left = '';\n        this._bottom = '';\n        this._right = '';\n        this._paddingLeft = '';\n        this._fontFamily = '';\n        this._fontWeight = '';\n        this._fontSize = '';\n        this._fontStyle = '';\n        this._fontFeatureSettings = '';\n        this._fontVariationSettings = '';\n        this._textDecoration = '';\n        this._lineHeight = '';\n        this._letterSpacing = '';\n        this._className = '';\n        this._display = '';\n        this._position = '';\n        this._visibility = '';\n        this._color = '';\n        this._backgroundColor = '';\n        this._layerHint = false;\n        this._contain = 'none';\n        this._boxShadow = '';\n    }\n    setMaxWidth(_maxWidth) {\n        const maxWidth = numberAsPixels(_maxWidth);\n        if (this._maxWidth === maxWidth) {\n            return;\n        }\n        this._maxWidth = maxWidth;\n        this.domNode.style.maxWidth = this._maxWidth;\n    }\n    setWidth(_width) {\n        const width = numberAsPixels(_width);\n        if (this._width === width) {\n            return;\n        }\n        this._width = width;\n        this.domNode.style.width = this._width;\n    }\n    setHeight(_height) {\n        const height = numberAsPixels(_height);\n        if (this._height === height) {\n            return;\n        }\n        this._height = height;\n        this.domNode.style.height = this._height;\n    }\n    setTop(_top) {\n        const top = numberAsPixels(_top);\n        if (this._top === top) {\n            return;\n        }\n        this._top = top;\n        this.domNode.style.top = this._top;\n    }\n    setLeft(_left) {\n        const left = numberAsPixels(_left);\n        if (this._left === left) {\n            return;\n        }\n        this._left = left;\n        this.domNode.style.left = this._left;\n    }\n    setBottom(_bottom) {\n        const bottom = numberAsPixels(_bottom);\n        if (this._bottom === bottom) {\n            return;\n        }\n        this._bottom = bottom;\n        this.domNode.style.bottom = this._bottom;\n    }\n    setRight(_right) {\n        const right = numberAsPixels(_right);\n        if (this._right === right) {\n            return;\n        }\n        this._right = right;\n        this.domNode.style.right = this._right;\n    }\n    setPaddingLeft(_paddingLeft) {\n        const paddingLeft = numberAsPixels(_paddingLeft);\n        if (this._paddingLeft === paddingLeft) {\n            return;\n        }\n        this._paddingLeft = paddingLeft;\n        this.domNode.style.paddingLeft = this._paddingLeft;\n    }\n    setFontFamily(fontFamily) {\n        if (this._fontFamily === fontFamily) {\n            return;\n        }\n        this._fontFamily = fontFamily;\n        this.domNode.style.fontFamily = this._fontFamily;\n    }\n    setFontWeight(fontWeight) {\n        if (this._fontWeight === fontWeight) {\n            return;\n        }\n        this._fontWeight = fontWeight;\n        this.domNode.style.fontWeight = this._fontWeight;\n    }\n    setFontSize(_fontSize) {\n        const fontSize = numberAsPixels(_fontSize);\n        if (this._fontSize === fontSize) {\n            return;\n        }\n        this._fontSize = fontSize;\n        this.domNode.style.fontSize = this._fontSize;\n    }\n    setFontStyle(fontStyle) {\n        if (this._fontStyle === fontStyle) {\n            return;\n        }\n        this._fontStyle = fontStyle;\n        this.domNode.style.fontStyle = this._fontStyle;\n    }\n    setFontFeatureSettings(fontFeatureSettings) {\n        if (this._fontFeatureSettings === fontFeatureSettings) {\n            return;\n        }\n        this._fontFeatureSettings = fontFeatureSettings;\n        this.domNode.style.fontFeatureSettings = this._fontFeatureSettings;\n    }\n    setFontVariationSettings(fontVariationSettings) {\n        if (this._fontVariationSettings === fontVariationSettings) {\n            return;\n        }\n        this._fontVariationSettings = fontVariationSettings;\n        this.domNode.style.fontVariationSettings = this._fontVariationSettings;\n    }\n    setTextDecoration(textDecoration) {\n        if (this._textDecoration === textDecoration) {\n            return;\n        }\n        this._textDecoration = textDecoration;\n        this.domNode.style.textDecoration = this._textDecoration;\n    }\n    setLineHeight(_lineHeight) {\n        const lineHeight = numberAsPixels(_lineHeight);\n        if (this._lineHeight === lineHeight) {\n            return;\n        }\n        this._lineHeight = lineHeight;\n        this.domNode.style.lineHeight = this._lineHeight;\n    }\n    setLetterSpacing(_letterSpacing) {\n        const letterSpacing = numberAsPixels(_letterSpacing);\n        if (this._letterSpacing === letterSpacing) {\n            return;\n        }\n        this._letterSpacing = letterSpacing;\n        this.domNode.style.letterSpacing = this._letterSpacing;\n    }\n    setClassName(className) {\n        if (this._className === className) {\n            return;\n        }\n        this._className = className;\n        this.domNode.className = this._className;\n    }\n    toggleClassName(className, shouldHaveIt) {\n        this.domNode.classList.toggle(className, shouldHaveIt);\n        this._className = this.domNode.className;\n    }\n    setDisplay(display) {\n        if (this._display === display) {\n            return;\n        }\n        this._display = display;\n        this.domNode.style.display = this._display;\n    }\n    setPosition(position) {\n        if (this._position === position) {\n            return;\n        }\n        this._position = position;\n        this.domNode.style.position = this._position;\n    }\n    setVisibility(visibility) {\n        if (this._visibility === visibility) {\n            return;\n        }\n        this._visibility = visibility;\n        this.domNode.style.visibility = this._visibility;\n    }\n    setColor(color) {\n        if (this._color === color) {\n            return;\n        }\n        this._color = color;\n        this.domNode.style.color = this._color;\n    }\n    setBackgroundColor(backgroundColor) {\n        if (this._backgroundColor === backgroundColor) {\n            return;\n        }\n        this._backgroundColor = backgroundColor;\n        this.domNode.style.backgroundColor = this._backgroundColor;\n    }\n    setLayerHinting(layerHint) {\n        if (this._layerHint === layerHint) {\n            return;\n        }\n        this._layerHint = layerHint;\n        this.domNode.style.transform = this._layerHint ? 'translate3d(0px, 0px, 0px)' : '';\n    }\n    setBoxShadow(boxShadow) {\n        if (this._boxShadow === boxShadow) {\n            return;\n        }\n        this._boxShadow = boxShadow;\n        this.domNode.style.boxShadow = boxShadow;\n    }\n    setContain(contain) {\n        if (this._contain === contain) {\n            return;\n        }\n        this._contain = contain;\n        this.domNode.style.contain = this._contain;\n    }\n    setAttribute(name, value) {\n        this.domNode.setAttribute(name, value);\n    }\n    removeAttribute(name) {\n        this.domNode.removeAttribute(name);\n    }\n    appendChild(child) {\n        this.domNode.appendChild(child.domNode);\n    }\n    removeChild(child) {\n        this.domNode.removeChild(child.domNode);\n    }\n}\nfunction numberAsPixels(value) {\n    return (typeof value === 'number' ? `${value}px` : value);\n}\nexport function createFastDomNode(domNode) {\n    return new FastDomNode(domNode);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { FastDomNode } from '../../../base/browser/fastDomNode.js';\nexport function applyFontInfo(domNode, fontInfo) {\n    if (domNode instanceof FastDomNode) {\n        domNode.setFontFamily(fontInfo.getMassagedFontFamily());\n        domNode.setFontWeight(fontInfo.fontWeight);\n        domNode.setFontSize(fontInfo.fontSize);\n        domNode.setFontFeatureSettings(fontInfo.fontFeatureSettings);\n        domNode.setFontVariationSettings(fontInfo.fontVariationSettings);\n        domNode.setLineHeight(fontInfo.lineHeight);\n        domNode.setLetterSpacing(fontInfo.letterSpacing);\n    }\n    else {\n        domNode.style.fontFamily = fontInfo.getMassagedFontFamily();\n        domNode.style.fontWeight = fontInfo.fontWeight;\n        domNode.style.fontSize = fontInfo.fontSize + 'px';\n        domNode.style.fontFeatureSettings = fontInfo.fontFeatureSettings;\n        domNode.style.fontVariationSettings = fontInfo.fontVariationSettings;\n        domNode.style.lineHeight = fontInfo.lineHeight + 'px';\n        domNode.style.letterSpacing = fontInfo.letterSpacing + 'px';\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { applyFontInfo } from './domFontInfo.js';\nexport class CharWidthRequest {\n    constructor(chr, type) {\n        this.chr = chr;\n        this.type = type;\n        this.width = 0;\n    }\n    fulfill(width) {\n        this.width = width;\n    }\n}\nclass DomCharWidthReader {\n    constructor(bareFontInfo, requests) {\n        this._bareFontInfo = bareFontInfo;\n        this._requests = requests;\n        this._container = null;\n        this._testElements = null;\n    }\n    read() {\n        // Create a test container with all these test elements\n        this._createDomElements();\n        // Add the container to the DOM\n        document.body.appendChild(this._container);\n        // Read character widths\n        this._readFromDomElements();\n        // Remove the container from the DOM\n        document.body.removeChild(this._container);\n        this._container = null;\n        this._testElements = null;\n    }\n    _createDomElements() {\n        const container = document.createElement('div');\n        container.style.position = 'absolute';\n        container.style.top = '-50000px';\n        container.style.width = '50000px';\n        const regularDomNode = document.createElement('div');\n        applyFontInfo(regularDomNode, this._bareFontInfo);\n        container.appendChild(regularDomNode);\n        const boldDomNode = document.createElement('div');\n        applyFontInfo(boldDomNode, this._bareFontInfo);\n        boldDomNode.style.fontWeight = 'bold';\n        container.appendChild(boldDomNode);\n        const italicDomNode = document.createElement('div');\n        applyFontInfo(italicDomNode, this._bareFontInfo);\n        italicDomNode.style.fontStyle = 'italic';\n        container.appendChild(italicDomNode);\n        const testElements = [];\n        for (const request of this._requests) {\n            let parent;\n            if (request.type === 0 /* CharWidthRequestType.Regular */) {\n                parent = regularDomNode;\n            }\n            if (request.type === 2 /* CharWidthRequestType.Bold */) {\n                parent = boldDomNode;\n            }\n            if (request.type === 1 /* CharWidthRequestType.Italic */) {\n                parent = italicDomNode;\n            }\n            parent.appendChild(document.createElement('br'));\n            const testElement = document.createElement('span');\n            DomCharWidthReader._render(testElement, request);\n            parent.appendChild(testElement);\n            testElements.push(testElement);\n        }\n        this._container = container;\n        this._testElements = testElements;\n    }\n    static _render(testElement, request) {\n        if (request.chr === ' ') {\n            let htmlString = '\\u00a0';\n            // Repeat character 256 (2^8) times\n            for (let i = 0; i < 8; i++) {\n                htmlString += htmlString;\n            }\n            testElement.innerText = htmlString;\n        }\n        else {\n            let testString = request.chr;\n            // Repeat character 256 (2^8) times\n            for (let i = 0; i < 8; i++) {\n                testString += testString;\n            }\n            testElement.textContent = testString;\n        }\n    }\n    _readFromDomElements() {\n        for (let i = 0, len = this._requests.length; i < len; i++) {\n            const request = this._requests[i];\n            const testElement = this._testElements[i];\n            request.fulfill(testElement.offsetWidth / 256);\n        }\n    }\n}\nexport function readCharWidths(bareFontInfo, requests) {\n    const reader = new DomCharWidthReader(bareFontInfo, requests);\n    reader.read();\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Emitter } from '../../../base/common/event.js';\nexport const EditorZoom = new class {\n    constructor() {\n        this._zoomLevel = 0;\n        this._onDidChangeZoomLevel = new Emitter();\n        this.onDidChangeZoomLevel = this._onDidChangeZoomLevel.event;\n    }\n    getZoomLevel() {\n        return this._zoomLevel;\n    }\n    setZoomLevel(zoomLevel) {\n        zoomLevel = Math.min(Math.max(-5, zoomLevel), 20);\n        if (this._zoomLevel === zoomLevel) {\n            return;\n        }\n        this._zoomLevel = zoomLevel;\n        this._onDidChangeZoomLevel.fire(this._zoomLevel);\n    }\n};\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as platform from '../../../base/common/platform.js';\nimport { EditorFontVariations, EDITOR_FONT_DEFAULTS } from './editorOptions.js';\nimport { EditorZoom } from './editorZoom.js';\n/**\n * Determined from empirical observations.\n * @internal\n */\nconst GOLDEN_LINE_HEIGHT_RATIO = platform.isMacintosh ? 1.5 : 1.35;\n/**\n * @internal\n */\nconst MINIMUM_LINE_HEIGHT = 8;\nexport class BareFontInfo {\n    /**\n     * @internal\n     */\n    static createFromValidatedSettings(options, pixelRatio, ignoreEditorZoom) {\n        const fontFamily = options.get(47 /* EditorOption.fontFamily */);\n        const fontWeight = options.get(51 /* EditorOption.fontWeight */);\n        const fontSize = options.get(50 /* EditorOption.fontSize */);\n        const fontFeatureSettings = options.get(49 /* EditorOption.fontLigatures */);\n        const fontVariationSettings = options.get(52 /* EditorOption.fontVariations */);\n        const lineHeight = options.get(64 /* EditorOption.lineHeight */);\n        const letterSpacing = options.get(61 /* EditorOption.letterSpacing */);\n        return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, fontVariationSettings, lineHeight, letterSpacing, pixelRatio, ignoreEditorZoom);\n    }\n    /**\n     * @internal\n     */\n    static _create(fontFamily, fontWeight, fontSize, fontFeatureSettings, fontVariationSettings, lineHeight, letterSpacing, pixelRatio, ignoreEditorZoom) {\n        if (lineHeight === 0) {\n            lineHeight = GOLDEN_LINE_HEIGHT_RATIO * fontSize;\n        }\n        else if (lineHeight < MINIMUM_LINE_HEIGHT) {\n            // Values too small to be line heights in pixels are in ems.\n            lineHeight = lineHeight * fontSize;\n        }\n        // Enforce integer, minimum constraints\n        lineHeight = Math.round(lineHeight);\n        if (lineHeight < MINIMUM_LINE_HEIGHT) {\n            lineHeight = MINIMUM_LINE_HEIGHT;\n        }\n        const editorZoomLevelMultiplier = 1 + (ignoreEditorZoom ? 0 : EditorZoom.getZoomLevel() * 0.1);\n        fontSize *= editorZoomLevelMultiplier;\n        lineHeight *= editorZoomLevelMultiplier;\n        if (fontVariationSettings === EditorFontVariations.TRANSLATE) {\n            if (fontWeight === 'normal' || fontWeight === 'bold') {\n                fontVariationSettings = EditorFontVariations.OFF;\n            }\n            else {\n                const fontWeightAsNumber = parseInt(fontWeight, 10);\n                fontVariationSettings = `'wght' ${fontWeightAsNumber}`;\n                fontWeight = 'normal';\n            }\n        }\n        return new BareFontInfo({\n            pixelRatio: pixelRatio,\n            fontFamily: fontFamily,\n            fontWeight: fontWeight,\n            fontSize: fontSize,\n            fontFeatureSettings: fontFeatureSettings,\n            fontVariationSettings,\n            lineHeight: lineHeight,\n            letterSpacing: letterSpacing\n        });\n    }\n    /**\n     * @internal\n     */\n    constructor(opts) {\n        this._bareFontInfoBrand = undefined;\n        this.pixelRatio = opts.pixelRatio;\n        this.fontFamily = String(opts.fontFamily);\n        this.fontWeight = String(opts.fontWeight);\n        this.fontSize = opts.fontSize;\n        this.fontFeatureSettings = opts.fontFeatureSettings;\n        this.fontVariationSettings = opts.fontVariationSettings;\n        this.lineHeight = opts.lineHeight | 0;\n        this.letterSpacing = opts.letterSpacing;\n    }\n    /**\n     * @internal\n     */\n    getId() {\n        return `${this.pixelRatio}-${this.fontFamily}-${this.fontWeight}-${this.fontSize}-${this.fontFeatureSettings}-${this.fontVariationSettings}-${this.lineHeight}-${this.letterSpacing}`;\n    }\n    /**\n     * @internal\n     */\n    getMassagedFontFamily() {\n        const fallbackFontFamily = EDITOR_FONT_DEFAULTS.fontFamily;\n        const fontFamily = BareFontInfo._wrapInQuotes(this.fontFamily);\n        if (fallbackFontFamily && this.fontFamily !== fallbackFontFamily) {\n            return `${fontFamily}, ${fallbackFontFamily}`;\n        }\n        return fontFamily;\n    }\n    static _wrapInQuotes(fontFamily) {\n        if (/[,\"']/.test(fontFamily)) {\n            // Looks like the font family might be already escaped\n            return fontFamily;\n        }\n        if (/[+ ]/.test(fontFamily)) {\n            // Wrap a font family using + or  with quotes\n            return `\"${fontFamily}\"`;\n        }\n        return fontFamily;\n    }\n}\n// change this whenever `FontInfo` members are changed\nexport const SERIALIZED_FONT_INFO_VERSION = 2;\nexport class FontInfo extends BareFontInfo {\n    /**\n     * @internal\n     */\n    constructor(opts, isTrusted) {\n        super(opts);\n        this._editorStylingBrand = undefined;\n        this.version = SERIALIZED_FONT_INFO_VERSION;\n        this.isTrusted = isTrusted;\n        this.isMonospace = opts.isMonospace;\n        this.typicalHalfwidthCharacterWidth = opts.typicalHalfwidthCharacterWidth;\n        this.typicalFullwidthCharacterWidth = opts.typicalFullwidthCharacterWidth;\n        this.canUseHalfwidthRightwardsArrow = opts.canUseHalfwidthRightwardsArrow;\n        this.spaceWidth = opts.spaceWidth;\n        this.middotWidth = opts.middotWidth;\n        this.wsmiddotWidth = opts.wsmiddotWidth;\n        this.maxDigitWidth = opts.maxDigitWidth;\n    }\n    /**\n     * @internal\n     */\n    equals(other) {\n        return (this.fontFamily === other.fontFamily\n            && this.fontWeight === other.fontWeight\n            && this.fontSize === other.fontSize\n            && this.fontFeatureSettings === other.fontFeatureSettings\n            && this.fontVariationSettings === other.fontVariationSettings\n            && this.lineHeight === other.lineHeight\n            && this.letterSpacing === other.letterSpacing\n            && this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth\n            && this.typicalFullwidthCharacterWidth === other.typicalFullwidthCharacterWidth\n            && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow\n            && this.spaceWidth === other.spaceWidth\n            && this.middotWidth === other.middotWidth\n            && this.wsmiddotWidth === other.wsmiddotWidth\n            && this.maxDigitWidth === other.maxDigitWidth);\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as browser from '../../../base/browser/browser.js';\nimport { Emitter } from '../../../base/common/event.js';\nimport { Disposable } from '../../../base/common/lifecycle.js';\nimport { CharWidthRequest, readCharWidths } from './charWidthReader.js';\nimport { EditorFontLigatures } from '../../common/config/editorOptions.js';\nimport { FontInfo } from '../../common/config/fontInfo.js';\nexport class FontMeasurementsImpl extends Disposable {\n    constructor() {\n        super();\n        this._onDidChange = this._register(new Emitter());\n        this.onDidChange = this._onDidChange.event;\n        this._cache = new FontMeasurementsCache();\n        this._evictUntrustedReadingsTimeout = -1;\n    }\n    dispose() {\n        if (this._evictUntrustedReadingsTimeout !== -1) {\n            window.clearTimeout(this._evictUntrustedReadingsTimeout);\n            this._evictUntrustedReadingsTimeout = -1;\n        }\n        super.dispose();\n    }\n    /**\n     * Clear all cached font information and trigger a change event.\n     */\n    clearAllFontInfos() {\n        this._cache = new FontMeasurementsCache();\n        this._onDidChange.fire();\n    }\n    _writeToCache(item, value) {\n        this._cache.put(item, value);\n        if (!value.isTrusted && this._evictUntrustedReadingsTimeout === -1) {\n            // Try reading again after some time\n            this._evictUntrustedReadingsTimeout = window.setTimeout(() => {\n                this._evictUntrustedReadingsTimeout = -1;\n                this._evictUntrustedReadings();\n            }, 5000);\n        }\n    }\n    _evictUntrustedReadings() {\n        const values = this._cache.getValues();\n        let somethingRemoved = false;\n        for (const item of values) {\n            if (!item.isTrusted) {\n                somethingRemoved = true;\n                this._cache.remove(item);\n            }\n        }\n        if (somethingRemoved) {\n            this._onDidChange.fire();\n        }\n    }\n    /**\n     * Read font information.\n     */\n    readFontInfo(bareFontInfo) {\n        if (!this._cache.has(bareFontInfo)) {\n            let readConfig = this._actualReadFontInfo(bareFontInfo);\n            if (readConfig.typicalHalfwidthCharacterWidth <= 2 || readConfig.typicalFullwidthCharacterWidth <= 2 || readConfig.spaceWidth <= 2 || readConfig.maxDigitWidth <= 2) {\n                // Hey, it's Bug 14341 ... we couldn't read\n                readConfig = new FontInfo({\n                    pixelRatio: browser.PixelRatio.value,\n                    fontFamily: readConfig.fontFamily,\n                    fontWeight: readConfig.fontWeight,\n                    fontSize: readConfig.fontSize,\n                    fontFeatureSettings: readConfig.fontFeatureSettings,\n                    fontVariationSettings: readConfig.fontVariationSettings,\n                    lineHeight: readConfig.lineHeight,\n                    letterSpacing: readConfig.letterSpacing,\n                    isMonospace: readConfig.isMonospace,\n                    typicalHalfwidthCharacterWidth: Math.max(readConfig.typicalHalfwidthCharacterWidth, 5),\n                    typicalFullwidthCharacterWidth: Math.max(readConfig.typicalFullwidthCharacterWidth, 5),\n                    canUseHalfwidthRightwardsArrow: readConfig.canUseHalfwidthRightwardsArrow,\n                    spaceWidth: Math.max(readConfig.spaceWidth, 5),\n                    middotWidth: Math.max(readConfig.middotWidth, 5),\n                    wsmiddotWidth: Math.max(readConfig.wsmiddotWidth, 5),\n                    maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5),\n                }, false);\n            }\n            this._writeToCache(bareFontInfo, readConfig);\n        }\n        return this._cache.get(bareFontInfo);\n    }\n    _createRequest(chr, type, all, monospace) {\n        const result = new CharWidthRequest(chr, type);\n        all.push(result);\n        monospace === null || monospace === void 0 ? void 0 : monospace.push(result);\n        return result;\n    }\n    _actualReadFontInfo(bareFontInfo) {\n        const all = [];\n        const monospace = [];\n        const typicalHalfwidthCharacter = this._createRequest('n', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const typicalFullwidthCharacter = this._createRequest('\\uff4d', 0 /* CharWidthRequestType.Regular */, all, null);\n        const space = this._createRequest(' ', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit0 = this._createRequest('0', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit1 = this._createRequest('1', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit2 = this._createRequest('2', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit3 = this._createRequest('3', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit4 = this._createRequest('4', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit5 = this._createRequest('5', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit6 = this._createRequest('6', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit7 = this._createRequest('7', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit8 = this._createRequest('8', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const digit9 = this._createRequest('9', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        // monospace test: used for whitespace rendering\n        const rightwardsArrow = this._createRequest('→', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        const halfwidthRightwardsArrow = this._createRequest('→', 0 /* CharWidthRequestType.Regular */, all, null);\n        // U+00B7 - MIDDLE DOT\n        const middot = this._createRequest('·', 0 /* CharWidthRequestType.Regular */, all, monospace);\n        // U+2E31 - WORD SEPARATOR MIDDLE DOT\n        const wsmiddotWidth = this._createRequest(String.fromCharCode(0x2E31), 0 /* CharWidthRequestType.Regular */, all, null);\n        // monospace test: some characters\n        const monospaceTestChars = '|/-_ilm%';\n        for (let i = 0, len = monospaceTestChars.length; i < len; i++) {\n            this._createRequest(monospaceTestChars.charAt(i), 0 /* CharWidthRequestType.Regular */, all, monospace);\n            this._createRequest(monospaceTestChars.charAt(i), 1 /* CharWidthRequestType.Italic */, all, monospace);\n            this._createRequest(monospaceTestChars.charAt(i), 2 /* CharWidthRequestType.Bold */, all, monospace);\n        }\n        readCharWidths(bareFontInfo, all);\n        const maxDigitWidth = Math.max(digit0.width, digit1.width, digit2.width, digit3.width, digit4.width, digit5.width, digit6.width, digit7.width, digit8.width, digit9.width);\n        let isMonospace = (bareFontInfo.fontFeatureSettings === EditorFontLigatures.OFF);\n        const referenceWidth = monospace[0].width;\n        for (let i = 1, len = monospace.length; isMonospace && i < len; i++) {\n            const diff = referenceWidth - monospace[i].width;\n            if (diff < -0.001 || diff > 0.001) {\n                isMonospace = false;\n                break;\n            }\n        }\n        let canUseHalfwidthRightwardsArrow = true;\n        if (isMonospace && halfwidthRightwardsArrow.width !== referenceWidth) {\n            // using a halfwidth rightwards arrow would break monospace...\n            canUseHalfwidthRightwardsArrow = false;\n        }\n        if (halfwidthRightwardsArrow.width > rightwardsArrow.width) {\n            // using a halfwidth rightwards arrow would paint a larger arrow than a regular rightwards arrow\n            canUseHalfwidthRightwardsArrow = false;\n        }\n        return new FontInfo({\n            pixelRatio: browser.PixelRatio.value,\n            fontFamily: bareFontInfo.fontFamily,\n            fontWeight: bareFontInfo.fontWeight,\n            fontSize: bareFontInfo.fontSize,\n            fontFeatureSettings: bareFontInfo.fontFeatureSettings,\n            fontVariationSettings: bareFontInfo.fontVariationSettings,\n            lineHeight: bareFontInfo.lineHeight,\n            letterSpacing: bareFontInfo.letterSpacing,\n            isMonospace: isMonospace,\n            typicalHalfwidthCharacterWidth: typicalHalfwidthCharacter.width,\n            typicalFullwidthCharacterWidth: typicalFullwidthCharacter.width,\n            canUseHalfwidthRightwardsArrow: canUseHalfwidthRightwardsArrow,\n            spaceWidth: space.width,\n            middotWidth: middot.width,\n            wsmiddotWidth: wsmiddotWidth.width,\n            maxDigitWidth: maxDigitWidth\n        }, true);\n    }\n}\nclass FontMeasurementsCache {\n    constructor() {\n        this._keys = Object.create(null);\n        this._values = Object.create(null);\n    }\n    has(item) {\n        const itemId = item.getId();\n        return !!this._values[itemId];\n    }\n    get(item) {\n        const itemId = item.getId();\n        return this._values[itemId];\n    }\n    put(item, value) {\n        const itemId = item.getId();\n        this._keys[itemId] = item;\n        this._values[itemId] = value;\n    }\n    remove(item) {\n        const itemId = item.getId();\n        delete this._keys[itemId];\n        delete this._values[itemId];\n    }\n    getValues() {\n        return Object.keys(this._keys).map(id => this._values[id]);\n    }\n}\nexport const FontMeasurements = new FontMeasurementsImpl();\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n// ------ internal util\nexport var _util;\n(function (_util) {\n    _util.serviceIds = new Map();\n    _util.DI_TARGET = '$di$target';\n    _util.DI_DEPENDENCIES = '$di$dependencies';\n    function getServiceDependencies(ctor) {\n        return ctor[_util.DI_DEPENDENCIES] || [];\n    }\n    _util.getServiceDependencies = getServiceDependencies;\n})(_util || (_util = {}));\nexport const IInstantiationService = createDecorator('instantiationService');\nfunction storeServiceDependency(id, target, index) {\n    if (target[_util.DI_TARGET] === target) {\n        target[_util.DI_DEPENDENCIES].push({ id, index });\n    }\n    else {\n        target[_util.DI_DEPENDENCIES] = [{ id, index }];\n        target[_util.DI_TARGET] = target;\n    }\n}\n/**\n * The *only* valid way to create a {{ServiceIdentifier}}.\n */\nexport function createDecorator(serviceId) {\n    if (_util.serviceIds.has(serviceId)) {\n        return _util.serviceIds.get(serviceId);\n    }\n    const id = function (target, key, index) {\n        if (arguments.length !== 3) {\n            throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n        }\n        storeServiceDependency(id, target, index);\n    };\n    id.toString = () => serviceId;\n    _util.serviceIds.set(serviceId, id);\n    return id;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { createDecorator } from '../../../platform/instantiation/common/instantiation.js';\nexport const ICodeEditorService = createDecorator('codeEditorService');\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { BugIndicatingError, onUnexpectedError } from './errors.js';\n/**\n * Throws an error with the provided message if the provided value does not evaluate to a true Javascript value.\n *\n * @deprecated Use `assert(...)` instead.\n * This method is usually used like this:\n * ```ts\n * import * as assert from 'vs/base/common/assert';\n * assert.ok(...);\n * ```\n *\n * However, `assert` in that example is a user chosen name.\n * There is no tooling for generating such an import statement.\n * Thus, the `assert(...)` function should be used instead.\n */\nexport function ok(value, message) {\n    if (!value) {\n        throw new Error(message ? `Assertion failed (${message})` : 'Assertion Failed');\n    }\n}\nexport function assertNever(value, message = 'Unreachable') {\n    throw new Error(message);\n}\n/**\n * condition must be side-effect free!\n */\nexport function assertFn(condition) {\n    if (!condition()) {\n        // eslint-disable-next-line no-debugger\n        debugger;\n        // Reevaluate `condition` again to make debugging easier\n        condition();\n        onUnexpectedError(new BugIndicatingError('Assertion Failed'));\n    }\n}\nexport function checkAdjacentItems(items, predicate) {\n    let i = 0;\n    while (i < items.length - 1) {\n        const a = items[i];\n        const b = items[i + 1];\n        if (!predicate(a, b)) {\n            return false;\n        }\n        i++;\n    }\n    return true;\n}\n","var _a;\nimport { createDecorator } from '../../instantiation/common/instantiation.js';\nimport { localize } from '../../../nls.js';\nexport const IAudioCueService = createDecorator('audioCue');\n/**\n * Corresponds to the audio files in ./media.\n*/\nexport class Sound {\n    static register(options) {\n        const sound = new Sound(options.fileName);\n        return sound;\n    }\n    constructor(fileName) {\n        this.fileName = fileName;\n    }\n}\nSound.error = Sound.register({ fileName: 'error.mp3' });\nSound.warning = Sound.register({ fileName: 'warning.mp3' });\nSound.foldedArea = Sound.register({ fileName: 'foldedAreas.mp3' });\nSound.break = Sound.register({ fileName: 'break.mp3' });\nSound.quickFixes = Sound.register({ fileName: 'quickFixes.mp3' });\nSound.taskCompleted = Sound.register({ fileName: 'taskCompleted.mp3' });\nSound.taskFailed = Sound.register({ fileName: 'taskFailed.mp3' });\nSound.terminalBell = Sound.register({ fileName: 'terminalBell.mp3' });\nSound.diffLineInserted = Sound.register({ fileName: 'diffLineInserted.mp3' });\nSound.diffLineDeleted = Sound.register({ fileName: 'diffLineDeleted.mp3' });\nSound.diffLineModified = Sound.register({ fileName: 'diffLineModified.mp3' });\nSound.chatRequestSent = Sound.register({ fileName: 'chatRequestSent.mp3' });\nSound.chatResponsePending = Sound.register({ fileName: 'chatResponsePending.mp3' });\nSound.chatResponseReceived1 = Sound.register({ fileName: 'chatResponseReceived1.mp3' });\nSound.chatResponseReceived2 = Sound.register({ fileName: 'chatResponseReceived2.mp3' });\nSound.chatResponseReceived3 = Sound.register({ fileName: 'chatResponseReceived3.mp3' });\nSound.chatResponseReceived4 = Sound.register({ fileName: 'chatResponseReceived4.mp3' });\nexport class AudioCue {\n    static register(options) {\n        const audioCue = new AudioCue(options.sound, options.name, options.settingsKey, options.groupId);\n        AudioCue._audioCues.add(audioCue);\n        return audioCue;\n    }\n    constructor(sound, name, settingsKey, groupId) {\n        this.sound = sound;\n        this.name = name;\n        this.settingsKey = settingsKey;\n        this.groupId = groupId;\n    }\n}\n_a = AudioCue;\nAudioCue._audioCues = new Set();\nAudioCue.error = AudioCue.register({\n    name: localize('audioCues.lineHasError.name', 'Error on Line'),\n    sound: Sound.error,\n    settingsKey: 'audioCues.lineHasError',\n});\nAudioCue.warning = AudioCue.register({\n    name: localize('audioCues.lineHasWarning.name', 'Warning on Line'),\n    sound: Sound.warning,\n    settingsKey: 'audioCues.lineHasWarning',\n});\nAudioCue.foldedArea = AudioCue.register({\n    name: localize('audioCues.lineHasFoldedArea.name', 'Folded Area on Line'),\n    sound: Sound.foldedArea,\n    settingsKey: 'audioCues.lineHasFoldedArea',\n});\nAudioCue.break = AudioCue.register({\n    name: localize('audioCues.lineHasBreakpoint.name', 'Breakpoint on Line'),\n    sound: Sound.break,\n    settingsKey: 'audioCues.lineHasBreakpoint',\n});\nAudioCue.inlineSuggestion = AudioCue.register({\n    name: localize('audioCues.lineHasInlineSuggestion.name', 'Inline Suggestion on Line'),\n    sound: Sound.quickFixes,\n    settingsKey: 'audioCues.lineHasInlineSuggestion',\n});\nAudioCue.terminalQuickFix = AudioCue.register({\n    name: localize('audioCues.terminalQuickFix.name', 'Terminal Quick Fix'),\n    sound: Sound.quickFixes,\n    settingsKey: 'audioCues.terminalQuickFix',\n});\nAudioCue.onDebugBreak = AudioCue.register({\n    name: localize('audioCues.onDebugBreak.name', 'Debugger Stopped on Breakpoint'),\n    sound: Sound.break,\n    settingsKey: 'audioCues.onDebugBreak',\n});\nAudioCue.noInlayHints = AudioCue.register({\n    name: localize('audioCues.noInlayHints', 'No Inlay Hints on Line'),\n    sound: Sound.error,\n    settingsKey: 'audioCues.noInlayHints'\n});\nAudioCue.taskCompleted = AudioCue.register({\n    name: localize('audioCues.taskCompleted', 'Task Completed'),\n    sound: Sound.taskCompleted,\n    settingsKey: 'audioCues.taskCompleted'\n});\nAudioCue.taskFailed = AudioCue.register({\n    name: localize('audioCues.taskFailed', 'Task Failed'),\n    sound: Sound.taskFailed,\n    settingsKey: 'audioCues.taskFailed'\n});\nAudioCue.terminalCommandFailed = AudioCue.register({\n    name: localize('audioCues.terminalCommandFailed', 'Terminal Command Failed'),\n    sound: Sound.error,\n    settingsKey: 'audioCues.terminalCommandFailed'\n});\nAudioCue.terminalBell = AudioCue.register({\n    name: localize('audioCues.terminalBell', 'Terminal Bell'),\n    sound: Sound.terminalBell,\n    settingsKey: 'audioCues.terminalBell'\n});\nAudioCue.notebookCellCompleted = AudioCue.register({\n    name: localize('audioCues.notebookCellCompleted', 'Notebook Cell Completed'),\n    sound: Sound.taskCompleted,\n    settingsKey: 'audioCues.notebookCellCompleted'\n});\nAudioCue.notebookCellFailed = AudioCue.register({\n    name: localize('audioCues.notebookCellFailed', 'Notebook Cell Failed'),\n    sound: Sound.taskFailed,\n    settingsKey: 'audioCues.notebookCellFailed'\n});\nAudioCue.diffLineInserted = AudioCue.register({\n    name: localize('audioCues.diffLineInserted', 'Diff Line Inserted'),\n    sound: Sound.diffLineInserted,\n    settingsKey: 'audioCues.diffLineInserted'\n});\nAudioCue.diffLineDeleted = AudioCue.register({\n    name: localize('audioCues.diffLineDeleted', 'Diff Line Deleted'),\n    sound: Sound.diffLineDeleted,\n    settingsKey: 'audioCues.diffLineDeleted'\n});\nAudioCue.diffLineModified = AudioCue.register({\n    name: localize('audioCues.diffLineModified', 'Diff Line Modified'),\n    sound: Sound.diffLineModified,\n    settingsKey: 'audioCues.diffLineModified'\n});\nAudioCue.chatRequestSent = AudioCue.register({\n    name: localize('audioCues.chatRequestSent', 'Chat Request Sent'),\n    sound: Sound.chatRequestSent,\n    settingsKey: 'audioCues.chatRequestSent'\n});\nAudioCue.chatResponseReceived = {\n    name: localize('audioCues.chatResponseReceived', 'Chat Response Received'),\n    settingsKey: 'audioCues.chatResponseReceived',\n    groupId: \"chatResponseReceived\" /* AudioCueGroupId.chatResponseReceived */\n};\nAudioCue.chatResponseReceived1 = AudioCue.register(Object.assign({ sound: Sound.chatResponseReceived1 }, _a.chatResponseReceived));\nAudioCue.chatResponseReceived2 = AudioCue.register(Object.assign({ sound: Sound.chatResponseReceived2 }, _a.chatResponseReceived));\nAudioCue.chatResponseReceived3 = AudioCue.register(Object.assign({ sound: Sound.chatResponseReceived3 }, _a.chatResponseReceived));\nAudioCue.chatResponseReceived4 = AudioCue.register(Object.assign({ sound: Sound.chatResponseReceived4 }, _a.chatResponseReceived));\nAudioCue.chatResponsePending = AudioCue.register({\n    name: localize('audioCues.chatResponsePending', 'Chat Response Pending'),\n    sound: Sound.chatResponsePending,\n    settingsKey: 'audioCues.chatResponsePending'\n});\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { illegalState } from '../../../base/common/errors.js';\nimport { localize } from '../../../nls.js';\nfunction hintDidYouMean(...meant) {\n    switch (meant.length) {\n        case 1:\n            return localize('contextkey.scanner.hint.didYouMean1', \"Did you mean {0}?\", meant[0]);\n        case 2:\n            return localize('contextkey.scanner.hint.didYouMean2', \"Did you mean {0} or {1}?\", meant[0], meant[1]);\n        case 3:\n            return localize('contextkey.scanner.hint.didYouMean3', \"Did you mean {0}, {1} or {2}?\", meant[0], meant[1], meant[2]);\n        default: // we just don't expect that many\n            return undefined;\n    }\n}\nconst hintDidYouForgetToOpenOrCloseQuote = localize('contextkey.scanner.hint.didYouForgetToOpenOrCloseQuote', \"Did you forget to open or close the quote?\");\nconst hintDidYouForgetToEscapeSlash = localize('contextkey.scanner.hint.didYouForgetToEscapeSlash', \"Did you forget to escape the '/' (slash) character? Put two backslashes before it to escape, e.g., '\\\\\\\\/\\'.\");\n/**\n * A simple scanner for context keys.\n *\n * Example:\n *\n * ```ts\n * const scanner = new Scanner().reset('resourceFileName =~ /docker/ && !config.docker.enabled');\n * const tokens = [...scanner];\n * if (scanner.errorTokens.length > 0) {\n *     scanner.errorTokens.forEach(err => console.error(`Unexpected token at ${err.offset}: ${err.lexeme}\\nHint: ${err.additional}`));\n * } else {\n *     // process tokens\n * }\n * ```\n */\nexport class Scanner {\n    constructor() {\n        this._input = '';\n        this._start = 0;\n        this._current = 0;\n        this._tokens = [];\n        this._errors = [];\n        // u - unicode, y - sticky // TODO@ulugbekna: we accept double quotes as part of the string rather than as a delimiter (to preserve old parser's behavior)\n        this.stringRe = /[a-zA-Z0-9_<>\\-\\./\\\\:\\*\\?\\+\\[\\]\\^,#@;\"%\\$\\p{L}-]+/uy;\n    }\n    static getLexeme(token) {\n        switch (token.type) {\n            case 0 /* TokenType.LParen */:\n                return '(';\n            case 1 /* TokenType.RParen */:\n                return ')';\n            case 2 /* TokenType.Neg */:\n                return '!';\n            case 3 /* TokenType.Eq */:\n                return token.isTripleEq ? '===' : '==';\n            case 4 /* TokenType.NotEq */:\n                return token.isTripleEq ? '!==' : '!=';\n            case 5 /* TokenType.Lt */:\n                return '<';\n            case 6 /* TokenType.LtEq */:\n                return '<=';\n            case 7 /* TokenType.Gt */:\n                return '>=';\n            case 8 /* TokenType.GtEq */:\n                return '>=';\n            case 9 /* TokenType.RegexOp */:\n                return '=~';\n            case 10 /* TokenType.RegexStr */:\n                return token.lexeme;\n            case 11 /* TokenType.True */:\n                return 'true';\n            case 12 /* TokenType.False */:\n                return 'false';\n            case 13 /* TokenType.In */:\n                return 'in';\n            case 14 /* TokenType.Not */:\n                return 'not';\n            case 15 /* TokenType.And */:\n                return '&&';\n            case 16 /* TokenType.Or */:\n                return '||';\n            case 17 /* TokenType.Str */:\n                return token.lexeme;\n            case 18 /* TokenType.QuotedStr */:\n                return token.lexeme;\n            case 19 /* TokenType.Error */:\n                return token.lexeme;\n            case 20 /* TokenType.EOF */:\n                return 'EOF';\n            default:\n                throw illegalState(`unhandled token type: ${JSON.stringify(token)}; have you forgotten to add a case?`);\n        }\n    }\n    reset(value) {\n        this._input = value;\n        this._start = 0;\n        this._current = 0;\n        this._tokens = [];\n        this._errors = [];\n        return this;\n    }\n    scan() {\n        while (!this._isAtEnd()) {\n            this._start = this._current;\n            const ch = this._advance();\n            switch (ch) {\n                case 40 /* CharCode.OpenParen */:\n                    this._addToken(0 /* TokenType.LParen */);\n                    break;\n                case 41 /* CharCode.CloseParen */:\n                    this._addToken(1 /* TokenType.RParen */);\n                    break;\n                case 33 /* CharCode.ExclamationMark */:\n                    if (this._match(61 /* CharCode.Equals */)) {\n                        const isTripleEq = this._match(61 /* CharCode.Equals */); // eat last `=` if `!==`\n                        this._tokens.push({ type: 4 /* TokenType.NotEq */, offset: this._start, isTripleEq });\n                    }\n                    else {\n                        this._addToken(2 /* TokenType.Neg */);\n                    }\n                    break;\n                case 39 /* CharCode.SingleQuote */:\n                    this._quotedString();\n                    break;\n                case 47 /* CharCode.Slash */:\n                    this._regex();\n                    break;\n                case 61 /* CharCode.Equals */:\n                    if (this._match(61 /* CharCode.Equals */)) { // support `==`\n                        const isTripleEq = this._match(61 /* CharCode.Equals */); // eat last `=` if `===`\n                        this._tokens.push({ type: 3 /* TokenType.Eq */, offset: this._start, isTripleEq });\n                    }\n                    else if (this._match(126 /* CharCode.Tilde */)) {\n                        this._addToken(9 /* TokenType.RegexOp */);\n                    }\n                    else {\n                        this._error(hintDidYouMean('==', '=~'));\n                    }\n                    break;\n                case 60 /* CharCode.LessThan */:\n                    this._addToken(this._match(61 /* CharCode.Equals */) ? 6 /* TokenType.LtEq */ : 5 /* TokenType.Lt */);\n                    break;\n                case 62 /* CharCode.GreaterThan */:\n                    this._addToken(this._match(61 /* CharCode.Equals */) ? 8 /* TokenType.GtEq */ : 7 /* TokenType.Gt */);\n                    break;\n                case 38 /* CharCode.Ampersand */:\n                    if (this._match(38 /* CharCode.Ampersand */)) {\n                        this._addToken(15 /* TokenType.And */);\n                    }\n                    else {\n                        this._error(hintDidYouMean('&&'));\n                    }\n                    break;\n                case 124 /* CharCode.Pipe */:\n                    if (this._match(124 /* CharCode.Pipe */)) {\n                        this._addToken(16 /* TokenType.Or */);\n                    }\n                    else {\n                        this._error(hintDidYouMean('||'));\n                    }\n                    break;\n                // TODO@ulugbekna: 1) rewrite using a regex 2) reconsider what characters are considered whitespace, including unicode, nbsp, etc.\n                case 32 /* CharCode.Space */:\n                case 13 /* CharCode.CarriageReturn */:\n                case 9 /* CharCode.Tab */:\n                case 10 /* CharCode.LineFeed */:\n                case 160 /* CharCode.NoBreakSpace */: //  \n                    break;\n                default:\n                    this._string();\n            }\n        }\n        this._start = this._current;\n        this._addToken(20 /* TokenType.EOF */);\n        return Array.from(this._tokens);\n    }\n    _match(expected) {\n        if (this._isAtEnd()) {\n            return false;\n        }\n        if (this._input.charCodeAt(this._current) !== expected) {\n            return false;\n        }\n        this._current++;\n        return true;\n    }\n    _advance() {\n        return this._input.charCodeAt(this._current++);\n    }\n    _peek() {\n        return this._isAtEnd() ? 0 /* CharCode.Null */ : this._input.charCodeAt(this._current);\n    }\n    _addToken(type) {\n        this._tokens.push({ type, offset: this._start });\n    }\n    _error(additional) {\n        const offset = this._start;\n        const lexeme = this._input.substring(this._start, this._current);\n        const errToken = { type: 19 /* TokenType.Error */, offset: this._start, lexeme };\n        this._errors.push({ offset, lexeme, additionalInfo: additional });\n        this._tokens.push(errToken);\n    }\n    _string() {\n        this.stringRe.lastIndex = this._start;\n        const match = this.stringRe.exec(this._input);\n        if (match) {\n            this._current = this._start + match[0].length;\n            const lexeme = this._input.substring(this._start, this._current);\n            const keyword = Scanner._keywords.get(lexeme);\n            if (keyword) {\n                this._addToken(keyword);\n            }\n            else {\n                this._tokens.push({ type: 17 /* TokenType.Str */, lexeme, offset: this._start });\n            }\n        }\n    }\n    // captures the lexeme without the leading and trailing '\n    _quotedString() {\n        while (this._peek() !== 39 /* CharCode.SingleQuote */ && !this._isAtEnd()) { // TODO@ulugbekna: add support for escaping ' ?\n            this._advance();\n        }\n        if (this._isAtEnd()) {\n            this._error(hintDidYouForgetToOpenOrCloseQuote);\n            return;\n        }\n        // consume the closing '\n        this._advance();\n        this._tokens.push({ type: 18 /* TokenType.QuotedStr */, lexeme: this._input.substring(this._start + 1, this._current - 1), offset: this._start + 1 });\n    }\n    /*\n     * Lexing a regex expression: /.../[igsmyu]*\n     * Based on https://github.com/microsoft/TypeScript/blob/9247ef115e617805983740ba795d7a8164babf89/src/compiler/scanner.ts#L2129-L2181\n     *\n     * Note that we want slashes within a regex to be escaped, e.g., /file:\\\\/\\\\/\\\\// should match `file:///`\n     */\n    _regex() {\n        let p = this._current;\n        let inEscape = false;\n        let inCharacterClass = false;\n        while (true) {\n            if (p >= this._input.length) {\n                this._current = p;\n                this._error(hintDidYouForgetToEscapeSlash);\n                return;\n            }\n            const ch = this._input.charCodeAt(p);\n            if (inEscape) { // parsing an escape character\n                inEscape = false;\n            }\n            else if (ch === 47 /* CharCode.Slash */ && !inCharacterClass) { // end of regex\n                p++;\n                break;\n            }\n            else if (ch === 91 /* CharCode.OpenSquareBracket */) {\n                inCharacterClass = true;\n            }\n            else if (ch === 92 /* CharCode.Backslash */) {\n                inEscape = true;\n            }\n            else if (ch === 93 /* CharCode.CloseSquareBracket */) {\n                inCharacterClass = false;\n            }\n            p++;\n        }\n        // Consume flags // TODO@ulugbekna: use regex instead\n        while (p < this._input.length && Scanner._regexFlags.has(this._input.charCodeAt(p))) {\n            p++;\n        }\n        this._current = p;\n        const lexeme = this._input.substring(this._start, this._current);\n        this._tokens.push({ type: 10 /* TokenType.RegexStr */, lexeme, offset: this._start });\n    }\n    _isAtEnd() {\n        return this._current >= this._input.length;\n    }\n}\nScanner._regexFlags = new Set(['i', 'g', 's', 'm', 'y', 'u'].map(ch => ch.charCodeAt(0)));\nScanner._keywords = new Map([\n    ['not', 14 /* TokenType.Not */],\n    ['in', 13 /* TokenType.In */],\n    ['false', 12 /* TokenType.False */],\n    ['true', 11 /* TokenType.True */],\n]);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { isChrome, isEdge, isFirefox, isLinux, isMacintosh, isSafari, isWeb, isWindows } from '../../../base/common/platform.js';\nimport { isFalsyOrWhitespace } from '../../../base/common/strings.js';\nimport { Scanner } from './scanner.js';\nimport { createDecorator } from '../../instantiation/common/instantiation.js';\nimport { localize } from '../../../nls.js';\nconst CONSTANT_VALUES = new Map();\nCONSTANT_VALUES.set('false', false);\nCONSTANT_VALUES.set('true', true);\nCONSTANT_VALUES.set('isMac', isMacintosh);\nCONSTANT_VALUES.set('isLinux', isLinux);\nCONSTANT_VALUES.set('isWindows', isWindows);\nCONSTANT_VALUES.set('isWeb', isWeb);\nCONSTANT_VALUES.set('isMacNative', isMacintosh && !isWeb);\nCONSTANT_VALUES.set('isEdge', isEdge);\nCONSTANT_VALUES.set('isFirefox', isFirefox);\nCONSTANT_VALUES.set('isChrome', isChrome);\nCONSTANT_VALUES.set('isSafari', isSafari);\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst defaultConfig = {\n    regexParsingWithErrorRecovery: true\n};\nconst errorEmptyString = localize('contextkey.parser.error.emptyString', \"Empty context key expression\");\nconst hintEmptyString = localize('contextkey.parser.error.emptyString.hint', \"Did you forget to write an expression? You can also put 'false' or 'true' to always evaluate to false or true, respectively.\");\nconst errorNoInAfterNot = localize('contextkey.parser.error.noInAfterNot', \"'in' after 'not'.\");\nconst errorClosingParenthesis = localize('contextkey.parser.error.closingParenthesis', \"closing parenthesis ')'\");\nconst errorUnexpectedToken = localize('contextkey.parser.error.unexpectedToken', \"Unexpected token\");\nconst hintUnexpectedToken = localize('contextkey.parser.error.unexpectedToken.hint', \"Did you forget to put && or || before the token?\");\nconst errorUnexpectedEOF = localize('contextkey.parser.error.unexpectedEOF', \"Unexpected end of expression\");\nconst hintUnexpectedEOF = localize('contextkey.parser.error.unexpectedEOF.hint', \"Did you forget to put a context key?\");\n/**\n * A parser for context key expressions.\n *\n * Example:\n * ```ts\n * const parser = new Parser();\n * const expr = parser.parse('foo == \"bar\" && baz == true');\n *\n * if (expr === undefined) {\n * \t// there were lexing or parsing errors\n * \t// process lexing errors with `parser.lexingErrors`\n *  // process parsing errors with `parser.parsingErrors`\n * } else {\n * \t// expr is a valid expression\n * }\n * ```\n */\nexport class Parser {\n    constructor(_config = defaultConfig) {\n        this._config = _config;\n        // lifetime note: `_scanner` lives as long as the parser does, i.e., is not reset between calls to `parse`\n        this._scanner = new Scanner();\n        // lifetime note: `_tokens`, `_current`, and `_parsingErrors` must be reset between calls to `parse`\n        this._tokens = [];\n        this._current = 0; // invariant: 0 <= this._current < this._tokens.length ; any incrementation of this value must first call `_isAtEnd`\n        this._parsingErrors = [];\n        this._flagsGYRe = /g|y/g;\n    }\n    /**\n     * Parse a context key expression.\n     *\n     * @param input the expression to parse\n     * @returns the parsed expression or `undefined` if there's an error - call `lexingErrors` and `parsingErrors` to see the errors\n     */\n    parse(input) {\n        if (input === '') {\n            this._parsingErrors.push({ message: errorEmptyString, offset: 0, lexeme: '', additionalInfo: hintEmptyString });\n            return undefined;\n        }\n        this._tokens = this._scanner.reset(input).scan();\n        // @ulugbekna: we do not stop parsing if there are lexing errors to be able to reconstruct regexes with unescaped slashes; TODO@ulugbekna: make this respect config option for recovery\n        this._current = 0;\n        this._parsingErrors = [];\n        try {\n            const expr = this._expr();\n            if (!this._isAtEnd()) {\n                const peek = this._peek();\n                const additionalInfo = peek.type === 17 /* TokenType.Str */ ? hintUnexpectedToken : undefined;\n                this._parsingErrors.push({ message: errorUnexpectedToken, offset: peek.offset, lexeme: Scanner.getLexeme(peek), additionalInfo });\n                throw Parser._parseError;\n            }\n            return expr;\n        }\n        catch (e) {\n            if (!(e === Parser._parseError)) {\n                throw e;\n            }\n            return undefined;\n        }\n    }\n    _expr() {\n        return this._or();\n    }\n    _or() {\n        const expr = [this._and()];\n        while (this._matchOne(16 /* TokenType.Or */)) {\n            const right = this._and();\n            expr.push(right);\n        }\n        return expr.length === 1 ? expr[0] : ContextKeyExpr.or(...expr);\n    }\n    _and() {\n        const expr = [this._term()];\n        while (this._matchOne(15 /* TokenType.And */)) {\n            const right = this._term();\n            expr.push(right);\n        }\n        return expr.length === 1 ? expr[0] : ContextKeyExpr.and(...expr);\n    }\n    _term() {\n        if (this._matchOne(2 /* TokenType.Neg */)) {\n            const peek = this._peek();\n            switch (peek.type) {\n                case 11 /* TokenType.True */:\n                    this._advance();\n                    return ContextKeyFalseExpr.INSTANCE;\n                case 12 /* TokenType.False */:\n                    this._advance();\n                    return ContextKeyTrueExpr.INSTANCE;\n                case 0 /* TokenType.LParen */: {\n                    this._advance();\n                    const expr = this._expr();\n                    this._consume(1 /* TokenType.RParen */, errorClosingParenthesis);\n                    return expr === null || expr === void 0 ? void 0 : expr.negate();\n                }\n                case 17 /* TokenType.Str */:\n                    this._advance();\n                    return ContextKeyNotExpr.create(peek.lexeme);\n                default:\n                    throw this._errExpectedButGot(`KEY | true | false | '(' expression ')'`, peek);\n            }\n        }\n        return this._primary();\n    }\n    _primary() {\n        const peek = this._peek();\n        switch (peek.type) {\n            case 11 /* TokenType.True */:\n                this._advance();\n                return ContextKeyExpr.true();\n            case 12 /* TokenType.False */:\n                this._advance();\n                return ContextKeyExpr.false();\n            case 0 /* TokenType.LParen */: {\n                this._advance();\n                const expr = this._expr();\n                this._consume(1 /* TokenType.RParen */, errorClosingParenthesis);\n                return expr;\n            }\n            case 17 /* TokenType.Str */: {\n                // KEY\n                const key = peek.lexeme;\n                this._advance();\n                // =~ regex\n                if (this._matchOne(9 /* TokenType.RegexOp */)) {\n                    // @ulugbekna: we need to reconstruct the regex from the tokens because some extensions use unescaped slashes in regexes\n                    const expr = this._peek();\n                    if (!this._config.regexParsingWithErrorRecovery) {\n                        this._advance();\n                        if (expr.type !== 10 /* TokenType.RegexStr */) {\n                            throw this._errExpectedButGot(`REGEX`, expr);\n                        }\n                        const regexLexeme = expr.lexeme;\n                        const closingSlashIndex = regexLexeme.lastIndexOf('/');\n                        const flags = closingSlashIndex === regexLexeme.length - 1 ? undefined : this._removeFlagsGY(regexLexeme.substring(closingSlashIndex + 1));\n                        let regexp;\n                        try {\n                            regexp = new RegExp(regexLexeme.substring(1, closingSlashIndex), flags);\n                        }\n                        catch (e) {\n                            throw this._errExpectedButGot(`REGEX`, expr);\n                        }\n                        return ContextKeyRegexExpr.create(key, regexp);\n                    }\n                    switch (expr.type) {\n                        case 10 /* TokenType.RegexStr */:\n                        case 19 /* TokenType.Error */: { // also handle an ErrorToken in case of smth such as /(/file)/\n                            const lexemeReconstruction = [expr.lexeme]; // /REGEX/ or /REGEX/FLAGS\n                            this._advance();\n                            let followingToken = this._peek();\n                            let parenBalance = 0;\n                            for (let i = 0; i < expr.lexeme.length; i++) {\n                                if (expr.lexeme.charCodeAt(i) === 40 /* CharCode.OpenParen */) {\n                                    parenBalance++;\n                                }\n                                else if (expr.lexeme.charCodeAt(i) === 41 /* CharCode.CloseParen */) {\n                                    parenBalance--;\n                                }\n                            }\n                            while (!this._isAtEnd() && followingToken.type !== 15 /* TokenType.And */ && followingToken.type !== 16 /* TokenType.Or */) {\n                                switch (followingToken.type) {\n                                    case 0 /* TokenType.LParen */:\n                                        parenBalance++;\n                                        break;\n                                    case 1 /* TokenType.RParen */:\n                                        parenBalance--;\n                                        break;\n                                    case 10 /* TokenType.RegexStr */:\n                                    case 18 /* TokenType.QuotedStr */:\n                                        for (let i = 0; i < followingToken.lexeme.length; i++) {\n                                            if (followingToken.lexeme.charCodeAt(i) === 40 /* CharCode.OpenParen */) {\n                                                parenBalance++;\n                                            }\n                                            else if (expr.lexeme.charCodeAt(i) === 41 /* CharCode.CloseParen */) {\n                                                parenBalance--;\n                                            }\n                                        }\n                                }\n                                if (parenBalance < 0) {\n                                    break;\n                                }\n                                lexemeReconstruction.push(Scanner.getLexeme(followingToken));\n                                this._advance();\n                                followingToken = this._peek();\n                            }\n                            const regexLexeme = lexemeReconstruction.join('');\n                            const closingSlashIndex = regexLexeme.lastIndexOf('/');\n                            const flags = closingSlashIndex === regexLexeme.length - 1 ? undefined : this._removeFlagsGY(regexLexeme.substring(closingSlashIndex + 1));\n                            let regexp;\n                            try {\n                                regexp = new RegExp(regexLexeme.substring(1, closingSlashIndex), flags);\n                            }\n                            catch (e) {\n                                throw this._errExpectedButGot(`REGEX`, expr);\n                            }\n                            return ContextKeyExpr.regex(key, regexp);\n                        }\n                        case 18 /* TokenType.QuotedStr */: {\n                            const serializedValue = expr.lexeme;\n                            this._advance();\n                            // replicate old regex parsing behavior\n                            let regex = null;\n                            if (!isFalsyOrWhitespace(serializedValue)) {\n                                const start = serializedValue.indexOf('/');\n                                const end = serializedValue.lastIndexOf('/');\n                                if (start !== end && start >= 0) {\n                                    const value = serializedValue.slice(start + 1, end);\n                                    const caseIgnoreFlag = serializedValue[end + 1] === 'i' ? 'i' : '';\n                                    try {\n                                        regex = new RegExp(value, caseIgnoreFlag);\n                                    }\n                                    catch (_e) {\n                                        throw this._errExpectedButGot(`REGEX`, expr);\n                                    }\n                                }\n                            }\n                            if (regex === null) {\n                                throw this._errExpectedButGot('REGEX', expr);\n                            }\n                            return ContextKeyRegexExpr.create(key, regex);\n                        }\n                        default:\n                            throw this._errExpectedButGot('REGEX', this._peek());\n                    }\n                }\n                // [ 'not' 'in' value ]\n                if (this._matchOne(14 /* TokenType.Not */)) {\n                    this._consume(13 /* TokenType.In */, errorNoInAfterNot);\n                    const right = this._value();\n                    return ContextKeyExpr.notIn(key, right);\n                }\n                // [ ('==' | '!=' | '<' | '<=' | '>' | '>=' | 'in') value ]\n                const maybeOp = this._peek().type;\n                switch (maybeOp) {\n                    case 3 /* TokenType.Eq */: {\n                        this._advance();\n                        const right = this._value();\n                        if (this._previous().type === 18 /* TokenType.QuotedStr */) { // to preserve old parser behavior: \"foo == 'true'\" is preserved as \"foo == 'true'\", but \"foo == true\" is optimized as \"foo\"\n                            return ContextKeyExpr.equals(key, right);\n                        }\n                        switch (right) {\n                            case 'true':\n                                return ContextKeyExpr.has(key);\n                            case 'false':\n                                return ContextKeyExpr.not(key);\n                            default:\n                                return ContextKeyExpr.equals(key, right);\n                        }\n                    }\n                    case 4 /* TokenType.NotEq */: {\n                        this._advance();\n                        const right = this._value();\n                        if (this._previous().type === 18 /* TokenType.QuotedStr */) { // same as above with \"foo != 'true'\"\n                            return ContextKeyExpr.notEquals(key, right);\n                        }\n                        switch (right) {\n                            case 'true':\n                                return ContextKeyExpr.not(key);\n                            case 'false':\n                                return ContextKeyExpr.has(key);\n                            default:\n                                return ContextKeyExpr.notEquals(key, right);\n                        }\n                    }\n                    // TODO: ContextKeyExpr.smaller(key, right) accepts only `number` as `right` AND during eval of this node, we just eval to `false` if `right` is not a number\n                    // consequently, package.json linter should _warn_ the user if they're passing undesired things to ops\n                    case 5 /* TokenType.Lt */:\n                        this._advance();\n                        return ContextKeySmallerExpr.create(key, this._value());\n                    case 6 /* TokenType.LtEq */:\n                        this._advance();\n                        return ContextKeySmallerEqualsExpr.create(key, this._value());\n                    case 7 /* TokenType.Gt */:\n                        this._advance();\n                        return ContextKeyGreaterExpr.create(key, this._value());\n                    case 8 /* TokenType.GtEq */:\n                        this._advance();\n                        return ContextKeyGreaterEqualsExpr.create(key, this._value());\n                    case 13 /* TokenType.In */:\n                        this._advance();\n                        return ContextKeyExpr.in(key, this._value());\n                    default:\n                        return ContextKeyExpr.has(key);\n                }\n            }\n            case 20 /* TokenType.EOF */:\n                this._parsingErrors.push({ message: errorUnexpectedEOF, offset: peek.offset, lexeme: '', additionalInfo: hintUnexpectedEOF });\n                throw Parser._parseError;\n            default:\n                throw this._errExpectedButGot(`true | false | KEY \\n\\t| KEY '=~' REGEX \\n\\t| KEY ('==' | '!=' | '<' | '<=' | '>' | '>=' | 'in' | 'not' 'in') value`, this._peek());\n        }\n    }\n    _value() {\n        const token = this._peek();\n        switch (token.type) {\n            case 17 /* TokenType.Str */:\n            case 18 /* TokenType.QuotedStr */:\n                this._advance();\n                return token.lexeme;\n            case 11 /* TokenType.True */:\n                this._advance();\n                return 'true';\n            case 12 /* TokenType.False */:\n                this._advance();\n                return 'false';\n            case 13 /* TokenType.In */: // we support `in` as a value, e.g., \"when\": \"languageId == in\" - exists in existing extensions\n                this._advance();\n                return 'in';\n            default:\n                // this allows \"when\": \"foo == \" which's used by existing extensions\n                // we do not call `_advance` on purpose - we don't want to eat unintended tokens\n                return '';\n        }\n    }\n    _removeFlagsGY(flags) {\n        return flags.replaceAll(this._flagsGYRe, '');\n    }\n    // careful: this can throw if current token is the initial one (ie index = 0)\n    _previous() {\n        return this._tokens[this._current - 1];\n    }\n    _matchOne(token) {\n        if (this._check(token)) {\n            this._advance();\n            return true;\n        }\n        return false;\n    }\n    _advance() {\n        if (!this._isAtEnd()) {\n            this._current++;\n        }\n        return this._previous();\n    }\n    _consume(type, message) {\n        if (this._check(type)) {\n            return this._advance();\n        }\n        throw this._errExpectedButGot(message, this._peek());\n    }\n    _errExpectedButGot(expected, got, additionalInfo) {\n        const message = localize('contextkey.parser.error.expectedButGot', \"Expected: {0}\\nReceived: '{1}'.\", expected, Scanner.getLexeme(got));\n        const offset = got.offset;\n        const lexeme = Scanner.getLexeme(got);\n        this._parsingErrors.push({ message, offset, lexeme, additionalInfo });\n        return Parser._parseError;\n    }\n    _check(type) {\n        return this._peek().type === type;\n    }\n    _peek() {\n        return this._tokens[this._current];\n    }\n    _isAtEnd() {\n        return this._peek().type === 20 /* TokenType.EOF */;\n    }\n}\n// Note: this doesn't produce an exact syntax tree but a normalized one\n// ContextKeyExpression's that we use as AST nodes do not expose constructors that do not normalize\nParser._parseError = new Error();\nexport class ContextKeyExpr {\n    static false() {\n        return ContextKeyFalseExpr.INSTANCE;\n    }\n    static true() {\n        return ContextKeyTrueExpr.INSTANCE;\n    }\n    static has(key) {\n        return ContextKeyDefinedExpr.create(key);\n    }\n    static equals(key, value) {\n        return ContextKeyEqualsExpr.create(key, value);\n    }\n    static notEquals(key, value) {\n        return ContextKeyNotEqualsExpr.create(key, value);\n    }\n    static regex(key, value) {\n        return ContextKeyRegexExpr.create(key, value);\n    }\n    static in(key, value) {\n        return ContextKeyInExpr.create(key, value);\n    }\n    static notIn(key, value) {\n        return ContextKeyNotInExpr.create(key, value);\n    }\n    static not(key) {\n        return ContextKeyNotExpr.create(key);\n    }\n    static and(...expr) {\n        return ContextKeyAndExpr.create(expr, null, true);\n    }\n    static or(...expr) {\n        return ContextKeyOrExpr.create(expr, null, true);\n    }\n    static deserialize(serialized) {\n        if (serialized === undefined || serialized === null) { // an empty string needs to be handled by the parser to get a corresponding parsing error reported\n            return undefined;\n        }\n        const expr = this._parser.parse(serialized);\n        return expr;\n    }\n}\nContextKeyExpr._parser = new Parser({ regexParsingWithErrorRecovery: false });\nexport function expressionsAreEqualWithConstantSubstitution(a, b) {\n    const aExpr = a ? a.substituteConstants() : undefined;\n    const bExpr = b ? b.substituteConstants() : undefined;\n    if (!aExpr && !bExpr) {\n        return true;\n    }\n    if (!aExpr || !bExpr) {\n        return false;\n    }\n    return aExpr.equals(bExpr);\n}\nfunction cmp(a, b) {\n    return a.cmp(b);\n}\nexport class ContextKeyFalseExpr {\n    constructor() {\n        this.type = 0 /* ContextKeyExprType.False */;\n    }\n    cmp(other) {\n        return this.type - other.type;\n    }\n    equals(other) {\n        return (other.type === this.type);\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        return false;\n    }\n    serialize() {\n        return 'false';\n    }\n    keys() {\n        return [];\n    }\n    negate() {\n        return ContextKeyTrueExpr.INSTANCE;\n    }\n}\nContextKeyFalseExpr.INSTANCE = new ContextKeyFalseExpr();\nexport class ContextKeyTrueExpr {\n    constructor() {\n        this.type = 1 /* ContextKeyExprType.True */;\n    }\n    cmp(other) {\n        return this.type - other.type;\n    }\n    equals(other) {\n        return (other.type === this.type);\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        return true;\n    }\n    serialize() {\n        return 'true';\n    }\n    keys() {\n        return [];\n    }\n    negate() {\n        return ContextKeyFalseExpr.INSTANCE;\n    }\n}\nContextKeyTrueExpr.INSTANCE = new ContextKeyTrueExpr();\nexport class ContextKeyDefinedExpr {\n    static create(key, negated = null) {\n        const constantValue = CONSTANT_VALUES.get(key);\n        if (typeof constantValue === 'boolean') {\n            return constantValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE;\n        }\n        return new ContextKeyDefinedExpr(key, negated);\n    }\n    constructor(key, negated) {\n        this.key = key;\n        this.negated = negated;\n        this.type = 2 /* ContextKeyExprType.Defined */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp1(this.key, other.key);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key);\n        }\n        return false;\n    }\n    substituteConstants() {\n        const constantValue = CONSTANT_VALUES.get(this.key);\n        if (typeof constantValue === 'boolean') {\n            return constantValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE;\n        }\n        return this;\n    }\n    evaluate(context) {\n        return (!!context.getValue(this.key));\n    }\n    serialize() {\n        return this.key;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyNotExpr.create(this.key, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyEqualsExpr {\n    static create(key, value, negated = null) {\n        if (typeof value === 'boolean') {\n            return (value ? ContextKeyDefinedExpr.create(key, negated) : ContextKeyNotExpr.create(key, negated));\n        }\n        const constantValue = CONSTANT_VALUES.get(key);\n        if (typeof constantValue === 'boolean') {\n            const trueValue = constantValue ? 'true' : 'false';\n            return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE);\n        }\n        return new ContextKeyEqualsExpr(key, value, negated);\n    }\n    constructor(key, value, negated) {\n        this.key = key;\n        this.value = value;\n        this.negated = negated;\n        this.type = 4 /* ContextKeyExprType.Equals */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.value, other.key, other.value);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.value === other.value);\n        }\n        return false;\n    }\n    substituteConstants() {\n        const constantValue = CONSTANT_VALUES.get(this.key);\n        if (typeof constantValue === 'boolean') {\n            const trueValue = constantValue ? 'true' : 'false';\n            return (this.value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE);\n        }\n        return this;\n    }\n    evaluate(context) {\n        // Intentional ==\n        // eslint-disable-next-line eqeqeq\n        return (context.getValue(this.key) == this.value);\n    }\n    serialize() {\n        return `${this.key} == '${this.value}'`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyNotEqualsExpr.create(this.key, this.value, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyInExpr {\n    static create(key, valueKey) {\n        return new ContextKeyInExpr(key, valueKey);\n    }\n    constructor(key, valueKey) {\n        this.key = key;\n        this.valueKey = valueKey;\n        this.type = 10 /* ContextKeyExprType.In */;\n        this.negated = null;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.valueKey, other.key, other.valueKey);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.valueKey === other.valueKey);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        const source = context.getValue(this.valueKey);\n        const item = context.getValue(this.key);\n        if (Array.isArray(source)) {\n            return source.includes(item);\n        }\n        if (typeof item === 'string' && typeof source === 'object' && source !== null) {\n            return hasOwnProperty.call(source, item);\n        }\n        return false;\n    }\n    serialize() {\n        return `${this.key} in '${this.valueKey}'`;\n    }\n    keys() {\n        return [this.key, this.valueKey];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyNotInExpr.create(this.key, this.valueKey);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyNotInExpr {\n    static create(key, valueKey) {\n        return new ContextKeyNotInExpr(key, valueKey);\n    }\n    constructor(key, valueKey) {\n        this.key = key;\n        this.valueKey = valueKey;\n        this.type = 11 /* ContextKeyExprType.NotIn */;\n        this._negated = ContextKeyInExpr.create(key, valueKey);\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return this._negated.cmp(other._negated);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return this._negated.equals(other._negated);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        return !this._negated.evaluate(context);\n    }\n    serialize() {\n        return `${this.key} not in '${this.valueKey}'`;\n    }\n    keys() {\n        return this._negated.keys();\n    }\n    negate() {\n        return this._negated;\n    }\n}\nexport class ContextKeyNotEqualsExpr {\n    static create(key, value, negated = null) {\n        if (typeof value === 'boolean') {\n            if (value) {\n                return ContextKeyNotExpr.create(key, negated);\n            }\n            return ContextKeyDefinedExpr.create(key, negated);\n        }\n        const constantValue = CONSTANT_VALUES.get(key);\n        if (typeof constantValue === 'boolean') {\n            const falseValue = constantValue ? 'true' : 'false';\n            return (value === falseValue ? ContextKeyFalseExpr.INSTANCE : ContextKeyTrueExpr.INSTANCE);\n        }\n        return new ContextKeyNotEqualsExpr(key, value, negated);\n    }\n    constructor(key, value, negated) {\n        this.key = key;\n        this.value = value;\n        this.negated = negated;\n        this.type = 5 /* ContextKeyExprType.NotEquals */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.value, other.key, other.value);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.value === other.value);\n        }\n        return false;\n    }\n    substituteConstants() {\n        const constantValue = CONSTANT_VALUES.get(this.key);\n        if (typeof constantValue === 'boolean') {\n            const falseValue = constantValue ? 'true' : 'false';\n            return (this.value === falseValue ? ContextKeyFalseExpr.INSTANCE : ContextKeyTrueExpr.INSTANCE);\n        }\n        return this;\n    }\n    evaluate(context) {\n        // Intentional !=\n        // eslint-disable-next-line eqeqeq\n        return (context.getValue(this.key) != this.value);\n    }\n    serialize() {\n        return `${this.key} != '${this.value}'`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyEqualsExpr.create(this.key, this.value, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyNotExpr {\n    static create(key, negated = null) {\n        const constantValue = CONSTANT_VALUES.get(key);\n        if (typeof constantValue === 'boolean') {\n            return (constantValue ? ContextKeyFalseExpr.INSTANCE : ContextKeyTrueExpr.INSTANCE);\n        }\n        return new ContextKeyNotExpr(key, negated);\n    }\n    constructor(key, negated) {\n        this.key = key;\n        this.negated = negated;\n        this.type = 3 /* ContextKeyExprType.Not */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp1(this.key, other.key);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key);\n        }\n        return false;\n    }\n    substituteConstants() {\n        const constantValue = CONSTANT_VALUES.get(this.key);\n        if (typeof constantValue === 'boolean') {\n            return (constantValue ? ContextKeyFalseExpr.INSTANCE : ContextKeyTrueExpr.INSTANCE);\n        }\n        return this;\n    }\n    evaluate(context) {\n        return (!context.getValue(this.key));\n    }\n    serialize() {\n        return `!${this.key}`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyDefinedExpr.create(this.key, this);\n        }\n        return this.negated;\n    }\n}\nfunction withFloatOrStr(value, callback) {\n    if (typeof value === 'string') {\n        const n = parseFloat(value);\n        if (!isNaN(n)) {\n            value = n;\n        }\n    }\n    if (typeof value === 'string' || typeof value === 'number') {\n        return callback(value);\n    }\n    return ContextKeyFalseExpr.INSTANCE;\n}\nexport class ContextKeyGreaterExpr {\n    static create(key, _value, negated = null) {\n        return withFloatOrStr(_value, (value) => new ContextKeyGreaterExpr(key, value, negated));\n    }\n    constructor(key, value, negated) {\n        this.key = key;\n        this.value = value;\n        this.negated = negated;\n        this.type = 12 /* ContextKeyExprType.Greater */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.value, other.key, other.value);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.value === other.value);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        if (typeof this.value === 'string') {\n            return false;\n        }\n        return (parseFloat(context.getValue(this.key)) > this.value);\n    }\n    serialize() {\n        return `${this.key} > ${this.value}`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeySmallerEqualsExpr.create(this.key, this.value, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyGreaterEqualsExpr {\n    static create(key, _value, negated = null) {\n        return withFloatOrStr(_value, (value) => new ContextKeyGreaterEqualsExpr(key, value, negated));\n    }\n    constructor(key, value, negated) {\n        this.key = key;\n        this.value = value;\n        this.negated = negated;\n        this.type = 13 /* ContextKeyExprType.GreaterEquals */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.value, other.key, other.value);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.value === other.value);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        if (typeof this.value === 'string') {\n            return false;\n        }\n        return (parseFloat(context.getValue(this.key)) >= this.value);\n    }\n    serialize() {\n        return `${this.key} >= ${this.value}`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeySmallerExpr.create(this.key, this.value, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeySmallerExpr {\n    static create(key, _value, negated = null) {\n        return withFloatOrStr(_value, (value) => new ContextKeySmallerExpr(key, value, negated));\n    }\n    constructor(key, value, negated) {\n        this.key = key;\n        this.value = value;\n        this.negated = negated;\n        this.type = 14 /* ContextKeyExprType.Smaller */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.value, other.key, other.value);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.value === other.value);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        if (typeof this.value === 'string') {\n            return false;\n        }\n        return (parseFloat(context.getValue(this.key)) < this.value);\n    }\n    serialize() {\n        return `${this.key} < ${this.value}`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyGreaterEqualsExpr.create(this.key, this.value, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeySmallerEqualsExpr {\n    static create(key, _value, negated = null) {\n        return withFloatOrStr(_value, (value) => new ContextKeySmallerEqualsExpr(key, value, negated));\n    }\n    constructor(key, value, negated) {\n        this.key = key;\n        this.value = value;\n        this.negated = negated;\n        this.type = 15 /* ContextKeyExprType.SmallerEquals */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return cmp2(this.key, this.value, other.key, other.value);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return (this.key === other.key && this.value === other.value);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        if (typeof this.value === 'string') {\n            return false;\n        }\n        return (parseFloat(context.getValue(this.key)) <= this.value);\n    }\n    serialize() {\n        return `${this.key} <= ${this.value}`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyGreaterExpr.create(this.key, this.value, this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyRegexExpr {\n    static create(key, regexp) {\n        return new ContextKeyRegexExpr(key, regexp);\n    }\n    constructor(key, regexp) {\n        this.key = key;\n        this.regexp = regexp;\n        this.type = 7 /* ContextKeyExprType.Regex */;\n        this.negated = null;\n        //\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        if (this.key < other.key) {\n            return -1;\n        }\n        if (this.key > other.key) {\n            return 1;\n        }\n        const thisSource = this.regexp ? this.regexp.source : '';\n        const otherSource = other.regexp ? other.regexp.source : '';\n        if (thisSource < otherSource) {\n            return -1;\n        }\n        if (thisSource > otherSource) {\n            return 1;\n        }\n        return 0;\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            const thisSource = this.regexp ? this.regexp.source : '';\n            const otherSource = other.regexp ? other.regexp.source : '';\n            return (this.key === other.key && thisSource === otherSource);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        const value = context.getValue(this.key);\n        return this.regexp ? this.regexp.test(value) : false;\n    }\n    serialize() {\n        const value = this.regexp\n            ? `/${this.regexp.source}/${this.regexp.flags}`\n            : '/invalid/';\n        return `${this.key} =~ ${value}`;\n    }\n    keys() {\n        return [this.key];\n    }\n    negate() {\n        if (!this.negated) {\n            this.negated = ContextKeyNotRegexExpr.create(this);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyNotRegexExpr {\n    static create(actual) {\n        return new ContextKeyNotRegexExpr(actual);\n    }\n    constructor(_actual) {\n        this._actual = _actual;\n        this.type = 8 /* ContextKeyExprType.NotRegex */;\n        //\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        return this._actual.cmp(other._actual);\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            return this._actual.equals(other._actual);\n        }\n        return false;\n    }\n    substituteConstants() {\n        return this;\n    }\n    evaluate(context) {\n        return !this._actual.evaluate(context);\n    }\n    serialize() {\n        return `!(${this._actual.serialize()})`;\n    }\n    keys() {\n        return this._actual.keys();\n    }\n    negate() {\n        return this._actual;\n    }\n}\n/**\n * @returns the same instance if nothing changed.\n */\nfunction eliminateConstantsInArray(arr) {\n    // Allocate array only if there is a difference\n    let newArr = null;\n    for (let i = 0, len = arr.length; i < len; i++) {\n        const newExpr = arr[i].substituteConstants();\n        if (arr[i] !== newExpr) {\n            // something has changed!\n            // allocate array on first difference\n            if (newArr === null) {\n                newArr = [];\n                for (let j = 0; j < i; j++) {\n                    newArr[j] = arr[j];\n                }\n            }\n        }\n        if (newArr !== null) {\n            newArr[i] = newExpr;\n        }\n    }\n    if (newArr === null) {\n        return arr;\n    }\n    return newArr;\n}\nexport class ContextKeyAndExpr {\n    static create(_expr, negated, extraRedundantCheck) {\n        return ContextKeyAndExpr._normalizeArr(_expr, negated, extraRedundantCheck);\n    }\n    constructor(expr, negated) {\n        this.expr = expr;\n        this.negated = negated;\n        this.type = 6 /* ContextKeyExprType.And */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        if (this.expr.length < other.expr.length) {\n            return -1;\n        }\n        if (this.expr.length > other.expr.length) {\n            return 1;\n        }\n        for (let i = 0, len = this.expr.length; i < len; i++) {\n            const r = cmp(this.expr[i], other.expr[i]);\n            if (r !== 0) {\n                return r;\n            }\n        }\n        return 0;\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            if (this.expr.length !== other.expr.length) {\n                return false;\n            }\n            for (let i = 0, len = this.expr.length; i < len; i++) {\n                if (!this.expr[i].equals(other.expr[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        return false;\n    }\n    substituteConstants() {\n        const exprArr = eliminateConstantsInArray(this.expr);\n        if (exprArr === this.expr) {\n            // no change\n            return this;\n        }\n        return ContextKeyAndExpr.create(exprArr, this.negated, false);\n    }\n    evaluate(context) {\n        for (let i = 0, len = this.expr.length; i < len; i++) {\n            if (!this.expr[i].evaluate(context)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    static _normalizeArr(arr, negated, extraRedundantCheck) {\n        const expr = [];\n        let hasTrue = false;\n        for (const e of arr) {\n            if (!e) {\n                continue;\n            }\n            if (e.type === 1 /* ContextKeyExprType.True */) {\n                // anything && true ==> anything\n                hasTrue = true;\n                continue;\n            }\n            if (e.type === 0 /* ContextKeyExprType.False */) {\n                // anything && false ==> false\n                return ContextKeyFalseExpr.INSTANCE;\n            }\n            if (e.type === 6 /* ContextKeyExprType.And */) {\n                expr.push(...e.expr);\n                continue;\n            }\n            expr.push(e);\n        }\n        if (expr.length === 0 && hasTrue) {\n            return ContextKeyTrueExpr.INSTANCE;\n        }\n        if (expr.length === 0) {\n            return undefined;\n        }\n        if (expr.length === 1) {\n            return expr[0];\n        }\n        expr.sort(cmp);\n        // eliminate duplicate terms\n        for (let i = 1; i < expr.length; i++) {\n            if (expr[i - 1].equals(expr[i])) {\n                expr.splice(i, 1);\n                i--;\n            }\n        }\n        if (expr.length === 1) {\n            return expr[0];\n        }\n        // We must distribute any OR expression because we don't support parens\n        // OR extensions will be at the end (due to sorting rules)\n        while (expr.length > 1) {\n            const lastElement = expr[expr.length - 1];\n            if (lastElement.type !== 9 /* ContextKeyExprType.Or */) {\n                break;\n            }\n            // pop the last element\n            expr.pop();\n            // pop the second to last element\n            const secondToLastElement = expr.pop();\n            const isFinished = (expr.length === 0);\n            // distribute `lastElement` over `secondToLastElement`\n            const resultElement = ContextKeyOrExpr.create(lastElement.expr.map(el => ContextKeyAndExpr.create([el, secondToLastElement], null, extraRedundantCheck)), null, isFinished);\n            if (resultElement) {\n                expr.push(resultElement);\n                expr.sort(cmp);\n            }\n        }\n        if (expr.length === 1) {\n            return expr[0];\n        }\n        // resolve false AND expressions\n        if (extraRedundantCheck) {\n            for (let i = 0; i < expr.length; i++) {\n                for (let j = i + 1; j < expr.length; j++) {\n                    if (expr[i].negate().equals(expr[j])) {\n                        // A && !A case\n                        return ContextKeyFalseExpr.INSTANCE;\n                    }\n                }\n            }\n            if (expr.length === 1) {\n                return expr[0];\n            }\n        }\n        return new ContextKeyAndExpr(expr, negated);\n    }\n    serialize() {\n        return this.expr.map(e => e.serialize()).join(' && ');\n    }\n    keys() {\n        const result = [];\n        for (const expr of this.expr) {\n            result.push(...expr.keys());\n        }\n        return result;\n    }\n    negate() {\n        if (!this.negated) {\n            const result = [];\n            for (const expr of this.expr) {\n                result.push(expr.negate());\n            }\n            this.negated = ContextKeyOrExpr.create(result, this, true);\n        }\n        return this.negated;\n    }\n}\nexport class ContextKeyOrExpr {\n    static create(_expr, negated, extraRedundantCheck) {\n        return ContextKeyOrExpr._normalizeArr(_expr, negated, extraRedundantCheck);\n    }\n    constructor(expr, negated) {\n        this.expr = expr;\n        this.negated = negated;\n        this.type = 9 /* ContextKeyExprType.Or */;\n    }\n    cmp(other) {\n        if (other.type !== this.type) {\n            return this.type - other.type;\n        }\n        if (this.expr.length < other.expr.length) {\n            return -1;\n        }\n        if (this.expr.length > other.expr.length) {\n            return 1;\n        }\n        for (let i = 0, len = this.expr.length; i < len; i++) {\n            const r = cmp(this.expr[i], other.expr[i]);\n            if (r !== 0) {\n                return r;\n            }\n        }\n        return 0;\n    }\n    equals(other) {\n        if (other.type === this.type) {\n            if (this.expr.length !== other.expr.length) {\n                return false;\n            }\n            for (let i = 0, len = this.expr.length; i < len; i++) {\n                if (!this.expr[i].equals(other.expr[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        return false;\n    }\n    substituteConstants() {\n        const exprArr = eliminateConstantsInArray(this.expr);\n        if (exprArr === this.expr) {\n            // no change\n            return this;\n        }\n        return ContextKeyOrExpr.create(exprArr, this.negated, false);\n    }\n    evaluate(context) {\n        for (let i = 0, len = this.expr.length; i < len; i++) {\n            if (this.expr[i].evaluate(context)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    static _normalizeArr(arr, negated, extraRedundantCheck) {\n        let expr = [];\n        let hasFalse = false;\n        if (arr) {\n            for (let i = 0, len = arr.length; i < len; i++) {\n                const e = arr[i];\n                if (!e) {\n                    continue;\n                }\n                if (e.type === 0 /* ContextKeyExprType.False */) {\n                    // anything || false ==> anything\n                    hasFalse = true;\n                    continue;\n                }\n                if (e.type === 1 /* ContextKeyExprType.True */) {\n                    // anything || true ==> true\n                    return ContextKeyTrueExpr.INSTANCE;\n                }\n                if (e.type === 9 /* ContextKeyExprType.Or */) {\n                    expr = expr.concat(e.expr);\n                    continue;\n                }\n                expr.push(e);\n            }\n            if (expr.length === 0 && hasFalse) {\n                return ContextKeyFalseExpr.INSTANCE;\n            }\n            expr.sort(cmp);\n        }\n        if (expr.length === 0) {\n            return undefined;\n        }\n        if (expr.length === 1) {\n            return expr[0];\n        }\n        // eliminate duplicate terms\n        for (let i = 1; i < expr.length; i++) {\n            if (expr[i - 1].equals(expr[i])) {\n                expr.splice(i, 1);\n                i--;\n            }\n        }\n        if (expr.length === 1) {\n            return expr[0];\n        }\n        // resolve true OR expressions\n        if (extraRedundantCheck) {\n            for (let i = 0; i < expr.length; i++) {\n                for (let j = i + 1; j < expr.length; j++) {\n                    if (expr[i].negate().equals(expr[j])) {\n                        // A || !A case\n                        return ContextKeyTrueExpr.INSTANCE;\n                    }\n                }\n            }\n            if (expr.length === 1) {\n                return expr[0];\n            }\n        }\n        return new ContextKeyOrExpr(expr, negated);\n    }\n    serialize() {\n        return this.expr.map(e => e.serialize()).join(' || ');\n    }\n    keys() {\n        const result = [];\n        for (const expr of this.expr) {\n            result.push(...expr.keys());\n        }\n        return result;\n    }\n    negate() {\n        if (!this.negated) {\n            const result = [];\n            for (const expr of this.expr) {\n                result.push(expr.negate());\n            }\n            // We don't support parens, so here we distribute the AND over the OR terminals\n            // We always take the first 2 AND pairs and distribute them\n            while (result.length > 1) {\n                const LEFT = result.shift();\n                const RIGHT = result.shift();\n                const all = [];\n                for (const left of getTerminals(LEFT)) {\n                    for (const right of getTerminals(RIGHT)) {\n                        all.push(ContextKeyAndExpr.create([left, right], null, false));\n                    }\n                }\n                result.unshift(ContextKeyOrExpr.create(all, null, false));\n            }\n            this.negated = ContextKeyOrExpr.create(result, this, true);\n        }\n        return this.negated;\n    }\n}\nexport class RawContextKey extends ContextKeyDefinedExpr {\n    static all() {\n        return RawContextKey._info.values();\n    }\n    constructor(key, defaultValue, metaOrHide) {\n        super(key, null);\n        this._defaultValue = defaultValue;\n        // collect all context keys into a central place\n        if (typeof metaOrHide === 'object') {\n            RawContextKey._info.push(Object.assign(Object.assign({}, metaOrHide), { key }));\n        }\n        else if (metaOrHide !== true) {\n            RawContextKey._info.push({ key, description: metaOrHide, type: defaultValue !== null && defaultValue !== undefined ? typeof defaultValue : undefined });\n        }\n    }\n    bindTo(target) {\n        return target.createKey(this.key, this._defaultValue);\n    }\n    getValue(target) {\n        return target.getContextKeyValue(this.key);\n    }\n    toNegated() {\n        return this.negate();\n    }\n    isEqualTo(value) {\n        return ContextKeyEqualsExpr.create(this.key, value);\n    }\n}\nRawContextKey._info = [];\nexport const IContextKeyService = createDecorator('contextKeyService');\nfunction cmp1(key1, key2) {\n    if (key1 < key2) {\n        return -1;\n    }\n    if (key1 > key2) {\n        return 1;\n    }\n    return 0;\n}\nfunction cmp2(key1, value1, key2, value2) {\n    if (key1 < key2) {\n        return -1;\n    }\n    if (key1 > key2) {\n        return 1;\n    }\n    if (value1 < value2) {\n        return -1;\n    }\n    if (value1 > value2) {\n        return 1;\n    }\n    return 0;\n}\n/**\n * Returns true if it is provable `p` implies `q`.\n */\nexport function implies(p, q) {\n    if (p.type === 0 /* ContextKeyExprType.False */ || q.type === 1 /* ContextKeyExprType.True */) {\n        // false implies anything\n        // anything implies true\n        return true;\n    }\n    if (p.type === 9 /* ContextKeyExprType.Or */) {\n        if (q.type === 9 /* ContextKeyExprType.Or */) {\n            // `a || b || c` can only imply something like `a || b || c || d`\n            return allElementsIncluded(p.expr, q.expr);\n        }\n        return false;\n    }\n    if (q.type === 9 /* ContextKeyExprType.Or */) {\n        for (const element of q.expr) {\n            if (implies(p, element)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    if (p.type === 6 /* ContextKeyExprType.And */) {\n        if (q.type === 6 /* ContextKeyExprType.And */) {\n            // `a && b && c` implies `a && c`\n            return allElementsIncluded(q.expr, p.expr);\n        }\n        for (const element of p.expr) {\n            if (implies(element, q)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    return p.equals(q);\n}\n/**\n * Returns true if all elements in `p` are also present in `q`.\n * The two arrays are assumed to be sorted\n */\nfunction allElementsIncluded(p, q) {\n    let pIndex = 0;\n    let qIndex = 0;\n    while (pIndex < p.length && qIndex < q.length) {\n        const cmp = p[pIndex].cmp(q[qIndex]);\n        if (cmp < 0) {\n            // an element from `p` is missing from `q`\n            return false;\n        }\n        else if (cmp === 0) {\n            pIndex++;\n            qIndex++;\n        }\n        else {\n            qIndex++;\n        }\n    }\n    return (pIndex === p.length);\n}\nfunction getTerminals(node) {\n    if (node.type === 9 /* ContextKeyExprType.Or */) {\n        return node.expr;\n    }\n    return [node];\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { RawContextKey } from '../../contextkey/common/contextkey.js';\nimport { createDecorator } from '../../instantiation/common/instantiation.js';\nexport const IAccessibilityService = createDecorator('accessibilityService');\nexport const CONTEXT_ACCESSIBILITY_MODE_ENABLED = new RawContextKey('accessibilityModeEnabled', false);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\n};\nvar __param = (this && this.__param) || function (paramIndex, decorator) {\n    return function (target, key) { decorator(target, key, paramIndex); }\n};\nimport * as assert from '../../../base/common/assert.js';\nimport { Emitter } from '../../../base/common/event.js';\nimport { Disposable } from '../../../base/common/lifecycle.js';\nimport * as objects from '../../../base/common/objects.js';\nimport { Range } from '../../common/core/range.js';\nimport { AudioCue, IAudioCueService } from '../../../platform/audioCues/browser/audioCueService.js';\nimport { ICodeEditorService } from '../services/codeEditorService.js';\nimport { IAccessibilityService } from '../../../platform/accessibility/common/accessibility.js';\nconst defaultOptions = {\n    followsCaret: true,\n    ignoreCharChanges: true,\n    alwaysRevealFirst: true,\n    findResultLoop: true\n};\n/**\n * Create a new diff navigator for the provided diff editor.\n */\nexport let DiffNavigator = class DiffNavigator extends Disposable {\n    constructor(editor, options = {}, _audioCueService, _codeEditorService, _accessibilityService) {\n        super();\n        this._audioCueService = _audioCueService;\n        this._codeEditorService = _codeEditorService;\n        this._accessibilityService = _accessibilityService;\n        this._onDidUpdate = this._register(new Emitter());\n        this._editor = editor;\n        this._options = objects.mixin(options, defaultOptions, false);\n        this.disposed = false;\n        this.nextIdx = -1;\n        this.ranges = [];\n        this.ignoreSelectionChange = false;\n        this.revealFirst = Boolean(this._options.alwaysRevealFirst);\n        this._register(this._editor.onDidUpdateDiff(() => this._onDiffUpdated()));\n        if (this._options.followsCaret) {\n            this._register(this._editor.getModifiedEditor().onDidChangeCursorPosition((e) => {\n                if (this.ignoreSelectionChange) {\n                    return;\n                }\n                this._updateAccessibilityState(e.position.lineNumber);\n                this.nextIdx = -1;\n            }));\n        }\n        // init things\n        this._init();\n    }\n    _init() {\n        const changes = this._editor.getLineChanges();\n        if (!changes) {\n            return;\n        }\n    }\n    _onDiffUpdated() {\n        this._init();\n        this._compute(this._editor.getLineChanges());\n        if (this.revealFirst) {\n            // Only reveal first on first non-null changes\n            if (this._editor.getLineChanges() !== null) {\n                this.revealFirst = false;\n                this.nextIdx = -1;\n                this.next(1 /* ScrollType.Immediate */);\n            }\n        }\n    }\n    _compute(lineChanges) {\n        // new ranges\n        this.ranges = [];\n        if (lineChanges) {\n            // create ranges from changes\n            lineChanges.forEach((lineChange) => {\n                if (!this._options.ignoreCharChanges && lineChange.charChanges) {\n                    lineChange.charChanges.forEach((charChange) => {\n                        this.ranges.push({\n                            rhs: true,\n                            range: new Range(charChange.modifiedStartLineNumber, charChange.modifiedStartColumn, charChange.modifiedEndLineNumber, charChange.modifiedEndColumn)\n                        });\n                    });\n                }\n                else {\n                    if (lineChange.modifiedEndLineNumber === 0) {\n                        // a deletion\n                        this.ranges.push({\n                            rhs: true,\n                            range: new Range(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedStartLineNumber + 1, 1)\n                        });\n                    }\n                    else {\n                        // an insertion or modification\n                        this.ranges.push({\n                            rhs: true,\n                            range: new Range(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedEndLineNumber + 1, 1)\n                        });\n                    }\n                }\n            });\n        }\n        // sort\n        this.ranges.sort((left, right) => Range.compareRangesUsingStarts(left.range, right.range));\n        this._onDidUpdate.fire(this);\n    }\n    _initIdx(fwd) {\n        let found = false;\n        const position = this._editor.getPosition();\n        if (!position) {\n            this.nextIdx = 0;\n            return;\n        }\n        for (let i = 0, len = this.ranges.length; i < len && !found; i++) {\n            const range = this.ranges[i].range;\n            if (position.isBeforeOrEqual(range.getStartPosition())) {\n                this.nextIdx = i + (fwd ? 0 : -1);\n                found = true;\n            }\n        }\n        if (!found) {\n            // after the last change\n            this.nextIdx = fwd ? 0 : this.ranges.length - 1;\n        }\n        if (this.nextIdx < 0) {\n            this.nextIdx = this.ranges.length - 1;\n        }\n    }\n    _move(fwd, scrollType) {\n        assert.ok(!this.disposed, 'Illegal State - diff navigator has been disposed');\n        if (!this.canNavigate()) {\n            return;\n        }\n        if (this.nextIdx === -1) {\n            this._initIdx(fwd);\n        }\n        else if (fwd) {\n            this.nextIdx += 1;\n            if (this.nextIdx >= this.ranges.length) {\n                this.nextIdx = 0;\n            }\n        }\n        else {\n            this.nextIdx -= 1;\n            if (this.nextIdx < 0) {\n                this.nextIdx = this.ranges.length - 1;\n            }\n        }\n        const info = this.ranges[this.nextIdx];\n        this.ignoreSelectionChange = true;\n        try {\n            const pos = info.range.getStartPosition();\n            this._editor.setPosition(pos);\n            this._editor.revealRangeInCenter(info.range, scrollType);\n            this._updateAccessibilityState(pos.lineNumber, true);\n        }\n        finally {\n            this.ignoreSelectionChange = false;\n        }\n    }\n    _updateAccessibilityState(lineNumber, jumpToChange) {\n        var _a;\n        const modifiedEditor = (_a = this._editor.getModel()) === null || _a === void 0 ? void 0 : _a.modified;\n        if (!modifiedEditor) {\n            return;\n        }\n        const insertedOrModified = modifiedEditor.getLineDecorations(lineNumber).find(l => l.options.className === 'line-insert');\n        if (insertedOrModified) {\n            this._audioCueService.playAudioCue(AudioCue.diffLineModified, true);\n        }\n        else if (jumpToChange) {\n            // The modified editor does not include deleted lines, but when\n            // we are moved to the area where lines were deleted, play this cue\n            this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, true);\n        }\n        else {\n            return;\n        }\n        const codeEditor = this._codeEditorService.getActiveCodeEditor();\n        if (jumpToChange && codeEditor && insertedOrModified && this._accessibilityService.isScreenReaderOptimized()) {\n            codeEditor.setSelection({ startLineNumber: lineNumber, startColumn: 0, endLineNumber: lineNumber, endColumn: Number.MAX_VALUE });\n            codeEditor.writeScreenReaderContent('diff-navigation');\n        }\n    }\n    canNavigate() {\n        return this.ranges && this.ranges.length > 0;\n    }\n    next(scrollType = 0 /* ScrollType.Smooth */) {\n        if (!this.canNavigateNext()) {\n            return;\n        }\n        this._move(true, scrollType);\n    }\n    previous(scrollType = 0 /* ScrollType.Smooth */) {\n        if (!this.canNavigatePrevious()) {\n            return;\n        }\n        this._move(false, scrollType);\n    }\n    canNavigateNext() {\n        return this.canNavigateLoop() || this.nextIdx < this.ranges.length - 1;\n    }\n    canNavigatePrevious() {\n        return this.canNavigateLoop() || this.nextIdx !== 0;\n    }\n    canNavigateLoop() {\n        return Boolean(this._options.findResultLoop);\n    }\n    dispose() {\n        super.dispose();\n        this.ranges = [];\n        this.disposed = true;\n    }\n};\nDiffNavigator = __decorate([\n    __param(2, IAudioCueService),\n    __param(3, ICodeEditorService),\n    __param(4, IAccessibilityService)\n], DiffNavigator);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * The type of the `IEditor`.\n */\nexport const EditorType = {\n    ICodeEditor: 'vs.editor.ICodeEditor',\n    IDiffEditor: 'vs.editor.IDiffEditor'\n};\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { equals } from '../../base/common/objects.js';\n/**\n * Vertical Lane in the overview ruler of the editor.\n */\nexport var OverviewRulerLane;\n(function (OverviewRulerLane) {\n    OverviewRulerLane[OverviewRulerLane[\"Left\"] = 1] = \"Left\";\n    OverviewRulerLane[OverviewRulerLane[\"Center\"] = 2] = \"Center\";\n    OverviewRulerLane[OverviewRulerLane[\"Right\"] = 4] = \"Right\";\n    OverviewRulerLane[OverviewRulerLane[\"Full\"] = 7] = \"Full\";\n})(OverviewRulerLane || (OverviewRulerLane = {}));\n/**\n * Vertical Lane in the glyph margin of the editor.\n */\nexport var GlyphMarginLane;\n(function (GlyphMarginLane) {\n    GlyphMarginLane[GlyphMarginLane[\"Left\"] = 1] = \"Left\";\n    GlyphMarginLane[GlyphMarginLane[\"Right\"] = 2] = \"Right\";\n})(GlyphMarginLane || (GlyphMarginLane = {}));\n/**\n * Position in the minimap to render the decoration.\n */\nexport var MinimapPosition;\n(function (MinimapPosition) {\n    MinimapPosition[MinimapPosition[\"Inline\"] = 1] = \"Inline\";\n    MinimapPosition[MinimapPosition[\"Gutter\"] = 2] = \"Gutter\";\n})(MinimapPosition || (MinimapPosition = {}));\nexport var InjectedTextCursorStops;\n(function (InjectedTextCursorStops) {\n    InjectedTextCursorStops[InjectedTextCursorStops[\"Both\"] = 0] = \"Both\";\n    InjectedTextCursorStops[InjectedTextCursorStops[\"Right\"] = 1] = \"Right\";\n    InjectedTextCursorStops[InjectedTextCursorStops[\"Left\"] = 2] = \"Left\";\n    InjectedTextCursorStops[InjectedTextCursorStops[\"None\"] = 3] = \"None\";\n})(InjectedTextCursorStops || (InjectedTextCursorStops = {}));\nexport class TextModelResolvedOptions {\n    get originalIndentSize() {\n        return this._indentSizeIsTabSize ? 'tabSize' : this.indentSize;\n    }\n    /**\n     * @internal\n     */\n    constructor(src) {\n        this._textModelResolvedOptionsBrand = undefined;\n        this.tabSize = Math.max(1, src.tabSize | 0);\n        if (src.indentSize === 'tabSize') {\n            this.indentSize = this.tabSize;\n            this._indentSizeIsTabSize = true;\n        }\n        else {\n            this.indentSize = Math.max(1, src.indentSize | 0);\n            this._indentSizeIsTabSize = false;\n        }\n        this.insertSpaces = Boolean(src.insertSpaces);\n        this.defaultEOL = src.defaultEOL | 0;\n        this.trimAutoWhitespace = Boolean(src.trimAutoWhitespace);\n        this.bracketPairColorizationOptions = src.bracketPairColorizationOptions;\n    }\n    /**\n     * @internal\n     */\n    equals(other) {\n        return (this.tabSize === other.tabSize\n            && this._indentSizeIsTabSize === other._indentSizeIsTabSize\n            && this.indentSize === other.indentSize\n            && this.insertSpaces === other.insertSpaces\n            && this.defaultEOL === other.defaultEOL\n            && this.trimAutoWhitespace === other.trimAutoWhitespace\n            && equals(this.bracketPairColorizationOptions, other.bracketPairColorizationOptions));\n    }\n    /**\n     * @internal\n     */\n    createChangeEvent(newOpts) {\n        return {\n            tabSize: this.tabSize !== newOpts.tabSize,\n            indentSize: this.indentSize !== newOpts.indentSize,\n            insertSpaces: this.insertSpaces !== newOpts.insertSpaces,\n            trimAutoWhitespace: this.trimAutoWhitespace !== newOpts.trimAutoWhitespace,\n        };\n    }\n}\nexport class FindMatch {\n    /**\n     * @internal\n     */\n    constructor(range, matches) {\n        this._findMatchBrand = undefined;\n        this.range = range;\n        this.matches = matches;\n    }\n}\n/**\n * @internal\n */\nexport function isITextSnapshot(obj) {\n    return (obj && typeof obj.read === 'function');\n}\n/**\n * @internal\n */\nexport class ValidAnnotatedEditOperation {\n    constructor(identifier, range, text, forceMoveMarkers, isAutoWhitespaceEdit, _isTracked) {\n        this.identifier = identifier;\n        this.range = range;\n        this.text = text;\n        this.forceMoveMarkers = forceMoveMarkers;\n        this.isAutoWhitespaceEdit = isAutoWhitespaceEdit;\n        this._isTracked = _isTracked;\n    }\n}\n/**\n * @internal\n */\nexport class SearchData {\n    constructor(regex, wordSeparators, simpleSearch) {\n        this.regex = regex;\n        this.wordSeparators = wordSeparators;\n        this.simpleSearch = simpleSearch;\n    }\n}\n/**\n * @internal\n */\nexport class ApplyEditsResult {\n    constructor(reverseEdits, changes, trimAutoWhitespaceLineNumbers) {\n        this.reverseEdits = reverseEdits;\n        this.changes = changes;\n        this.trimAutoWhitespaceLineNumbers = trimAutoWhitespaceLineNumbers;\n    }\n}\n/**\n * @internal\n */\nexport function shouldSynchronizeModel(model) {\n    return (!model.isTooLargeForSyncing() && !model.isForSimpleWidget);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * Describes what to do with the indentation when pressing Enter.\n */\nexport var IndentAction;\n(function (IndentAction) {\n    /**\n     * Insert new line and copy the previous line's indentation.\n     */\n    IndentAction[IndentAction[\"None\"] = 0] = \"None\";\n    /**\n     * Insert new line and indent once (relative to the previous line's indentation).\n     */\n    IndentAction[IndentAction[\"Indent\"] = 1] = \"Indent\";\n    /**\n     * Insert two new lines:\n     *  - the first one indented which will hold the cursor\n     *  - the second one at the same indentation level\n     */\n    IndentAction[IndentAction[\"IndentOutdent\"] = 2] = \"IndentOutdent\";\n    /**\n     * Insert new line and outdent once (relative to the previous line's indentation).\n     */\n    IndentAction[IndentAction[\"Outdent\"] = 3] = \"Outdent\";\n})(IndentAction || (IndentAction = {}));\n/**\n * @internal\n */\nexport class StandardAutoClosingPairConditional {\n    constructor(source) {\n        this._neutralCharacter = null;\n        this._neutralCharacterSearched = false;\n        this.open = source.open;\n        this.close = source.close;\n        // initially allowed in all tokens\n        this._inString = true;\n        this._inComment = true;\n        this._inRegEx = true;\n        if (Array.isArray(source.notIn)) {\n            for (let i = 0, len = source.notIn.length; i < len; i++) {\n                const notIn = source.notIn[i];\n                switch (notIn) {\n                    case 'string':\n                        this._inString = false;\n                        break;\n                    case 'comment':\n                        this._inComment = false;\n                        break;\n                    case 'regex':\n                        this._inRegEx = false;\n                        break;\n                }\n            }\n        }\n    }\n    isOK(standardToken) {\n        switch (standardToken) {\n            case 0 /* StandardTokenType.Other */:\n                return true;\n            case 1 /* StandardTokenType.Comment */:\n                return this._inComment;\n            case 2 /* StandardTokenType.String */:\n                return this._inString;\n            case 3 /* StandardTokenType.RegEx */:\n                return this._inRegEx;\n        }\n    }\n    shouldAutoClose(context, column) {\n        // Always complete on empty line\n        if (context.getTokenCount() === 0) {\n            return true;\n        }\n        const tokenIndex = context.findTokenIndexAtOffset(column - 2);\n        const standardTokenType = context.getStandardTokenType(tokenIndex);\n        return this.isOK(standardTokenType);\n    }\n    _findNeutralCharacterInRange(fromCharCode, toCharCode) {\n        for (let charCode = fromCharCode; charCode <= toCharCode; charCode++) {\n            const character = String.fromCharCode(charCode);\n            if (!this.open.includes(character) && !this.close.includes(character)) {\n                return character;\n            }\n        }\n        return null;\n    }\n    /**\n     * Find a character in the range [0-9a-zA-Z] that does not appear in the open or close\n     */\n    findNeutralCharacter() {\n        if (!this._neutralCharacterSearched) {\n            this._neutralCharacterSearched = true;\n            if (!this._neutralCharacter) {\n                this._neutralCharacter = this._findNeutralCharacterInRange(48 /* CharCode.Digit0 */, 57 /* CharCode.Digit9 */);\n            }\n            if (!this._neutralCharacter) {\n                this._neutralCharacter = this._findNeutralCharacterInRange(97 /* CharCode.a */, 122 /* CharCode.z */);\n            }\n            if (!this._neutralCharacter) {\n                this._neutralCharacter = this._findNeutralCharacterInRange(65 /* CharCode.A */, 90 /* CharCode.Z */);\n            }\n        }\n        return this._neutralCharacter;\n    }\n}\n/**\n * @internal\n */\nexport class AutoClosingPairs {\n    constructor(autoClosingPairs) {\n        this.autoClosingPairsOpenByStart = new Map();\n        this.autoClosingPairsOpenByEnd = new Map();\n        this.autoClosingPairsCloseByStart = new Map();\n        this.autoClosingPairsCloseByEnd = new Map();\n        this.autoClosingPairsCloseSingleChar = new Map();\n        for (const pair of autoClosingPairs) {\n            appendEntry(this.autoClosingPairsOpenByStart, pair.open.charAt(0), pair);\n            appendEntry(this.autoClosingPairsOpenByEnd, pair.open.charAt(pair.open.length - 1), pair);\n            appendEntry(this.autoClosingPairsCloseByStart, pair.close.charAt(0), pair);\n            appendEntry(this.autoClosingPairsCloseByEnd, pair.close.charAt(pair.close.length - 1), pair);\n            if (pair.close.length === 1 && pair.open.length === 1) {\n                appendEntry(this.autoClosingPairsCloseSingleChar, pair.close, pair);\n            }\n        }\n    }\n}\nfunction appendEntry(target, key, value) {\n    if (target.has(key)) {\n        target.get(key).push(value);\n    }\n    else {\n        target.set(key, [value]);\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport function createScopedLineTokens(context, offset) {\n    const tokenCount = context.getCount();\n    const tokenIndex = context.findTokenIndexAtOffset(offset);\n    const desiredLanguageId = context.getLanguageId(tokenIndex);\n    let lastTokenIndex = tokenIndex;\n    while (lastTokenIndex + 1 < tokenCount && context.getLanguageId(lastTokenIndex + 1) === desiredLanguageId) {\n        lastTokenIndex++;\n    }\n    let firstTokenIndex = tokenIndex;\n    while (firstTokenIndex > 0 && context.getLanguageId(firstTokenIndex - 1) === desiredLanguageId) {\n        firstTokenIndex--;\n    }\n    return new ScopedLineTokens(context, desiredLanguageId, firstTokenIndex, lastTokenIndex + 1, context.getStartOffset(firstTokenIndex), context.getEndOffset(lastTokenIndex));\n}\nexport class ScopedLineTokens {\n    constructor(actual, languageId, firstTokenIndex, lastTokenIndex, firstCharOffset, lastCharOffset) {\n        this._scopedLineTokensBrand = undefined;\n        this._actual = actual;\n        this.languageId = languageId;\n        this._firstTokenIndex = firstTokenIndex;\n        this._lastTokenIndex = lastTokenIndex;\n        this.firstCharOffset = firstCharOffset;\n        this._lastCharOffset = lastCharOffset;\n    }\n    getLineContent() {\n        const actualLineContent = this._actual.getLineContent();\n        return actualLineContent.substring(this.firstCharOffset, this._lastCharOffset);\n    }\n    getActualLineContentBefore(offset) {\n        const actualLineContent = this._actual.getLineContent();\n        return actualLineContent.substring(0, this.firstCharOffset + offset);\n    }\n    getTokenCount() {\n        return this._lastTokenIndex - this._firstTokenIndex;\n    }\n    findTokenIndexAtOffset(offset) {\n        return this._actual.findTokenIndexAtOffset(offset + this.firstCharOffset) - this._firstTokenIndex;\n    }\n    getStandardTokenType(tokenIndex) {\n        return this._actual.getStandardTokenType(tokenIndex + this._firstTokenIndex);\n    }\n}\nexport function ignoreBracketsInToken(standardTokenType) {\n    return (standardTokenType & 3 /* IgnoreBracketsInTokens.value */) !== 0;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { StandardAutoClosingPairConditional } from '../languageConfiguration.js';\nexport class CharacterPairSupport {\n    constructor(config) {\n        if (config.autoClosingPairs) {\n            this._autoClosingPairs = config.autoClosingPairs.map(el => new StandardAutoClosingPairConditional(el));\n        }\n        else if (config.brackets) {\n            this._autoClosingPairs = config.brackets.map(b => new StandardAutoClosingPairConditional({ open: b[0], close: b[1] }));\n        }\n        else {\n            this._autoClosingPairs = [];\n        }\n        if (config.__electricCharacterSupport && config.__electricCharacterSupport.docComment) {\n            const docComment = config.__electricCharacterSupport.docComment;\n            // IDocComment is legacy, only partially supported\n            this._autoClosingPairs.push(new StandardAutoClosingPairConditional({ open: docComment.open, close: docComment.close || '' }));\n        }\n        this._autoCloseBeforeForQuotes = typeof config.autoCloseBefore === 'string' ? config.autoCloseBefore : CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED_QUOTES;\n        this._autoCloseBeforeForBrackets = typeof config.autoCloseBefore === 'string' ? config.autoCloseBefore : CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED_BRACKETS;\n        this._surroundingPairs = config.surroundingPairs || this._autoClosingPairs;\n    }\n    getAutoClosingPairs() {\n        return this._autoClosingPairs;\n    }\n    getAutoCloseBeforeSet(forQuotes) {\n        return (forQuotes ? this._autoCloseBeforeForQuotes : this._autoCloseBeforeForBrackets);\n    }\n    getSurroundingPairs() {\n        return this._surroundingPairs;\n    }\n}\nCharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED_QUOTES = ';:.,=}])> \\n\\t';\nCharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED_BRACKETS = '\\'\"`;:.,=}])> \\n\\t';\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Lazy } from './lazy.js';\nconst hasBuffer = (typeof Buffer !== 'undefined');\nconst indexOfTable = new Lazy(() => new Uint8Array(256));\nlet textDecoder;\nexport class VSBuffer {\n    /**\n     * When running in a nodejs context, if `actual` is not a nodejs Buffer, the backing store for\n     * the returned `VSBuffer` instance might use a nodejs Buffer allocated from node's Buffer pool,\n     * which is not transferrable.\n     */\n    static wrap(actual) {\n        if (hasBuffer && !(Buffer.isBuffer(actual))) {\n            // https://nodejs.org/dist/latest-v10.x/docs/api/buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length\n            // Create a zero-copy Buffer wrapper around the ArrayBuffer pointed to by the Uint8Array\n            actual = Buffer.from(actual.buffer, actual.byteOffset, actual.byteLength);\n        }\n        return new VSBuffer(actual);\n    }\n    constructor(buffer) {\n        this.buffer = buffer;\n        this.byteLength = this.buffer.byteLength;\n    }\n    toString() {\n        if (hasBuffer) {\n            return this.buffer.toString();\n        }\n        else {\n            if (!textDecoder) {\n                textDecoder = new TextDecoder();\n            }\n            return textDecoder.decode(this.buffer);\n        }\n    }\n}\nexport function readUInt16LE(source, offset) {\n    return (((source[offset + 0] << 0) >>> 0) |\n        ((source[offset + 1] << 8) >>> 0));\n}\nexport function writeUInt16LE(destination, value, offset) {\n    destination[offset + 0] = (value & 0b11111111);\n    value = value >>> 8;\n    destination[offset + 1] = (value & 0b11111111);\n}\nexport function readUInt32BE(source, offset) {\n    return (source[offset] * Math.pow(2, 24)\n        + source[offset + 1] * Math.pow(2, 16)\n        + source[offset + 2] * Math.pow(2, 8)\n        + source[offset + 3]);\n}\nexport function writeUInt32BE(destination, value, offset) {\n    destination[offset + 3] = value;\n    value = value >>> 8;\n    destination[offset + 2] = value;\n    value = value >>> 8;\n    destination[offset + 1] = value;\n    value = value >>> 8;\n    destination[offset] = value;\n}\nexport function readUInt8(source, offset) {\n    return source[offset];\n}\nexport function writeUInt8(destination, value, offset) {\n    destination[offset] = value;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../../base/common/strings.js';\nimport * as platform from '../../../base/common/platform.js';\nimport * as buffer from '../../../base/common/buffer.js';\nlet _utf16LE_TextDecoder;\nfunction getUTF16LE_TextDecoder() {\n    if (!_utf16LE_TextDecoder) {\n        _utf16LE_TextDecoder = new TextDecoder('UTF-16LE');\n    }\n    return _utf16LE_TextDecoder;\n}\nlet _utf16BE_TextDecoder;\nfunction getUTF16BE_TextDecoder() {\n    if (!_utf16BE_TextDecoder) {\n        _utf16BE_TextDecoder = new TextDecoder('UTF-16BE');\n    }\n    return _utf16BE_TextDecoder;\n}\nlet _platformTextDecoder;\nexport function getPlatformTextDecoder() {\n    if (!_platformTextDecoder) {\n        _platformTextDecoder = platform.isLittleEndian() ? getUTF16LE_TextDecoder() : getUTF16BE_TextDecoder();\n    }\n    return _platformTextDecoder;\n}\nexport function decodeUTF16LE(source, offset, len) {\n    const view = new Uint16Array(source.buffer, offset, len);\n    if (len > 0 && (view[0] === 0xFEFF || view[0] === 0xFFFE)) {\n        // UTF16 sometimes starts with a BOM https://de.wikipedia.org/wiki/Byte_Order_Mark\n        // It looks like TextDecoder.decode will eat up a leading BOM (0xFEFF or 0xFFFE)\n        // We don't want that behavior because we know the string is UTF16LE and the BOM should be maintained\n        // So we use the manual decoder\n        return compatDecodeUTF16LE(source, offset, len);\n    }\n    return getUTF16LE_TextDecoder().decode(view);\n}\nfunction compatDecodeUTF16LE(source, offset, len) {\n    const result = [];\n    let resultLen = 0;\n    for (let i = 0; i < len; i++) {\n        const charCode = buffer.readUInt16LE(source, offset);\n        offset += 2;\n        result[resultLen++] = String.fromCharCode(charCode);\n    }\n    return result.join('');\n}\nexport class StringBuilder {\n    constructor(capacity) {\n        this._capacity = capacity | 0;\n        this._buffer = new Uint16Array(this._capacity);\n        this._completedStrings = null;\n        this._bufferLength = 0;\n    }\n    reset() {\n        this._completedStrings = null;\n        this._bufferLength = 0;\n    }\n    build() {\n        if (this._completedStrings !== null) {\n            this._flushBuffer();\n            return this._completedStrings.join('');\n        }\n        return this._buildBuffer();\n    }\n    _buildBuffer() {\n        if (this._bufferLength === 0) {\n            return '';\n        }\n        const view = new Uint16Array(this._buffer.buffer, 0, this._bufferLength);\n        return getPlatformTextDecoder().decode(view);\n    }\n    _flushBuffer() {\n        const bufferString = this._buildBuffer();\n        this._bufferLength = 0;\n        if (this._completedStrings === null) {\n            this._completedStrings = [bufferString];\n        }\n        else {\n            this._completedStrings[this._completedStrings.length] = bufferString;\n        }\n    }\n    /**\n     * Append a char code (<2^16)\n     */\n    appendCharCode(charCode) {\n        const remainingSpace = this._capacity - this._bufferLength;\n        if (remainingSpace <= 1) {\n            if (remainingSpace === 0 || strings.isHighSurrogate(charCode)) {\n                this._flushBuffer();\n            }\n        }\n        this._buffer[this._bufferLength++] = charCode;\n    }\n    /**\n     * Append an ASCII char code (<2^8)\n     */\n    appendASCIICharCode(charCode) {\n        if (this._bufferLength === this._capacity) {\n            // buffer is full\n            this._flushBuffer();\n        }\n        this._buffer[this._bufferLength++] = charCode;\n    }\n    appendString(str) {\n        const strLen = str.length;\n        if (this._bufferLength + strLen >= this._capacity) {\n            // This string does not fit in the remaining buffer space\n            this._flushBuffer();\n            this._completedStrings[this._completedStrings.length] = str;\n            return;\n        }\n        for (let i = 0; i < strLen; i++) {\n            this._buffer[this._bufferLength++] = str.charCodeAt(i);\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../../../base/common/strings.js';\nimport * as stringBuilder from '../../core/stringBuilder.js';\nimport { Range } from '../../core/range.js';\n/**\n * Represents a grouping of colliding bracket pairs.\n *\n * Most of the times this contains a single bracket pair,\n * but sometimes this contains multiple bracket pairs in cases\n * where the same string appears as a closing bracket for multiple\n * bracket pairs, or the same string appears an opening bracket for\n * multiple bracket pairs.\n *\n * e.g. of a group containing a single pair:\n *   open: ['{'], close: ['}']\n *\n * e.g. of a group containing multiple pairs:\n *   open: ['if', 'for'], close: ['end', 'end']\n */\nexport class RichEditBracket {\n    constructor(languageId, index, open, close, forwardRegex, reversedRegex) {\n        this._richEditBracketBrand = undefined;\n        this.languageId = languageId;\n        this.index = index;\n        this.open = open;\n        this.close = close;\n        this.forwardRegex = forwardRegex;\n        this.reversedRegex = reversedRegex;\n        this._openSet = RichEditBracket._toSet(this.open);\n        this._closeSet = RichEditBracket._toSet(this.close);\n    }\n    /**\n     * Check if the provided `text` is an open bracket in this group.\n     */\n    isOpen(text) {\n        return this._openSet.has(text);\n    }\n    /**\n     * Check if the provided `text` is a close bracket in this group.\n     */\n    isClose(text) {\n        return this._closeSet.has(text);\n    }\n    static _toSet(arr) {\n        const result = new Set();\n        for (const element of arr) {\n            result.add(element);\n        }\n        return result;\n    }\n}\n/**\n * Groups together brackets that have equal open or close sequences.\n *\n * For example, if the following brackets are defined:\n *   ['IF','END']\n *   ['for','end']\n *   ['{','}']\n *\n * Then the grouped brackets would be:\n *   { open: ['if', 'for'], close: ['end', 'end'] }\n *   { open: ['{'], close: ['}'] }\n *\n */\nfunction groupFuzzyBrackets(brackets) {\n    const N = brackets.length;\n    brackets = brackets.map(b => [b[0].toLowerCase(), b[1].toLowerCase()]);\n    const group = [];\n    for (let i = 0; i < N; i++) {\n        group[i] = i;\n    }\n    const areOverlapping = (a, b) => {\n        const [aOpen, aClose] = a;\n        const [bOpen, bClose] = b;\n        return (aOpen === bOpen || aOpen === bClose || aClose === bOpen || aClose === bClose);\n    };\n    const mergeGroups = (g1, g2) => {\n        const newG = Math.min(g1, g2);\n        const oldG = Math.max(g1, g2);\n        for (let i = 0; i < N; i++) {\n            if (group[i] === oldG) {\n                group[i] = newG;\n            }\n        }\n    };\n    // group together brackets that have the same open or the same close sequence\n    for (let i = 0; i < N; i++) {\n        const a = brackets[i];\n        for (let j = i + 1; j < N; j++) {\n            const b = brackets[j];\n            if (areOverlapping(a, b)) {\n                mergeGroups(group[i], group[j]);\n            }\n        }\n    }\n    const result = [];\n    for (let g = 0; g < N; g++) {\n        const currentOpen = [];\n        const currentClose = [];\n        for (let i = 0; i < N; i++) {\n            if (group[i] === g) {\n                const [open, close] = brackets[i];\n                currentOpen.push(open);\n                currentClose.push(close);\n            }\n        }\n        if (currentOpen.length > 0) {\n            result.push({\n                open: currentOpen,\n                close: currentClose\n            });\n        }\n    }\n    return result;\n}\nexport class RichEditBrackets {\n    constructor(languageId, _brackets) {\n        this._richEditBracketsBrand = undefined;\n        const brackets = groupFuzzyBrackets(_brackets);\n        this.brackets = brackets.map((b, index) => {\n            return new RichEditBracket(languageId, index, b.open, b.close, getRegexForBracketPair(b.open, b.close, brackets, index), getReversedRegexForBracketPair(b.open, b.close, brackets, index));\n        });\n        this.forwardRegex = getRegexForBrackets(this.brackets);\n        this.reversedRegex = getReversedRegexForBrackets(this.brackets);\n        this.textIsBracket = {};\n        this.textIsOpenBracket = {};\n        this.maxBracketLength = 0;\n        for (const bracket of this.brackets) {\n            for (const open of bracket.open) {\n                this.textIsBracket[open] = bracket;\n                this.textIsOpenBracket[open] = true;\n                this.maxBracketLength = Math.max(this.maxBracketLength, open.length);\n            }\n            for (const close of bracket.close) {\n                this.textIsBracket[close] = bracket;\n                this.textIsOpenBracket[close] = false;\n                this.maxBracketLength = Math.max(this.maxBracketLength, close.length);\n            }\n        }\n    }\n}\nfunction collectSuperstrings(str, brackets, currentIndex, dest) {\n    for (let i = 0, len = brackets.length; i < len; i++) {\n        if (i === currentIndex) {\n            continue;\n        }\n        const bracket = brackets[i];\n        for (const open of bracket.open) {\n            if (open.indexOf(str) >= 0) {\n                dest.push(open);\n            }\n        }\n        for (const close of bracket.close) {\n            if (close.indexOf(str) >= 0) {\n                dest.push(close);\n            }\n        }\n    }\n}\nfunction lengthcmp(a, b) {\n    return a.length - b.length;\n}\nfunction unique(arr) {\n    if (arr.length <= 1) {\n        return arr;\n    }\n    const result = [];\n    const seen = new Set();\n    for (const element of arr) {\n        if (seen.has(element)) {\n            continue;\n        }\n        result.push(element);\n        seen.add(element);\n    }\n    return result;\n}\n/**\n * Create a regular expression that can be used to search forward in a piece of text\n * for a group of bracket pairs. But this regex must be built in a way in which\n * it is aware of the other bracket pairs defined for the language.\n *\n * For example, if a language contains the following bracket pairs:\n *   ['begin', 'end']\n *   ['if', 'end if']\n * The two bracket pairs do not collide because no open or close brackets are equal.\n * So the function getRegexForBracketPair is called twice, once with\n * the ['begin'], ['end'] group consisting of one bracket pair, and once with\n * the ['if'], ['end if'] group consiting of the other bracket pair.\n *\n * But there could be a situation where an occurrence of 'end if' is mistaken\n * for an occurrence of 'end'.\n *\n * Therefore, for the bracket pair ['begin', 'end'], the regex will also\n * target 'end if'. The regex will be something like:\n *   /(\\bend if\\b)|(\\bend\\b)|(\\bif\\b)/\n *\n * The regex also searches for \"superstrings\" (other brackets that might be mistaken with the current bracket).\n *\n */\nfunction getRegexForBracketPair(open, close, brackets, currentIndex) {\n    // search in all brackets for other brackets that are a superstring of these brackets\n    let pieces = [];\n    pieces = pieces.concat(open);\n    pieces = pieces.concat(close);\n    for (let i = 0, len = pieces.length; i < len; i++) {\n        collectSuperstrings(pieces[i], brackets, currentIndex, pieces);\n    }\n    pieces = unique(pieces);\n    pieces.sort(lengthcmp);\n    pieces.reverse();\n    return createBracketOrRegExp(pieces);\n}\n/**\n * Matching a regular expression in JS can only be done \"forwards\". So JS offers natively only\n * methods to find the first match of a regex in a string. But sometimes, it is useful to\n * find the last match of a regex in a string. For such a situation, a nice solution is to\n * simply reverse the string and then search for a reversed regex.\n *\n * This function also has the fine details of `getRegexForBracketPair`. For the same example\n * given above, the regex produced here would look like:\n *   /(\\bfi dne\\b)|(\\bdne\\b)|(\\bfi\\b)/\n */\nfunction getReversedRegexForBracketPair(open, close, brackets, currentIndex) {\n    // search in all brackets for other brackets that are a superstring of these brackets\n    let pieces = [];\n    pieces = pieces.concat(open);\n    pieces = pieces.concat(close);\n    for (let i = 0, len = pieces.length; i < len; i++) {\n        collectSuperstrings(pieces[i], brackets, currentIndex, pieces);\n    }\n    pieces = unique(pieces);\n    pieces.sort(lengthcmp);\n    pieces.reverse();\n    return createBracketOrRegExp(pieces.map(toReversedString));\n}\n/**\n * Creates a regular expression that targets all bracket pairs.\n *\n * e.g. for the bracket pairs:\n *  ['{','}']\n *  ['begin,'end']\n *  ['for','end']\n * the regex would look like:\n *  /(\\{)|(\\})|(\\bbegin\\b)|(\\bend\\b)|(\\bfor\\b)/\n */\nfunction getRegexForBrackets(brackets) {\n    let pieces = [];\n    for (const bracket of brackets) {\n        for (const open of bracket.open) {\n            pieces.push(open);\n        }\n        for (const close of bracket.close) {\n            pieces.push(close);\n        }\n    }\n    pieces = unique(pieces);\n    return createBracketOrRegExp(pieces);\n}\n/**\n * Matching a regular expression in JS can only be done \"forwards\". So JS offers natively only\n * methods to find the first match of a regex in a string. But sometimes, it is useful to\n * find the last match of a regex in a string. For such a situation, a nice solution is to\n * simply reverse the string and then search for a reversed regex.\n *\n * e.g. for the bracket pairs:\n *  ['{','}']\n *  ['begin,'end']\n *  ['for','end']\n * the regex would look like:\n *  /(\\{)|(\\})|(\\bnigeb\\b)|(\\bdne\\b)|(\\brof\\b)/\n */\nfunction getReversedRegexForBrackets(brackets) {\n    let pieces = [];\n    for (const bracket of brackets) {\n        for (const open of bracket.open) {\n            pieces.push(open);\n        }\n        for (const close of bracket.close) {\n            pieces.push(close);\n        }\n    }\n    pieces = unique(pieces);\n    return createBracketOrRegExp(pieces.map(toReversedString));\n}\nfunction prepareBracketForRegExp(str) {\n    // This bracket pair uses letters like e.g. \"begin\" - \"end\"\n    const insertWordBoundaries = (/^[\\w ]+$/.test(str));\n    str = strings.escapeRegExpCharacters(str);\n    return (insertWordBoundaries ? `\\\\b${str}\\\\b` : str);\n}\nfunction createBracketOrRegExp(pieces) {\n    const regexStr = `(${pieces.map(prepareBracketForRegExp).join(')|(')})`;\n    return strings.createRegExp(regexStr, true);\n}\nconst toReversedString = (function () {\n    function reverse(str) {\n        // create a Uint16Array and then use a TextDecoder to create a string\n        const arr = new Uint16Array(str.length);\n        let offset = 0;\n        for (let i = str.length - 1; i >= 0; i--) {\n            arr[offset++] = str.charCodeAt(i);\n        }\n        return stringBuilder.getPlatformTextDecoder().decode(arr);\n    }\n    let lastInput = null;\n    let lastOutput = null;\n    return function toReversedString(str) {\n        if (lastInput !== str) {\n            lastInput = str;\n            lastOutput = reverse(lastInput);\n        }\n        return lastOutput;\n    };\n})();\nexport class BracketsUtils {\n    static _findPrevBracketInText(reversedBracketRegex, lineNumber, reversedText, offset) {\n        const m = reversedText.match(reversedBracketRegex);\n        if (!m) {\n            return null;\n        }\n        const matchOffset = reversedText.length - (m.index || 0);\n        const matchLength = m[0].length;\n        const absoluteMatchOffset = offset + matchOffset;\n        return new Range(lineNumber, absoluteMatchOffset - matchLength + 1, lineNumber, absoluteMatchOffset + 1);\n    }\n    static findPrevBracketInRange(reversedBracketRegex, lineNumber, lineText, startOffset, endOffset) {\n        // Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;)\n        const reversedLineText = toReversedString(lineText);\n        const reversedSubstr = reversedLineText.substring(lineText.length - endOffset, lineText.length - startOffset);\n        return this._findPrevBracketInText(reversedBracketRegex, lineNumber, reversedSubstr, startOffset);\n    }\n    static findNextBracketInText(bracketRegex, lineNumber, text, offset) {\n        const m = text.match(bracketRegex);\n        if (!m) {\n            return null;\n        }\n        const matchOffset = m.index || 0;\n        const matchLength = m[0].length;\n        if (matchLength === 0) {\n            return null;\n        }\n        const absoluteMatchOffset = offset + matchOffset;\n        return new Range(lineNumber, absoluteMatchOffset + 1, lineNumber, absoluteMatchOffset + 1 + matchLength);\n    }\n    static findNextBracketInRange(bracketRegex, lineNumber, lineText, startOffset, endOffset) {\n        const substr = lineText.substring(startOffset, endOffset);\n        return this.findNextBracketInText(bracketRegex, lineNumber, substr, startOffset);\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { distinct } from '../../../../base/common/arrays.js';\nimport { ignoreBracketsInToken } from '../supports.js';\nimport { BracketsUtils } from './richEditBrackets.js';\nexport class BracketElectricCharacterSupport {\n    constructor(richEditBrackets) {\n        this._richEditBrackets = richEditBrackets;\n    }\n    getElectricCharacters() {\n        const result = [];\n        if (this._richEditBrackets) {\n            for (const bracket of this._richEditBrackets.brackets) {\n                for (const close of bracket.close) {\n                    const lastChar = close.charAt(close.length - 1);\n                    result.push(lastChar);\n                }\n            }\n        }\n        return distinct(result);\n    }\n    onElectricCharacter(character, context, column) {\n        if (!this._richEditBrackets || this._richEditBrackets.brackets.length === 0) {\n            return null;\n        }\n        const tokenIndex = context.findTokenIndexAtOffset(column - 1);\n        if (ignoreBracketsInToken(context.getStandardTokenType(tokenIndex))) {\n            return null;\n        }\n        const reversedBracketRegex = this._richEditBrackets.reversedRegex;\n        const text = context.getLineContent().substring(0, column - 1) + character;\n        const r = BracketsUtils.findPrevBracketInRange(reversedBracketRegex, 1, text, 0, text.length);\n        if (!r) {\n            return null;\n        }\n        const bracketText = text.substring(r.startColumn - 1, r.endColumn - 1).toLowerCase();\n        const isOpen = this._richEditBrackets.textIsOpenBracket[bracketText];\n        if (isOpen) {\n            return null;\n        }\n        const textBeforeBracket = context.getActualLineContentBefore(r.startColumn - 1);\n        if (!/^\\s*$/.test(textBeforeBracket)) {\n            // There is other text on the line before the bracket\n            return null;\n        }\n        return {\n            matchOpenBracket: bracketText\n        };\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nfunction resetGlobalRegex(reg) {\n    if (reg.global) {\n        reg.lastIndex = 0;\n    }\n    return true;\n}\nexport class IndentRulesSupport {\n    constructor(indentationRules) {\n        this._indentationRules = indentationRules;\n    }\n    shouldIncrease(text) {\n        if (this._indentationRules) {\n            if (this._indentationRules.increaseIndentPattern && resetGlobalRegex(this._indentationRules.increaseIndentPattern) && this._indentationRules.increaseIndentPattern.test(text)) {\n                return true;\n            }\n            // if (this._indentationRules.indentNextLinePattern && this._indentationRules.indentNextLinePattern.test(text)) {\n            // \treturn true;\n            // }\n        }\n        return false;\n    }\n    shouldDecrease(text) {\n        if (this._indentationRules && this._indentationRules.decreaseIndentPattern && resetGlobalRegex(this._indentationRules.decreaseIndentPattern) && this._indentationRules.decreaseIndentPattern.test(text)) {\n            return true;\n        }\n        return false;\n    }\n    shouldIndentNextLine(text) {\n        if (this._indentationRules && this._indentationRules.indentNextLinePattern && resetGlobalRegex(this._indentationRules.indentNextLinePattern) && this._indentationRules.indentNextLinePattern.test(text)) {\n            return true;\n        }\n        return false;\n    }\n    shouldIgnore(text) {\n        // the text matches `unIndentedLinePattern`\n        if (this._indentationRules && this._indentationRules.unIndentedLinePattern && resetGlobalRegex(this._indentationRules.unIndentedLinePattern) && this._indentationRules.unIndentedLinePattern.test(text)) {\n            return true;\n        }\n        return false;\n    }\n    getIndentMetadata(text) {\n        let ret = 0;\n        if (this.shouldIncrease(text)) {\n            ret += 1 /* IndentConsts.INCREASE_MASK */;\n        }\n        if (this.shouldDecrease(text)) {\n            ret += 2 /* IndentConsts.DECREASE_MASK */;\n        }\n        if (this.shouldIndentNextLine(text)) {\n            ret += 4 /* IndentConsts.INDENT_NEXTLINE_MASK */;\n        }\n        if (this.shouldIgnore(text)) {\n            ret += 8 /* IndentConsts.UNINDENT_MASK */;\n        }\n        return ret;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { onUnexpectedError } from '../../../../base/common/errors.js';\nimport * as strings from '../../../../base/common/strings.js';\nimport { IndentAction } from '../languageConfiguration.js';\nexport class OnEnterSupport {\n    constructor(opts) {\n        opts = opts || {};\n        opts.brackets = opts.brackets || [\n            ['(', ')'],\n            ['{', '}'],\n            ['[', ']']\n        ];\n        this._brackets = [];\n        opts.brackets.forEach((bracket) => {\n            const openRegExp = OnEnterSupport._createOpenBracketRegExp(bracket[0]);\n            const closeRegExp = OnEnterSupport._createCloseBracketRegExp(bracket[1]);\n            if (openRegExp && closeRegExp) {\n                this._brackets.push({\n                    open: bracket[0],\n                    openRegExp: openRegExp,\n                    close: bracket[1],\n                    closeRegExp: closeRegExp,\n                });\n            }\n        });\n        this._regExpRules = opts.onEnterRules || [];\n    }\n    onEnter(autoIndent, previousLineText, beforeEnterText, afterEnterText) {\n        // (1): `regExpRules`\n        if (autoIndent >= 3 /* EditorAutoIndentStrategy.Advanced */) {\n            for (let i = 0, len = this._regExpRules.length; i < len; i++) {\n                const rule = this._regExpRules[i];\n                const regResult = [{\n                        reg: rule.beforeText,\n                        text: beforeEnterText\n                    }, {\n                        reg: rule.afterText,\n                        text: afterEnterText\n                    }, {\n                        reg: rule.previousLineText,\n                        text: previousLineText\n                    }].every((obj) => {\n                    if (!obj.reg) {\n                        return true;\n                    }\n                    obj.reg.lastIndex = 0; // To disable the effect of the \"g\" flag.\n                    return obj.reg.test(obj.text);\n                });\n                if (regResult) {\n                    return rule.action;\n                }\n            }\n        }\n        // (2): Special indent-outdent\n        if (autoIndent >= 2 /* EditorAutoIndentStrategy.Brackets */) {\n            if (beforeEnterText.length > 0 && afterEnterText.length > 0) {\n                for (let i = 0, len = this._brackets.length; i < len; i++) {\n                    const bracket = this._brackets[i];\n                    if (bracket.openRegExp.test(beforeEnterText) && bracket.closeRegExp.test(afterEnterText)) {\n                        return { indentAction: IndentAction.IndentOutdent };\n                    }\n                }\n            }\n        }\n        // (4): Open bracket based logic\n        if (autoIndent >= 2 /* EditorAutoIndentStrategy.Brackets */) {\n            if (beforeEnterText.length > 0) {\n                for (let i = 0, len = this._brackets.length; i < len; i++) {\n                    const bracket = this._brackets[i];\n                    if (bracket.openRegExp.test(beforeEnterText)) {\n                        return { indentAction: IndentAction.Indent };\n                    }\n                }\n            }\n        }\n        return null;\n    }\n    static _createOpenBracketRegExp(bracket) {\n        let str = strings.escapeRegExpCharacters(bracket);\n        if (!/\\B/.test(str.charAt(0))) {\n            str = '\\\\b' + str;\n        }\n        str += '\\\\s*$';\n        return OnEnterSupport._safeRegExp(str);\n    }\n    static _createCloseBracketRegExp(bracket) {\n        let str = strings.escapeRegExpCharacters(bracket);\n        if (!/\\B/.test(str.charAt(str.length - 1))) {\n            str = str + '\\\\b';\n        }\n        str = '^\\\\s*' + str;\n        return OnEnterSupport._safeRegExp(str);\n    }\n    static _safeRegExp(def) {\n        try {\n            return new RegExp(def);\n        }\n        catch (err) {\n            onUnexpectedError(err);\n            return null;\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { createDecorator } from '../../instantiation/common/instantiation.js';\nexport const IConfigurationService = createDecorator('configurationService');\nexport function toValuesTree(properties, conflictReporter) {\n    const root = Object.create(null);\n    for (const key in properties) {\n        addToValueTree(root, key, properties[key], conflictReporter);\n    }\n    return root;\n}\nexport function addToValueTree(settingsTreeRoot, key, value, conflictReporter) {\n    const segments = key.split('.');\n    const last = segments.pop();\n    let curr = settingsTreeRoot;\n    for (let i = 0; i < segments.length; i++) {\n        const s = segments[i];\n        let obj = curr[s];\n        switch (typeof obj) {\n            case 'undefined':\n                obj = curr[s] = Object.create(null);\n                break;\n            case 'object':\n                break;\n            default:\n                conflictReporter(`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is ${JSON.stringify(obj)}`);\n                return;\n        }\n        curr = obj;\n    }\n    if (typeof curr === 'object' && curr !== null) {\n        try {\n            curr[last] = value; // workaround https://github.com/microsoft/vscode/issues/13606\n        }\n        catch (e) {\n            conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);\n        }\n    }\n    else {\n        conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);\n    }\n}\nexport function removeFromValueTree(valueTree, key) {\n    const segments = key.split('.');\n    doRemoveFromValueTree(valueTree, segments);\n}\nfunction doRemoveFromValueTree(valueTree, segments) {\n    const first = segments.shift();\n    if (segments.length === 0) {\n        // Reached last segment\n        delete valueTree[first];\n        return;\n    }\n    if (Object.keys(valueTree).indexOf(first) !== -1) {\n        const value = valueTree[first];\n        if (typeof value === 'object' && !Array.isArray(value)) {\n            doRemoveFromValueTree(value, segments);\n            if (Object.keys(value).length === 0) {\n                delete valueTree[first];\n            }\n        }\n    }\n}\n/**\n * A helper function to get the configuration value with a specific settings path (e.g. config.some.setting)\n */\nexport function getConfigurationValue(config, settingPath, defaultValue) {\n    function accessSetting(config, path) {\n        let current = config;\n        for (const component of path) {\n            if (typeof current !== 'object' || current === null) {\n                return undefined;\n            }\n            current = current[component];\n        }\n        return current;\n    }\n    const path = settingPath.split('.');\n    const result = accessSetting(config, path);\n    return typeof result === 'undefined' ? defaultValue : result;\n}\nexport function getLanguageTagSettingPlainKey(settingKey) {\n    return settingKey.replace(/[\\[\\]]/g, '');\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { createDecorator } from '../../../platform/instantiation/common/instantiation.js';\nexport const ILanguageService = createDecorator('languageService');\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport class SyncDescriptor {\n    constructor(ctor, staticArguments = [], supportsDelayedInstantiation = false) {\n        this.ctor = ctor;\n        this.staticArguments = staticArguments;\n        this.supportsDelayedInstantiation = supportsDelayedInstantiation;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { SyncDescriptor } from './descriptors.js';\nconst _registry = [];\nexport function registerSingleton(id, ctorOrDescriptor, supportsDelayedInstantiation) {\n    if (!(ctorOrDescriptor instanceof SyncDescriptor)) {\n        ctorOrDescriptor = new SyncDescriptor(ctorOrDescriptor, [], Boolean(supportsDelayedInstantiation));\n    }\n    _registry.push([id, ctorOrDescriptor]);\n}\nexport function getSingletonServiceDescriptors() {\n    return _registry;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as Assert from '../../../base/common/assert.js';\nimport * as Types from '../../../base/common/types.js';\nclass RegistryImpl {\n    constructor() {\n        this.data = new Map();\n    }\n    add(id, data) {\n        Assert.ok(Types.isString(id));\n        Assert.ok(Types.isObject(data));\n        Assert.ok(!this.data.has(id), 'There is already an extension with this id');\n        this.data.set(id, data);\n    }\n    as(id) {\n        return this.data.get(id) || null;\n    }\n}\nexport const Registry = new RegistryImpl();\n","export const Mimes = Object.freeze({\n    text: 'text/plain',\n    binary: 'application/octet-stream',\n    unknown: 'application/unknown',\n    markdown: 'text/markdown',\n    latex: 'text/latex',\n    uriList: 'text/uri-list',\n});\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Emitter } from '../../../base/common/event.js';\nimport * as platform from '../../registry/common/platform.js';\nexport const Extensions = {\n    JSONContribution: 'base.contributions.json'\n};\nfunction normalizeId(id) {\n    if (id.length > 0 && id.charAt(id.length - 1) === '#') {\n        return id.substring(0, id.length - 1);\n    }\n    return id;\n}\nclass JSONContributionRegistry {\n    constructor() {\n        this._onDidChangeSchema = new Emitter();\n        this.schemasById = {};\n    }\n    registerSchema(uri, unresolvedSchemaContent) {\n        this.schemasById[normalizeId(uri)] = unresolvedSchemaContent;\n        this._onDidChangeSchema.fire(uri);\n    }\n    notifySchemaChanged(uri) {\n        this._onDidChangeSchema.fire(uri);\n    }\n}\nconst jsonContributionRegistry = new JSONContributionRegistry();\nplatform.Registry.add(Extensions.JSONContribution, jsonContributionRegistry);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { distinct } from '../../../base/common/arrays.js';\nimport { Emitter } from '../../../base/common/event.js';\nimport * as types from '../../../base/common/types.js';\nimport * as nls from '../../../nls.js';\nimport { getLanguageTagSettingPlainKey } from './configuration.js';\nimport { Extensions as JSONExtensions } from '../../jsonschemas/common/jsonContributionRegistry.js';\nimport { Registry } from '../../registry/common/platform.js';\nexport const Extensions = {\n    Configuration: 'base.contributions.configuration'\n};\nexport const allSettings = { properties: {}, patternProperties: {} };\nexport const applicationSettings = { properties: {}, patternProperties: {} };\nexport const machineSettings = { properties: {}, patternProperties: {} };\nexport const machineOverridableSettings = { properties: {}, patternProperties: {} };\nexport const windowSettings = { properties: {}, patternProperties: {} };\nexport const resourceSettings = { properties: {}, patternProperties: {} };\nexport const resourceLanguageSettingsSchemaId = 'vscode://schemas/settings/resourceLanguage';\nconst contributionRegistry = Registry.as(JSONExtensions.JSONContribution);\nclass ConfigurationRegistry {\n    constructor() {\n        this.overrideIdentifiers = new Set();\n        this._onDidSchemaChange = new Emitter();\n        this._onDidUpdateConfiguration = new Emitter();\n        this.configurationDefaultsOverrides = new Map();\n        this.defaultLanguageConfigurationOverridesNode = {\n            id: 'defaultOverrides',\n            title: nls.localize('defaultLanguageConfigurationOverrides.title', \"Default Language Configuration Overrides\"),\n            properties: {}\n        };\n        this.configurationContributors = [this.defaultLanguageConfigurationOverridesNode];\n        this.resourceLanguageSettingsSchema = {\n            properties: {},\n            patternProperties: {},\n            additionalProperties: true,\n            allowTrailingCommas: true,\n            allowComments: true\n        };\n        this.configurationProperties = {};\n        this.policyConfigurations = new Map();\n        this.excludedConfigurationProperties = {};\n        contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);\n        this.registerOverridePropertyPatternKey();\n    }\n    registerConfiguration(configuration, validate = true) {\n        this.registerConfigurations([configuration], validate);\n    }\n    registerConfigurations(configurations, validate = true) {\n        const properties = new Set();\n        this.doRegisterConfigurations(configurations, validate, properties);\n        contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);\n        this._onDidSchemaChange.fire();\n        this._onDidUpdateConfiguration.fire({ properties });\n    }\n    registerDefaultConfigurations(configurationDefaults) {\n        const properties = new Set();\n        this.doRegisterDefaultConfigurations(configurationDefaults, properties);\n        this._onDidSchemaChange.fire();\n        this._onDidUpdateConfiguration.fire({ properties, defaultsOverrides: true });\n    }\n    doRegisterDefaultConfigurations(configurationDefaults, bucket) {\n        var _a;\n        const overrideIdentifiers = [];\n        for (const { overrides, source } of configurationDefaults) {\n            for (const key in overrides) {\n                bucket.add(key);\n                if (OVERRIDE_PROPERTY_REGEX.test(key)) {\n                    const configurationDefaultOverride = this.configurationDefaultsOverrides.get(key);\n                    const valuesSources = (_a = configurationDefaultOverride === null || configurationDefaultOverride === void 0 ? void 0 : configurationDefaultOverride.valuesSources) !== null && _a !== void 0 ? _a : new Map();\n                    if (source) {\n                        for (const configuration of Object.keys(overrides[key])) {\n                            valuesSources.set(configuration, source);\n                        }\n                    }\n                    const defaultValue = Object.assign(Object.assign({}, ((configurationDefaultOverride === null || configurationDefaultOverride === void 0 ? void 0 : configurationDefaultOverride.value) || {})), overrides[key]);\n                    this.configurationDefaultsOverrides.set(key, { source, value: defaultValue, valuesSources });\n                    const plainKey = getLanguageTagSettingPlainKey(key);\n                    const property = {\n                        type: 'object',\n                        default: defaultValue,\n                        description: nls.localize('defaultLanguageConfiguration.description', \"Configure settings to be overridden for the {0} language.\", plainKey),\n                        $ref: resourceLanguageSettingsSchemaId,\n                        defaultDefaultValue: defaultValue,\n                        source: types.isString(source) ? undefined : source,\n                        defaultValueSource: source\n                    };\n                    overrideIdentifiers.push(...overrideIdentifiersFromKey(key));\n                    this.configurationProperties[key] = property;\n                    this.defaultLanguageConfigurationOverridesNode.properties[key] = property;\n                }\n                else {\n                    this.configurationDefaultsOverrides.set(key, { value: overrides[key], source });\n                    const property = this.configurationProperties[key];\n                    if (property) {\n                        this.updatePropertyDefaultValue(key, property);\n                        this.updateSchema(key, property);\n                    }\n                }\n            }\n        }\n        this.doRegisterOverrideIdentifiers(overrideIdentifiers);\n    }\n    registerOverrideIdentifiers(overrideIdentifiers) {\n        this.doRegisterOverrideIdentifiers(overrideIdentifiers);\n        this._onDidSchemaChange.fire();\n    }\n    doRegisterOverrideIdentifiers(overrideIdentifiers) {\n        for (const overrideIdentifier of overrideIdentifiers) {\n            this.overrideIdentifiers.add(overrideIdentifier);\n        }\n        this.updateOverridePropertyPatternKey();\n    }\n    doRegisterConfigurations(configurations, validate, bucket) {\n        configurations.forEach(configuration => {\n            this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo, configuration.restrictedProperties, undefined, bucket);\n            this.configurationContributors.push(configuration);\n            this.registerJSONConfiguration(configuration);\n        });\n    }\n    validateAndRegisterProperties(configuration, validate = true, extensionInfo, restrictedProperties, scope = 3 /* ConfigurationScope.WINDOW */, bucket) {\n        var _a;\n        scope = types.isUndefinedOrNull(configuration.scope) ? scope : configuration.scope;\n        const properties = configuration.properties;\n        if (properties) {\n            for (const key in properties) {\n                const property = properties[key];\n                if (validate && validateProperty(key, property)) {\n                    delete properties[key];\n                    continue;\n                }\n                property.source = extensionInfo;\n                // update default value\n                property.defaultDefaultValue = properties[key].default;\n                this.updatePropertyDefaultValue(key, property);\n                // update scope\n                if (OVERRIDE_PROPERTY_REGEX.test(key)) {\n                    property.scope = undefined; // No scope for overridable properties `[${identifier}]`\n                }\n                else {\n                    property.scope = types.isUndefinedOrNull(property.scope) ? scope : property.scope;\n                    property.restricted = types.isUndefinedOrNull(property.restricted) ? !!(restrictedProperties === null || restrictedProperties === void 0 ? void 0 : restrictedProperties.includes(key)) : property.restricted;\n                }\n                // Add to properties maps\n                // Property is included by default if 'included' is unspecified\n                if (properties[key].hasOwnProperty('included') && !properties[key].included) {\n                    this.excludedConfigurationProperties[key] = properties[key];\n                    delete properties[key];\n                    continue;\n                }\n                else {\n                    this.configurationProperties[key] = properties[key];\n                    if ((_a = properties[key].policy) === null || _a === void 0 ? void 0 : _a.name) {\n                        this.policyConfigurations.set(properties[key].policy.name, key);\n                    }\n                }\n                if (!properties[key].deprecationMessage && properties[key].markdownDeprecationMessage) {\n                    // If not set, default deprecationMessage to the markdown source\n                    properties[key].deprecationMessage = properties[key].markdownDeprecationMessage;\n                }\n                bucket.add(key);\n            }\n        }\n        const subNodes = configuration.allOf;\n        if (subNodes) {\n            for (const node of subNodes) {\n                this.validateAndRegisterProperties(node, validate, extensionInfo, restrictedProperties, scope, bucket);\n            }\n        }\n    }\n    getConfigurationProperties() {\n        return this.configurationProperties;\n    }\n    getPolicyConfigurations() {\n        return this.policyConfigurations;\n    }\n    registerJSONConfiguration(configuration) {\n        const register = (configuration) => {\n            const properties = configuration.properties;\n            if (properties) {\n                for (const key in properties) {\n                    this.updateSchema(key, properties[key]);\n                }\n            }\n            const subNodes = configuration.allOf;\n            subNodes === null || subNodes === void 0 ? void 0 : subNodes.forEach(register);\n        };\n        register(configuration);\n    }\n    updateSchema(key, property) {\n        allSettings.properties[key] = property;\n        switch (property.scope) {\n            case 1 /* ConfigurationScope.APPLICATION */:\n                applicationSettings.properties[key] = property;\n                break;\n            case 2 /* ConfigurationScope.MACHINE */:\n                machineSettings.properties[key] = property;\n                break;\n            case 6 /* ConfigurationScope.MACHINE_OVERRIDABLE */:\n                machineOverridableSettings.properties[key] = property;\n                break;\n            case 3 /* ConfigurationScope.WINDOW */:\n                windowSettings.properties[key] = property;\n                break;\n            case 4 /* ConfigurationScope.RESOURCE */:\n                resourceSettings.properties[key] = property;\n                break;\n            case 5 /* ConfigurationScope.LANGUAGE_OVERRIDABLE */:\n                resourceSettings.properties[key] = property;\n                this.resourceLanguageSettingsSchema.properties[key] = property;\n                break;\n        }\n    }\n    updateOverridePropertyPatternKey() {\n        for (const overrideIdentifier of this.overrideIdentifiers.values()) {\n            const overrideIdentifierProperty = `[${overrideIdentifier}]`;\n            const resourceLanguagePropertiesSchema = {\n                type: 'object',\n                description: nls.localize('overrideSettings.defaultDescription', \"Configure editor settings to be overridden for a language.\"),\n                errorMessage: nls.localize('overrideSettings.errorMessage', \"This setting does not support per-language configuration.\"),\n                $ref: resourceLanguageSettingsSchemaId,\n            };\n            this.updatePropertyDefaultValue(overrideIdentifierProperty, resourceLanguagePropertiesSchema);\n            allSettings.properties[overrideIdentifierProperty] = resourceLanguagePropertiesSchema;\n            applicationSettings.properties[overrideIdentifierProperty] = resourceLanguagePropertiesSchema;\n            machineSettings.properties[overrideIdentifierProperty] = resourceLanguagePropertiesSchema;\n            machineOverridableSettings.properties[overrideIdentifierProperty] = resourceLanguagePropertiesSchema;\n            windowSettings.properties[overrideIdentifierProperty] = resourceLanguagePropertiesSchema;\n            resourceSettings.properties[overrideIdentifierProperty] = resourceLanguagePropertiesSchema;\n        }\n    }\n    registerOverridePropertyPatternKey() {\n        const resourceLanguagePropertiesSchema = {\n            type: 'object',\n            description: nls.localize('overrideSettings.defaultDescription', \"Configure editor settings to be overridden for a language.\"),\n            errorMessage: nls.localize('overrideSettings.errorMessage', \"This setting does not support per-language configuration.\"),\n            $ref: resourceLanguageSettingsSchemaId,\n        };\n        allSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;\n        applicationSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;\n        machineSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;\n        machineOverridableSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;\n        windowSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;\n        resourceSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;\n        this._onDidSchemaChange.fire();\n    }\n    updatePropertyDefaultValue(key, property) {\n        const configurationdefaultOverride = this.configurationDefaultsOverrides.get(key);\n        let defaultValue = configurationdefaultOverride === null || configurationdefaultOverride === void 0 ? void 0 : configurationdefaultOverride.value;\n        let defaultSource = configurationdefaultOverride === null || configurationdefaultOverride === void 0 ? void 0 : configurationdefaultOverride.source;\n        if (types.isUndefined(defaultValue)) {\n            defaultValue = property.defaultDefaultValue;\n            defaultSource = undefined;\n        }\n        if (types.isUndefined(defaultValue)) {\n            defaultValue = getDefaultValue(property.type);\n        }\n        property.default = defaultValue;\n        property.defaultValueSource = defaultSource;\n    }\n}\nconst OVERRIDE_IDENTIFIER_PATTERN = `\\\\[([^\\\\]]+)\\\\]`;\nconst OVERRIDE_IDENTIFIER_REGEX = new RegExp(OVERRIDE_IDENTIFIER_PATTERN, 'g');\nexport const OVERRIDE_PROPERTY_PATTERN = `^(${OVERRIDE_IDENTIFIER_PATTERN})+$`;\nexport const OVERRIDE_PROPERTY_REGEX = new RegExp(OVERRIDE_PROPERTY_PATTERN);\nexport function overrideIdentifiersFromKey(key) {\n    const identifiers = [];\n    if (OVERRIDE_PROPERTY_REGEX.test(key)) {\n        let matches = OVERRIDE_IDENTIFIER_REGEX.exec(key);\n        while (matches === null || matches === void 0 ? void 0 : matches.length) {\n            const identifier = matches[1].trim();\n            if (identifier) {\n                identifiers.push(identifier);\n            }\n            matches = OVERRIDE_IDENTIFIER_REGEX.exec(key);\n        }\n    }\n    return distinct(identifiers);\n}\nexport function getDefaultValue(type) {\n    const t = Array.isArray(type) ? type[0] : type;\n    switch (t) {\n        case 'boolean':\n            return false;\n        case 'integer':\n        case 'number':\n            return 0;\n        case 'string':\n            return '';\n        case 'array':\n            return [];\n        case 'object':\n            return {};\n        default:\n            return null;\n    }\n}\nconst configurationRegistry = new ConfigurationRegistry();\nRegistry.add(Extensions.Configuration, configurationRegistry);\nexport function validateProperty(property, schema) {\n    var _a, _b, _c, _d;\n    if (!property.trim()) {\n        return nls.localize('config.property.empty', \"Cannot register an empty property\");\n    }\n    if (OVERRIDE_PROPERTY_REGEX.test(property)) {\n        return nls.localize('config.property.languageDefault', \"Cannot register '{0}'. This matches property pattern '\\\\\\\\[.*\\\\\\\\]$' for describing language specific editor settings. Use 'configurationDefaults' contribution.\", property);\n    }\n    if (configurationRegistry.getConfigurationProperties()[property] !== undefined) {\n        return nls.localize('config.property.duplicate', \"Cannot register '{0}'. This property is already registered.\", property);\n    }\n    if (((_a = schema.policy) === null || _a === void 0 ? void 0 : _a.name) && configurationRegistry.getPolicyConfigurations().get((_b = schema.policy) === null || _b === void 0 ? void 0 : _b.name) !== undefined) {\n        return nls.localize('config.policy.duplicate', \"Cannot register '{0}'. The associated policy {1} is already registered with {2}.\", property, (_c = schema.policy) === null || _c === void 0 ? void 0 : _c.name, configurationRegistry.getPolicyConfigurations().get((_d = schema.policy) === null || _d === void 0 ? void 0 : _d.name));\n    }\n    return null;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as nls from '../../../nls.js';\nimport { Emitter } from '../../../base/common/event.js';\nimport { Registry } from '../../../platform/registry/common/platform.js';\nimport { Mimes } from '../../../base/common/mime.js';\nimport { Extensions as ConfigurationExtensions } from '../../../platform/configuration/common/configurationRegistry.js';\n// Define extension point ids\nexport const Extensions = {\n    ModesRegistry: 'editor.modesRegistry'\n};\nexport class EditorModesRegistry {\n    constructor() {\n        this._onDidChangeLanguages = new Emitter();\n        this.onDidChangeLanguages = this._onDidChangeLanguages.event;\n        this._languages = [];\n    }\n    registerLanguage(def) {\n        this._languages.push(def);\n        this._onDidChangeLanguages.fire(undefined);\n        return {\n            dispose: () => {\n                for (let i = 0, len = this._languages.length; i < len; i++) {\n                    if (this._languages[i] === def) {\n                        this._languages.splice(i, 1);\n                        return;\n                    }\n                }\n            }\n        };\n    }\n    getLanguages() {\n        return this._languages;\n    }\n}\nexport const ModesRegistry = new EditorModesRegistry();\nRegistry.add(Extensions.ModesRegistry, ModesRegistry);\nexport const PLAINTEXT_LANGUAGE_ID = 'plaintext';\nexport const PLAINTEXT_EXTENSION = '.txt';\nModesRegistry.registerLanguage({\n    id: PLAINTEXT_LANGUAGE_ID,\n    extensions: [PLAINTEXT_EXTENSION],\n    aliases: [nls.localize('plainText.alias', \"Plain Text\"), 'text'],\n    mimetypes: [Mimes.text]\n});\nRegistry.as(ConfigurationExtensions.Configuration)\n    .registerDefaultConfigurations([{\n        overrides: {\n            '[plaintext]': {\n                'editor.unicodeHighlight.ambiguousCharacters': false,\n                'editor.unicodeHighlight.invisibleCharacters': false\n            }\n        }\n    }]);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { CachedFunction } from '../../../../base/common/cache.js';\n/**\n * Captures all bracket related configurations for a single language.\n * Immutable.\n*/\nexport class LanguageBracketsConfiguration {\n    constructor(languageId, config) {\n        this.languageId = languageId;\n        const bracketPairs = config.brackets ? filterValidBrackets(config.brackets) : [];\n        const openingBracketInfos = new CachedFunction((bracket) => {\n            const closing = new Set();\n            return {\n                info: new OpeningBracketKind(this, bracket, closing),\n                closing,\n            };\n        });\n        const closingBracketInfos = new CachedFunction((bracket) => {\n            const opening = new Set();\n            const openingColorized = new Set();\n            return {\n                info: new ClosingBracketKind(this, bracket, opening, openingColorized),\n                opening,\n                openingColorized,\n            };\n        });\n        for (const [open, close] of bracketPairs) {\n            const opening = openingBracketInfos.get(open);\n            const closing = closingBracketInfos.get(close);\n            opening.closing.add(closing.info);\n            closing.opening.add(opening.info);\n        }\n        // Treat colorized brackets as brackets, and mark them as colorized.\n        const colorizedBracketPairs = config.colorizedBracketPairs\n            ? filterValidBrackets(config.colorizedBracketPairs)\n            // If not configured: Take all brackets except `<` ... `>`\n            // Many languages set < ... > as bracket pair, even though they also use it as comparison operator.\n            // This leads to problems when colorizing this bracket, so we exclude it if not explicitly configured otherwise.\n            // https://github.com/microsoft/vscode/issues/132476\n            : bracketPairs.filter((p) => !(p[0] === '<' && p[1] === '>'));\n        for (const [open, close] of colorizedBracketPairs) {\n            const opening = openingBracketInfos.get(open);\n            const closing = closingBracketInfos.get(close);\n            opening.closing.add(closing.info);\n            closing.openingColorized.add(opening.info);\n            closing.opening.add(opening.info);\n        }\n        this._openingBrackets = new Map([...openingBracketInfos.cachedValues].map(([k, v]) => [k, v.info]));\n        this._closingBrackets = new Map([...closingBracketInfos.cachedValues].map(([k, v]) => [k, v.info]));\n    }\n    /**\n     * No two brackets have the same bracket text.\n    */\n    get openingBrackets() {\n        return [...this._openingBrackets.values()];\n    }\n    /**\n     * No two brackets have the same bracket text.\n    */\n    get closingBrackets() {\n        return [...this._closingBrackets.values()];\n    }\n    getOpeningBracketInfo(bracketText) {\n        return this._openingBrackets.get(bracketText);\n    }\n    getClosingBracketInfo(bracketText) {\n        return this._closingBrackets.get(bracketText);\n    }\n    getBracketInfo(bracketText) {\n        return this.getOpeningBracketInfo(bracketText) || this.getClosingBracketInfo(bracketText);\n    }\n}\nfunction filterValidBrackets(bracketPairs) {\n    return bracketPairs.filter(([open, close]) => open !== '' && close !== '');\n}\nexport class BracketKindBase {\n    constructor(config, bracketText) {\n        this.config = config;\n        this.bracketText = bracketText;\n    }\n    get languageId() {\n        return this.config.languageId;\n    }\n}\nexport class OpeningBracketKind extends BracketKindBase {\n    constructor(config, bracketText, openedBrackets) {\n        super(config, bracketText);\n        this.openedBrackets = openedBrackets;\n        this.isOpeningBracket = true;\n    }\n}\nexport class ClosingBracketKind extends BracketKindBase {\n    constructor(config, bracketText, \n    /**\n     * Non empty array of all opening brackets this bracket closes.\n    */\n    openingBrackets, openingColorizedBrackets) {\n        super(config, bracketText);\n        this.openingBrackets = openingBrackets;\n        this.openingColorizedBrackets = openingColorizedBrackets;\n        this.isOpeningBracket = false;\n    }\n    /**\n     * Checks if this bracket closes the given other bracket.\n     * If the bracket infos come from different configurations, this method will return false.\n    */\n    closes(other) {\n        if (other['config'] !== this.config) {\n            return false;\n        }\n        return this.openingBrackets.has(other);\n    }\n    closesColorized(other) {\n        if (other['config'] !== this.config) {\n            return false;\n        }\n        return this.openingColorizedBrackets.has(other);\n    }\n    getOpeningBrackets() {\n        return [...this.openingBrackets];\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\n};\nvar __param = (this && this.__param) || function (paramIndex, decorator) {\n    return function (target, key) { decorator(target, key, paramIndex); }\n};\nimport { Emitter } from '../../../base/common/event.js';\nimport { Disposable, toDisposable } from '../../../base/common/lifecycle.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { DEFAULT_WORD_REGEXP, ensureValidWordDefinition } from '../core/wordHelper.js';\nimport { AutoClosingPairs } from './languageConfiguration.js';\nimport { createScopedLineTokens } from './supports.js';\nimport { CharacterPairSupport } from './supports/characterPair.js';\nimport { BracketElectricCharacterSupport } from './supports/electricCharacter.js';\nimport { IndentRulesSupport } from './supports/indentRules.js';\nimport { OnEnterSupport } from './supports/onEnter.js';\nimport { RichEditBrackets } from './supports/richEditBrackets.js';\nimport { createDecorator } from '../../../platform/instantiation/common/instantiation.js';\nimport { IConfigurationService } from '../../../platform/configuration/common/configuration.js';\nimport { ILanguageService } from './language.js';\nimport { registerSingleton } from '../../../platform/instantiation/common/extensions.js';\nimport { PLAINTEXT_LANGUAGE_ID } from './modesRegistry.js';\nimport { LanguageBracketsConfiguration } from './supports/languageBracketsConfiguration.js';\nexport class LanguageConfigurationServiceChangeEvent {\n    constructor(languageId) {\n        this.languageId = languageId;\n    }\n    affects(languageId) {\n        return !this.languageId ? true : this.languageId === languageId;\n    }\n}\nexport const ILanguageConfigurationService = createDecorator('languageConfigurationService');\nexport let LanguageConfigurationService = class LanguageConfigurationService extends Disposable {\n    constructor(configurationService, languageService) {\n        super();\n        this.configurationService = configurationService;\n        this.languageService = languageService;\n        this._registry = this._register(new LanguageConfigurationRegistry());\n        this.onDidChangeEmitter = this._register(new Emitter());\n        this.onDidChange = this.onDidChangeEmitter.event;\n        this.configurations = new Map();\n        const languageConfigKeys = new Set(Object.values(customizedLanguageConfigKeys));\n        this._register(this.configurationService.onDidChangeConfiguration((e) => {\n            const globalConfigChanged = e.change.keys.some((k) => languageConfigKeys.has(k));\n            const localConfigChanged = e.change.overrides\n                .filter(([overrideLangName, keys]) => keys.some((k) => languageConfigKeys.has(k)))\n                .map(([overrideLangName]) => overrideLangName);\n            if (globalConfigChanged) {\n                this.configurations.clear();\n                this.onDidChangeEmitter.fire(new LanguageConfigurationServiceChangeEvent(undefined));\n            }\n            else {\n                for (const languageId of localConfigChanged) {\n                    if (this.languageService.isRegisteredLanguageId(languageId)) {\n                        this.configurations.delete(languageId);\n                        this.onDidChangeEmitter.fire(new LanguageConfigurationServiceChangeEvent(languageId));\n                    }\n                }\n            }\n        }));\n        this._register(this._registry.onDidChange((e) => {\n            this.configurations.delete(e.languageId);\n            this.onDidChangeEmitter.fire(new LanguageConfigurationServiceChangeEvent(e.languageId));\n        }));\n    }\n    register(languageId, configuration, priority) {\n        return this._registry.register(languageId, configuration, priority);\n    }\n    getLanguageConfiguration(languageId) {\n        let result = this.configurations.get(languageId);\n        if (!result) {\n            result = computeConfig(languageId, this._registry, this.configurationService, this.languageService);\n            this.configurations.set(languageId, result);\n        }\n        return result;\n    }\n};\nLanguageConfigurationService = __decorate([\n    __param(0, IConfigurationService),\n    __param(1, ILanguageService)\n], LanguageConfigurationService);\nfunction computeConfig(languageId, registry, configurationService, languageService) {\n    let languageConfig = registry.getLanguageConfiguration(languageId);\n    if (!languageConfig) {\n        if (!languageService.isRegisteredLanguageId(languageId)) {\n            // this happens for the null language, which can be returned by monarch.\n            // Instead of throwing an error, we just return a default config.\n            return new ResolvedLanguageConfiguration(languageId, {});\n        }\n        languageConfig = new ResolvedLanguageConfiguration(languageId, {});\n    }\n    const customizedConfig = getCustomizedLanguageConfig(languageConfig.languageId, configurationService);\n    const data = combineLanguageConfigurations([languageConfig.underlyingConfig, customizedConfig]);\n    const config = new ResolvedLanguageConfiguration(languageConfig.languageId, data);\n    return config;\n}\nconst customizedLanguageConfigKeys = {\n    brackets: 'editor.language.brackets',\n    colorizedBracketPairs: 'editor.language.colorizedBracketPairs'\n};\nfunction getCustomizedLanguageConfig(languageId, configurationService) {\n    const brackets = configurationService.getValue(customizedLanguageConfigKeys.brackets, {\n        overrideIdentifier: languageId,\n    });\n    const colorizedBracketPairs = configurationService.getValue(customizedLanguageConfigKeys.colorizedBracketPairs, {\n        overrideIdentifier: languageId,\n    });\n    return {\n        brackets: validateBracketPairs(brackets),\n        colorizedBracketPairs: validateBracketPairs(colorizedBracketPairs),\n    };\n}\nfunction validateBracketPairs(data) {\n    if (!Array.isArray(data)) {\n        return undefined;\n    }\n    return data.map(pair => {\n        if (!Array.isArray(pair) || pair.length !== 2) {\n            return undefined;\n        }\n        return [pair[0], pair[1]];\n    }).filter((p) => !!p);\n}\nexport function getIndentationAtPosition(model, lineNumber, column) {\n    const lineText = model.getLineContent(lineNumber);\n    let indentation = strings.getLeadingWhitespace(lineText);\n    if (indentation.length > column - 1) {\n        indentation = indentation.substring(0, column - 1);\n    }\n    return indentation;\n}\nexport function getScopedLineTokens(model, lineNumber, columnNumber) {\n    model.tokenization.forceTokenization(lineNumber);\n    const lineTokens = model.tokenization.getLineTokens(lineNumber);\n    const column = (typeof columnNumber === 'undefined' ? model.getLineMaxColumn(lineNumber) - 1 : columnNumber - 1);\n    return createScopedLineTokens(lineTokens, column);\n}\nclass ComposedLanguageConfiguration {\n    constructor(languageId) {\n        this.languageId = languageId;\n        this._resolved = null;\n        this._entries = [];\n        this._order = 0;\n        this._resolved = null;\n    }\n    register(configuration, priority) {\n        const entry = new LanguageConfigurationContribution(configuration, priority, ++this._order);\n        this._entries.push(entry);\n        this._resolved = null;\n        return toDisposable(() => {\n            for (let i = 0; i < this._entries.length; i++) {\n                if (this._entries[i] === entry) {\n                    this._entries.splice(i, 1);\n                    this._resolved = null;\n                    break;\n                }\n            }\n        });\n    }\n    getResolvedConfiguration() {\n        if (!this._resolved) {\n            const config = this._resolve();\n            if (config) {\n                this._resolved = new ResolvedLanguageConfiguration(this.languageId, config);\n            }\n        }\n        return this._resolved;\n    }\n    _resolve() {\n        if (this._entries.length === 0) {\n            return null;\n        }\n        this._entries.sort(LanguageConfigurationContribution.cmp);\n        return combineLanguageConfigurations(this._entries.map(e => e.configuration));\n    }\n}\nfunction combineLanguageConfigurations(configs) {\n    let result = {\n        comments: undefined,\n        brackets: undefined,\n        wordPattern: undefined,\n        indentationRules: undefined,\n        onEnterRules: undefined,\n        autoClosingPairs: undefined,\n        surroundingPairs: undefined,\n        autoCloseBefore: undefined,\n        folding: undefined,\n        colorizedBracketPairs: undefined,\n        __electricCharacterSupport: undefined,\n    };\n    for (const entry of configs) {\n        result = {\n            comments: entry.comments || result.comments,\n            brackets: entry.brackets || result.brackets,\n            wordPattern: entry.wordPattern || result.wordPattern,\n            indentationRules: entry.indentationRules || result.indentationRules,\n            onEnterRules: entry.onEnterRules || result.onEnterRules,\n            autoClosingPairs: entry.autoClosingPairs || result.autoClosingPairs,\n            surroundingPairs: entry.surroundingPairs || result.surroundingPairs,\n            autoCloseBefore: entry.autoCloseBefore || result.autoCloseBefore,\n            folding: entry.folding || result.folding,\n            colorizedBracketPairs: entry.colorizedBracketPairs || result.colorizedBracketPairs,\n            __electricCharacterSupport: entry.__electricCharacterSupport || result.__electricCharacterSupport,\n        };\n    }\n    return result;\n}\nclass LanguageConfigurationContribution {\n    constructor(configuration, priority, order) {\n        this.configuration = configuration;\n        this.priority = priority;\n        this.order = order;\n    }\n    static cmp(a, b) {\n        if (a.priority === b.priority) {\n            // higher order last\n            return a.order - b.order;\n        }\n        // higher priority last\n        return a.priority - b.priority;\n    }\n}\nexport class LanguageConfigurationChangeEvent {\n    constructor(languageId) {\n        this.languageId = languageId;\n    }\n}\nexport class LanguageConfigurationRegistry extends Disposable {\n    constructor() {\n        super();\n        this._entries = new Map();\n        this._onDidChange = this._register(new Emitter());\n        this.onDidChange = this._onDidChange.event;\n        this._register(this.register(PLAINTEXT_LANGUAGE_ID, {\n            brackets: [\n                ['(', ')'],\n                ['[', ']'],\n                ['{', '}'],\n            ],\n            surroundingPairs: [\n                { open: '{', close: '}' },\n                { open: '[', close: ']' },\n                { open: '(', close: ')' },\n                { open: '<', close: '>' },\n                { open: '\\\"', close: '\\\"' },\n                { open: '\\'', close: '\\'' },\n                { open: '`', close: '`' },\n            ],\n            colorizedBracketPairs: [],\n            folding: {\n                offSide: true\n            }\n        }, 0));\n    }\n    /**\n     * @param priority Use a higher number for higher priority\n     */\n    register(languageId, configuration, priority = 0) {\n        let entries = this._entries.get(languageId);\n        if (!entries) {\n            entries = new ComposedLanguageConfiguration(languageId);\n            this._entries.set(languageId, entries);\n        }\n        const disposable = entries.register(configuration, priority);\n        this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageId));\n        return toDisposable(() => {\n            disposable.dispose();\n            this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageId));\n        });\n    }\n    getLanguageConfiguration(languageId) {\n        const entries = this._entries.get(languageId);\n        return (entries === null || entries === void 0 ? void 0 : entries.getResolvedConfiguration()) || null;\n    }\n}\n/**\n * Immutable.\n*/\nexport class ResolvedLanguageConfiguration {\n    constructor(languageId, underlyingConfig) {\n        this.languageId = languageId;\n        this.underlyingConfig = underlyingConfig;\n        this._brackets = null;\n        this._electricCharacter = null;\n        this._onEnterSupport =\n            this.underlyingConfig.brackets ||\n                this.underlyingConfig.indentationRules ||\n                this.underlyingConfig.onEnterRules\n                ? new OnEnterSupport(this.underlyingConfig)\n                : null;\n        this.comments = ResolvedLanguageConfiguration._handleComments(this.underlyingConfig);\n        this.characterPair = new CharacterPairSupport(this.underlyingConfig);\n        this.wordDefinition = this.underlyingConfig.wordPattern || DEFAULT_WORD_REGEXP;\n        this.indentationRules = this.underlyingConfig.indentationRules;\n        if (this.underlyingConfig.indentationRules) {\n            this.indentRulesSupport = new IndentRulesSupport(this.underlyingConfig.indentationRules);\n        }\n        else {\n            this.indentRulesSupport = null;\n        }\n        this.foldingRules = this.underlyingConfig.folding || {};\n        this.bracketsNew = new LanguageBracketsConfiguration(languageId, this.underlyingConfig);\n    }\n    getWordDefinition() {\n        return ensureValidWordDefinition(this.wordDefinition);\n    }\n    get brackets() {\n        if (!this._brackets && this.underlyingConfig.brackets) {\n            this._brackets = new RichEditBrackets(this.languageId, this.underlyingConfig.brackets);\n        }\n        return this._brackets;\n    }\n    get electricCharacter() {\n        if (!this._electricCharacter) {\n            this._electricCharacter = new BracketElectricCharacterSupport(this.brackets);\n        }\n        return this._electricCharacter;\n    }\n    onEnter(autoIndent, previousLineText, beforeEnterText, afterEnterText) {\n        if (!this._onEnterSupport) {\n            return null;\n        }\n        return this._onEnterSupport.onEnter(autoIndent, previousLineText, beforeEnterText, afterEnterText);\n    }\n    getAutoClosingPairs() {\n        return new AutoClosingPairs(this.characterPair.getAutoClosingPairs());\n    }\n    getAutoCloseBeforeSet(forQuotes) {\n        return this.characterPair.getAutoCloseBeforeSet(forQuotes);\n    }\n    getSurroundingPairs() {\n        return this.characterPair.getSurroundingPairs();\n    }\n    static _handleComments(conf) {\n        const commentRule = conf.comments;\n        if (!commentRule) {\n            return null;\n        }\n        // comment configuration\n        const comments = {};\n        if (commentRule.lineComment) {\n            comments.lineCommentToken = commentRule.lineComment;\n        }\n        if (commentRule.blockComment) {\n            const [blockStart, blockEnd] = commentRule.blockComment;\n            comments.blockCommentStartToken = blockStart;\n            comments.blockCommentEndToken = blockEnd;\n        }\n        return comments;\n    }\n}\nregisterSingleton(ILanguageConfigurationService, LanguageConfigurationService, 1 /* InstantiationType.Delayed */);\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Token, TokenizationResult, EncodedTokenizationResult } from '../languages.js';\nexport const NullState = new class {\n    clone() {\n        return this;\n    }\n    equals(other) {\n        return (this === other);\n    }\n};\nexport function nullTokenize(languageId, state) {\n    return new TokenizationResult([new Token(0, '', languageId)], state);\n}\nexport function nullTokenizeEncoded(languageId, state) {\n    const tokens = new Uint32Array(2);\n    tokens[0] = 0;\n    tokens[1] = ((languageId << 0 /* MetadataConsts.LANGUAGEID_OFFSET */)\n        | (0 /* StandardTokenType.Other */ << 8 /* MetadataConsts.TOKEN_TYPE_OFFSET */)\n        | (0 /* FontStyle.None */ << 11 /* MetadataConsts.FONT_STYLE_OFFSET */)\n        | (1 /* ColorId.DefaultForeground */ << 15 /* MetadataConsts.FOREGROUND_OFFSET */)\n        | (2 /* ColorId.DefaultBackground */ << 24 /* MetadataConsts.BACKGROUND_OFFSET */)) >>> 0;\n    return new EncodedTokenizationResult(tokens, state === null ? NullState : state);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { createDecorator } from '../../../platform/instantiation/common/instantiation.js';\nexport const IModelService = createDecorator('modelService');\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * Can be passed into the Delayed to defer using a microtask\n * */\nexport const MicrotaskDelay = Symbol('MicrotaskDelay');\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __asyncValues = (this && this.__asyncValues) || function (o) {\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n    var m = o[Symbol.asyncIterator], i;\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n};\nimport { CancellationTokenSource } from './cancellation.js';\nimport { CancellationError } from './errors.js';\nimport { Emitter, Event } from './event.js';\nimport { toDisposable } from './lifecycle.js';\nimport { setTimeout0 } from './platform.js';\nimport { MicrotaskDelay } from './symbols.js';\nexport function isThenable(obj) {\n    return !!obj && typeof obj.then === 'function';\n}\nexport function createCancelablePromise(callback) {\n    const source = new CancellationTokenSource();\n    const thenable = callback(source.token);\n    const promise = new Promise((resolve, reject) => {\n        const subscription = source.token.onCancellationRequested(() => {\n            subscription.dispose();\n            source.dispose();\n            reject(new CancellationError());\n        });\n        Promise.resolve(thenable).then(value => {\n            subscription.dispose();\n            source.dispose();\n            resolve(value);\n        }, err => {\n            subscription.dispose();\n            source.dispose();\n            reject(err);\n        });\n    });\n    return new class {\n        cancel() {\n            source.cancel();\n        }\n        then(resolve, reject) {\n            return promise.then(resolve, reject);\n        }\n        catch(reject) {\n            return this.then(undefined, reject);\n        }\n        finally(onfinally) {\n            return promise.finally(onfinally);\n        }\n    };\n}\nexport function raceCancellation(promise, token, defaultValue) {\n    return new Promise((resolve, reject) => {\n        const ref = token.onCancellationRequested(() => {\n            ref.dispose();\n            resolve(defaultValue);\n        });\n        promise.then(resolve, reject).finally(() => ref.dispose());\n    });\n}\n/**\n * A helper to prevent accumulation of sequential async tasks.\n *\n * Imagine a mail man with the sole task of delivering letters. As soon as\n * a letter submitted for delivery, he drives to the destination, delivers it\n * and returns to his base. Imagine that during the trip, N more letters were submitted.\n * When the mail man returns, he picks those N letters and delivers them all in a\n * single trip. Even though N+1 submissions occurred, only 2 deliveries were made.\n *\n * The throttler implements this via the queue() method, by providing it a task\n * factory. Following the example:\n *\n * \t\tconst throttler = new Throttler();\n * \t\tconst letters = [];\n *\n * \t\tfunction deliver() {\n * \t\t\tconst lettersToDeliver = letters;\n * \t\t\tletters = [];\n * \t\t\treturn makeTheTrip(lettersToDeliver);\n * \t\t}\n *\n * \t\tfunction onLetterReceived(l) {\n * \t\t\tletters.push(l);\n * \t\t\tthrottler.queue(deliver);\n * \t\t}\n */\nexport class Throttler {\n    constructor() {\n        this.isDisposed = false;\n        this.activePromise = null;\n        this.queuedPromise = null;\n        this.queuedPromiseFactory = null;\n    }\n    queue(promiseFactory) {\n        if (this.isDisposed) {\n            throw new Error('Throttler is disposed');\n        }\n        if (this.activePromise) {\n            this.queuedPromiseFactory = promiseFactory;\n            if (!this.queuedPromise) {\n                const onComplete = () => {\n                    this.queuedPromise = null;\n                    if (this.isDisposed) {\n                        return;\n                    }\n                    const result = this.queue(this.queuedPromiseFactory);\n                    this.queuedPromiseFactory = null;\n                    return result;\n                };\n                this.queuedPromise = new Promise(resolve => {\n                    this.activePromise.then(onComplete, onComplete).then(resolve);\n                });\n            }\n            return new Promise((resolve, reject) => {\n                this.queuedPromise.then(resolve, reject);\n            });\n        }\n        this.activePromise = promiseFactory();\n        return new Promise((resolve, reject) => {\n            this.activePromise.then((result) => {\n                this.activePromise = null;\n                resolve(result);\n            }, (err) => {\n                this.activePromise = null;\n                reject(err);\n            });\n        });\n    }\n    dispose() {\n        this.isDisposed = true;\n    }\n}\nconst timeoutDeferred = (timeout, fn) => {\n    let scheduled = true;\n    const handle = setTimeout(() => {\n        scheduled = false;\n        fn();\n    }, timeout);\n    return {\n        isTriggered: () => scheduled,\n        dispose: () => {\n            clearTimeout(handle);\n            scheduled = false;\n        },\n    };\n};\nconst microtaskDeferred = (fn) => {\n    let scheduled = true;\n    queueMicrotask(() => {\n        if (scheduled) {\n            scheduled = false;\n            fn();\n        }\n    });\n    return {\n        isTriggered: () => scheduled,\n        dispose: () => { scheduled = false; },\n    };\n};\n/**\n * A helper to delay (debounce) execution of a task that is being requested often.\n *\n * Following the throttler, now imagine the mail man wants to optimize the number of\n * trips proactively. The trip itself can be long, so he decides not to make the trip\n * as soon as a letter is submitted. Instead he waits a while, in case more\n * letters are submitted. After said waiting period, if no letters were submitted, he\n * decides to make the trip. Imagine that N more letters were submitted after the first\n * one, all within a short period of time between each other. Even though N+1\n * submissions occurred, only 1 delivery was made.\n *\n * The delayer offers this behavior via the trigger() method, into which both the task\n * to be executed and the waiting period (delay) must be passed in as arguments. Following\n * the example:\n *\n * \t\tconst delayer = new Delayer(WAITING_PERIOD);\n * \t\tconst letters = [];\n *\n * \t\tfunction letterReceived(l) {\n * \t\t\tletters.push(l);\n * \t\t\tdelayer.trigger(() => { return makeTheTrip(); });\n * \t\t}\n */\nexport class Delayer {\n    constructor(defaultDelay) {\n        this.defaultDelay = defaultDelay;\n        this.deferred = null;\n        this.completionPromise = null;\n        this.doResolve = null;\n        this.doReject = null;\n        this.task = null;\n    }\n    trigger(task, delay = this.defaultDelay) {\n        this.task = task;\n        this.cancelTimeout();\n        if (!this.completionPromise) {\n            this.completionPromise = new Promise((resolve, reject) => {\n                this.doResolve = resolve;\n                this.doReject = reject;\n            }).then(() => {\n                this.completionPromise = null;\n                this.doResolve = null;\n                if (this.task) {\n                    const task = this.task;\n                    this.task = null;\n                    return task();\n                }\n                return undefined;\n            });\n        }\n        const fn = () => {\n            var _a;\n            this.deferred = null;\n            (_a = this.doResolve) === null || _a === void 0 ? void 0 : _a.call(this, null);\n        };\n        this.deferred = delay === MicrotaskDelay ? microtaskDeferred(fn) : timeoutDeferred(delay, fn);\n        return this.completionPromise;\n    }\n    isTriggered() {\n        var _a;\n        return !!((_a = this.deferred) === null || _a === void 0 ? void 0 : _a.isTriggered());\n    }\n    cancel() {\n        var _a;\n        this.cancelTimeout();\n        if (this.completionPromise) {\n            (_a = this.doReject) === null || _a === void 0 ? void 0 : _a.call(this, new CancellationError());\n            this.completionPromise = null;\n        }\n    }\n    cancelTimeout() {\n        var _a;\n        (_a = this.deferred) === null || _a === void 0 ? void 0 : _a.dispose();\n        this.deferred = null;\n    }\n    dispose() {\n        this.cancel();\n    }\n}\n/**\n * A helper to delay execution of a task that is being requested often, while\n * preventing accumulation of consecutive executions, while the task runs.\n *\n * The mail man is clever and waits for a certain amount of time, before going\n * out to deliver letters. While the mail man is going out, more letters arrive\n * and can only be delivered once he is back. Once he is back the mail man will\n * do one more trip to deliver the letters that have accumulated while he was out.\n */\nexport class ThrottledDelayer {\n    constructor(defaultDelay) {\n        this.delayer = new Delayer(defaultDelay);\n        this.throttler = new Throttler();\n    }\n    trigger(promiseFactory, delay) {\n        return this.delayer.trigger(() => this.throttler.queue(promiseFactory), delay);\n    }\n    cancel() {\n        this.delayer.cancel();\n    }\n    dispose() {\n        this.delayer.dispose();\n    }\n}\nexport function timeout(millis, token) {\n    if (!token) {\n        return createCancelablePromise(token => timeout(millis, token));\n    }\n    return new Promise((resolve, reject) => {\n        const handle = setTimeout(() => {\n            disposable.dispose();\n            resolve();\n        }, millis);\n        const disposable = token.onCancellationRequested(() => {\n            clearTimeout(handle);\n            disposable.dispose();\n            reject(new CancellationError());\n        });\n    });\n}\nexport function disposableTimeout(handler, timeout = 0) {\n    const timer = setTimeout(handler, timeout);\n    return toDisposable(() => clearTimeout(timer));\n}\nexport function first(promiseFactories, shouldStop = t => !!t, defaultValue = null) {\n    let index = 0;\n    const len = promiseFactories.length;\n    const loop = () => {\n        if (index >= len) {\n            return Promise.resolve(defaultValue);\n        }\n        const factory = promiseFactories[index++];\n        const promise = Promise.resolve(factory());\n        return promise.then(result => {\n            if (shouldStop(result)) {\n                return Promise.resolve(result);\n            }\n            return loop();\n        });\n    };\n    return loop();\n}\nexport class TimeoutTimer {\n    constructor(runner, timeout) {\n        this._token = -1;\n        if (typeof runner === 'function' && typeof timeout === 'number') {\n            this.setIfNotSet(runner, timeout);\n        }\n    }\n    dispose() {\n        this.cancel();\n    }\n    cancel() {\n        if (this._token !== -1) {\n            clearTimeout(this._token);\n            this._token = -1;\n        }\n    }\n    cancelAndSet(runner, timeout) {\n        this.cancel();\n        this._token = setTimeout(() => {\n            this._token = -1;\n            runner();\n        }, timeout);\n    }\n    setIfNotSet(runner, timeout) {\n        if (this._token !== -1) {\n            // timer is already set\n            return;\n        }\n        this._token = setTimeout(() => {\n            this._token = -1;\n            runner();\n        }, timeout);\n    }\n}\nexport class IntervalTimer {\n    constructor() {\n        this._token = -1;\n    }\n    dispose() {\n        this.cancel();\n    }\n    cancel() {\n        if (this._token !== -1) {\n            clearInterval(this._token);\n            this._token = -1;\n        }\n    }\n    cancelAndSet(runner, interval) {\n        this.cancel();\n        this._token = setInterval(() => {\n            runner();\n        }, interval);\n    }\n}\nexport class RunOnceScheduler {\n    constructor(runner, delay) {\n        this.timeoutToken = -1;\n        this.runner = runner;\n        this.timeout = delay;\n        this.timeoutHandler = this.onTimeout.bind(this);\n    }\n    /**\n     * Dispose RunOnceScheduler\n     */\n    dispose() {\n        this.cancel();\n        this.runner = null;\n    }\n    /**\n     * Cancel current scheduled runner (if any).\n     */\n    cancel() {\n        if (this.isScheduled()) {\n            clearTimeout(this.timeoutToken);\n            this.timeoutToken = -1;\n        }\n    }\n    /**\n     * Cancel previous runner (if any) & schedule a new runner.\n     */\n    schedule(delay = this.timeout) {\n        this.cancel();\n        this.timeoutToken = setTimeout(this.timeoutHandler, delay);\n    }\n    get delay() {\n        return this.timeout;\n    }\n    set delay(value) {\n        this.timeout = value;\n    }\n    /**\n     * Returns true if scheduled.\n     */\n    isScheduled() {\n        return this.timeoutToken !== -1;\n    }\n    onTimeout() {\n        this.timeoutToken = -1;\n        if (this.runner) {\n            this.doRun();\n        }\n    }\n    doRun() {\n        var _a;\n        (_a = this.runner) === null || _a === void 0 ? void 0 : _a.call(this);\n    }\n}\n/**\n * Execute the callback the next time the browser is idle, returning an\n * {@link IDisposable} that will cancel the callback when disposed. This wraps\n * [requestIdleCallback] so it will fallback to [setTimeout] if the environment\n * doesn't support it.\n *\n * @param callback The callback to run when idle, this includes an\n * [IdleDeadline] that provides the time alloted for the idle callback by the\n * browser. Not respecting this deadline will result in a degraded user\n * experience.\n * @param timeout A timeout at which point to queue no longer wait for an idle\n * callback but queue it on the regular event loop (like setTimeout). Typically\n * this should not be used.\n *\n * [IdleDeadline]: https://developer.mozilla.org/en-US/docs/Web/API/IdleDeadline\n * [requestIdleCallback]: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback\n * [setTimeout]: https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout\n */\nexport let runWhenIdle;\n(function () {\n    if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {\n        runWhenIdle = (runner) => {\n            setTimeout0(() => {\n                if (disposed) {\n                    return;\n                }\n                const end = Date.now() + 15; // one frame at 64fps\n                runner(Object.freeze({\n                    didTimeout: true,\n                    timeRemaining() {\n                        return Math.max(0, end - Date.now());\n                    }\n                }));\n            });\n            let disposed = false;\n            return {\n                dispose() {\n                    if (disposed) {\n                        return;\n                    }\n                    disposed = true;\n                }\n            };\n        };\n    }\n    else {\n        runWhenIdle = (runner, timeout) => {\n            const handle = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined);\n            let disposed = false;\n            return {\n                dispose() {\n                    if (disposed) {\n                        return;\n                    }\n                    disposed = true;\n                    cancelIdleCallback(handle);\n                }\n            };\n        };\n    }\n})();\n/**\n * An implementation of the \"idle-until-urgent\"-strategy as introduced\n * here: https://philipwalton.com/articles/idle-until-urgent/\n */\nexport class IdleValue {\n    constructor(executor) {\n        this._didRun = false;\n        this._executor = () => {\n            try {\n                this._value = executor();\n            }\n            catch (err) {\n                this._error = err;\n            }\n            finally {\n                this._didRun = true;\n            }\n        };\n        this._handle = runWhenIdle(() => this._executor());\n    }\n    dispose() {\n        this._handle.dispose();\n    }\n    get value() {\n        if (!this._didRun) {\n            this._handle.dispose();\n            this._executor();\n        }\n        if (this._error) {\n            throw this._error;\n        }\n        return this._value;\n    }\n    get isInitialized() {\n        return this._didRun;\n    }\n}\n/**\n * Creates a promise whose resolution or rejection can be controlled imperatively.\n */\nexport class DeferredPromise {\n    get isRejected() {\n        var _a;\n        return ((_a = this.outcome) === null || _a === void 0 ? void 0 : _a.outcome) === 1 /* DeferredOutcome.Rejected */;\n    }\n    get isSettled() {\n        return !!this.outcome;\n    }\n    constructor() {\n        this.p = new Promise((c, e) => {\n            this.completeCallback = c;\n            this.errorCallback = e;\n        });\n    }\n    complete(value) {\n        return new Promise(resolve => {\n            this.completeCallback(value);\n            this.outcome = { outcome: 0 /* DeferredOutcome.Resolved */, value };\n            resolve();\n        });\n    }\n    error(err) {\n        return new Promise(resolve => {\n            this.errorCallback(err);\n            this.outcome = { outcome: 1 /* DeferredOutcome.Rejected */, value: err };\n            resolve();\n        });\n    }\n    cancel() {\n        return this.error(new CancellationError());\n    }\n}\n//#endregion\n//#region Promises\nexport var Promises;\n(function (Promises) {\n    /**\n     * A drop-in replacement for `Promise.all` with the only difference\n     * that the method awaits every promise to either fulfill or reject.\n     *\n     * Similar to `Promise.all`, only the first error will be returned\n     * if any.\n     */\n    function settled(promises) {\n        return __awaiter(this, void 0, void 0, function* () {\n            let firstError = undefined;\n            const result = yield Promise.all(promises.map(promise => promise.then(value => value, error => {\n                if (!firstError) {\n                    firstError = error;\n                }\n                return undefined; // do not rethrow so that other promises can settle\n            })));\n            if (typeof firstError !== 'undefined') {\n                throw firstError;\n            }\n            return result; // cast is needed and protected by the `throw` above\n        });\n    }\n    Promises.settled = settled;\n    /**\n     * A helper to create a new `Promise` with a body that is a promise\n     * itself. By default, an error that raises from the async body will\n     * end up as a unhandled rejection, so this utility properly awaits the\n     * body and rejects the promise as a normal promise does without async\n     * body.\n     *\n     * This method should only be used in rare cases where otherwise `async`\n     * cannot be used (e.g. when callbacks are involved that require this).\n     */\n    function withAsyncBody(bodyFn) {\n        // eslint-disable-next-line no-async-promise-executor\n        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n            try {\n                yield bodyFn(resolve, reject);\n            }\n            catch (error) {\n                reject(error);\n            }\n        }));\n    }\n    Promises.withAsyncBody = withAsyncBody;\n})(Promises || (Promises = {}));\n/**\n * A rich implementation for an `AsyncIterable`.\n */\nexport class AsyncIterableObject {\n    static fromArray(items) {\n        return new AsyncIterableObject((writer) => {\n            writer.emitMany(items);\n        });\n    }\n    static fromPromise(promise) {\n        return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {\n            emitter.emitMany(yield promise);\n        }));\n    }\n    static fromPromises(promises) {\n        return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {\n            yield Promise.all(promises.map((p) => __awaiter(this, void 0, void 0, function* () { return emitter.emitOne(yield p); })));\n        }));\n    }\n    static merge(iterables) {\n        return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {\n            yield Promise.all(iterables.map((iterable) => { var _a, iterable_1, iterable_1_1; return __awaiter(this, void 0, void 0, function* () {\n                var _b, e_1, _c, _d;\n                try {\n                    for (_a = true, iterable_1 = __asyncValues(iterable); iterable_1_1 = yield iterable_1.next(), _b = iterable_1_1.done, !_b; _a = true) {\n                        _d = iterable_1_1.value;\n                        _a = false;\n                        const item = _d;\n                        emitter.emitOne(item);\n                    }\n                }\n                catch (e_1_1) { e_1 = { error: e_1_1 }; }\n                finally {\n                    try {\n                        if (!_a && !_b && (_c = iterable_1.return)) yield _c.call(iterable_1);\n                    }\n                    finally { if (e_1) throw e_1.error; }\n                }\n            }); }));\n        }));\n    }\n    constructor(executor) {\n        this._state = 0 /* AsyncIterableSourceState.Initial */;\n        this._results = [];\n        this._error = null;\n        this._onStateChanged = new Emitter();\n        queueMicrotask(() => __awaiter(this, void 0, void 0, function* () {\n            const writer = {\n                emitOne: (item) => this.emitOne(item),\n                emitMany: (items) => this.emitMany(items),\n                reject: (error) => this.reject(error)\n            };\n            try {\n                yield Promise.resolve(executor(writer));\n                this.resolve();\n            }\n            catch (err) {\n                this.reject(err);\n            }\n            finally {\n                writer.emitOne = undefined;\n                writer.emitMany = undefined;\n                writer.reject = undefined;\n            }\n        }));\n    }\n    [Symbol.asyncIterator]() {\n        let i = 0;\n        return {\n            next: () => __awaiter(this, void 0, void 0, function* () {\n                do {\n                    if (this._state === 2 /* AsyncIterableSourceState.DoneError */) {\n                        throw this._error;\n                    }\n                    if (i < this._results.length) {\n                        return { done: false, value: this._results[i++] };\n                    }\n                    if (this._state === 1 /* AsyncIterableSourceState.DoneOK */) {\n                        return { done: true, value: undefined };\n                    }\n                    yield Event.toPromise(this._onStateChanged.event);\n                } while (true);\n            })\n        };\n    }\n    static map(iterable, mapFn) {\n        return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {\n            var _a, e_2, _b, _c;\n            try {\n                for (var _d = true, iterable_2 = __asyncValues(iterable), iterable_2_1; iterable_2_1 = yield iterable_2.next(), _a = iterable_2_1.done, !_a; _d = true) {\n                    _c = iterable_2_1.value;\n                    _d = false;\n                    const item = _c;\n                    emitter.emitOne(mapFn(item));\n                }\n            }\n            catch (e_2_1) { e_2 = { error: e_2_1 }; }\n            finally {\n                try {\n                    if (!_d && !_a && (_b = iterable_2.return)) yield _b.call(iterable_2);\n                }\n                finally { if (e_2) throw e_2.error; }\n            }\n        }));\n    }\n    map(mapFn) {\n        return AsyncIterableObject.map(this, mapFn);\n    }\n    static filter(iterable, filterFn) {\n        return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {\n            var _a, e_3, _b, _c;\n            try {\n                for (var _d = true, iterable_3 = __asyncValues(iterable), iterable_3_1; iterable_3_1 = yield iterable_3.next(), _a = iterable_3_1.done, !_a; _d = true) {\n                    _c = iterable_3_1.value;\n                    _d = false;\n                    const item = _c;\n                    if (filterFn(item)) {\n                        emitter.emitOne(item);\n                    }\n                }\n            }\n            catch (e_3_1) { e_3 = { error: e_3_1 }; }\n            finally {\n                try {\n                    if (!_d && !_a && (_b = iterable_3.return)) yield _b.call(iterable_3);\n                }\n                finally { if (e_3) throw e_3.error; }\n            }\n        }));\n    }\n    filter(filterFn) {\n        return AsyncIterableObject.filter(this, filterFn);\n    }\n    static coalesce(iterable) {\n        return AsyncIterableObject.filter(iterable, item => !!item);\n    }\n    coalesce() {\n        return AsyncIterableObject.coalesce(this);\n    }\n    static toPromise(iterable) {\n        var _a, iterable_4, iterable_4_1;\n        var _b, e_4, _c, _d;\n        return __awaiter(this, void 0, void 0, function* () {\n            const result = [];\n            try {\n                for (_a = true, iterable_4 = __asyncValues(iterable); iterable_4_1 = yield iterable_4.next(), _b = iterable_4_1.done, !_b; _a = true) {\n                    _d = iterable_4_1.value;\n                    _a = false;\n                    const item = _d;\n                    result.push(item);\n                }\n            }\n            catch (e_4_1) { e_4 = { error: e_4_1 }; }\n            finally {\n                try {\n                    if (!_a && !_b && (_c = iterable_4.return)) yield _c.call(iterable_4);\n                }\n                finally { if (e_4) throw e_4.error; }\n            }\n            return result;\n        });\n    }\n    toPromise() {\n        return AsyncIterableObject.toPromise(this);\n    }\n    /**\n     * The value will be appended at the end.\n     *\n     * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.\n     */\n    emitOne(value) {\n        if (this._state !== 0 /* AsyncIterableSourceState.Initial */) {\n            return;\n        }\n        // it is important to add new values at the end,\n        // as we may have iterators already running on the array\n        this._results.push(value);\n        this._onStateChanged.fire();\n    }\n    /**\n     * The values will be appended at the end.\n     *\n     * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.\n     */\n    emitMany(values) {\n        if (this._state !== 0 /* AsyncIterableSourceState.Initial */) {\n            return;\n        }\n        // it is important to add new values at the end,\n        // as we may have iterators already running on the array\n        this._results = this._results.concat(values);\n        this._onStateChanged.fire();\n    }\n    /**\n     * Calling `resolve()` will mark the result array as complete.\n     *\n     * **NOTE** `resolve()` must be called, otherwise all consumers of this iterable will hang indefinitely, similar to a non-resolved promise.\n     * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.\n     */\n    resolve() {\n        if (this._state !== 0 /* AsyncIterableSourceState.Initial */) {\n            return;\n        }\n        this._state = 1 /* AsyncIterableSourceState.DoneOK */;\n        this._onStateChanged.fire();\n    }\n    /**\n     * Writing an error will permanently invalidate this iterable.\n     * The current users will receive an error thrown, as will all future users.\n     *\n     * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.\n     */\n    reject(error) {\n        if (this._state !== 0 /* AsyncIterableSourceState.Initial */) {\n            return;\n        }\n        this._state = 2 /* AsyncIterableSourceState.DoneError */;\n        this._error = error;\n        this._onStateChanged.fire();\n    }\n}\nAsyncIterableObject.EMPTY = AsyncIterableObject.fromArray([]);\nexport class CancelableAsyncIterableObject extends AsyncIterableObject {\n    constructor(_source, executor) {\n        super(executor);\n        this._source = _source;\n    }\n    cancel() {\n        this._source.cancel();\n    }\n}\nexport function createCancelableAsyncIterable(callback) {\n    const source = new CancellationTokenSource();\n    const innerIterable = callback(source.token);\n    return new CancelableAsyncIterableObject(source, (emitter) => __awaiter(this, void 0, void 0, function* () {\n        var _a, e_5, _b, _c;\n        const subscription = source.token.onCancellationRequested(() => {\n            subscription.dispose();\n            source.dispose();\n            emitter.reject(new CancellationError());\n        });\n        try {\n            try {\n                for (var _d = true, innerIterable_1 = __asyncValues(innerIterable), innerIterable_1_1; innerIterable_1_1 = yield innerIterable_1.next(), _a = innerIterable_1_1.done, !_a; _d = true) {\n                    _c = innerIterable_1_1.value;\n                    _d = false;\n                    const item = _c;\n                    if (source.token.isCancellationRequested) {\n                        // canceled in the meantime\n                        return;\n                    }\n                    emitter.emitOne(item);\n                }\n            }\n            catch (e_5_1) { e_5 = { error: e_5_1 }; }\n            finally {\n                try {\n                    if (!_d && !_a && (_b = innerIterable_1.return)) yield _b.call(innerIterable_1);\n                }\n                finally { if (e_5) throw e_5.error; }\n            }\n            subscription.dispose();\n            source.dispose();\n        }\n        catch (err) {\n            subscription.dispose();\n            source.dispose();\n            emitter.reject(err);\n        }\n    }));\n}\n//#endregion\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { transformErrorForSerialization } from '../errors.js';\nimport { Emitter } from '../event.js';\nimport { Disposable } from '../lifecycle.js';\nimport { getAllMethodNames } from '../objects.js';\nimport { isWeb } from '../platform.js';\nimport * as strings from '../strings.js';\nconst INITIALIZE = '$initialize';\nlet webWorkerWarningLogged = false;\nexport function logOnceWebWorkerWarning(err) {\n    if (!isWeb) {\n        // running tests\n        return;\n    }\n    if (!webWorkerWarningLogged) {\n        webWorkerWarningLogged = true;\n        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');\n    }\n    console.warn(err.message);\n}\nclass RequestMessage {\n    constructor(vsWorker, req, method, args) {\n        this.vsWorker = vsWorker;\n        this.req = req;\n        this.method = method;\n        this.args = args;\n        this.type = 0 /* MessageType.Request */;\n    }\n}\nclass ReplyMessage {\n    constructor(vsWorker, seq, res, err) {\n        this.vsWorker = vsWorker;\n        this.seq = seq;\n        this.res = res;\n        this.err = err;\n        this.type = 1 /* MessageType.Reply */;\n    }\n}\nclass SubscribeEventMessage {\n    constructor(vsWorker, req, eventName, arg) {\n        this.vsWorker = vsWorker;\n        this.req = req;\n        this.eventName = eventName;\n        this.arg = arg;\n        this.type = 2 /* MessageType.SubscribeEvent */;\n    }\n}\nclass EventMessage {\n    constructor(vsWorker, req, event) {\n        this.vsWorker = vsWorker;\n        this.req = req;\n        this.event = event;\n        this.type = 3 /* MessageType.Event */;\n    }\n}\nclass UnsubscribeEventMessage {\n    constructor(vsWorker, req) {\n        this.vsWorker = vsWorker;\n        this.req = req;\n        this.type = 4 /* MessageType.UnsubscribeEvent */;\n    }\n}\nclass SimpleWorkerProtocol {\n    constructor(handler) {\n        this._workerId = -1;\n        this._handler = handler;\n        this._lastSentReq = 0;\n        this._pendingReplies = Object.create(null);\n        this._pendingEmitters = new Map();\n        this._pendingEvents = new Map();\n    }\n    setWorkerId(workerId) {\n        this._workerId = workerId;\n    }\n    sendMessage(method, args) {\n        const req = String(++this._lastSentReq);\n        return new Promise((resolve, reject) => {\n            this._pendingReplies[req] = {\n                resolve: resolve,\n                reject: reject\n            };\n            this._send(new RequestMessage(this._workerId, req, method, args));\n        });\n    }\n    listen(eventName, arg) {\n        let req = null;\n        const emitter = new Emitter({\n            onWillAddFirstListener: () => {\n                req = String(++this._lastSentReq);\n                this._pendingEmitters.set(req, emitter);\n                this._send(new SubscribeEventMessage(this._workerId, req, eventName, arg));\n            },\n            onDidRemoveLastListener: () => {\n                this._pendingEmitters.delete(req);\n                this._send(new UnsubscribeEventMessage(this._workerId, req));\n                req = null;\n            }\n        });\n        return emitter.event;\n    }\n    handleMessage(message) {\n        if (!message || !message.vsWorker) {\n            return;\n        }\n        if (this._workerId !== -1 && message.vsWorker !== this._workerId) {\n            return;\n        }\n        this._handleMessage(message);\n    }\n    _handleMessage(msg) {\n        switch (msg.type) {\n            case 1 /* MessageType.Reply */:\n                return this._handleReplyMessage(msg);\n            case 0 /* MessageType.Request */:\n                return this._handleRequestMessage(msg);\n            case 2 /* MessageType.SubscribeEvent */:\n                return this._handleSubscribeEventMessage(msg);\n            case 3 /* MessageType.Event */:\n                return this._handleEventMessage(msg);\n            case 4 /* MessageType.UnsubscribeEvent */:\n                return this._handleUnsubscribeEventMessage(msg);\n        }\n    }\n    _handleReplyMessage(replyMessage) {\n        if (!this._pendingReplies[replyMessage.seq]) {\n            console.warn('Got reply to unknown seq');\n            return;\n        }\n        const reply = this._pendingReplies[replyMessage.seq];\n        delete this._pendingReplies[replyMessage.seq];\n        if (replyMessage.err) {\n            let err = replyMessage.err;\n            if (replyMessage.err.$isError) {\n                err = new Error();\n                err.name = replyMessage.err.name;\n                err.message = replyMessage.err.message;\n                err.stack = replyMessage.err.stack;\n            }\n            reply.reject(err);\n            return;\n        }\n        reply.resolve(replyMessage.res);\n    }\n    _handleRequestMessage(requestMessage) {\n        const req = requestMessage.req;\n        const result = this._handler.handleMessage(requestMessage.method, requestMessage.args);\n        result.then((r) => {\n            this._send(new ReplyMessage(this._workerId, req, r, undefined));\n        }, (e) => {\n            if (e.detail instanceof Error) {\n                // Loading errors have a detail property that points to the actual error\n                e.detail = transformErrorForSerialization(e.detail);\n            }\n            this._send(new ReplyMessage(this._workerId, req, undefined, transformErrorForSerialization(e)));\n        });\n    }\n    _handleSubscribeEventMessage(msg) {\n        const req = msg.req;\n        const disposable = this._handler.handleEvent(msg.eventName, msg.arg)((event) => {\n            this._send(new EventMessage(this._workerId, req, event));\n        });\n        this._pendingEvents.set(req, disposable);\n    }\n    _handleEventMessage(msg) {\n        if (!this._pendingEmitters.has(msg.req)) {\n            console.warn('Got event for unknown req');\n            return;\n        }\n        this._pendingEmitters.get(msg.req).fire(msg.event);\n    }\n    _handleUnsubscribeEventMessage(msg) {\n        if (!this._pendingEvents.has(msg.req)) {\n            console.warn('Got unsubscribe for unknown req');\n            return;\n        }\n        this._pendingEvents.get(msg.req).dispose();\n        this._pendingEvents.delete(msg.req);\n    }\n    _send(msg) {\n        const transfer = [];\n        if (msg.type === 0 /* MessageType.Request */) {\n            for (let i = 0; i < msg.args.length; i++) {\n                if (msg.args[i] instanceof ArrayBuffer) {\n                    transfer.push(msg.args[i]);\n                }\n            }\n        }\n        else if (msg.type === 1 /* MessageType.Reply */) {\n            if (msg.res instanceof ArrayBuffer) {\n                transfer.push(msg.res);\n            }\n        }\n        this._handler.sendMessage(msg, transfer);\n    }\n}\n/**\n * Main thread side\n */\nexport class SimpleWorkerClient extends Disposable {\n    constructor(workerFactory, moduleId, host) {\n        super();\n        let lazyProxyReject = null;\n        this._worker = this._register(workerFactory.create('vs/base/common/worker/simpleWorker', (msg) => {\n            this._protocol.handleMessage(msg);\n        }, (err) => {\n            // in Firefox, web workers fail lazily :(\n            // we will reject the proxy\n            lazyProxyReject === null || lazyProxyReject === void 0 ? void 0 : lazyProxyReject(err);\n        }));\n        this._protocol = new SimpleWorkerProtocol({\n            sendMessage: (msg, transfer) => {\n                this._worker.postMessage(msg, transfer);\n            },\n            handleMessage: (method, args) => {\n                if (typeof host[method] !== 'function') {\n                    return Promise.reject(new Error('Missing method ' + method + ' on main thread host.'));\n                }\n                try {\n                    return Promise.resolve(host[method].apply(host, args));\n                }\n                catch (e) {\n                    return Promise.reject(e);\n                }\n            },\n            handleEvent: (eventName, arg) => {\n                if (propertyIsDynamicEvent(eventName)) {\n                    const event = host[eventName].call(host, arg);\n                    if (typeof event !== 'function') {\n                        throw new Error(`Missing dynamic event ${eventName} on main thread host.`);\n                    }\n                    return event;\n                }\n                if (propertyIsEvent(eventName)) {\n                    const event = host[eventName];\n                    if (typeof event !== 'function') {\n                        throw new Error(`Missing event ${eventName} on main thread host.`);\n                    }\n                    return event;\n                }\n                throw new Error(`Malformed event name ${eventName}`);\n            }\n        });\n        this._protocol.setWorkerId(this._worker.getId());\n        // Gather loader configuration\n        let loaderConfiguration = null;\n        const globalRequire = globalThis.require;\n        if (typeof globalRequire !== 'undefined' && typeof globalRequire.getConfig === 'function') {\n            // Get the configuration from the Monaco AMD Loader\n            loaderConfiguration = globalRequire.getConfig();\n        }\n        else if (typeof globalThis.requirejs !== 'undefined') {\n            // Get the configuration from requirejs\n            loaderConfiguration = globalThis.requirejs.s.contexts._.config;\n        }\n        const hostMethods = getAllMethodNames(host);\n        // Send initialize message\n        this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [\n            this._worker.getId(),\n            JSON.parse(JSON.stringify(loaderConfiguration)),\n            moduleId,\n            hostMethods,\n        ]);\n        // Create proxy to loaded code\n        const proxyMethodRequest = (method, args) => {\n            return this._request(method, args);\n        };\n        const proxyListen = (eventName, arg) => {\n            return this._protocol.listen(eventName, arg);\n        };\n        this._lazyProxy = new Promise((resolve, reject) => {\n            lazyProxyReject = reject;\n            this._onModuleLoaded.then((availableMethods) => {\n                resolve(createProxyObject(availableMethods, proxyMethodRequest, proxyListen));\n            }, (e) => {\n                reject(e);\n                this._onError('Worker failed to load ' + moduleId, e);\n            });\n        });\n    }\n    getProxyObject() {\n        return this._lazyProxy;\n    }\n    _request(method, args) {\n        return new Promise((resolve, reject) => {\n            this._onModuleLoaded.then(() => {\n                this._protocol.sendMessage(method, args).then(resolve, reject);\n            }, reject);\n        });\n    }\n    _onError(message, error) {\n        console.error(message);\n        console.info(error);\n    }\n}\nfunction propertyIsEvent(name) {\n    // Assume a property is an event if it has a form of \"onSomething\"\n    return name[0] === 'o' && name[1] === 'n' && strings.isUpperAsciiLetter(name.charCodeAt(2));\n}\nfunction propertyIsDynamicEvent(name) {\n    // Assume a property is a dynamic event (a method that returns an event) if it has a form of \"onDynamicSomething\"\n    return /^onDynamic/.test(name) && strings.isUpperAsciiLetter(name.charCodeAt(9));\n}\nfunction createProxyObject(methodNames, invoke, proxyListen) {\n    const createProxyMethod = (method) => {\n        return function () {\n            const args = Array.prototype.slice.call(arguments, 0);\n            return invoke(method, args);\n        };\n    };\n    const createProxyDynamicEvent = (eventName) => {\n        return function (arg) {\n            return proxyListen(eventName, arg);\n        };\n    };\n    const result = {};\n    for (const methodName of methodNames) {\n        if (propertyIsDynamicEvent(methodName)) {\n            result[methodName] = createProxyDynamicEvent(methodName);\n            continue;\n        }\n        if (propertyIsEvent(methodName)) {\n            result[methodName] = proxyListen(methodName, undefined);\n            continue;\n        }\n        result[methodName] = createProxyMethod(methodName);\n    }\n    return result;\n}\n/**\n * Worker side\n */\nexport class SimpleWorkerServer {\n    constructor(postMessage, requestHandlerFactory) {\n        this._requestHandlerFactory = requestHandlerFactory;\n        this._requestHandler = null;\n        this._protocol = new SimpleWorkerProtocol({\n            sendMessage: (msg, transfer) => {\n                postMessage(msg, transfer);\n            },\n            handleMessage: (method, args) => this._handleMessage(method, args),\n            handleEvent: (eventName, arg) => this._handleEvent(eventName, arg)\n        });\n    }\n    onmessage(msg) {\n        this._protocol.handleMessage(msg);\n    }\n    _handleMessage(method, args) {\n        if (method === INITIALIZE) {\n            return this.initialize(args[0], args[1], args[2], args[3]);\n        }\n        if (!this._requestHandler || typeof this._requestHandler[method] !== 'function') {\n            return Promise.reject(new Error('Missing requestHandler or method: ' + method));\n        }\n        try {\n            return Promise.resolve(this._requestHandler[method].apply(this._requestHandler, args));\n        }\n        catch (e) {\n            return Promise.reject(e);\n        }\n    }\n    _handleEvent(eventName, arg) {\n        if (!this._requestHandler) {\n            throw new Error(`Missing requestHandler`);\n        }\n        if (propertyIsDynamicEvent(eventName)) {\n            const event = this._requestHandler[eventName].call(this._requestHandler, arg);\n            if (typeof event !== 'function') {\n                throw new Error(`Missing dynamic event ${eventName} on request handler.`);\n            }\n            return event;\n        }\n        if (propertyIsEvent(eventName)) {\n            const event = this._requestHandler[eventName];\n            if (typeof event !== 'function') {\n                throw new Error(`Missing event ${eventName} on request handler.`);\n            }\n            return event;\n        }\n        throw new Error(`Malformed event name ${eventName}`);\n    }\n    initialize(workerId, loaderConfig, moduleId, hostMethods) {\n        this._protocol.setWorkerId(workerId);\n        const proxyMethodRequest = (method, args) => {\n            return this._protocol.sendMessage(method, args);\n        };\n        const proxyListen = (eventName, arg) => {\n            return this._protocol.listen(eventName, arg);\n        };\n        const hostProxy = createProxyObject(hostMethods, proxyMethodRequest, proxyListen);\n        if (this._requestHandlerFactory) {\n            // static request handler\n            this._requestHandler = this._requestHandlerFactory(hostProxy);\n            return Promise.resolve(getAllMethodNames(this._requestHandler));\n        }\n        if (loaderConfig) {\n            // Remove 'baseUrl', handling it is beyond scope for now\n            if (typeof loaderConfig.baseUrl !== 'undefined') {\n                delete loaderConfig['baseUrl'];\n            }\n            if (typeof loaderConfig.paths !== 'undefined') {\n                if (typeof loaderConfig.paths.vs !== 'undefined') {\n                    delete loaderConfig.paths['vs'];\n                }\n            }\n            if (typeof loaderConfig.trustedTypesPolicy !== undefined) {\n                // don't use, it has been destroyed during serialize\n                delete loaderConfig['trustedTypesPolicy'];\n            }\n            // Since this is in a web worker, enable catching errors\n            loaderConfig.catchError = true;\n            globalThis.require.config(loaderConfig);\n        }\n        return new Promise((resolve, reject) => {\n            // Use the global require to be sure to get the global config\n            // ESM-comment-begin\n            // \t\t\tconst req = (globalThis.require || require);\n            // ESM-comment-end\n            // ESM-uncomment-begin\n            const req = globalThis.require;\n            // ESM-uncomment-end\n            req([moduleId], (module) => {\n                this._requestHandler = module.create(hostProxy);\n                if (!this._requestHandler) {\n                    reject(new Error(`No RequestHandler!`));\n                    return;\n                }\n                resolve(getAllMethodNames(this._requestHandler));\n            }, reject);\n        });\n    }\n}\n/**\n * Called on the worker side\n * @skipMangle\n */\nexport function create(postMessage) {\n    return new SimpleWorkerServer(postMessage, null);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { onUnexpectedError } from '../common/errors.js';\nexport function createTrustedTypesPolicy(policyName, policyOptions) {\n    var _a;\n    const monacoEnvironment = globalThis.MonacoEnvironment;\n    if (monacoEnvironment === null || monacoEnvironment === void 0 ? void 0 : monacoEnvironment.createTrustedTypesPolicy) {\n        try {\n            return monacoEnvironment.createTrustedTypesPolicy(policyName, policyOptions);\n        }\n        catch (err) {\n            onUnexpectedError(err);\n            return undefined;\n        }\n    }\n    try {\n        return (_a = window.trustedTypes) === null || _a === void 0 ? void 0 : _a.createPolicy(policyName, policyOptions);\n    }\n    catch (err) {\n        onUnexpectedError(err);\n        return undefined;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { createTrustedTypesPolicy } from './trustedTypes.js';\nimport { logOnceWebWorkerWarning } from '../common/worker/simpleWorker.js';\nconst ttPolicy = createTrustedTypesPolicy('defaultWorkerFactory', { createScriptURL: value => value });\nfunction getWorker(label) {\n    const monacoEnvironment = globalThis.MonacoEnvironment;\n    if (monacoEnvironment) {\n        if (typeof monacoEnvironment.getWorker === 'function') {\n            return monacoEnvironment.getWorker('workerMain.js', label);\n        }\n        if (typeof monacoEnvironment.getWorkerUrl === 'function') {\n            const workerUrl = monacoEnvironment.getWorkerUrl('workerMain.js', label);\n            return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) : workerUrl, { name: label });\n        }\n    }\n    // ESM-comment-begin\n    // \tif (typeof require === 'function') {\n    // \t\t// check if the JS lives on a different origin\n    // \t\tconst workerMain = require.toUrl('vs/base/worker/workerMain.js'); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321\n    // \t\tconst workerUrl = getWorkerBootstrapUrl(workerMain, label);\n    // \t\treturn new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label });\n    // \t}\n    // ESM-comment-end\n    throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);\n}\n// ESM-comment-begin\n// export function getWorkerBootstrapUrl(scriptPath: string, label: string): string {\n// \tif (/^((http:)|(https:)|(file:))/.test(scriptPath) && scriptPath.substring(0, globalThis.origin.length) !== globalThis.origin) {\n// \t\t// this is the cross-origin case\n// \t\t// i.e. the webpage is running at a different origin than where the scripts are loaded from\n// \t\tconst myPath = 'vs/base/worker/defaultWorkerFactory.js';\n// \t\tconst workerBaseUrl = require.toUrl(myPath).slice(0, -myPath.length); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321\n// \t\tconst js = `/*${label}*/globalThis.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });importScripts(ttPolicy?.createScriptURL('${scriptPath}') ?? '${scriptPath}');/*${label}*/`;\n// \t\tconst blob = new Blob([js], { type: 'application/javascript' });\n// \t\treturn URL.createObjectURL(blob);\n// \t}\n// \n// \tconst start = scriptPath.lastIndexOf('?');\n// \tconst end = scriptPath.lastIndexOf('#', start);\n// \tconst params = start > 0\n// \t\t? new URLSearchParams(scriptPath.substring(start + 1, ~end ? end : undefined))\n// \t\t: new URLSearchParams();\n// \n// \tCOI.addSearchParam(params, true, true);\n// \tconst search = params.toString();\n// \n// \tif (!search) {\n// \t\treturn `${scriptPath}#${label}`;\n// \t} else {\n// \t\treturn `${scriptPath}?${params.toString()}#${label}`;\n// \t}\n// }\n// ESM-comment-end\nfunction isPromiseLike(obj) {\n    if (typeof obj.then === 'function') {\n        return true;\n    }\n    return false;\n}\n/**\n * A worker that uses HTML5 web workers so that is has\n * its own global scope and its own thread.\n */\nclass WebWorker {\n    constructor(moduleId, id, label, onMessageCallback, onErrorCallback) {\n        this.id = id;\n        const workerOrPromise = getWorker(label);\n        if (isPromiseLike(workerOrPromise)) {\n            this.worker = workerOrPromise;\n        }\n        else {\n            this.worker = Promise.resolve(workerOrPromise);\n        }\n        this.postMessage(moduleId, []);\n        this.worker.then((w) => {\n            w.onmessage = function (ev) {\n                onMessageCallback(ev.data);\n            };\n            w.onmessageerror = onErrorCallback;\n            if (typeof w.addEventListener === 'function') {\n                w.addEventListener('error', onErrorCallback);\n            }\n        });\n    }\n    getId() {\n        return this.id;\n    }\n    postMessage(message, transfer) {\n        var _a;\n        (_a = this.worker) === null || _a === void 0 ? void 0 : _a.then(w => w.postMessage(message, transfer));\n    }\n    dispose() {\n        var _a;\n        (_a = this.worker) === null || _a === void 0 ? void 0 : _a.then(w => w.terminate());\n        this.worker = null;\n    }\n}\nexport class DefaultWorkerFactory {\n    constructor(label) {\n        this._label = label;\n        this._webWorkerFailedBeforeError = false;\n    }\n    create(moduleId, onMessageCallback, onErrorCallback) {\n        const workerId = (++DefaultWorkerFactory.LAST_WORKER_ID);\n        if (this._webWorkerFailedBeforeError) {\n            throw this._webWorkerFailedBeforeError;\n        }\n        return new WebWorker(moduleId, workerId, this._label || 'anonymous' + workerId, onMessageCallback, (err) => {\n            logOnceWebWorkerWarning(err);\n            this._webWorkerFailedBeforeError = err;\n            onErrorCallback(err);\n        });\n    }\n}\nDefaultWorkerFactory.LAST_WORKER_ID = 0;\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * Represents information about a specific difference between two sequences.\n */\nexport class DiffChange {\n    /**\n     * Constructs a new DiffChange with the given sequence information\n     * and content.\n     */\n    constructor(originalStart, originalLength, modifiedStart, modifiedLength) {\n        //Debug.Assert(originalLength > 0 || modifiedLength > 0, \"originalLength and modifiedLength cannot both be <= 0\");\n        this.originalStart = originalStart;\n        this.originalLength = originalLength;\n        this.modifiedStart = modifiedStart;\n        this.modifiedLength = modifiedLength;\n    }\n    /**\n     * The end point (exclusive) of the change in the original sequence.\n     */\n    getOriginalEnd() {\n        return this.originalStart + this.originalLength;\n    }\n    /**\n     * The end point (exclusive) of the change in the modified sequence.\n     */\n    getModifiedEnd() {\n        return this.modifiedStart + this.modifiedLength;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from './strings.js';\n/**\n * Return a hash value for an object.\n */\nexport function hash(obj) {\n    return doHash(obj, 0);\n}\nexport function doHash(obj, hashVal) {\n    switch (typeof obj) {\n        case 'object':\n            if (obj === null) {\n                return numberHash(349, hashVal);\n            }\n            else if (Array.isArray(obj)) {\n                return arrayHash(obj, hashVal);\n            }\n            return objectHash(obj, hashVal);\n        case 'string':\n            return stringHash(obj, hashVal);\n        case 'boolean':\n            return booleanHash(obj, hashVal);\n        case 'number':\n            return numberHash(obj, hashVal);\n        case 'undefined':\n            return numberHash(937, hashVal);\n        default:\n            return numberHash(617, hashVal);\n    }\n}\nexport function numberHash(val, initialHashVal) {\n    return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32\n}\nfunction booleanHash(b, initialHashVal) {\n    return numberHash(b ? 433 : 863, initialHashVal);\n}\nexport function stringHash(s, hashVal) {\n    hashVal = numberHash(149417, hashVal);\n    for (let i = 0, length = s.length; i < length; i++) {\n        hashVal = numberHash(s.charCodeAt(i), hashVal);\n    }\n    return hashVal;\n}\nfunction arrayHash(arr, initialHashVal) {\n    initialHashVal = numberHash(104579, initialHashVal);\n    return arr.reduce((hashVal, item) => doHash(item, hashVal), initialHashVal);\n}\nfunction objectHash(obj, initialHashVal) {\n    initialHashVal = numberHash(181387, initialHashVal);\n    return Object.keys(obj).sort().reduce((hashVal, key) => {\n        hashVal = stringHash(key, hashVal);\n        return doHash(obj[key], hashVal);\n    }, initialHashVal);\n}\nfunction leftRotate(value, bits, totalBits = 32) {\n    // delta + bits = totalBits\n    const delta = totalBits - bits;\n    // All ones, expect `delta` zeros aligned to the right\n    const mask = ~((1 << delta) - 1);\n    // Join (value left-shifted `bits` bits) with (masked value right-shifted `delta` bits)\n    return ((value << bits) | ((mask & value) >>> delta)) >>> 0;\n}\nfunction fill(dest, index = 0, count = dest.byteLength, value = 0) {\n    for (let i = 0; i < count; i++) {\n        dest[index + i] = value;\n    }\n}\nfunction leftPad(value, length, char = '0') {\n    while (value.length < length) {\n        value = char + value;\n    }\n    return value;\n}\nexport function toHexString(bufferOrValue, bitsize = 32) {\n    if (bufferOrValue instanceof ArrayBuffer) {\n        return Array.from(new Uint8Array(bufferOrValue)).map(b => b.toString(16).padStart(2, '0')).join('');\n    }\n    return leftPad((bufferOrValue >>> 0).toString(16), bitsize / 4);\n}\n/**\n * A SHA1 implementation that works with strings and does not allocate.\n */\nexport class StringSHA1 {\n    constructor() {\n        this._h0 = 0x67452301;\n        this._h1 = 0xEFCDAB89;\n        this._h2 = 0x98BADCFE;\n        this._h3 = 0x10325476;\n        this._h4 = 0xC3D2E1F0;\n        this._buff = new Uint8Array(64 /* SHA1Constant.BLOCK_SIZE */ + 3 /* to fit any utf-8 */);\n        this._buffDV = new DataView(this._buff.buffer);\n        this._buffLen = 0;\n        this._totalLen = 0;\n        this._leftoverHighSurrogate = 0;\n        this._finished = false;\n    }\n    update(str) {\n        const strLen = str.length;\n        if (strLen === 0) {\n            return;\n        }\n        const buff = this._buff;\n        let buffLen = this._buffLen;\n        let leftoverHighSurrogate = this._leftoverHighSurrogate;\n        let charCode;\n        let offset;\n        if (leftoverHighSurrogate !== 0) {\n            charCode = leftoverHighSurrogate;\n            offset = -1;\n            leftoverHighSurrogate = 0;\n        }\n        else {\n            charCode = str.charCodeAt(0);\n            offset = 0;\n        }\n        while (true) {\n            let codePoint = charCode;\n            if (strings.isHighSurrogate(charCode)) {\n                if (offset + 1 < strLen) {\n                    const nextCharCode = str.charCodeAt(offset + 1);\n                    if (strings.isLowSurrogate(nextCharCode)) {\n                        offset++;\n                        codePoint = strings.computeCodePoint(charCode, nextCharCode);\n                    }\n                    else {\n                        // illegal => unicode replacement character\n                        codePoint = 65533 /* SHA1Constant.UNICODE_REPLACEMENT */;\n                    }\n                }\n                else {\n                    // last character is a surrogate pair\n                    leftoverHighSurrogate = charCode;\n                    break;\n                }\n            }\n            else if (strings.isLowSurrogate(charCode)) {\n                // illegal => unicode replacement character\n                codePoint = 65533 /* SHA1Constant.UNICODE_REPLACEMENT */;\n            }\n            buffLen = this._push(buff, buffLen, codePoint);\n            offset++;\n            if (offset < strLen) {\n                charCode = str.charCodeAt(offset);\n            }\n            else {\n                break;\n            }\n        }\n        this._buffLen = buffLen;\n        this._leftoverHighSurrogate = leftoverHighSurrogate;\n    }\n    _push(buff, buffLen, codePoint) {\n        if (codePoint < 0x0080) {\n            buff[buffLen++] = codePoint;\n        }\n        else if (codePoint < 0x0800) {\n            buff[buffLen++] = 0b11000000 | ((codePoint & 0b00000000000000000000011111000000) >>> 6);\n            buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);\n        }\n        else if (codePoint < 0x10000) {\n            buff[buffLen++] = 0b11100000 | ((codePoint & 0b00000000000000001111000000000000) >>> 12);\n            buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000111111000000) >>> 6);\n            buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);\n        }\n        else {\n            buff[buffLen++] = 0b11110000 | ((codePoint & 0b00000000000111000000000000000000) >>> 18);\n            buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000111111000000000000) >>> 12);\n            buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000111111000000) >>> 6);\n            buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);\n        }\n        if (buffLen >= 64 /* SHA1Constant.BLOCK_SIZE */) {\n            this._step();\n            buffLen -= 64 /* SHA1Constant.BLOCK_SIZE */;\n            this._totalLen += 64 /* SHA1Constant.BLOCK_SIZE */;\n            // take last 3 in case of UTF8 overflow\n            buff[0] = buff[64 /* SHA1Constant.BLOCK_SIZE */ + 0];\n            buff[1] = buff[64 /* SHA1Constant.BLOCK_SIZE */ + 1];\n            buff[2] = buff[64 /* SHA1Constant.BLOCK_SIZE */ + 2];\n        }\n        return buffLen;\n    }\n    digest() {\n        if (!this._finished) {\n            this._finished = true;\n            if (this._leftoverHighSurrogate) {\n                // illegal => unicode replacement character\n                this._leftoverHighSurrogate = 0;\n                this._buffLen = this._push(this._buff, this._buffLen, 65533 /* SHA1Constant.UNICODE_REPLACEMENT */);\n            }\n            this._totalLen += this._buffLen;\n            this._wrapUp();\n        }\n        return toHexString(this._h0) + toHexString(this._h1) + toHexString(this._h2) + toHexString(this._h3) + toHexString(this._h4);\n    }\n    _wrapUp() {\n        this._buff[this._buffLen++] = 0x80;\n        fill(this._buff, this._buffLen);\n        if (this._buffLen > 56) {\n            this._step();\n            fill(this._buff);\n        }\n        // this will fit because the mantissa can cover up to 52 bits\n        const ml = 8 * this._totalLen;\n        this._buffDV.setUint32(56, Math.floor(ml / 4294967296), false);\n        this._buffDV.setUint32(60, ml % 4294967296, false);\n        this._step();\n    }\n    _step() {\n        const bigBlock32 = StringSHA1._bigBlock32;\n        const data = this._buffDV;\n        for (let j = 0; j < 64 /* 16*4 */; j += 4) {\n            bigBlock32.setUint32(j, data.getUint32(j, false), false);\n        }\n        for (let j = 64; j < 320 /* 80*4 */; j += 4) {\n            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);\n        }\n        let a = this._h0;\n        let b = this._h1;\n        let c = this._h2;\n        let d = this._h3;\n        let e = this._h4;\n        let f, k;\n        let temp;\n        for (let j = 0; j < 80; j++) {\n            if (j < 20) {\n                f = (b & c) | ((~b) & d);\n                k = 0x5A827999;\n            }\n            else if (j < 40) {\n                f = b ^ c ^ d;\n                k = 0x6ED9EBA1;\n            }\n            else if (j < 60) {\n                f = (b & c) | (b & d) | (c & d);\n                k = 0x8F1BBCDC;\n            }\n            else {\n                f = b ^ c ^ d;\n                k = 0xCA62C1D6;\n            }\n            temp = (leftRotate(a, 5) + f + e + k + bigBlock32.getUint32(j * 4, false)) & 0xffffffff;\n            e = d;\n            d = c;\n            c = leftRotate(b, 30);\n            b = a;\n            a = temp;\n        }\n        this._h0 = (this._h0 + a) & 0xffffffff;\n        this._h1 = (this._h1 + b) & 0xffffffff;\n        this._h2 = (this._h2 + c) & 0xffffffff;\n        this._h3 = (this._h3 + d) & 0xffffffff;\n        this._h4 = (this._h4 + e) & 0xffffffff;\n    }\n}\nStringSHA1._bigBlock32 = new DataView(new ArrayBuffer(320)); // 80 * 4 = 320\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { DiffChange } from './diffChange.js';\nimport { stringHash } from '../hash.js';\nexport class StringDiffSequence {\n    constructor(source) {\n        this.source = source;\n    }\n    getElements() {\n        const source = this.source;\n        const characters = new Int32Array(source.length);\n        for (let i = 0, len = source.length; i < len; i++) {\n            characters[i] = source.charCodeAt(i);\n        }\n        return characters;\n    }\n}\nexport function stringDiff(original, modified, pretty) {\n    return new LcsDiff(new StringDiffSequence(original), new StringDiffSequence(modified)).ComputeDiff(pretty).changes;\n}\n//\n// The code below has been ported from a C# implementation in VS\n//\nclass Debug {\n    static Assert(condition, message) {\n        if (!condition) {\n            throw new Error(message);\n        }\n    }\n}\nclass MyArray {\n    /**\n     * Copies a range of elements from an Array starting at the specified source index and pastes\n     * them to another Array starting at the specified destination index. The length and the indexes\n     * are specified as 64-bit integers.\n     * sourceArray:\n     *\t\tThe Array that contains the data to copy.\n     * sourceIndex:\n     *\t\tA 64-bit integer that represents the index in the sourceArray at which copying begins.\n     * destinationArray:\n     *\t\tThe Array that receives the data.\n     * destinationIndex:\n     *\t\tA 64-bit integer that represents the index in the destinationArray at which storing begins.\n     * length:\n     *\t\tA 64-bit integer that represents the number of elements to copy.\n     */\n    static Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {\n        for (let i = 0; i < length; i++) {\n            destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];\n        }\n    }\n    static Copy2(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {\n        for (let i = 0; i < length; i++) {\n            destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];\n        }\n    }\n}\n/**\n * A utility class which helps to create the set of DiffChanges from\n * a difference operation. This class accepts original DiffElements and\n * modified DiffElements that are involved in a particular change. The\n * MarkNextChange() method can be called to mark the separation between\n * distinct changes. At the end, the Changes property can be called to retrieve\n * the constructed changes.\n */\nclass DiffChangeHelper {\n    /**\n     * Constructs a new DiffChangeHelper for the given DiffSequences.\n     */\n    constructor() {\n        this.m_changes = [];\n        this.m_originalStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n        this.m_modifiedStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n        this.m_originalCount = 0;\n        this.m_modifiedCount = 0;\n    }\n    /**\n     * Marks the beginning of the next change in the set of differences.\n     */\n    MarkNextChange() {\n        // Only add to the list if there is something to add\n        if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {\n            // Add the new change to our list\n            this.m_changes.push(new DiffChange(this.m_originalStart, this.m_originalCount, this.m_modifiedStart, this.m_modifiedCount));\n        }\n        // Reset for the next change\n        this.m_originalCount = 0;\n        this.m_modifiedCount = 0;\n        this.m_originalStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n        this.m_modifiedStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n    }\n    /**\n     * Adds the original element at the given position to the elements\n     * affected by the current change. The modified index gives context\n     * to the change position with respect to the original sequence.\n     * @param originalIndex The index of the original element to add.\n     * @param modifiedIndex The index of the modified element that provides corresponding position in the modified sequence.\n     */\n    AddOriginalElement(originalIndex, modifiedIndex) {\n        // The 'true' start index is the smallest of the ones we've seen\n        this.m_originalStart = Math.min(this.m_originalStart, originalIndex);\n        this.m_modifiedStart = Math.min(this.m_modifiedStart, modifiedIndex);\n        this.m_originalCount++;\n    }\n    /**\n     * Adds the modified element at the given position to the elements\n     * affected by the current change. The original index gives context\n     * to the change position with respect to the modified sequence.\n     * @param originalIndex The index of the original element that provides corresponding position in the original sequence.\n     * @param modifiedIndex The index of the modified element to add.\n     */\n    AddModifiedElement(originalIndex, modifiedIndex) {\n        // The 'true' start index is the smallest of the ones we've seen\n        this.m_originalStart = Math.min(this.m_originalStart, originalIndex);\n        this.m_modifiedStart = Math.min(this.m_modifiedStart, modifiedIndex);\n        this.m_modifiedCount++;\n    }\n    /**\n     * Retrieves all of the changes marked by the class.\n     */\n    getChanges() {\n        if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {\n            // Finish up on whatever is left\n            this.MarkNextChange();\n        }\n        return this.m_changes;\n    }\n    /**\n     * Retrieves all of the changes marked by the class in the reverse order\n     */\n    getReverseChanges() {\n        if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {\n            // Finish up on whatever is left\n            this.MarkNextChange();\n        }\n        this.m_changes.reverse();\n        return this.m_changes;\n    }\n}\n/**\n * An implementation of the difference algorithm described in\n * \"An O(ND) Difference Algorithm and its variations\" by Eugene W. Myers\n */\nexport class LcsDiff {\n    /**\n     * Constructs the DiffFinder\n     */\n    constructor(originalSequence, modifiedSequence, continueProcessingPredicate = null) {\n        this.ContinueProcessingPredicate = continueProcessingPredicate;\n        this._originalSequence = originalSequence;\n        this._modifiedSequence = modifiedSequence;\n        const [originalStringElements, originalElementsOrHash, originalHasStrings] = LcsDiff._getElements(originalSequence);\n        const [modifiedStringElements, modifiedElementsOrHash, modifiedHasStrings] = LcsDiff._getElements(modifiedSequence);\n        this._hasStrings = (originalHasStrings && modifiedHasStrings);\n        this._originalStringElements = originalStringElements;\n        this._originalElementsOrHash = originalElementsOrHash;\n        this._modifiedStringElements = modifiedStringElements;\n        this._modifiedElementsOrHash = modifiedElementsOrHash;\n        this.m_forwardHistory = [];\n        this.m_reverseHistory = [];\n    }\n    static _isStringArray(arr) {\n        return (arr.length > 0 && typeof arr[0] === 'string');\n    }\n    static _getElements(sequence) {\n        const elements = sequence.getElements();\n        if (LcsDiff._isStringArray(elements)) {\n            const hashes = new Int32Array(elements.length);\n            for (let i = 0, len = elements.length; i < len; i++) {\n                hashes[i] = stringHash(elements[i], 0);\n            }\n            return [elements, hashes, true];\n        }\n        if (elements instanceof Int32Array) {\n            return [[], elements, false];\n        }\n        return [[], new Int32Array(elements), false];\n    }\n    ElementsAreEqual(originalIndex, newIndex) {\n        if (this._originalElementsOrHash[originalIndex] !== this._modifiedElementsOrHash[newIndex]) {\n            return false;\n        }\n        return (this._hasStrings ? this._originalStringElements[originalIndex] === this._modifiedStringElements[newIndex] : true);\n    }\n    ElementsAreStrictEqual(originalIndex, newIndex) {\n        if (!this.ElementsAreEqual(originalIndex, newIndex)) {\n            return false;\n        }\n        const originalElement = LcsDiff._getStrictElement(this._originalSequence, originalIndex);\n        const modifiedElement = LcsDiff._getStrictElement(this._modifiedSequence, newIndex);\n        return (originalElement === modifiedElement);\n    }\n    static _getStrictElement(sequence, index) {\n        if (typeof sequence.getStrictElement === 'function') {\n            return sequence.getStrictElement(index);\n        }\n        return null;\n    }\n    OriginalElementsAreEqual(index1, index2) {\n        if (this._originalElementsOrHash[index1] !== this._originalElementsOrHash[index2]) {\n            return false;\n        }\n        return (this._hasStrings ? this._originalStringElements[index1] === this._originalStringElements[index2] : true);\n    }\n    ModifiedElementsAreEqual(index1, index2) {\n        if (this._modifiedElementsOrHash[index1] !== this._modifiedElementsOrHash[index2]) {\n            return false;\n        }\n        return (this._hasStrings ? this._modifiedStringElements[index1] === this._modifiedStringElements[index2] : true);\n    }\n    ComputeDiff(pretty) {\n        return this._ComputeDiff(0, this._originalElementsOrHash.length - 1, 0, this._modifiedElementsOrHash.length - 1, pretty);\n    }\n    /**\n     * Computes the differences between the original and modified input\n     * sequences on the bounded range.\n     * @returns An array of the differences between the two input sequences.\n     */\n    _ComputeDiff(originalStart, originalEnd, modifiedStart, modifiedEnd, pretty) {\n        const quitEarlyArr = [false];\n        let changes = this.ComputeDiffRecursive(originalStart, originalEnd, modifiedStart, modifiedEnd, quitEarlyArr);\n        if (pretty) {\n            // We have to clean up the computed diff to be more intuitive\n            // but it turns out this cannot be done correctly until the entire set\n            // of diffs have been computed\n            changes = this.PrettifyChanges(changes);\n        }\n        return {\n            quitEarly: quitEarlyArr[0],\n            changes: changes\n        };\n    }\n    /**\n     * Private helper method which computes the differences on the bounded range\n     * recursively.\n     * @returns An array of the differences between the two input sequences.\n     */\n    ComputeDiffRecursive(originalStart, originalEnd, modifiedStart, modifiedEnd, quitEarlyArr) {\n        quitEarlyArr[0] = false;\n        // Find the start of the differences\n        while (originalStart <= originalEnd && modifiedStart <= modifiedEnd && this.ElementsAreEqual(originalStart, modifiedStart)) {\n            originalStart++;\n            modifiedStart++;\n        }\n        // Find the end of the differences\n        while (originalEnd >= originalStart && modifiedEnd >= modifiedStart && this.ElementsAreEqual(originalEnd, modifiedEnd)) {\n            originalEnd--;\n            modifiedEnd--;\n        }\n        // In the special case where we either have all insertions or all deletions or the sequences are identical\n        if (originalStart > originalEnd || modifiedStart > modifiedEnd) {\n            let changes;\n            if (modifiedStart <= modifiedEnd) {\n                Debug.Assert(originalStart === originalEnd + 1, 'originalStart should only be one more than originalEnd');\n                // All insertions\n                changes = [\n                    new DiffChange(originalStart, 0, modifiedStart, modifiedEnd - modifiedStart + 1)\n                ];\n            }\n            else if (originalStart <= originalEnd) {\n                Debug.Assert(modifiedStart === modifiedEnd + 1, 'modifiedStart should only be one more than modifiedEnd');\n                // All deletions\n                changes = [\n                    new DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, 0)\n                ];\n            }\n            else {\n                Debug.Assert(originalStart === originalEnd + 1, 'originalStart should only be one more than originalEnd');\n                Debug.Assert(modifiedStart === modifiedEnd + 1, 'modifiedStart should only be one more than modifiedEnd');\n                // Identical sequences - No differences\n                changes = [];\n            }\n            return changes;\n        }\n        // This problem can be solved using the Divide-And-Conquer technique.\n        const midOriginalArr = [0];\n        const midModifiedArr = [0];\n        const result = this.ComputeRecursionPoint(originalStart, originalEnd, modifiedStart, modifiedEnd, midOriginalArr, midModifiedArr, quitEarlyArr);\n        const midOriginal = midOriginalArr[0];\n        const midModified = midModifiedArr[0];\n        if (result !== null) {\n            // Result is not-null when there was enough memory to compute the changes while\n            // searching for the recursion point\n            return result;\n        }\n        else if (!quitEarlyArr[0]) {\n            // We can break the problem down recursively by finding the changes in the\n            // First Half:   (originalStart, modifiedStart) to (midOriginal, midModified)\n            // Second Half:  (midOriginal + 1, minModified + 1) to (originalEnd, modifiedEnd)\n            // NOTE: ComputeDiff() is inclusive, therefore the second range starts on the next point\n            const leftChanges = this.ComputeDiffRecursive(originalStart, midOriginal, modifiedStart, midModified, quitEarlyArr);\n            let rightChanges = [];\n            if (!quitEarlyArr[0]) {\n                rightChanges = this.ComputeDiffRecursive(midOriginal + 1, originalEnd, midModified + 1, modifiedEnd, quitEarlyArr);\n            }\n            else {\n                // We didn't have time to finish the first half, so we don't have time to compute this half.\n                // Consider the entire rest of the sequence different.\n                rightChanges = [\n                    new DiffChange(midOriginal + 1, originalEnd - (midOriginal + 1) + 1, midModified + 1, modifiedEnd - (midModified + 1) + 1)\n                ];\n            }\n            return this.ConcatenateChanges(leftChanges, rightChanges);\n        }\n        // If we hit here, we quit early, and so can't return anything meaningful\n        return [\n            new DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, modifiedEnd - modifiedStart + 1)\n        ];\n    }\n    WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr) {\n        let forwardChanges = null;\n        let reverseChanges = null;\n        // First, walk backward through the forward diagonals history\n        let changeHelper = new DiffChangeHelper();\n        let diagonalMin = diagonalForwardStart;\n        let diagonalMax = diagonalForwardEnd;\n        let diagonalRelative = (midOriginalArr[0] - midModifiedArr[0]) - diagonalForwardOffset;\n        let lastOriginalIndex = -1073741824 /* Constants.MIN_SAFE_SMALL_INTEGER */;\n        let historyIndex = this.m_forwardHistory.length - 1;\n        do {\n            // Get the diagonal index from the relative diagonal number\n            const diagonal = diagonalRelative + diagonalForwardBase;\n            // Figure out where we came from\n            if (diagonal === diagonalMin || (diagonal < diagonalMax && forwardPoints[diagonal - 1] < forwardPoints[diagonal + 1])) {\n                // Vertical line (the element is an insert)\n                originalIndex = forwardPoints[diagonal + 1];\n                modifiedIndex = originalIndex - diagonalRelative - diagonalForwardOffset;\n                if (originalIndex < lastOriginalIndex) {\n                    changeHelper.MarkNextChange();\n                }\n                lastOriginalIndex = originalIndex;\n                changeHelper.AddModifiedElement(originalIndex + 1, modifiedIndex);\n                diagonalRelative = (diagonal + 1) - diagonalForwardBase; //Setup for the next iteration\n            }\n            else {\n                // Horizontal line (the element is a deletion)\n                originalIndex = forwardPoints[diagonal - 1] + 1;\n                modifiedIndex = originalIndex - diagonalRelative - diagonalForwardOffset;\n                if (originalIndex < lastOriginalIndex) {\n                    changeHelper.MarkNextChange();\n                }\n                lastOriginalIndex = originalIndex - 1;\n                changeHelper.AddOriginalElement(originalIndex, modifiedIndex + 1);\n                diagonalRelative = (diagonal - 1) - diagonalForwardBase; //Setup for the next iteration\n            }\n            if (historyIndex >= 0) {\n                forwardPoints = this.m_forwardHistory[historyIndex];\n                diagonalForwardBase = forwardPoints[0]; //We stored this in the first spot\n                diagonalMin = 1;\n                diagonalMax = forwardPoints.length - 1;\n            }\n        } while (--historyIndex >= -1);\n        // Ironically, we get the forward changes as the reverse of the\n        // order we added them since we technically added them backwards\n        forwardChanges = changeHelper.getReverseChanges();\n        if (quitEarlyArr[0]) {\n            // TODO: Calculate a partial from the reverse diagonals.\n            //       For now, just assume everything after the midOriginal/midModified point is a diff\n            let originalStartPoint = midOriginalArr[0] + 1;\n            let modifiedStartPoint = midModifiedArr[0] + 1;\n            if (forwardChanges !== null && forwardChanges.length > 0) {\n                const lastForwardChange = forwardChanges[forwardChanges.length - 1];\n                originalStartPoint = Math.max(originalStartPoint, lastForwardChange.getOriginalEnd());\n                modifiedStartPoint = Math.max(modifiedStartPoint, lastForwardChange.getModifiedEnd());\n            }\n            reverseChanges = [\n                new DiffChange(originalStartPoint, originalEnd - originalStartPoint + 1, modifiedStartPoint, modifiedEnd - modifiedStartPoint + 1)\n            ];\n        }\n        else {\n            // Now walk backward through the reverse diagonals history\n            changeHelper = new DiffChangeHelper();\n            diagonalMin = diagonalReverseStart;\n            diagonalMax = diagonalReverseEnd;\n            diagonalRelative = (midOriginalArr[0] - midModifiedArr[0]) - diagonalReverseOffset;\n            lastOriginalIndex = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n            historyIndex = (deltaIsEven) ? this.m_reverseHistory.length - 1 : this.m_reverseHistory.length - 2;\n            do {\n                // Get the diagonal index from the relative diagonal number\n                const diagonal = diagonalRelative + diagonalReverseBase;\n                // Figure out where we came from\n                if (diagonal === diagonalMin || (diagonal < diagonalMax && reversePoints[diagonal - 1] >= reversePoints[diagonal + 1])) {\n                    // Horizontal line (the element is a deletion))\n                    originalIndex = reversePoints[diagonal + 1] - 1;\n                    modifiedIndex = originalIndex - diagonalRelative - diagonalReverseOffset;\n                    if (originalIndex > lastOriginalIndex) {\n                        changeHelper.MarkNextChange();\n                    }\n                    lastOriginalIndex = originalIndex + 1;\n                    changeHelper.AddOriginalElement(originalIndex + 1, modifiedIndex + 1);\n                    diagonalRelative = (diagonal + 1) - diagonalReverseBase; //Setup for the next iteration\n                }\n                else {\n                    // Vertical line (the element is an insertion)\n                    originalIndex = reversePoints[diagonal - 1];\n                    modifiedIndex = originalIndex - diagonalRelative - diagonalReverseOffset;\n                    if (originalIndex > lastOriginalIndex) {\n                        changeHelper.MarkNextChange();\n                    }\n                    lastOriginalIndex = originalIndex;\n                    changeHelper.AddModifiedElement(originalIndex + 1, modifiedIndex + 1);\n                    diagonalRelative = (diagonal - 1) - diagonalReverseBase; //Setup for the next iteration\n                }\n                if (historyIndex >= 0) {\n                    reversePoints = this.m_reverseHistory[historyIndex];\n                    diagonalReverseBase = reversePoints[0]; //We stored this in the first spot\n                    diagonalMin = 1;\n                    diagonalMax = reversePoints.length - 1;\n                }\n            } while (--historyIndex >= -1);\n            // There are cases where the reverse history will find diffs that\n            // are correct, but not intuitive, so we need shift them.\n            reverseChanges = changeHelper.getChanges();\n        }\n        return this.ConcatenateChanges(forwardChanges, reverseChanges);\n    }\n    /**\n     * Given the range to compute the diff on, this method finds the point:\n     * (midOriginal, midModified)\n     * that exists in the middle of the LCS of the two sequences and\n     * is the point at which the LCS problem may be broken down recursively.\n     * This method will try to keep the LCS trace in memory. If the LCS recursion\n     * point is calculated and the full trace is available in memory, then this method\n     * will return the change list.\n     * @param originalStart The start bound of the original sequence range\n     * @param originalEnd The end bound of the original sequence range\n     * @param modifiedStart The start bound of the modified sequence range\n     * @param modifiedEnd The end bound of the modified sequence range\n     * @param midOriginal The middle point of the original sequence range\n     * @param midModified The middle point of the modified sequence range\n     * @returns The diff changes, if available, otherwise null\n     */\n    ComputeRecursionPoint(originalStart, originalEnd, modifiedStart, modifiedEnd, midOriginalArr, midModifiedArr, quitEarlyArr) {\n        let originalIndex = 0, modifiedIndex = 0;\n        let diagonalForwardStart = 0, diagonalForwardEnd = 0;\n        let diagonalReverseStart = 0, diagonalReverseEnd = 0;\n        // To traverse the edit graph and produce the proper LCS, our actual\n        // start position is just outside the given boundary\n        originalStart--;\n        modifiedStart--;\n        // We set these up to make the compiler happy, but they will\n        // be replaced before we return with the actual recursion point\n        midOriginalArr[0] = 0;\n        midModifiedArr[0] = 0;\n        // Clear out the history\n        this.m_forwardHistory = [];\n        this.m_reverseHistory = [];\n        // Each cell in the two arrays corresponds to a diagonal in the edit graph.\n        // The integer value in the cell represents the originalIndex of the furthest\n        // reaching point found so far that ends in that diagonal.\n        // The modifiedIndex can be computed mathematically from the originalIndex and the diagonal number.\n        const maxDifferences = (originalEnd - originalStart) + (modifiedEnd - modifiedStart);\n        const numDiagonals = maxDifferences + 1;\n        const forwardPoints = new Int32Array(numDiagonals);\n        const reversePoints = new Int32Array(numDiagonals);\n        // diagonalForwardBase: Index into forwardPoints of the diagonal which passes through (originalStart, modifiedStart)\n        // diagonalReverseBase: Index into reversePoints of the diagonal which passes through (originalEnd, modifiedEnd)\n        const diagonalForwardBase = (modifiedEnd - modifiedStart);\n        const diagonalReverseBase = (originalEnd - originalStart);\n        // diagonalForwardOffset: Geometric offset which allows modifiedIndex to be computed from originalIndex and the\n        //    diagonal number (relative to diagonalForwardBase)\n        // diagonalReverseOffset: Geometric offset which allows modifiedIndex to be computed from originalIndex and the\n        //    diagonal number (relative to diagonalReverseBase)\n        const diagonalForwardOffset = (originalStart - modifiedStart);\n        const diagonalReverseOffset = (originalEnd - modifiedEnd);\n        // delta: The difference between the end diagonal and the start diagonal. This is used to relate diagonal numbers\n        //   relative to the start diagonal with diagonal numbers relative to the end diagonal.\n        // The Even/Oddn-ness of this delta is important for determining when we should check for overlap\n        const delta = diagonalReverseBase - diagonalForwardBase;\n        const deltaIsEven = (delta % 2 === 0);\n        // Here we set up the start and end points as the furthest points found so far\n        // in both the forward and reverse directions, respectively\n        forwardPoints[diagonalForwardBase] = originalStart;\n        reversePoints[diagonalReverseBase] = originalEnd;\n        // Remember if we quit early, and thus need to do a best-effort result instead of a real result.\n        quitEarlyArr[0] = false;\n        // A couple of points:\n        // --With this method, we iterate on the number of differences between the two sequences.\n        //   The more differences there actually are, the longer this will take.\n        // --Also, as the number of differences increases, we have to search on diagonals further\n        //   away from the reference diagonal (which is diagonalForwardBase for forward, diagonalReverseBase for reverse).\n        // --We extend on even diagonals (relative to the reference diagonal) only when numDifferences\n        //   is even and odd diagonals only when numDifferences is odd.\n        for (let numDifferences = 1; numDifferences <= (maxDifferences / 2) + 1; numDifferences++) {\n            let furthestOriginalIndex = 0;\n            let furthestModifiedIndex = 0;\n            // Run the algorithm in the forward direction\n            diagonalForwardStart = this.ClipDiagonalBound(diagonalForwardBase - numDifferences, numDifferences, diagonalForwardBase, numDiagonals);\n            diagonalForwardEnd = this.ClipDiagonalBound(diagonalForwardBase + numDifferences, numDifferences, diagonalForwardBase, numDiagonals);\n            for (let diagonal = diagonalForwardStart; diagonal <= diagonalForwardEnd; diagonal += 2) {\n                // STEP 1: We extend the furthest reaching point in the present diagonal\n                // by looking at the diagonals above and below and picking the one whose point\n                // is further away from the start point (originalStart, modifiedStart)\n                if (diagonal === diagonalForwardStart || (diagonal < diagonalForwardEnd && forwardPoints[diagonal - 1] < forwardPoints[diagonal + 1])) {\n                    originalIndex = forwardPoints[diagonal + 1];\n                }\n                else {\n                    originalIndex = forwardPoints[diagonal - 1] + 1;\n                }\n                modifiedIndex = originalIndex - (diagonal - diagonalForwardBase) - diagonalForwardOffset;\n                // Save the current originalIndex so we can test for false overlap in step 3\n                const tempOriginalIndex = originalIndex;\n                // STEP 2: We can continue to extend the furthest reaching point in the present diagonal\n                // so long as the elements are equal.\n                while (originalIndex < originalEnd && modifiedIndex < modifiedEnd && this.ElementsAreEqual(originalIndex + 1, modifiedIndex + 1)) {\n                    originalIndex++;\n                    modifiedIndex++;\n                }\n                forwardPoints[diagonal] = originalIndex;\n                if (originalIndex + modifiedIndex > furthestOriginalIndex + furthestModifiedIndex) {\n                    furthestOriginalIndex = originalIndex;\n                    furthestModifiedIndex = modifiedIndex;\n                }\n                // STEP 3: If delta is odd (overlap first happens on forward when delta is odd)\n                // and diagonal is in the range of reverse diagonals computed for numDifferences-1\n                // (the previous iteration; we haven't computed reverse diagonals for numDifferences yet)\n                // then check for overlap.\n                if (!deltaIsEven && Math.abs(diagonal - diagonalReverseBase) <= (numDifferences - 1)) {\n                    if (originalIndex >= reversePoints[diagonal]) {\n                        midOriginalArr[0] = originalIndex;\n                        midModifiedArr[0] = modifiedIndex;\n                        if (tempOriginalIndex <= reversePoints[diagonal] && 1447 /* LocalConstants.MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* LocalConstants.MaxDifferencesHistory */ + 1)) {\n                            // BINGO! We overlapped, and we have the full trace in memory!\n                            return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);\n                        }\n                        else {\n                            // Either false overlap, or we didn't have enough memory for the full trace\n                            // Just return the recursion point\n                            return null;\n                        }\n                    }\n                }\n            }\n            // Check to see if we should be quitting early, before moving on to the next iteration.\n            const matchLengthOfLongest = ((furthestOriginalIndex - originalStart) + (furthestModifiedIndex - modifiedStart) - numDifferences) / 2;\n            if (this.ContinueProcessingPredicate !== null && !this.ContinueProcessingPredicate(furthestOriginalIndex, matchLengthOfLongest)) {\n                // We can't finish, so skip ahead to generating a result from what we have.\n                quitEarlyArr[0] = true;\n                // Use the furthest distance we got in the forward direction.\n                midOriginalArr[0] = furthestOriginalIndex;\n                midModifiedArr[0] = furthestModifiedIndex;\n                if (matchLengthOfLongest > 0 && 1447 /* LocalConstants.MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* LocalConstants.MaxDifferencesHistory */ + 1)) {\n                    // Enough of the history is in memory to walk it backwards\n                    return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);\n                }\n                else {\n                    // We didn't actually remember enough of the history.\n                    //Since we are quitting the diff early, we need to shift back the originalStart and modified start\n                    //back into the boundary limits since we decremented their value above beyond the boundary limit.\n                    originalStart++;\n                    modifiedStart++;\n                    return [\n                        new DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, modifiedEnd - modifiedStart + 1)\n                    ];\n                }\n            }\n            // Run the algorithm in the reverse direction\n            diagonalReverseStart = this.ClipDiagonalBound(diagonalReverseBase - numDifferences, numDifferences, diagonalReverseBase, numDiagonals);\n            diagonalReverseEnd = this.ClipDiagonalBound(diagonalReverseBase + numDifferences, numDifferences, diagonalReverseBase, numDiagonals);\n            for (let diagonal = diagonalReverseStart; diagonal <= diagonalReverseEnd; diagonal += 2) {\n                // STEP 1: We extend the furthest reaching point in the present diagonal\n                // by looking at the diagonals above and below and picking the one whose point\n                // is further away from the start point (originalEnd, modifiedEnd)\n                if (diagonal === diagonalReverseStart || (diagonal < diagonalReverseEnd && reversePoints[diagonal - 1] >= reversePoints[diagonal + 1])) {\n                    originalIndex = reversePoints[diagonal + 1] - 1;\n                }\n                else {\n                    originalIndex = reversePoints[diagonal - 1];\n                }\n                modifiedIndex = originalIndex - (diagonal - diagonalReverseBase) - diagonalReverseOffset;\n                // Save the current originalIndex so we can test for false overlap\n                const tempOriginalIndex = originalIndex;\n                // STEP 2: We can continue to extend the furthest reaching point in the present diagonal\n                // as long as the elements are equal.\n                while (originalIndex > originalStart && modifiedIndex > modifiedStart && this.ElementsAreEqual(originalIndex, modifiedIndex)) {\n                    originalIndex--;\n                    modifiedIndex--;\n                }\n                reversePoints[diagonal] = originalIndex;\n                // STEP 4: If delta is even (overlap first happens on reverse when delta is even)\n                // and diagonal is in the range of forward diagonals computed for numDifferences\n                // then check for overlap.\n                if (deltaIsEven && Math.abs(diagonal - diagonalForwardBase) <= numDifferences) {\n                    if (originalIndex <= forwardPoints[diagonal]) {\n                        midOriginalArr[0] = originalIndex;\n                        midModifiedArr[0] = modifiedIndex;\n                        if (tempOriginalIndex >= forwardPoints[diagonal] && 1447 /* LocalConstants.MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* LocalConstants.MaxDifferencesHistory */ + 1)) {\n                            // BINGO! We overlapped, and we have the full trace in memory!\n                            return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);\n                        }\n                        else {\n                            // Either false overlap, or we didn't have enough memory for the full trace\n                            // Just return the recursion point\n                            return null;\n                        }\n                    }\n                }\n            }\n            // Save current vectors to history before the next iteration\n            if (numDifferences <= 1447 /* LocalConstants.MaxDifferencesHistory */) {\n                // We are allocating space for one extra int, which we fill with\n                // the index of the diagonal base index\n                let temp = new Int32Array(diagonalForwardEnd - diagonalForwardStart + 2);\n                temp[0] = diagonalForwardBase - diagonalForwardStart + 1;\n                MyArray.Copy2(forwardPoints, diagonalForwardStart, temp, 1, diagonalForwardEnd - diagonalForwardStart + 1);\n                this.m_forwardHistory.push(temp);\n                temp = new Int32Array(diagonalReverseEnd - diagonalReverseStart + 2);\n                temp[0] = diagonalReverseBase - diagonalReverseStart + 1;\n                MyArray.Copy2(reversePoints, diagonalReverseStart, temp, 1, diagonalReverseEnd - diagonalReverseStart + 1);\n                this.m_reverseHistory.push(temp);\n            }\n        }\n        // If we got here, then we have the full trace in history. We just have to convert it to a change list\n        // NOTE: This part is a bit messy\n        return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);\n    }\n    /**\n     * Shifts the given changes to provide a more intuitive diff.\n     * While the first element in a diff matches the first element after the diff,\n     * we shift the diff down.\n     *\n     * @param changes The list of changes to shift\n     * @returns The shifted changes\n     */\n    PrettifyChanges(changes) {\n        // Shift all the changes down first\n        for (let i = 0; i < changes.length; i++) {\n            const change = changes[i];\n            const originalStop = (i < changes.length - 1) ? changes[i + 1].originalStart : this._originalElementsOrHash.length;\n            const modifiedStop = (i < changes.length - 1) ? changes[i + 1].modifiedStart : this._modifiedElementsOrHash.length;\n            const checkOriginal = change.originalLength > 0;\n            const checkModified = change.modifiedLength > 0;\n            while (change.originalStart + change.originalLength < originalStop\n                && change.modifiedStart + change.modifiedLength < modifiedStop\n                && (!checkOriginal || this.OriginalElementsAreEqual(change.originalStart, change.originalStart + change.originalLength))\n                && (!checkModified || this.ModifiedElementsAreEqual(change.modifiedStart, change.modifiedStart + change.modifiedLength))) {\n                const startStrictEqual = this.ElementsAreStrictEqual(change.originalStart, change.modifiedStart);\n                const endStrictEqual = this.ElementsAreStrictEqual(change.originalStart + change.originalLength, change.modifiedStart + change.modifiedLength);\n                if (endStrictEqual && !startStrictEqual) {\n                    // moving the change down would create an equal change, but the elements are not strict equal\n                    break;\n                }\n                change.originalStart++;\n                change.modifiedStart++;\n            }\n            const mergedChangeArr = [null];\n            if (i < changes.length - 1 && this.ChangesOverlap(changes[i], changes[i + 1], mergedChangeArr)) {\n                changes[i] = mergedChangeArr[0];\n                changes.splice(i + 1, 1);\n                i--;\n                continue;\n            }\n        }\n        // Shift changes back up until we hit empty or whitespace-only lines\n        for (let i = changes.length - 1; i >= 0; i--) {\n            const change = changes[i];\n            let originalStop = 0;\n            let modifiedStop = 0;\n            if (i > 0) {\n                const prevChange = changes[i - 1];\n                originalStop = prevChange.originalStart + prevChange.originalLength;\n                modifiedStop = prevChange.modifiedStart + prevChange.modifiedLength;\n            }\n            const checkOriginal = change.originalLength > 0;\n            const checkModified = change.modifiedLength > 0;\n            let bestDelta = 0;\n            let bestScore = this._boundaryScore(change.originalStart, change.originalLength, change.modifiedStart, change.modifiedLength);\n            for (let delta = 1;; delta++) {\n                const originalStart = change.originalStart - delta;\n                const modifiedStart = change.modifiedStart - delta;\n                if (originalStart < originalStop || modifiedStart < modifiedStop) {\n                    break;\n                }\n                if (checkOriginal && !this.OriginalElementsAreEqual(originalStart, originalStart + change.originalLength)) {\n                    break;\n                }\n                if (checkModified && !this.ModifiedElementsAreEqual(modifiedStart, modifiedStart + change.modifiedLength)) {\n                    break;\n                }\n                const touchingPreviousChange = (originalStart === originalStop && modifiedStart === modifiedStop);\n                const score = ((touchingPreviousChange ? 5 : 0)\n                    + this._boundaryScore(originalStart, change.originalLength, modifiedStart, change.modifiedLength));\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestDelta = delta;\n                }\n            }\n            change.originalStart -= bestDelta;\n            change.modifiedStart -= bestDelta;\n            const mergedChangeArr = [null];\n            if (i > 0 && this.ChangesOverlap(changes[i - 1], changes[i], mergedChangeArr)) {\n                changes[i - 1] = mergedChangeArr[0];\n                changes.splice(i, 1);\n                i++;\n                continue;\n            }\n        }\n        // There could be multiple longest common substrings.\n        // Give preference to the ones containing longer lines\n        if (this._hasStrings) {\n            for (let i = 1, len = changes.length; i < len; i++) {\n                const aChange = changes[i - 1];\n                const bChange = changes[i];\n                const matchedLength = bChange.originalStart - aChange.originalStart - aChange.originalLength;\n                const aOriginalStart = aChange.originalStart;\n                const bOriginalEnd = bChange.originalStart + bChange.originalLength;\n                const abOriginalLength = bOriginalEnd - aOriginalStart;\n                const aModifiedStart = aChange.modifiedStart;\n                const bModifiedEnd = bChange.modifiedStart + bChange.modifiedLength;\n                const abModifiedLength = bModifiedEnd - aModifiedStart;\n                // Avoid wasting a lot of time with these searches\n                if (matchedLength < 5 && abOriginalLength < 20 && abModifiedLength < 20) {\n                    const t = this._findBetterContiguousSequence(aOriginalStart, abOriginalLength, aModifiedStart, abModifiedLength, matchedLength);\n                    if (t) {\n                        const [originalMatchStart, modifiedMatchStart] = t;\n                        if (originalMatchStart !== aChange.originalStart + aChange.originalLength || modifiedMatchStart !== aChange.modifiedStart + aChange.modifiedLength) {\n                            // switch to another sequence that has a better score\n                            aChange.originalLength = originalMatchStart - aChange.originalStart;\n                            aChange.modifiedLength = modifiedMatchStart - aChange.modifiedStart;\n                            bChange.originalStart = originalMatchStart + matchedLength;\n                            bChange.modifiedStart = modifiedMatchStart + matchedLength;\n                            bChange.originalLength = bOriginalEnd - bChange.originalStart;\n                            bChange.modifiedLength = bModifiedEnd - bChange.modifiedStart;\n                        }\n                    }\n                }\n            }\n        }\n        return changes;\n    }\n    _findBetterContiguousSequence(originalStart, originalLength, modifiedStart, modifiedLength, desiredLength) {\n        if (originalLength < desiredLength || modifiedLength < desiredLength) {\n            return null;\n        }\n        const originalMax = originalStart + originalLength - desiredLength + 1;\n        const modifiedMax = modifiedStart + modifiedLength - desiredLength + 1;\n        let bestScore = 0;\n        let bestOriginalStart = 0;\n        let bestModifiedStart = 0;\n        for (let i = originalStart; i < originalMax; i++) {\n            for (let j = modifiedStart; j < modifiedMax; j++) {\n                const score = this._contiguousSequenceScore(i, j, desiredLength);\n                if (score > 0 && score > bestScore) {\n                    bestScore = score;\n                    bestOriginalStart = i;\n                    bestModifiedStart = j;\n                }\n            }\n        }\n        if (bestScore > 0) {\n            return [bestOriginalStart, bestModifiedStart];\n        }\n        return null;\n    }\n    _contiguousSequenceScore(originalStart, modifiedStart, length) {\n        let score = 0;\n        for (let l = 0; l < length; l++) {\n            if (!this.ElementsAreEqual(originalStart + l, modifiedStart + l)) {\n                return 0;\n            }\n            score += this._originalStringElements[originalStart + l].length;\n        }\n        return score;\n    }\n    _OriginalIsBoundary(index) {\n        if (index <= 0 || index >= this._originalElementsOrHash.length - 1) {\n            return true;\n        }\n        return (this._hasStrings && /^\\s*$/.test(this._originalStringElements[index]));\n    }\n    _OriginalRegionIsBoundary(originalStart, originalLength) {\n        if (this._OriginalIsBoundary(originalStart) || this._OriginalIsBoundary(originalStart - 1)) {\n            return true;\n        }\n        if (originalLength > 0) {\n            const originalEnd = originalStart + originalLength;\n            if (this._OriginalIsBoundary(originalEnd - 1) || this._OriginalIsBoundary(originalEnd)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    _ModifiedIsBoundary(index) {\n        if (index <= 0 || index >= this._modifiedElementsOrHash.length - 1) {\n            return true;\n        }\n        return (this._hasStrings && /^\\s*$/.test(this._modifiedStringElements[index]));\n    }\n    _ModifiedRegionIsBoundary(modifiedStart, modifiedLength) {\n        if (this._ModifiedIsBoundary(modifiedStart) || this._ModifiedIsBoundary(modifiedStart - 1)) {\n            return true;\n        }\n        if (modifiedLength > 0) {\n            const modifiedEnd = modifiedStart + modifiedLength;\n            if (this._ModifiedIsBoundary(modifiedEnd - 1) || this._ModifiedIsBoundary(modifiedEnd)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    _boundaryScore(originalStart, originalLength, modifiedStart, modifiedLength) {\n        const originalScore = (this._OriginalRegionIsBoundary(originalStart, originalLength) ? 1 : 0);\n        const modifiedScore = (this._ModifiedRegionIsBoundary(modifiedStart, modifiedLength) ? 1 : 0);\n        return (originalScore + modifiedScore);\n    }\n    /**\n     * Concatenates the two input DiffChange lists and returns the resulting\n     * list.\n     * @param The left changes\n     * @param The right changes\n     * @returns The concatenated list\n     */\n    ConcatenateChanges(left, right) {\n        const mergedChangeArr = [];\n        if (left.length === 0 || right.length === 0) {\n            return (right.length > 0) ? right : left;\n        }\n        else if (this.ChangesOverlap(left[left.length - 1], right[0], mergedChangeArr)) {\n            // Since we break the problem down recursively, it is possible that we\n            // might recurse in the middle of a change thereby splitting it into\n            // two changes. Here in the combining stage, we detect and fuse those\n            // changes back together\n            const result = new Array(left.length + right.length - 1);\n            MyArray.Copy(left, 0, result, 0, left.length - 1);\n            result[left.length - 1] = mergedChangeArr[0];\n            MyArray.Copy(right, 1, result, left.length, right.length - 1);\n            return result;\n        }\n        else {\n            const result = new Array(left.length + right.length);\n            MyArray.Copy(left, 0, result, 0, left.length);\n            MyArray.Copy(right, 0, result, left.length, right.length);\n            return result;\n        }\n    }\n    /**\n     * Returns true if the two changes overlap and can be merged into a single\n     * change\n     * @param left The left change\n     * @param right The right change\n     * @param mergedChange The merged change if the two overlap, null otherwise\n     * @returns True if the two changes overlap\n     */\n    ChangesOverlap(left, right, mergedChangeArr) {\n        Debug.Assert(left.originalStart <= right.originalStart, 'Left change is not less than or equal to right change');\n        Debug.Assert(left.modifiedStart <= right.modifiedStart, 'Left change is not less than or equal to right change');\n        if (left.originalStart + left.originalLength >= right.originalStart || left.modifiedStart + left.modifiedLength >= right.modifiedStart) {\n            const originalStart = left.originalStart;\n            let originalLength = left.originalLength;\n            const modifiedStart = left.modifiedStart;\n            let modifiedLength = left.modifiedLength;\n            if (left.originalStart + left.originalLength >= right.originalStart) {\n                originalLength = right.originalStart + right.originalLength - left.originalStart;\n            }\n            if (left.modifiedStart + left.modifiedLength >= right.modifiedStart) {\n                modifiedLength = right.modifiedStart + right.modifiedLength - left.modifiedStart;\n            }\n            mergedChangeArr[0] = new DiffChange(originalStart, originalLength, modifiedStart, modifiedLength);\n            return true;\n        }\n        else {\n            mergedChangeArr[0] = null;\n            return false;\n        }\n    }\n    /**\n     * Helper method used to clip a diagonal index to the range of valid\n     * diagonals. This also decides whether or not the diagonal index,\n     * if it exceeds the boundary, should be clipped to the boundary or clipped\n     * one inside the boundary depending on the Even/Odd status of the boundary\n     * and numDifferences.\n     * @param diagonal The index of the diagonal to clip.\n     * @param numDifferences The current number of differences being iterated upon.\n     * @param diagonalBaseIndex The base reference diagonal.\n     * @param numDiagonals The total number of diagonals.\n     * @returns The clipped diagonal index.\n     */\n    ClipDiagonalBound(diagonal, numDifferences, diagonalBaseIndex, numDiagonals) {\n        if (diagonal >= 0 && diagonal < numDiagonals) {\n            // Nothing to clip, its in range\n            return diagonal;\n        }\n        // diagonalsBelow: The number of diagonals below the reference diagonal\n        // diagonalsAbove: The number of diagonals above the reference diagonal\n        const diagonalsBelow = diagonalBaseIndex;\n        const diagonalsAbove = numDiagonals - diagonalBaseIndex - 1;\n        const diffEven = (numDifferences % 2 === 0);\n        if (diagonal < 0) {\n            const lowerBoundEven = (diagonalsBelow % 2 === 0);\n            return (diffEven === lowerBoundEven) ? 0 : 1;\n        }\n        else {\n            const upperBoundEven = (diagonalsAbove % 2 === 0);\n            return (diffEven === upperBoundEven) ? numDiagonals - 1 : numDiagonals - 2;\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport function toUint8(v) {\n    if (v < 0) {\n        return 0;\n    }\n    if (v > 255 /* Constants.MAX_UINT_8 */) {\n        return 255 /* Constants.MAX_UINT_8 */;\n    }\n    return v | 0;\n}\nexport function toUint32(v) {\n    if (v < 0) {\n        return 0;\n    }\n    if (v > 4294967295 /* Constants.MAX_UINT_32 */) {\n        return 4294967295 /* Constants.MAX_UINT_32 */;\n    }\n    return v | 0;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { arrayInsert } from '../../../base/common/arrays.js';\nimport { toUint32 } from '../../../base/common/uint.js';\nexport class PrefixSumComputer {\n    constructor(values) {\n        this.values = values;\n        this.prefixSum = new Uint32Array(values.length);\n        this.prefixSumValidIndex = new Int32Array(1);\n        this.prefixSumValidIndex[0] = -1;\n    }\n    insertValues(insertIndex, insertValues) {\n        insertIndex = toUint32(insertIndex);\n        const oldValues = this.values;\n        const oldPrefixSum = this.prefixSum;\n        const insertValuesLen = insertValues.length;\n        if (insertValuesLen === 0) {\n            return false;\n        }\n        this.values = new Uint32Array(oldValues.length + insertValuesLen);\n        this.values.set(oldValues.subarray(0, insertIndex), 0);\n        this.values.set(oldValues.subarray(insertIndex), insertIndex + insertValuesLen);\n        this.values.set(insertValues, insertIndex);\n        if (insertIndex - 1 < this.prefixSumValidIndex[0]) {\n            this.prefixSumValidIndex[0] = insertIndex - 1;\n        }\n        this.prefixSum = new Uint32Array(this.values.length);\n        if (this.prefixSumValidIndex[0] >= 0) {\n            this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));\n        }\n        return true;\n    }\n    setValue(index, value) {\n        index = toUint32(index);\n        value = toUint32(value);\n        if (this.values[index] === value) {\n            return false;\n        }\n        this.values[index] = value;\n        if (index - 1 < this.prefixSumValidIndex[0]) {\n            this.prefixSumValidIndex[0] = index - 1;\n        }\n        return true;\n    }\n    removeValues(startIndex, count) {\n        startIndex = toUint32(startIndex);\n        count = toUint32(count);\n        const oldValues = this.values;\n        const oldPrefixSum = this.prefixSum;\n        if (startIndex >= oldValues.length) {\n            return false;\n        }\n        const maxCount = oldValues.length - startIndex;\n        if (count >= maxCount) {\n            count = maxCount;\n        }\n        if (count === 0) {\n            return false;\n        }\n        this.values = new Uint32Array(oldValues.length - count);\n        this.values.set(oldValues.subarray(0, startIndex), 0);\n        this.values.set(oldValues.subarray(startIndex + count), startIndex);\n        this.prefixSum = new Uint32Array(this.values.length);\n        if (startIndex - 1 < this.prefixSumValidIndex[0]) {\n            this.prefixSumValidIndex[0] = startIndex - 1;\n        }\n        if (this.prefixSumValidIndex[0] >= 0) {\n            this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));\n        }\n        return true;\n    }\n    getTotalSum() {\n        if (this.values.length === 0) {\n            return 0;\n        }\n        return this._getPrefixSum(this.values.length - 1);\n    }\n    /**\n     * Returns the sum of the first `index + 1` many items.\n     * @returns `SUM(0 <= j <= index, values[j])`.\n     */\n    getPrefixSum(index) {\n        if (index < 0) {\n            return 0;\n        }\n        index = toUint32(index);\n        return this._getPrefixSum(index);\n    }\n    _getPrefixSum(index) {\n        if (index <= this.prefixSumValidIndex[0]) {\n            return this.prefixSum[index];\n        }\n        let startIndex = this.prefixSumValidIndex[0] + 1;\n        if (startIndex === 0) {\n            this.prefixSum[0] = this.values[0];\n            startIndex++;\n        }\n        if (index >= this.values.length) {\n            index = this.values.length - 1;\n        }\n        for (let i = startIndex; i <= index; i++) {\n            this.prefixSum[i] = this.prefixSum[i - 1] + this.values[i];\n        }\n        this.prefixSumValidIndex[0] = Math.max(this.prefixSumValidIndex[0], index);\n        return this.prefixSum[index];\n    }\n    getIndexOf(sum) {\n        sum = Math.floor(sum);\n        // Compute all sums (to get a fully valid prefixSum)\n        this.getTotalSum();\n        let low = 0;\n        let high = this.values.length - 1;\n        let mid = 0;\n        let midStop = 0;\n        let midStart = 0;\n        while (low <= high) {\n            mid = low + ((high - low) / 2) | 0;\n            midStop = this.prefixSum[mid];\n            midStart = midStop - this.values[mid];\n            if (sum < midStart) {\n                high = mid - 1;\n            }\n            else if (sum >= midStop) {\n                low = mid + 1;\n            }\n            else {\n                break;\n            }\n        }\n        return new PrefixSumIndexOfResult(mid, sum - midStart);\n    }\n}\n/**\n * {@link getIndexOf} has an amortized runtime complexity of O(1).\n *\n * ({@link PrefixSumComputer.getIndexOf} is just  O(log n))\n*/\nexport class ConstantTimePrefixSumComputer {\n    constructor(values) {\n        this._values = values;\n        this._isValid = false;\n        this._validEndIndex = -1;\n        this._prefixSum = [];\n        this._indexBySum = [];\n    }\n    /**\n     * @returns SUM(0 <= j < values.length, values[j])\n     */\n    getTotalSum() {\n        this._ensureValid();\n        return this._indexBySum.length;\n    }\n    /**\n     * Returns the sum of the first `count` many items.\n     * @returns `SUM(0 <= j < count, values[j])`.\n     */\n    getPrefixSum(count) {\n        this._ensureValid();\n        if (count === 0) {\n            return 0;\n        }\n        return this._prefixSum[count - 1];\n    }\n    /**\n     * @returns `result`, such that `getPrefixSum(result.index) + result.remainder = sum`\n     */\n    getIndexOf(sum) {\n        this._ensureValid();\n        const idx = this._indexBySum[sum];\n        const viewLinesAbove = idx > 0 ? this._prefixSum[idx - 1] : 0;\n        return new PrefixSumIndexOfResult(idx, sum - viewLinesAbove);\n    }\n    removeValues(start, deleteCount) {\n        this._values.splice(start, deleteCount);\n        this._invalidate(start);\n    }\n    insertValues(insertIndex, insertArr) {\n        this._values = arrayInsert(this._values, insertIndex, insertArr);\n        this._invalidate(insertIndex);\n    }\n    _invalidate(index) {\n        this._isValid = false;\n        this._validEndIndex = Math.min(this._validEndIndex, index - 1);\n    }\n    _ensureValid() {\n        if (this._isValid) {\n            return;\n        }\n        for (let i = this._validEndIndex + 1, len = this._values.length; i < len; i++) {\n            const value = this._values[i];\n            const sumAbove = i > 0 ? this._prefixSum[i - 1] : 0;\n            this._prefixSum[i] = sumAbove + value;\n            for (let j = 0; j < value; j++) {\n                this._indexBySum[sumAbove + j] = i;\n            }\n        }\n        // trim things\n        this._prefixSum.length = this._values.length;\n        this._indexBySum.length = this._prefixSum[this._prefixSum.length - 1];\n        // mark as valid\n        this._isValid = true;\n        this._validEndIndex = this._values.length - 1;\n    }\n    setValue(index, value) {\n        if (this._values[index] === value) {\n            // no change\n            return;\n        }\n        this._values[index] = value;\n        this._invalidate(index);\n    }\n}\nexport class PrefixSumIndexOfResult {\n    constructor(index, remainder) {\n        this.index = index;\n        this.remainder = remainder;\n        this._prefixSumIndexOfResultBrand = undefined;\n        this.index = index;\n        this.remainder = remainder;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { splitLines } from '../../../base/common/strings.js';\nimport { Position } from '../core/position.js';\nimport { PrefixSumComputer } from './prefixSumComputer.js';\nexport class MirrorTextModel {\n    constructor(uri, lines, eol, versionId) {\n        this._uri = uri;\n        this._lines = lines;\n        this._eol = eol;\n        this._versionId = versionId;\n        this._lineStarts = null;\n        this._cachedTextValue = null;\n    }\n    dispose() {\n        this._lines.length = 0;\n    }\n    get version() {\n        return this._versionId;\n    }\n    getText() {\n        if (this._cachedTextValue === null) {\n            this._cachedTextValue = this._lines.join(this._eol);\n        }\n        return this._cachedTextValue;\n    }\n    onEvents(e) {\n        if (e.eol && e.eol !== this._eol) {\n            this._eol = e.eol;\n            this._lineStarts = null;\n        }\n        // Update my lines\n        const changes = e.changes;\n        for (const change of changes) {\n            this._acceptDeleteRange(change.range);\n            this._acceptInsertText(new Position(change.range.startLineNumber, change.range.startColumn), change.text);\n        }\n        this._versionId = e.versionId;\n        this._cachedTextValue = null;\n    }\n    _ensureLineStarts() {\n        if (!this._lineStarts) {\n            const eolLength = this._eol.length;\n            const linesLength = this._lines.length;\n            const lineStartValues = new Uint32Array(linesLength);\n            for (let i = 0; i < linesLength; i++) {\n                lineStartValues[i] = this._lines[i].length + eolLength;\n            }\n            this._lineStarts = new PrefixSumComputer(lineStartValues);\n        }\n    }\n    /**\n     * All changes to a line's text go through this method\n     */\n    _setLineText(lineIndex, newValue) {\n        this._lines[lineIndex] = newValue;\n        if (this._lineStarts) {\n            // update prefix sum\n            this._lineStarts.setValue(lineIndex, this._lines[lineIndex].length + this._eol.length);\n        }\n    }\n    _acceptDeleteRange(range) {\n        if (range.startLineNumber === range.endLineNumber) {\n            if (range.startColumn === range.endColumn) {\n                // Nothing to delete\n                return;\n            }\n            // Delete text on the affected line\n            this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)\n                + this._lines[range.startLineNumber - 1].substring(range.endColumn - 1));\n            return;\n        }\n        // Take remaining text on last line and append it to remaining text on first line\n        this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)\n            + this._lines[range.endLineNumber - 1].substring(range.endColumn - 1));\n        // Delete middle lines\n        this._lines.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber);\n        if (this._lineStarts) {\n            // update prefix sum\n            this._lineStarts.removeValues(range.startLineNumber, range.endLineNumber - range.startLineNumber);\n        }\n    }\n    _acceptInsertText(position, insertText) {\n        if (insertText.length === 0) {\n            // Nothing to insert\n            return;\n        }\n        const insertLines = splitLines(insertText);\n        if (insertLines.length === 1) {\n            // Inserting text on one line\n            this._setLineText(position.lineNumber - 1, this._lines[position.lineNumber - 1].substring(0, position.column - 1)\n                + insertLines[0]\n                + this._lines[position.lineNumber - 1].substring(position.column - 1));\n            return;\n        }\n        // Append overflowing text from first line to the end of text to insert\n        insertLines[insertLines.length - 1] += this._lines[position.lineNumber - 1].substring(position.column - 1);\n        // Delete overflowing text from first line and insert text on first line\n        this._setLineText(position.lineNumber - 1, this._lines[position.lineNumber - 1].substring(0, position.column - 1)\n            + insertLines[0]);\n        // Insert new lines & store lengths\n        const newLengths = new Uint32Array(insertLines.length - 1);\n        for (let i = 1; i < insertLines.length; i++) {\n            this._lines.splice(position.lineNumber + i - 1, 0, insertLines[i]);\n            newLengths[i - 1] = insertLines[i].length + this._eol.length;\n        }\n        if (this._lineStarts) {\n            // update prefix sum\n            this._lineStarts.insertValues(position.lineNumber, newLengths);\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { toUint8 } from '../../../base/common/uint.js';\n/**\n * A fast character classifier that uses a compact array for ASCII values.\n */\nexport class CharacterClassifier {\n    constructor(_defaultValue) {\n        const defaultValue = toUint8(_defaultValue);\n        this._defaultValue = defaultValue;\n        this._asciiMap = CharacterClassifier._createAsciiMap(defaultValue);\n        this._map = new Map();\n    }\n    static _createAsciiMap(defaultValue) {\n        const asciiMap = new Uint8Array(256);\n        asciiMap.fill(defaultValue);\n        return asciiMap;\n    }\n    set(charCode, _value) {\n        const value = toUint8(_value);\n        if (charCode >= 0 && charCode < 256) {\n            this._asciiMap[charCode] = value;\n        }\n        else {\n            this._map.set(charCode, value);\n        }\n    }\n    get(charCode) {\n        if (charCode >= 0 && charCode < 256) {\n            return this._asciiMap[charCode];\n        }\n        else {\n            return (this._map.get(charCode) || this._defaultValue);\n        }\n    }\n    clear() {\n        this._asciiMap.fill(this._defaultValue);\n        this._map.clear();\n    }\n}\nexport class CharacterSet {\n    constructor() {\n        this._actual = new CharacterClassifier(0 /* Boolean.False */);\n    }\n    add(charCode) {\n        this._actual.set(charCode, 1 /* Boolean.True */);\n    }\n    has(charCode) {\n        return (this._actual.get(charCode) === 1 /* Boolean.True */);\n    }\n    clear() {\n        return this._actual.clear();\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { CharacterClassifier } from '../core/characterClassifier.js';\nclass Uint8Matrix {\n    constructor(rows, cols, defaultValue) {\n        const data = new Uint8Array(rows * cols);\n        for (let i = 0, len = rows * cols; i < len; i++) {\n            data[i] = defaultValue;\n        }\n        this._data = data;\n        this.rows = rows;\n        this.cols = cols;\n    }\n    get(row, col) {\n        return this._data[row * this.cols + col];\n    }\n    set(row, col, value) {\n        this._data[row * this.cols + col] = value;\n    }\n}\nexport class StateMachine {\n    constructor(edges) {\n        let maxCharCode = 0;\n        let maxState = 0 /* State.Invalid */;\n        for (let i = 0, len = edges.length; i < len; i++) {\n            const [from, chCode, to] = edges[i];\n            if (chCode > maxCharCode) {\n                maxCharCode = chCode;\n            }\n            if (from > maxState) {\n                maxState = from;\n            }\n            if (to > maxState) {\n                maxState = to;\n            }\n        }\n        maxCharCode++;\n        maxState++;\n        const states = new Uint8Matrix(maxState, maxCharCode, 0 /* State.Invalid */);\n        for (let i = 0, len = edges.length; i < len; i++) {\n            const [from, chCode, to] = edges[i];\n            states.set(from, chCode, to);\n        }\n        this._states = states;\n        this._maxCharCode = maxCharCode;\n    }\n    nextState(currentState, chCode) {\n        if (chCode < 0 || chCode >= this._maxCharCode) {\n            return 0 /* State.Invalid */;\n        }\n        return this._states.get(currentState, chCode);\n    }\n}\n// State machine for http:// or https:// or file://\nlet _stateMachine = null;\nfunction getStateMachine() {\n    if (_stateMachine === null) {\n        _stateMachine = new StateMachine([\n            [1 /* State.Start */, 104 /* CharCode.h */, 2 /* State.H */],\n            [1 /* State.Start */, 72 /* CharCode.H */, 2 /* State.H */],\n            [1 /* State.Start */, 102 /* CharCode.f */, 6 /* State.F */],\n            [1 /* State.Start */, 70 /* CharCode.F */, 6 /* State.F */],\n            [2 /* State.H */, 116 /* CharCode.t */, 3 /* State.HT */],\n            [2 /* State.H */, 84 /* CharCode.T */, 3 /* State.HT */],\n            [3 /* State.HT */, 116 /* CharCode.t */, 4 /* State.HTT */],\n            [3 /* State.HT */, 84 /* CharCode.T */, 4 /* State.HTT */],\n            [4 /* State.HTT */, 112 /* CharCode.p */, 5 /* State.HTTP */],\n            [4 /* State.HTT */, 80 /* CharCode.P */, 5 /* State.HTTP */],\n            [5 /* State.HTTP */, 115 /* CharCode.s */, 9 /* State.BeforeColon */],\n            [5 /* State.HTTP */, 83 /* CharCode.S */, 9 /* State.BeforeColon */],\n            [5 /* State.HTTP */, 58 /* CharCode.Colon */, 10 /* State.AfterColon */],\n            [6 /* State.F */, 105 /* CharCode.i */, 7 /* State.FI */],\n            [6 /* State.F */, 73 /* CharCode.I */, 7 /* State.FI */],\n            [7 /* State.FI */, 108 /* CharCode.l */, 8 /* State.FIL */],\n            [7 /* State.FI */, 76 /* CharCode.L */, 8 /* State.FIL */],\n            [8 /* State.FIL */, 101 /* CharCode.e */, 9 /* State.BeforeColon */],\n            [8 /* State.FIL */, 69 /* CharCode.E */, 9 /* State.BeforeColon */],\n            [9 /* State.BeforeColon */, 58 /* CharCode.Colon */, 10 /* State.AfterColon */],\n            [10 /* State.AfterColon */, 47 /* CharCode.Slash */, 11 /* State.AlmostThere */],\n            [11 /* State.AlmostThere */, 47 /* CharCode.Slash */, 12 /* State.End */],\n        ]);\n    }\n    return _stateMachine;\n}\nlet _classifier = null;\nfunction getClassifier() {\n    if (_classifier === null) {\n        _classifier = new CharacterClassifier(0 /* CharacterClass.None */);\n        // allow-any-unicode-next-line\n        const FORCE_TERMINATION_CHARACTERS = ' \\t<>\\'\\\"、。。、,.:;‘〈「『〔([{「」}])〕』」〉’`~…';\n        for (let i = 0; i < FORCE_TERMINATION_CHARACTERS.length; i++) {\n            _classifier.set(FORCE_TERMINATION_CHARACTERS.charCodeAt(i), 1 /* CharacterClass.ForceTermination */);\n        }\n        const CANNOT_END_WITH_CHARACTERS = '.,;:';\n        for (let i = 0; i < CANNOT_END_WITH_CHARACTERS.length; i++) {\n            _classifier.set(CANNOT_END_WITH_CHARACTERS.charCodeAt(i), 2 /* CharacterClass.CannotEndIn */);\n        }\n    }\n    return _classifier;\n}\nexport class LinkComputer {\n    static _createLink(classifier, line, lineNumber, linkBeginIndex, linkEndIndex) {\n        // Do not allow to end link in certain characters...\n        let lastIncludedCharIndex = linkEndIndex - 1;\n        do {\n            const chCode = line.charCodeAt(lastIncludedCharIndex);\n            const chClass = classifier.get(chCode);\n            if (chClass !== 2 /* CharacterClass.CannotEndIn */) {\n                break;\n            }\n            lastIncludedCharIndex--;\n        } while (lastIncludedCharIndex > linkBeginIndex);\n        // Handle links enclosed in parens, square brackets and curlys.\n        if (linkBeginIndex > 0) {\n            const charCodeBeforeLink = line.charCodeAt(linkBeginIndex - 1);\n            const lastCharCodeInLink = line.charCodeAt(lastIncludedCharIndex);\n            if ((charCodeBeforeLink === 40 /* CharCode.OpenParen */ && lastCharCodeInLink === 41 /* CharCode.CloseParen */)\n                || (charCodeBeforeLink === 91 /* CharCode.OpenSquareBracket */ && lastCharCodeInLink === 93 /* CharCode.CloseSquareBracket */)\n                || (charCodeBeforeLink === 123 /* CharCode.OpenCurlyBrace */ && lastCharCodeInLink === 125 /* CharCode.CloseCurlyBrace */)) {\n                // Do not end in ) if ( is before the link start\n                // Do not end in ] if [ is before the link start\n                // Do not end in } if { is before the link start\n                lastIncludedCharIndex--;\n            }\n        }\n        return {\n            range: {\n                startLineNumber: lineNumber,\n                startColumn: linkBeginIndex + 1,\n                endLineNumber: lineNumber,\n                endColumn: lastIncludedCharIndex + 2\n            },\n            url: line.substring(linkBeginIndex, lastIncludedCharIndex + 1)\n        };\n    }\n    static computeLinks(model, stateMachine = getStateMachine()) {\n        const classifier = getClassifier();\n        const result = [];\n        for (let i = 1, lineCount = model.getLineCount(); i <= lineCount; i++) {\n            const line = model.getLineContent(i);\n            const len = line.length;\n            let j = 0;\n            let linkBeginIndex = 0;\n            let linkBeginChCode = 0;\n            let state = 1 /* State.Start */;\n            let hasOpenParens = false;\n            let hasOpenSquareBracket = false;\n            let inSquareBrackets = false;\n            let hasOpenCurlyBracket = false;\n            while (j < len) {\n                let resetStateMachine = false;\n                const chCode = line.charCodeAt(j);\n                if (state === 13 /* State.Accept */) {\n                    let chClass;\n                    switch (chCode) {\n                        case 40 /* CharCode.OpenParen */:\n                            hasOpenParens = true;\n                            chClass = 0 /* CharacterClass.None */;\n                            break;\n                        case 41 /* CharCode.CloseParen */:\n                            chClass = (hasOpenParens ? 0 /* CharacterClass.None */ : 1 /* CharacterClass.ForceTermination */);\n                            break;\n                        case 91 /* CharCode.OpenSquareBracket */:\n                            inSquareBrackets = true;\n                            hasOpenSquareBracket = true;\n                            chClass = 0 /* CharacterClass.None */;\n                            break;\n                        case 93 /* CharCode.CloseSquareBracket */:\n                            inSquareBrackets = false;\n                            chClass = (hasOpenSquareBracket ? 0 /* CharacterClass.None */ : 1 /* CharacterClass.ForceTermination */);\n                            break;\n                        case 123 /* CharCode.OpenCurlyBrace */:\n                            hasOpenCurlyBracket = true;\n                            chClass = 0 /* CharacterClass.None */;\n                            break;\n                        case 125 /* CharCode.CloseCurlyBrace */:\n                            chClass = (hasOpenCurlyBracket ? 0 /* CharacterClass.None */ : 1 /* CharacterClass.ForceTermination */);\n                            break;\n                        // The following three rules make it that ' or \" or ` are allowed inside links\n                        // only if the link is wrapped by some other quote character\n                        case 39 /* CharCode.SingleQuote */:\n                        case 34 /* CharCode.DoubleQuote */:\n                        case 96 /* CharCode.BackTick */:\n                            if (linkBeginChCode === chCode) {\n                                chClass = 1 /* CharacterClass.ForceTermination */;\n                            }\n                            else if (linkBeginChCode === 39 /* CharCode.SingleQuote */ || linkBeginChCode === 34 /* CharCode.DoubleQuote */ || linkBeginChCode === 96 /* CharCode.BackTick */) {\n                                chClass = 0 /* CharacterClass.None */;\n                            }\n                            else {\n                                chClass = 1 /* CharacterClass.ForceTermination */;\n                            }\n                            break;\n                        case 42 /* CharCode.Asterisk */:\n                            // `*` terminates a link if the link began with `*`\n                            chClass = (linkBeginChCode === 42 /* CharCode.Asterisk */) ? 1 /* CharacterClass.ForceTermination */ : 0 /* CharacterClass.None */;\n                            break;\n                        case 124 /* CharCode.Pipe */:\n                            // `|` terminates a link if the link began with `|`\n                            chClass = (linkBeginChCode === 124 /* CharCode.Pipe */) ? 1 /* CharacterClass.ForceTermination */ : 0 /* CharacterClass.None */;\n                            break;\n                        case 32 /* CharCode.Space */:\n                            // ` ` allow space in between [ and ]\n                            chClass = (inSquareBrackets ? 0 /* CharacterClass.None */ : 1 /* CharacterClass.ForceTermination */);\n                            break;\n                        default:\n                            chClass = classifier.get(chCode);\n                    }\n                    // Check if character terminates link\n                    if (chClass === 1 /* CharacterClass.ForceTermination */) {\n                        result.push(LinkComputer._createLink(classifier, line, i, linkBeginIndex, j));\n                        resetStateMachine = true;\n                    }\n                }\n                else if (state === 12 /* State.End */) {\n                    let chClass;\n                    if (chCode === 91 /* CharCode.OpenSquareBracket */) {\n                        // Allow for the authority part to contain ipv6 addresses which contain [ and ]\n                        hasOpenSquareBracket = true;\n                        chClass = 0 /* CharacterClass.None */;\n                    }\n                    else {\n                        chClass = classifier.get(chCode);\n                    }\n                    // Check if character terminates link\n                    if (chClass === 1 /* CharacterClass.ForceTermination */) {\n                        resetStateMachine = true;\n                    }\n                    else {\n                        state = 13 /* State.Accept */;\n                    }\n                }\n                else {\n                    state = stateMachine.nextState(state, chCode);\n                    if (state === 0 /* State.Invalid */) {\n                        resetStateMachine = true;\n                    }\n                }\n                if (resetStateMachine) {\n                    state = 1 /* State.Start */;\n                    hasOpenParens = false;\n                    hasOpenSquareBracket = false;\n                    hasOpenCurlyBracket = false;\n                    // Record where the link started\n                    linkBeginIndex = j + 1;\n                    linkBeginChCode = chCode;\n                }\n                j++;\n            }\n            if (state === 13 /* State.Accept */) {\n                result.push(LinkComputer._createLink(classifier, line, i, linkBeginIndex, len));\n            }\n        }\n        return result;\n    }\n}\n/**\n * Returns an array of all links contains in the provided\n * document. *Note* that this operation is computational\n * expensive and should not run in the UI thread.\n */\nexport function computeLinks(model) {\n    if (!model || typeof model.getLineCount !== 'function' || typeof model.getLineContent !== 'function') {\n        // Unknown caller!\n        return [];\n    }\n    return LinkComputer.computeLinks(model);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport class BasicInplaceReplace {\n    constructor() {\n        this._defaultValueSet = [\n            ['true', 'false'],\n            ['True', 'False'],\n            ['Private', 'Public', 'Friend', 'ReadOnly', 'Partial', 'Protected', 'WriteOnly'],\n            ['public', 'protected', 'private'],\n        ];\n    }\n    navigateValueSet(range1, text1, range2, text2, up) {\n        if (range1 && text1) {\n            const result = this.doNavigateValueSet(text1, up);\n            if (result) {\n                return {\n                    range: range1,\n                    value: result\n                };\n            }\n        }\n        if (range2 && text2) {\n            const result = this.doNavigateValueSet(text2, up);\n            if (result) {\n                return {\n                    range: range2,\n                    value: result\n                };\n            }\n        }\n        return null;\n    }\n    doNavigateValueSet(text, up) {\n        const numberResult = this.numberReplace(text, up);\n        if (numberResult !== null) {\n            return numberResult;\n        }\n        return this.textReplace(text, up);\n    }\n    numberReplace(value, up) {\n        const precision = Math.pow(10, value.length - (value.lastIndexOf('.') + 1));\n        let n1 = Number(value);\n        const n2 = parseFloat(value);\n        if (!isNaN(n1) && !isNaN(n2) && n1 === n2) {\n            if (n1 === 0 && !up) {\n                return null; // don't do negative\n                //\t\t\t} else if(n1 === 9 && up) {\n                //\t\t\t\treturn null; // don't insert 10 into a number\n            }\n            else {\n                n1 = Math.floor(n1 * precision);\n                n1 += up ? precision : -precision;\n                return String(n1 / precision);\n            }\n        }\n        return null;\n    }\n    textReplace(value, up) {\n        return this.valueSetsReplace(this._defaultValueSet, value, up);\n    }\n    valueSetsReplace(valueSets, value, up) {\n        let result = null;\n        for (let i = 0, len = valueSets.length; result === null && i < len; i++) {\n            result = this.valueSetReplace(valueSets[i], value, up);\n        }\n        return result;\n    }\n    valueSetReplace(valueSet, value, up) {\n        let idx = valueSet.indexOf(value);\n        if (idx >= 0) {\n            idx += up ? +1 : -1;\n            if (idx < 0) {\n                idx = valueSet.length - 1;\n            }\n            else {\n                idx %= valueSet.length;\n            }\n            return valueSet[idx];\n        }\n        return null;\n    }\n}\nBasicInplaceReplace.INSTANCE = new BasicInplaceReplace();\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { CharacterClassifier } from './characterClassifier.js';\nexport class WordCharacterClassifier extends CharacterClassifier {\n    constructor(wordSeparators) {\n        super(0 /* WordCharacterClass.Regular */);\n        for (let i = 0, len = wordSeparators.length; i < len; i++) {\n            this.set(wordSeparators.charCodeAt(i), 2 /* WordCharacterClass.WordSeparator */);\n        }\n        this.set(32 /* CharCode.Space */, 1 /* WordCharacterClass.Whitespace */);\n        this.set(9 /* CharCode.Tab */, 1 /* WordCharacterClass.Whitespace */);\n    }\n}\nfunction once(computeFn) {\n    const cache = {}; // TODO@Alex unbounded cache\n    return (input) => {\n        if (!cache.hasOwnProperty(input)) {\n            cache[input] = computeFn(input);\n        }\n        return cache[input];\n    };\n}\nexport const getMapForWordSeparators = once((input) => new WordCharacterClassifier(input));\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../../base/common/strings.js';\nimport { getMapForWordSeparators } from '../core/wordCharacterClassifier.js';\nimport { Position } from '../core/position.js';\nimport { Range } from '../core/range.js';\nimport { FindMatch, SearchData } from '../model.js';\nconst LIMIT_FIND_COUNT = 999;\nexport class SearchParams {\n    constructor(searchString, isRegex, matchCase, wordSeparators) {\n        this.searchString = searchString;\n        this.isRegex = isRegex;\n        this.matchCase = matchCase;\n        this.wordSeparators = wordSeparators;\n    }\n    parseSearchRequest() {\n        if (this.searchString === '') {\n            return null;\n        }\n        // Try to create a RegExp out of the params\n        let multiline;\n        if (this.isRegex) {\n            multiline = isMultilineRegexSource(this.searchString);\n        }\n        else {\n            multiline = (this.searchString.indexOf('\\n') >= 0);\n        }\n        let regex = null;\n        try {\n            regex = strings.createRegExp(this.searchString, this.isRegex, {\n                matchCase: this.matchCase,\n                wholeWord: false,\n                multiline: multiline,\n                global: true,\n                unicode: true\n            });\n        }\n        catch (err) {\n            return null;\n        }\n        if (!regex) {\n            return null;\n        }\n        let canUseSimpleSearch = (!this.isRegex && !multiline);\n        if (canUseSimpleSearch && this.searchString.toLowerCase() !== this.searchString.toUpperCase()) {\n            // casing might make a difference\n            canUseSimpleSearch = this.matchCase;\n        }\n        return new SearchData(regex, this.wordSeparators ? getMapForWordSeparators(this.wordSeparators) : null, canUseSimpleSearch ? this.searchString : null);\n    }\n}\nexport function isMultilineRegexSource(searchString) {\n    if (!searchString || searchString.length === 0) {\n        return false;\n    }\n    for (let i = 0, len = searchString.length; i < len; i++) {\n        const chCode = searchString.charCodeAt(i);\n        if (chCode === 10 /* CharCode.LineFeed */) {\n            return true;\n        }\n        if (chCode === 92 /* CharCode.Backslash */) {\n            // move to next char\n            i++;\n            if (i >= len) {\n                // string ends with a \\\n                break;\n            }\n            const nextChCode = searchString.charCodeAt(i);\n            if (nextChCode === 110 /* CharCode.n */ || nextChCode === 114 /* CharCode.r */ || nextChCode === 87 /* CharCode.W */) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\nexport function createFindMatch(range, rawMatches, captureMatches) {\n    if (!captureMatches) {\n        return new FindMatch(range, null);\n    }\n    const matches = [];\n    for (let i = 0, len = rawMatches.length; i < len; i++) {\n        matches[i] = rawMatches[i];\n    }\n    return new FindMatch(range, matches);\n}\nclass LineFeedCounter {\n    constructor(text) {\n        const lineFeedsOffsets = [];\n        let lineFeedsOffsetsLen = 0;\n        for (let i = 0, textLen = text.length; i < textLen; i++) {\n            if (text.charCodeAt(i) === 10 /* CharCode.LineFeed */) {\n                lineFeedsOffsets[lineFeedsOffsetsLen++] = i;\n            }\n        }\n        this._lineFeedsOffsets = lineFeedsOffsets;\n    }\n    findLineFeedCountBeforeOffset(offset) {\n        const lineFeedsOffsets = this._lineFeedsOffsets;\n        let min = 0;\n        let max = lineFeedsOffsets.length - 1;\n        if (max === -1) {\n            // no line feeds\n            return 0;\n        }\n        if (offset <= lineFeedsOffsets[0]) {\n            // before first line feed\n            return 0;\n        }\n        while (min < max) {\n            const mid = min + ((max - min) / 2 >> 0);\n            if (lineFeedsOffsets[mid] >= offset) {\n                max = mid - 1;\n            }\n            else {\n                if (lineFeedsOffsets[mid + 1] >= offset) {\n                    // bingo!\n                    min = mid;\n                    max = mid;\n                }\n                else {\n                    min = mid + 1;\n                }\n            }\n        }\n        return min + 1;\n    }\n}\nexport class TextModelSearch {\n    static findMatches(model, searchParams, searchRange, captureMatches, limitResultCount) {\n        const searchData = searchParams.parseSearchRequest();\n        if (!searchData) {\n            return [];\n        }\n        if (searchData.regex.multiline) {\n            return this._doFindMatchesMultiline(model, searchRange, new Searcher(searchData.wordSeparators, searchData.regex), captureMatches, limitResultCount);\n        }\n        return this._doFindMatchesLineByLine(model, searchRange, searchData, captureMatches, limitResultCount);\n    }\n    /**\n     * Multiline search always executes on the lines concatenated with \\n.\n     * We must therefore compensate for the count of \\n in case the model is CRLF\n     */\n    static _getMultilineMatchRange(model, deltaOffset, text, lfCounter, matchIndex, match0) {\n        let startOffset;\n        let lineFeedCountBeforeMatch = 0;\n        if (lfCounter) {\n            lineFeedCountBeforeMatch = lfCounter.findLineFeedCountBeforeOffset(matchIndex);\n            startOffset = deltaOffset + matchIndex + lineFeedCountBeforeMatch /* add as many \\r as there were \\n */;\n        }\n        else {\n            startOffset = deltaOffset + matchIndex;\n        }\n        let endOffset;\n        if (lfCounter) {\n            const lineFeedCountBeforeEndOfMatch = lfCounter.findLineFeedCountBeforeOffset(matchIndex + match0.length);\n            const lineFeedCountInMatch = lineFeedCountBeforeEndOfMatch - lineFeedCountBeforeMatch;\n            endOffset = startOffset + match0.length + lineFeedCountInMatch /* add as many \\r as there were \\n */;\n        }\n        else {\n            endOffset = startOffset + match0.length;\n        }\n        const startPosition = model.getPositionAt(startOffset);\n        const endPosition = model.getPositionAt(endOffset);\n        return new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column);\n    }\n    static _doFindMatchesMultiline(model, searchRange, searcher, captureMatches, limitResultCount) {\n        const deltaOffset = model.getOffsetAt(searchRange.getStartPosition());\n        // We always execute multiline search over the lines joined with \\n\n        // This makes it that \\n will match the EOL for both CRLF and LF models\n        // We compensate for offset errors in `_getMultilineMatchRange`\n        const text = model.getValueInRange(searchRange, 1 /* EndOfLinePreference.LF */);\n        const lfCounter = (model.getEOL() === '\\r\\n' ? new LineFeedCounter(text) : null);\n        const result = [];\n        let counter = 0;\n        let m;\n        searcher.reset(0);\n        while ((m = searcher.next(text))) {\n            result[counter++] = createFindMatch(this._getMultilineMatchRange(model, deltaOffset, text, lfCounter, m.index, m[0]), m, captureMatches);\n            if (counter >= limitResultCount) {\n                return result;\n            }\n        }\n        return result;\n    }\n    static _doFindMatchesLineByLine(model, searchRange, searchData, captureMatches, limitResultCount) {\n        const result = [];\n        let resultLen = 0;\n        // Early case for a search range that starts & stops on the same line number\n        if (searchRange.startLineNumber === searchRange.endLineNumber) {\n            const text = model.getLineContent(searchRange.startLineNumber).substring(searchRange.startColumn - 1, searchRange.endColumn - 1);\n            resultLen = this._findMatchesInLine(searchData, text, searchRange.startLineNumber, searchRange.startColumn - 1, resultLen, result, captureMatches, limitResultCount);\n            return result;\n        }\n        // Collect results from first line\n        const text = model.getLineContent(searchRange.startLineNumber).substring(searchRange.startColumn - 1);\n        resultLen = this._findMatchesInLine(searchData, text, searchRange.startLineNumber, searchRange.startColumn - 1, resultLen, result, captureMatches, limitResultCount);\n        // Collect results from middle lines\n        for (let lineNumber = searchRange.startLineNumber + 1; lineNumber < searchRange.endLineNumber && resultLen < limitResultCount; lineNumber++) {\n            resultLen = this._findMatchesInLine(searchData, model.getLineContent(lineNumber), lineNumber, 0, resultLen, result, captureMatches, limitResultCount);\n        }\n        // Collect results from last line\n        if (resultLen < limitResultCount) {\n            const text = model.getLineContent(searchRange.endLineNumber).substring(0, searchRange.endColumn - 1);\n            resultLen = this._findMatchesInLine(searchData, text, searchRange.endLineNumber, 0, resultLen, result, captureMatches, limitResultCount);\n        }\n        return result;\n    }\n    static _findMatchesInLine(searchData, text, lineNumber, deltaOffset, resultLen, result, captureMatches, limitResultCount) {\n        const wordSeparators = searchData.wordSeparators;\n        if (!captureMatches && searchData.simpleSearch) {\n            const searchString = searchData.simpleSearch;\n            const searchStringLen = searchString.length;\n            const textLength = text.length;\n            let lastMatchIndex = -searchStringLen;\n            while ((lastMatchIndex = text.indexOf(searchString, lastMatchIndex + searchStringLen)) !== -1) {\n                if (!wordSeparators || isValidMatch(wordSeparators, text, textLength, lastMatchIndex, searchStringLen)) {\n                    result[resultLen++] = new FindMatch(new Range(lineNumber, lastMatchIndex + 1 + deltaOffset, lineNumber, lastMatchIndex + 1 + searchStringLen + deltaOffset), null);\n                    if (resultLen >= limitResultCount) {\n                        return resultLen;\n                    }\n                }\n            }\n            return resultLen;\n        }\n        const searcher = new Searcher(searchData.wordSeparators, searchData.regex);\n        let m;\n        // Reset regex to search from the beginning\n        searcher.reset(0);\n        do {\n            m = searcher.next(text);\n            if (m) {\n                result[resultLen++] = createFindMatch(new Range(lineNumber, m.index + 1 + deltaOffset, lineNumber, m.index + 1 + m[0].length + deltaOffset), m, captureMatches);\n                if (resultLen >= limitResultCount) {\n                    return resultLen;\n                }\n            }\n        } while (m);\n        return resultLen;\n    }\n    static findNextMatch(model, searchParams, searchStart, captureMatches) {\n        const searchData = searchParams.parseSearchRequest();\n        if (!searchData) {\n            return null;\n        }\n        const searcher = new Searcher(searchData.wordSeparators, searchData.regex);\n        if (searchData.regex.multiline) {\n            return this._doFindNextMatchMultiline(model, searchStart, searcher, captureMatches);\n        }\n        return this._doFindNextMatchLineByLine(model, searchStart, searcher, captureMatches);\n    }\n    static _doFindNextMatchMultiline(model, searchStart, searcher, captureMatches) {\n        const searchTextStart = new Position(searchStart.lineNumber, 1);\n        const deltaOffset = model.getOffsetAt(searchTextStart);\n        const lineCount = model.getLineCount();\n        // We always execute multiline search over the lines joined with \\n\n        // This makes it that \\n will match the EOL for both CRLF and LF models\n        // We compensate for offset errors in `_getMultilineMatchRange`\n        const text = model.getValueInRange(new Range(searchTextStart.lineNumber, searchTextStart.column, lineCount, model.getLineMaxColumn(lineCount)), 1 /* EndOfLinePreference.LF */);\n        const lfCounter = (model.getEOL() === '\\r\\n' ? new LineFeedCounter(text) : null);\n        searcher.reset(searchStart.column - 1);\n        const m = searcher.next(text);\n        if (m) {\n            return createFindMatch(this._getMultilineMatchRange(model, deltaOffset, text, lfCounter, m.index, m[0]), m, captureMatches);\n        }\n        if (searchStart.lineNumber !== 1 || searchStart.column !== 1) {\n            // Try again from the top\n            return this._doFindNextMatchMultiline(model, new Position(1, 1), searcher, captureMatches);\n        }\n        return null;\n    }\n    static _doFindNextMatchLineByLine(model, searchStart, searcher, captureMatches) {\n        const lineCount = model.getLineCount();\n        const startLineNumber = searchStart.lineNumber;\n        // Look in first line\n        const text = model.getLineContent(startLineNumber);\n        const r = this._findFirstMatchInLine(searcher, text, startLineNumber, searchStart.column, captureMatches);\n        if (r) {\n            return r;\n        }\n        for (let i = 1; i <= lineCount; i++) {\n            const lineIndex = (startLineNumber + i - 1) % lineCount;\n            const text = model.getLineContent(lineIndex + 1);\n            const r = this._findFirstMatchInLine(searcher, text, lineIndex + 1, 1, captureMatches);\n            if (r) {\n                return r;\n            }\n        }\n        return null;\n    }\n    static _findFirstMatchInLine(searcher, text, lineNumber, fromColumn, captureMatches) {\n        // Set regex to search from column\n        searcher.reset(fromColumn - 1);\n        const m = searcher.next(text);\n        if (m) {\n            return createFindMatch(new Range(lineNumber, m.index + 1, lineNumber, m.index + 1 + m[0].length), m, captureMatches);\n        }\n        return null;\n    }\n    static findPreviousMatch(model, searchParams, searchStart, captureMatches) {\n        const searchData = searchParams.parseSearchRequest();\n        if (!searchData) {\n            return null;\n        }\n        const searcher = new Searcher(searchData.wordSeparators, searchData.regex);\n        if (searchData.regex.multiline) {\n            return this._doFindPreviousMatchMultiline(model, searchStart, searcher, captureMatches);\n        }\n        return this._doFindPreviousMatchLineByLine(model, searchStart, searcher, captureMatches);\n    }\n    static _doFindPreviousMatchMultiline(model, searchStart, searcher, captureMatches) {\n        const matches = this._doFindMatchesMultiline(model, new Range(1, 1, searchStart.lineNumber, searchStart.column), searcher, captureMatches, 10 * LIMIT_FIND_COUNT);\n        if (matches.length > 0) {\n            return matches[matches.length - 1];\n        }\n        const lineCount = model.getLineCount();\n        if (searchStart.lineNumber !== lineCount || searchStart.column !== model.getLineMaxColumn(lineCount)) {\n            // Try again with all content\n            return this._doFindPreviousMatchMultiline(model, new Position(lineCount, model.getLineMaxColumn(lineCount)), searcher, captureMatches);\n        }\n        return null;\n    }\n    static _doFindPreviousMatchLineByLine(model, searchStart, searcher, captureMatches) {\n        const lineCount = model.getLineCount();\n        const startLineNumber = searchStart.lineNumber;\n        // Look in first line\n        const text = model.getLineContent(startLineNumber).substring(0, searchStart.column - 1);\n        const r = this._findLastMatchInLine(searcher, text, startLineNumber, captureMatches);\n        if (r) {\n            return r;\n        }\n        for (let i = 1; i <= lineCount; i++) {\n            const lineIndex = (lineCount + startLineNumber - i - 1) % lineCount;\n            const text = model.getLineContent(lineIndex + 1);\n            const r = this._findLastMatchInLine(searcher, text, lineIndex + 1, captureMatches);\n            if (r) {\n                return r;\n            }\n        }\n        return null;\n    }\n    static _findLastMatchInLine(searcher, text, lineNumber, captureMatches) {\n        let bestResult = null;\n        let m;\n        searcher.reset(0);\n        while ((m = searcher.next(text))) {\n            bestResult = createFindMatch(new Range(lineNumber, m.index + 1, lineNumber, m.index + 1 + m[0].length), m, captureMatches);\n        }\n        return bestResult;\n    }\n}\nfunction leftIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength) {\n    if (matchStartIndex === 0) {\n        // Match starts at start of string\n        return true;\n    }\n    const charBefore = text.charCodeAt(matchStartIndex - 1);\n    if (wordSeparators.get(charBefore) !== 0 /* WordCharacterClass.Regular */) {\n        // The character before the match is a word separator\n        return true;\n    }\n    if (charBefore === 13 /* CharCode.CarriageReturn */ || charBefore === 10 /* CharCode.LineFeed */) {\n        // The character before the match is line break or carriage return.\n        return true;\n    }\n    if (matchLength > 0) {\n        const firstCharInMatch = text.charCodeAt(matchStartIndex);\n        if (wordSeparators.get(firstCharInMatch) !== 0 /* WordCharacterClass.Regular */) {\n            // The first character inside the match is a word separator\n            return true;\n        }\n    }\n    return false;\n}\nfunction rightIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength) {\n    if (matchStartIndex + matchLength === textLength) {\n        // Match ends at end of string\n        return true;\n    }\n    const charAfter = text.charCodeAt(matchStartIndex + matchLength);\n    if (wordSeparators.get(charAfter) !== 0 /* WordCharacterClass.Regular */) {\n        // The character after the match is a word separator\n        return true;\n    }\n    if (charAfter === 13 /* CharCode.CarriageReturn */ || charAfter === 10 /* CharCode.LineFeed */) {\n        // The character after the match is line break or carriage return.\n        return true;\n    }\n    if (matchLength > 0) {\n        const lastCharInMatch = text.charCodeAt(matchStartIndex + matchLength - 1);\n        if (wordSeparators.get(lastCharInMatch) !== 0 /* WordCharacterClass.Regular */) {\n            // The last character in the match is a word separator\n            return true;\n        }\n    }\n    return false;\n}\nexport function isValidMatch(wordSeparators, text, textLength, matchStartIndex, matchLength) {\n    return (leftIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength)\n        && rightIsWordBounday(wordSeparators, text, textLength, matchStartIndex, matchLength));\n}\nexport class Searcher {\n    constructor(wordSeparators, searchRegex) {\n        this._wordSeparators = wordSeparators;\n        this._searchRegex = searchRegex;\n        this._prevMatchStartIndex = -1;\n        this._prevMatchLength = 0;\n    }\n    reset(lastIndex) {\n        this._searchRegex.lastIndex = lastIndex;\n        this._prevMatchStartIndex = -1;\n        this._prevMatchLength = 0;\n    }\n    next(text) {\n        const textLength = text.length;\n        let m;\n        do {\n            if (this._prevMatchStartIndex + this._prevMatchLength === textLength) {\n                // Reached the end of the line\n                return null;\n            }\n            m = this._searchRegex.exec(text);\n            if (!m) {\n                return null;\n            }\n            const matchStartIndex = m.index;\n            const matchLength = m[0].length;\n            if (matchStartIndex === this._prevMatchStartIndex && matchLength === this._prevMatchLength) {\n                if (matchLength === 0) {\n                    // the search result is an empty string and won't advance `regex.lastIndex`, so `regex.exec` will stuck here\n                    // we attempt to recover from that by advancing by two if surrogate pair found and by one otherwise\n                    if (strings.getNextCodePoint(text, textLength, this._searchRegex.lastIndex) > 0xFFFF) {\n                        this._searchRegex.lastIndex += 2;\n                    }\n                    else {\n                        this._searchRegex.lastIndex += 1;\n                    }\n                    continue;\n                }\n                // Exit early if the regex matches the same range twice\n                return null;\n            }\n            this._prevMatchStartIndex = matchStartIndex;\n            this._prevMatchLength = matchLength;\n            if (!this._wordSeparators || isValidMatch(this._wordSeparators, text, textLength, matchStartIndex, matchLength)) {\n                return m;\n            }\n        } while (m);\n        return null;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Range } from '../core/range.js';\nimport { Searcher } from '../model/textModelSearch.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { assertNever } from '../../../base/common/assert.js';\nimport { DEFAULT_WORD_REGEXP, getWordAtText } from '../core/wordHelper.js';\nexport class UnicodeTextModelHighlighter {\n    static computeUnicodeHighlights(model, options, range) {\n        const startLine = range ? range.startLineNumber : 1;\n        const endLine = range ? range.endLineNumber : model.getLineCount();\n        const codePointHighlighter = new CodePointHighlighter(options);\n        const candidates = codePointHighlighter.getCandidateCodePoints();\n        let regex;\n        if (candidates === 'allNonBasicAscii') {\n            regex = new RegExp('[^\\\\t\\\\n\\\\r\\\\x20-\\\\x7E]', 'g');\n        }\n        else {\n            regex = new RegExp(`${buildRegExpCharClassExpr(Array.from(candidates))}`, 'g');\n        }\n        const searcher = new Searcher(null, regex);\n        const ranges = [];\n        let hasMore = false;\n        let m;\n        let ambiguousCharacterCount = 0;\n        let invisibleCharacterCount = 0;\n        let nonBasicAsciiCharacterCount = 0;\n        forLoop: for (let lineNumber = startLine, lineCount = endLine; lineNumber <= lineCount; lineNumber++) {\n            const lineContent = model.getLineContent(lineNumber);\n            const lineLength = lineContent.length;\n            // Reset regex to search from the beginning\n            searcher.reset(0);\n            do {\n                m = searcher.next(lineContent);\n                if (m) {\n                    let startIndex = m.index;\n                    let endIndex = m.index + m[0].length;\n                    // Extend range to entire code point\n                    if (startIndex > 0) {\n                        const charCodeBefore = lineContent.charCodeAt(startIndex - 1);\n                        if (strings.isHighSurrogate(charCodeBefore)) {\n                            startIndex--;\n                        }\n                    }\n                    if (endIndex + 1 < lineLength) {\n                        const charCodeBefore = lineContent.charCodeAt(endIndex - 1);\n                        if (strings.isHighSurrogate(charCodeBefore)) {\n                            endIndex++;\n                        }\n                    }\n                    const str = lineContent.substring(startIndex, endIndex);\n                    let word = getWordAtText(startIndex + 1, DEFAULT_WORD_REGEXP, lineContent, 0);\n                    if (word && word.endColumn <= startIndex + 1) {\n                        // The word does not include the problematic character, ignore the word\n                        word = null;\n                    }\n                    const highlightReason = codePointHighlighter.shouldHighlightNonBasicASCII(str, word ? word.word : null);\n                    if (highlightReason !== 0 /* SimpleHighlightReason.None */) {\n                        if (highlightReason === 3 /* SimpleHighlightReason.Ambiguous */) {\n                            ambiguousCharacterCount++;\n                        }\n                        else if (highlightReason === 2 /* SimpleHighlightReason.Invisible */) {\n                            invisibleCharacterCount++;\n                        }\n                        else if (highlightReason === 1 /* SimpleHighlightReason.NonBasicASCII */) {\n                            nonBasicAsciiCharacterCount++;\n                        }\n                        else {\n                            assertNever(highlightReason);\n                        }\n                        const MAX_RESULT_LENGTH = 1000;\n                        if (ranges.length >= MAX_RESULT_LENGTH) {\n                            hasMore = true;\n                            break forLoop;\n                        }\n                        ranges.push(new Range(lineNumber, startIndex + 1, lineNumber, endIndex + 1));\n                    }\n                }\n            } while (m);\n        }\n        return {\n            ranges,\n            hasMore,\n            ambiguousCharacterCount,\n            invisibleCharacterCount,\n            nonBasicAsciiCharacterCount\n        };\n    }\n    static computeUnicodeHighlightReason(char, options) {\n        const codePointHighlighter = new CodePointHighlighter(options);\n        const reason = codePointHighlighter.shouldHighlightNonBasicASCII(char, null);\n        switch (reason) {\n            case 0 /* SimpleHighlightReason.None */:\n                return null;\n            case 2 /* SimpleHighlightReason.Invisible */:\n                return { kind: 1 /* UnicodeHighlighterReasonKind.Invisible */ };\n            case 3 /* SimpleHighlightReason.Ambiguous */: {\n                const codePoint = char.codePointAt(0);\n                const primaryConfusable = codePointHighlighter.ambiguousCharacters.getPrimaryConfusable(codePoint);\n                const notAmbiguousInLocales = strings.AmbiguousCharacters.getLocales().filter((l) => !strings.AmbiguousCharacters.getInstance(new Set([...options.allowedLocales, l])).isAmbiguous(codePoint));\n                return { kind: 0 /* UnicodeHighlighterReasonKind.Ambiguous */, confusableWith: String.fromCodePoint(primaryConfusable), notAmbiguousInLocales };\n            }\n            case 1 /* SimpleHighlightReason.NonBasicASCII */:\n                return { kind: 2 /* UnicodeHighlighterReasonKind.NonBasicAscii */ };\n        }\n    }\n}\nfunction buildRegExpCharClassExpr(codePoints, flags) {\n    const src = `[${strings.escapeRegExpCharacters(codePoints.map((i) => String.fromCodePoint(i)).join(''))}]`;\n    return src;\n}\nclass CodePointHighlighter {\n    constructor(options) {\n        this.options = options;\n        this.allowedCodePoints = new Set(options.allowedCodePoints);\n        this.ambiguousCharacters = strings.AmbiguousCharacters.getInstance(new Set(options.allowedLocales));\n    }\n    getCandidateCodePoints() {\n        if (this.options.nonBasicASCII) {\n            return 'allNonBasicAscii';\n        }\n        const set = new Set();\n        if (this.options.invisibleCharacters) {\n            for (const cp of strings.InvisibleCharacters.codePoints) {\n                if (!isAllowedInvisibleCharacter(String.fromCodePoint(cp))) {\n                    set.add(cp);\n                }\n            }\n        }\n        if (this.options.ambiguousCharacters) {\n            for (const cp of this.ambiguousCharacters.getConfusableCodePoints()) {\n                set.add(cp);\n            }\n        }\n        for (const cp of this.allowedCodePoints) {\n            set.delete(cp);\n        }\n        return set;\n    }\n    shouldHighlightNonBasicASCII(character, wordContext) {\n        const codePoint = character.codePointAt(0);\n        if (this.allowedCodePoints.has(codePoint)) {\n            return 0 /* SimpleHighlightReason.None */;\n        }\n        if (this.options.nonBasicASCII) {\n            return 1 /* SimpleHighlightReason.NonBasicASCII */;\n        }\n        let hasBasicASCIICharacters = false;\n        let hasNonConfusableNonBasicAsciiCharacter = false;\n        if (wordContext) {\n            for (const char of wordContext) {\n                const codePoint = char.codePointAt(0);\n                const isBasicASCII = strings.isBasicASCII(char);\n                hasBasicASCIICharacters = hasBasicASCIICharacters || isBasicASCII;\n                if (!isBasicASCII &&\n                    !this.ambiguousCharacters.isAmbiguous(codePoint) &&\n                    !strings.InvisibleCharacters.isInvisibleCharacter(codePoint)) {\n                    hasNonConfusableNonBasicAsciiCharacter = true;\n                }\n            }\n        }\n        if (\n        /* Don't allow mixing weird looking characters with ASCII */ !hasBasicASCIICharacters &&\n            /* Is there an obviously weird looking character? */ hasNonConfusableNonBasicAsciiCharacter) {\n            return 0 /* SimpleHighlightReason.None */;\n        }\n        if (this.options.invisibleCharacters) {\n            // TODO check for emojis\n            if (!isAllowedInvisibleCharacter(character) && strings.InvisibleCharacters.isInvisibleCharacter(codePoint)) {\n                return 2 /* SimpleHighlightReason.Invisible */;\n            }\n        }\n        if (this.options.ambiguousCharacters) {\n            if (this.ambiguousCharacters.isAmbiguous(codePoint)) {\n                return 3 /* SimpleHighlightReason.Ambiguous */;\n            }\n        }\n        return 0 /* SimpleHighlightReason.None */;\n    }\n}\nfunction isAllowedInvisibleCharacter(character) {\n    return character === ' ' || character === '\\n' || character === '\\t';\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { BugIndicatingError } from '../../../base/common/errors.js';\nimport { Range } from './range.js';\n/**\n * A range of lines (1-based).\n */\nexport class LineRange {\n    static fromRange(range) {\n        return new LineRange(range.startLineNumber, range.endLineNumber);\n    }\n    static subtract(a, b) {\n        if (!b) {\n            return [a];\n        }\n        if (a.startLineNumber < b.startLineNumber && b.endLineNumberExclusive < a.endLineNumberExclusive) {\n            return [\n                new LineRange(a.startLineNumber, b.startLineNumber),\n                new LineRange(b.endLineNumberExclusive, a.endLineNumberExclusive)\n            ];\n        }\n        else if (b.startLineNumber <= a.startLineNumber && a.endLineNumberExclusive <= b.endLineNumberExclusive) {\n            return [];\n        }\n        else if (b.endLineNumberExclusive < a.endLineNumberExclusive) {\n            return [new LineRange(Math.max(b.endLineNumberExclusive, a.startLineNumber), a.endLineNumberExclusive)];\n        }\n        else {\n            return [new LineRange(a.startLineNumber, Math.min(b.startLineNumber, a.endLineNumberExclusive))];\n        }\n    }\n    /**\n     * @param lineRanges An array of sorted line ranges.\n     */\n    static joinMany(lineRanges) {\n        if (lineRanges.length === 0) {\n            return [];\n        }\n        let result = lineRanges[0];\n        for (let i = 1; i < lineRanges.length; i++) {\n            result = this.join(result, lineRanges[i]);\n        }\n        return result;\n    }\n    /**\n     * @param lineRanges1 Must be sorted.\n     * @param lineRanges2 Must be sorted.\n     */\n    static join(lineRanges1, lineRanges2) {\n        if (lineRanges1.length === 0) {\n            return lineRanges2;\n        }\n        if (lineRanges2.length === 0) {\n            return lineRanges1;\n        }\n        const result = [];\n        let i1 = 0;\n        let i2 = 0;\n        let current = null;\n        while (i1 < lineRanges1.length || i2 < lineRanges2.length) {\n            let next = null;\n            if (i1 < lineRanges1.length && i2 < lineRanges2.length) {\n                const lineRange1 = lineRanges1[i1];\n                const lineRange2 = lineRanges2[i2];\n                if (lineRange1.startLineNumber < lineRange2.startLineNumber) {\n                    next = lineRange1;\n                    i1++;\n                }\n                else {\n                    next = lineRange2;\n                    i2++;\n                }\n            }\n            else if (i1 < lineRanges1.length) {\n                next = lineRanges1[i1];\n                i1++;\n            }\n            else {\n                next = lineRanges2[i2];\n                i2++;\n            }\n            if (current === null) {\n                current = next;\n            }\n            else {\n                if (current.endLineNumberExclusive >= next.startLineNumber) {\n                    // merge\n                    current = new LineRange(current.startLineNumber, Math.max(current.endLineNumberExclusive, next.endLineNumberExclusive));\n                }\n                else {\n                    // push\n                    result.push(current);\n                    current = next;\n                }\n            }\n        }\n        if (current !== null) {\n            result.push(current);\n        }\n        return result;\n    }\n    static ofLength(startLineNumber, length) {\n        return new LineRange(startLineNumber, startLineNumber + length);\n    }\n    /**\n     * @internal\n     */\n    static deserialize(lineRange) {\n        return new LineRange(lineRange[0], lineRange[1]);\n    }\n    constructor(startLineNumber, endLineNumberExclusive) {\n        if (startLineNumber > endLineNumberExclusive) {\n            throw new BugIndicatingError(`startLineNumber ${startLineNumber} cannot be after endLineNumberExclusive ${endLineNumberExclusive}`);\n        }\n        this.startLineNumber = startLineNumber;\n        this.endLineNumberExclusive = endLineNumberExclusive;\n    }\n    /**\n     * Indicates if this line range contains the given line number.\n     */\n    contains(lineNumber) {\n        return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive;\n    }\n    /**\n     * Indicates if this line range is empty.\n     */\n    get isEmpty() {\n        return this.startLineNumber === this.endLineNumberExclusive;\n    }\n    /**\n     * Moves this line range by the given offset of line numbers.\n     */\n    delta(offset) {\n        return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset);\n    }\n    /**\n     * The number of lines this line range spans.\n     */\n    get length() {\n        return this.endLineNumberExclusive - this.startLineNumber;\n    }\n    /**\n     * Creates a line range that combines this and the given line range.\n     */\n    join(other) {\n        return new LineRange(Math.min(this.startLineNumber, other.startLineNumber), Math.max(this.endLineNumberExclusive, other.endLineNumberExclusive));\n    }\n    toString() {\n        return `[${this.startLineNumber},${this.endLineNumberExclusive})`;\n    }\n    /**\n     * The resulting range is empty if the ranges do not intersect, but touch.\n     * If the ranges don't even touch, the result is undefined.\n     */\n    intersect(other) {\n        const startLineNumber = Math.max(this.startLineNumber, other.startLineNumber);\n        const endLineNumberExclusive = Math.min(this.endLineNumberExclusive, other.endLineNumberExclusive);\n        if (startLineNumber <= endLineNumberExclusive) {\n            return new LineRange(startLineNumber, endLineNumberExclusive);\n        }\n        return undefined;\n    }\n    intersectsStrict(other) {\n        return this.startLineNumber < other.endLineNumberExclusive && other.startLineNumber < this.endLineNumberExclusive;\n    }\n    overlapOrTouch(other) {\n        return this.startLineNumber <= other.endLineNumberExclusive && other.startLineNumber <= this.endLineNumberExclusive;\n    }\n    equals(b) {\n        return this.startLineNumber === b.startLineNumber && this.endLineNumberExclusive === b.endLineNumberExclusive;\n    }\n    toInclusiveRange() {\n        if (this.isEmpty) {\n            return null;\n        }\n        return new Range(this.startLineNumber, 1, this.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER);\n    }\n    toExclusiveRange() {\n        return new Range(this.startLineNumber, 1, this.endLineNumberExclusive, 1);\n    }\n    mapToLineArray(f) {\n        const result = [];\n        for (let lineNumber = this.startLineNumber; lineNumber < this.endLineNumberExclusive; lineNumber++) {\n            result.push(f(lineNumber));\n        }\n        return result;\n    }\n    /**\n     * @internal\n     */\n    serialize() {\n        return [this.startLineNumber, this.endLineNumberExclusive];\n    }\n    includes(lineNumber) {\n        return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { LineRange } from '../core/lineRange.js';\nexport class LinesDiff {\n    constructor(changes, \n    /**\n     * Sorted by original line ranges.\n     * The original line ranges and the modified line ranges must be disjoint (but can be touching).\n     */\n    moves, \n    /**\n     * Indicates if the time out was reached.\n     * In that case, the diffs might be an approximation and the user should be asked to rerun the diff with more time.\n     */\n    hitTimeout) {\n        this.changes = changes;\n        this.moves = moves;\n        this.hitTimeout = hitTimeout;\n    }\n}\n/**\n * Maps a line range in the original text model to a line range in the modified text model.\n */\nexport class LineRangeMapping {\n    static inverse(mapping, originalLineCount, modifiedLineCount) {\n        const result = [];\n        let lastOriginalEndLineNumber = 1;\n        let lastModifiedEndLineNumber = 1;\n        for (const m of mapping) {\n            const r = new LineRangeMapping(new LineRange(lastOriginalEndLineNumber, m.originalRange.startLineNumber), new LineRange(lastModifiedEndLineNumber, m.modifiedRange.startLineNumber), undefined);\n            if (!r.modifiedRange.isEmpty) {\n                result.push(r);\n            }\n            lastOriginalEndLineNumber = m.originalRange.endLineNumberExclusive;\n            lastModifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive;\n        }\n        const r = new LineRangeMapping(new LineRange(lastOriginalEndLineNumber, originalLineCount + 1), new LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1), undefined);\n        if (!r.modifiedRange.isEmpty) {\n            result.push(r);\n        }\n        return result;\n    }\n    constructor(originalRange, modifiedRange, innerChanges) {\n        this.originalRange = originalRange;\n        this.modifiedRange = modifiedRange;\n        this.innerChanges = innerChanges;\n    }\n    toString() {\n        return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;\n    }\n    get changedLineCount() {\n        return Math.max(this.originalRange.length, this.modifiedRange.length);\n    }\n    flip() {\n        var _a;\n        return new LineRangeMapping(this.modifiedRange, this.originalRange, (_a = this.innerChanges) === null || _a === void 0 ? void 0 : _a.map(c => c.flip()));\n    }\n}\n/**\n * Maps a range in the original text model to a range in the modified text model.\n */\nexport class RangeMapping {\n    constructor(originalRange, modifiedRange) {\n        this.originalRange = originalRange;\n        this.modifiedRange = modifiedRange;\n    }\n    toString() {\n        return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;\n    }\n    flip() {\n        return new RangeMapping(this.modifiedRange, this.originalRange);\n    }\n}\nexport class SimpleLineRangeMapping {\n    constructor(originalRange, modifiedRange) {\n        this.originalRange = originalRange;\n        this.modifiedRange = modifiedRange;\n    }\n    toString() {\n        return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;\n    }\n    flip() {\n        return new SimpleLineRangeMapping(this.modifiedRange, this.originalRange);\n    }\n}\nexport class MovedText {\n    constructor(lineRangeMapping, changes) {\n        this.lineRangeMapping = lineRangeMapping;\n        this.changes = changes;\n    }\n    flip() {\n        return new MovedText(this.lineRangeMapping.flip(), this.changes.map(c => c.flip()));\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { LcsDiff } from '../../../base/common/diff/diff.js';\nimport { RangeMapping, LineRangeMapping, LinesDiff } from './linesDiffComputer.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { Range } from '../core/range.js';\nimport { assertFn, checkAdjacentItems } from '../../../base/common/assert.js';\nimport { LineRange } from '../core/lineRange.js';\nconst MINIMUM_MATCHING_CHARACTER_LENGTH = 3;\nexport class SmartLinesDiffComputer {\n    computeDiff(originalLines, modifiedLines, options) {\n        var _a;\n        const diffComputer = new DiffComputer(originalLines, modifiedLines, {\n            maxComputationTime: options.maxComputationTimeMs,\n            shouldIgnoreTrimWhitespace: options.ignoreTrimWhitespace,\n            shouldComputeCharChanges: true,\n            shouldMakePrettyDiff: true,\n            shouldPostProcessCharChanges: true,\n        });\n        const result = diffComputer.computeDiff();\n        const changes = [];\n        let lastChange = null;\n        for (const c of result.changes) {\n            let originalRange;\n            if (c.originalEndLineNumber === 0) {\n                // Insertion\n                originalRange = new LineRange(c.originalStartLineNumber + 1, c.originalStartLineNumber + 1);\n            }\n            else {\n                originalRange = new LineRange(c.originalStartLineNumber, c.originalEndLineNumber + 1);\n            }\n            let modifiedRange;\n            if (c.modifiedEndLineNumber === 0) {\n                // Deletion\n                modifiedRange = new LineRange(c.modifiedStartLineNumber + 1, c.modifiedStartLineNumber + 1);\n            }\n            else {\n                modifiedRange = new LineRange(c.modifiedStartLineNumber, c.modifiedEndLineNumber + 1);\n            }\n            let change = new LineRangeMapping(originalRange, modifiedRange, (_a = c.charChanges) === null || _a === void 0 ? void 0 : _a.map(c => new RangeMapping(new Range(c.originalStartLineNumber, c.originalStartColumn, c.originalEndLineNumber, c.originalEndColumn), new Range(c.modifiedStartLineNumber, c.modifiedStartColumn, c.modifiedEndLineNumber, c.modifiedEndColumn))));\n            if (lastChange) {\n                if (lastChange.modifiedRange.endLineNumberExclusive === change.modifiedRange.startLineNumber\n                    || lastChange.originalRange.endLineNumberExclusive === change.originalRange.startLineNumber) {\n                    // join touching diffs. Probably moving diffs up/down in the algorithm causes touching diffs.\n                    change = new LineRangeMapping(lastChange.originalRange.join(change.originalRange), lastChange.modifiedRange.join(change.modifiedRange), lastChange.innerChanges && change.innerChanges ?\n                        lastChange.innerChanges.concat(change.innerChanges) : undefined);\n                    changes.pop();\n                }\n            }\n            changes.push(change);\n            lastChange = change;\n        }\n        assertFn(() => {\n            return checkAdjacentItems(changes, (m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&\n                // There has to be an unchanged line in between (otherwise both diffs should have been joined)\n                m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&\n                m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber);\n        });\n        return new LinesDiff(changes, [], result.quitEarly);\n    }\n}\nfunction computeDiff(originalSequence, modifiedSequence, continueProcessingPredicate, pretty) {\n    const diffAlgo = new LcsDiff(originalSequence, modifiedSequence, continueProcessingPredicate);\n    return diffAlgo.ComputeDiff(pretty);\n}\nclass LineSequence {\n    constructor(lines) {\n        const startColumns = [];\n        const endColumns = [];\n        for (let i = 0, length = lines.length; i < length; i++) {\n            startColumns[i] = getFirstNonBlankColumn(lines[i], 1);\n            endColumns[i] = getLastNonBlankColumn(lines[i], 1);\n        }\n        this.lines = lines;\n        this._startColumns = startColumns;\n        this._endColumns = endColumns;\n    }\n    getElements() {\n        const elements = [];\n        for (let i = 0, len = this.lines.length; i < len; i++) {\n            elements[i] = this.lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1);\n        }\n        return elements;\n    }\n    getStrictElement(index) {\n        return this.lines[index];\n    }\n    getStartLineNumber(i) {\n        return i + 1;\n    }\n    getEndLineNumber(i) {\n        return i + 1;\n    }\n    createCharSequence(shouldIgnoreTrimWhitespace, startIndex, endIndex) {\n        const charCodes = [];\n        const lineNumbers = [];\n        const columns = [];\n        let len = 0;\n        for (let index = startIndex; index <= endIndex; index++) {\n            const lineContent = this.lines[index];\n            const startColumn = (shouldIgnoreTrimWhitespace ? this._startColumns[index] : 1);\n            const endColumn = (shouldIgnoreTrimWhitespace ? this._endColumns[index] : lineContent.length + 1);\n            for (let col = startColumn; col < endColumn; col++) {\n                charCodes[len] = lineContent.charCodeAt(col - 1);\n                lineNumbers[len] = index + 1;\n                columns[len] = col;\n                len++;\n            }\n            if (!shouldIgnoreTrimWhitespace && index < endIndex) {\n                // Add \\n if trim whitespace is not ignored\n                charCodes[len] = 10 /* CharCode.LineFeed */;\n                lineNumbers[len] = index + 1;\n                columns[len] = lineContent.length + 1;\n                len++;\n            }\n        }\n        return new CharSequence(charCodes, lineNumbers, columns);\n    }\n}\nclass CharSequence {\n    constructor(charCodes, lineNumbers, columns) {\n        this._charCodes = charCodes;\n        this._lineNumbers = lineNumbers;\n        this._columns = columns;\n    }\n    toString() {\n        return ('[' + this._charCodes.map((s, idx) => (s === 10 /* CharCode.LineFeed */ ? '\\\\n' : String.fromCharCode(s)) + `-(${this._lineNumbers[idx]},${this._columns[idx]})`).join(', ') + ']');\n    }\n    _assertIndex(index, arr) {\n        if (index < 0 || index >= arr.length) {\n            throw new Error(`Illegal index`);\n        }\n    }\n    getElements() {\n        return this._charCodes;\n    }\n    getStartLineNumber(i) {\n        if (i > 0 && i === this._lineNumbers.length) {\n            // the start line number of the element after the last element\n            // is the end line number of the last element\n            return this.getEndLineNumber(i - 1);\n        }\n        this._assertIndex(i, this._lineNumbers);\n        return this._lineNumbers[i];\n    }\n    getEndLineNumber(i) {\n        if (i === -1) {\n            // the end line number of the element before the first element\n            // is the start line number of the first element\n            return this.getStartLineNumber(i + 1);\n        }\n        this._assertIndex(i, this._lineNumbers);\n        if (this._charCodes[i] === 10 /* CharCode.LineFeed */) {\n            return this._lineNumbers[i] + 1;\n        }\n        return this._lineNumbers[i];\n    }\n    getStartColumn(i) {\n        if (i > 0 && i === this._columns.length) {\n            // the start column of the element after the last element\n            // is the end column of the last element\n            return this.getEndColumn(i - 1);\n        }\n        this._assertIndex(i, this._columns);\n        return this._columns[i];\n    }\n    getEndColumn(i) {\n        if (i === -1) {\n            // the end column of the element before the first element\n            // is the start column of the first element\n            return this.getStartColumn(i + 1);\n        }\n        this._assertIndex(i, this._columns);\n        if (this._charCodes[i] === 10 /* CharCode.LineFeed */) {\n            return 1;\n        }\n        return this._columns[i] + 1;\n    }\n}\nclass CharChange {\n    constructor(originalStartLineNumber, originalStartColumn, originalEndLineNumber, originalEndColumn, modifiedStartLineNumber, modifiedStartColumn, modifiedEndLineNumber, modifiedEndColumn) {\n        this.originalStartLineNumber = originalStartLineNumber;\n        this.originalStartColumn = originalStartColumn;\n        this.originalEndLineNumber = originalEndLineNumber;\n        this.originalEndColumn = originalEndColumn;\n        this.modifiedStartLineNumber = modifiedStartLineNumber;\n        this.modifiedStartColumn = modifiedStartColumn;\n        this.modifiedEndLineNumber = modifiedEndLineNumber;\n        this.modifiedEndColumn = modifiedEndColumn;\n    }\n    static createFromDiffChange(diffChange, originalCharSequence, modifiedCharSequence) {\n        const originalStartLineNumber = originalCharSequence.getStartLineNumber(diffChange.originalStart);\n        const originalStartColumn = originalCharSequence.getStartColumn(diffChange.originalStart);\n        const originalEndLineNumber = originalCharSequence.getEndLineNumber(diffChange.originalStart + diffChange.originalLength - 1);\n        const originalEndColumn = originalCharSequence.getEndColumn(diffChange.originalStart + diffChange.originalLength - 1);\n        const modifiedStartLineNumber = modifiedCharSequence.getStartLineNumber(diffChange.modifiedStart);\n        const modifiedStartColumn = modifiedCharSequence.getStartColumn(diffChange.modifiedStart);\n        const modifiedEndLineNumber = modifiedCharSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1);\n        const modifiedEndColumn = modifiedCharSequence.getEndColumn(diffChange.modifiedStart + diffChange.modifiedLength - 1);\n        return new CharChange(originalStartLineNumber, originalStartColumn, originalEndLineNumber, originalEndColumn, modifiedStartLineNumber, modifiedStartColumn, modifiedEndLineNumber, modifiedEndColumn);\n    }\n}\nfunction postProcessCharChanges(rawChanges) {\n    if (rawChanges.length <= 1) {\n        return rawChanges;\n    }\n    const result = [rawChanges[0]];\n    let prevChange = result[0];\n    for (let i = 1, len = rawChanges.length; i < len; i++) {\n        const currChange = rawChanges[i];\n        const originalMatchingLength = currChange.originalStart - (prevChange.originalStart + prevChange.originalLength);\n        const modifiedMatchingLength = currChange.modifiedStart - (prevChange.modifiedStart + prevChange.modifiedLength);\n        // Both of the above should be equal, but the continueProcessingPredicate may prevent this from being true\n        const matchingLength = Math.min(originalMatchingLength, modifiedMatchingLength);\n        if (matchingLength < MINIMUM_MATCHING_CHARACTER_LENGTH) {\n            // Merge the current change into the previous one\n            prevChange.originalLength = (currChange.originalStart + currChange.originalLength) - prevChange.originalStart;\n            prevChange.modifiedLength = (currChange.modifiedStart + currChange.modifiedLength) - prevChange.modifiedStart;\n        }\n        else {\n            // Add the current change\n            result.push(currChange);\n            prevChange = currChange;\n        }\n    }\n    return result;\n}\nclass LineChange {\n    constructor(originalStartLineNumber, originalEndLineNumber, modifiedStartLineNumber, modifiedEndLineNumber, charChanges) {\n        this.originalStartLineNumber = originalStartLineNumber;\n        this.originalEndLineNumber = originalEndLineNumber;\n        this.modifiedStartLineNumber = modifiedStartLineNumber;\n        this.modifiedEndLineNumber = modifiedEndLineNumber;\n        this.charChanges = charChanges;\n    }\n    static createFromDiffResult(shouldIgnoreTrimWhitespace, diffChange, originalLineSequence, modifiedLineSequence, continueCharDiff, shouldComputeCharChanges, shouldPostProcessCharChanges) {\n        let originalStartLineNumber;\n        let originalEndLineNumber;\n        let modifiedStartLineNumber;\n        let modifiedEndLineNumber;\n        let charChanges = undefined;\n        if (diffChange.originalLength === 0) {\n            originalStartLineNumber = originalLineSequence.getStartLineNumber(diffChange.originalStart) - 1;\n            originalEndLineNumber = 0;\n        }\n        else {\n            originalStartLineNumber = originalLineSequence.getStartLineNumber(diffChange.originalStart);\n            originalEndLineNumber = originalLineSequence.getEndLineNumber(diffChange.originalStart + diffChange.originalLength - 1);\n        }\n        if (diffChange.modifiedLength === 0) {\n            modifiedStartLineNumber = modifiedLineSequence.getStartLineNumber(diffChange.modifiedStart) - 1;\n            modifiedEndLineNumber = 0;\n        }\n        else {\n            modifiedStartLineNumber = modifiedLineSequence.getStartLineNumber(diffChange.modifiedStart);\n            modifiedEndLineNumber = modifiedLineSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1);\n        }\n        if (shouldComputeCharChanges && diffChange.originalLength > 0 && diffChange.originalLength < 20 && diffChange.modifiedLength > 0 && diffChange.modifiedLength < 20 && continueCharDiff()) {\n            // Compute character changes for diff chunks of at most 20 lines...\n            const originalCharSequence = originalLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1);\n            const modifiedCharSequence = modifiedLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1);\n            if (originalCharSequence.getElements().length > 0 && modifiedCharSequence.getElements().length > 0) {\n                let rawChanges = computeDiff(originalCharSequence, modifiedCharSequence, continueCharDiff, true).changes;\n                if (shouldPostProcessCharChanges) {\n                    rawChanges = postProcessCharChanges(rawChanges);\n                }\n                charChanges = [];\n                for (let i = 0, length = rawChanges.length; i < length; i++) {\n                    charChanges.push(CharChange.createFromDiffChange(rawChanges[i], originalCharSequence, modifiedCharSequence));\n                }\n            }\n        }\n        return new LineChange(originalStartLineNumber, originalEndLineNumber, modifiedStartLineNumber, modifiedEndLineNumber, charChanges);\n    }\n}\nexport class DiffComputer {\n    constructor(originalLines, modifiedLines, opts) {\n        this.shouldComputeCharChanges = opts.shouldComputeCharChanges;\n        this.shouldPostProcessCharChanges = opts.shouldPostProcessCharChanges;\n        this.shouldIgnoreTrimWhitespace = opts.shouldIgnoreTrimWhitespace;\n        this.shouldMakePrettyDiff = opts.shouldMakePrettyDiff;\n        this.originalLines = originalLines;\n        this.modifiedLines = modifiedLines;\n        this.original = new LineSequence(originalLines);\n        this.modified = new LineSequence(modifiedLines);\n        this.continueLineDiff = createContinueProcessingPredicate(opts.maxComputationTime);\n        this.continueCharDiff = createContinueProcessingPredicate(opts.maxComputationTime === 0 ? 0 : Math.min(opts.maxComputationTime, 5000)); // never run after 5s for character changes...\n    }\n    computeDiff() {\n        if (this.original.lines.length === 1 && this.original.lines[0].length === 0) {\n            // empty original => fast path\n            if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) {\n                return {\n                    quitEarly: false,\n                    changes: []\n                };\n            }\n            return {\n                quitEarly: false,\n                changes: [{\n                        originalStartLineNumber: 1,\n                        originalEndLineNumber: 1,\n                        modifiedStartLineNumber: 1,\n                        modifiedEndLineNumber: this.modified.lines.length,\n                        charChanges: undefined\n                    }]\n            };\n        }\n        if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) {\n            // empty modified => fast path\n            return {\n                quitEarly: false,\n                changes: [{\n                        originalStartLineNumber: 1,\n                        originalEndLineNumber: this.original.lines.length,\n                        modifiedStartLineNumber: 1,\n                        modifiedEndLineNumber: 1,\n                        charChanges: undefined\n                    }]\n            };\n        }\n        const diffResult = computeDiff(this.original, this.modified, this.continueLineDiff, this.shouldMakePrettyDiff);\n        const rawChanges = diffResult.changes;\n        const quitEarly = diffResult.quitEarly;\n        // The diff is always computed with ignoring trim whitespace\n        // This ensures we get the prettiest diff\n        if (this.shouldIgnoreTrimWhitespace) {\n            const lineChanges = [];\n            for (let i = 0, length = rawChanges.length; i < length; i++) {\n                lineChanges.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, rawChanges[i], this.original, this.modified, this.continueCharDiff, this.shouldComputeCharChanges, this.shouldPostProcessCharChanges));\n            }\n            return {\n                quitEarly: quitEarly,\n                changes: lineChanges\n            };\n        }\n        // Need to post-process and introduce changes where the trim whitespace is different\n        // Note that we are looping starting at -1 to also cover the lines before the first change\n        const result = [];\n        let originalLineIndex = 0;\n        let modifiedLineIndex = 0;\n        for (let i = -1 /* !!!! */, len = rawChanges.length; i < len; i++) {\n            const nextChange = (i + 1 < len ? rawChanges[i + 1] : null);\n            const originalStop = (nextChange ? nextChange.originalStart : this.originalLines.length);\n            const modifiedStop = (nextChange ? nextChange.modifiedStart : this.modifiedLines.length);\n            while (originalLineIndex < originalStop && modifiedLineIndex < modifiedStop) {\n                const originalLine = this.originalLines[originalLineIndex];\n                const modifiedLine = this.modifiedLines[modifiedLineIndex];\n                if (originalLine !== modifiedLine) {\n                    // These lines differ only in trim whitespace\n                    // Check the leading whitespace\n                    {\n                        let originalStartColumn = getFirstNonBlankColumn(originalLine, 1);\n                        let modifiedStartColumn = getFirstNonBlankColumn(modifiedLine, 1);\n                        while (originalStartColumn > 1 && modifiedStartColumn > 1) {\n                            const originalChar = originalLine.charCodeAt(originalStartColumn - 2);\n                            const modifiedChar = modifiedLine.charCodeAt(modifiedStartColumn - 2);\n                            if (originalChar !== modifiedChar) {\n                                break;\n                            }\n                            originalStartColumn--;\n                            modifiedStartColumn--;\n                        }\n                        if (originalStartColumn > 1 || modifiedStartColumn > 1) {\n                            this._pushTrimWhitespaceCharChange(result, originalLineIndex + 1, 1, originalStartColumn, modifiedLineIndex + 1, 1, modifiedStartColumn);\n                        }\n                    }\n                    // Check the trailing whitespace\n                    {\n                        let originalEndColumn = getLastNonBlankColumn(originalLine, 1);\n                        let modifiedEndColumn = getLastNonBlankColumn(modifiedLine, 1);\n                        const originalMaxColumn = originalLine.length + 1;\n                        const modifiedMaxColumn = modifiedLine.length + 1;\n                        while (originalEndColumn < originalMaxColumn && modifiedEndColumn < modifiedMaxColumn) {\n                            const originalChar = originalLine.charCodeAt(originalEndColumn - 1);\n                            const modifiedChar = originalLine.charCodeAt(modifiedEndColumn - 1);\n                            if (originalChar !== modifiedChar) {\n                                break;\n                            }\n                            originalEndColumn++;\n                            modifiedEndColumn++;\n                        }\n                        if (originalEndColumn < originalMaxColumn || modifiedEndColumn < modifiedMaxColumn) {\n                            this._pushTrimWhitespaceCharChange(result, originalLineIndex + 1, originalEndColumn, originalMaxColumn, modifiedLineIndex + 1, modifiedEndColumn, modifiedMaxColumn);\n                        }\n                    }\n                }\n                originalLineIndex++;\n                modifiedLineIndex++;\n            }\n            if (nextChange) {\n                // Emit the actual change\n                result.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, nextChange, this.original, this.modified, this.continueCharDiff, this.shouldComputeCharChanges, this.shouldPostProcessCharChanges));\n                originalLineIndex += nextChange.originalLength;\n                modifiedLineIndex += nextChange.modifiedLength;\n            }\n        }\n        return {\n            quitEarly: quitEarly,\n            changes: result\n        };\n    }\n    _pushTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn) {\n        if (this._mergeTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn)) {\n            // Merged into previous\n            return;\n        }\n        let charChanges = undefined;\n        if (this.shouldComputeCharChanges) {\n            charChanges = [new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn)];\n        }\n        result.push(new LineChange(originalLineNumber, originalLineNumber, modifiedLineNumber, modifiedLineNumber, charChanges));\n    }\n    _mergeTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn) {\n        const len = result.length;\n        if (len === 0) {\n            return false;\n        }\n        const prevChange = result[len - 1];\n        if (prevChange.originalEndLineNumber === 0 || prevChange.modifiedEndLineNumber === 0) {\n            // Don't merge with inserts/deletes\n            return false;\n        }\n        if (prevChange.originalEndLineNumber === originalLineNumber && prevChange.modifiedEndLineNumber === modifiedLineNumber) {\n            if (this.shouldComputeCharChanges && prevChange.charChanges) {\n                prevChange.charChanges.push(new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn));\n            }\n            return true;\n        }\n        if (prevChange.originalEndLineNumber + 1 === originalLineNumber && prevChange.modifiedEndLineNumber + 1 === modifiedLineNumber) {\n            prevChange.originalEndLineNumber = originalLineNumber;\n            prevChange.modifiedEndLineNumber = modifiedLineNumber;\n            if (this.shouldComputeCharChanges && prevChange.charChanges) {\n                prevChange.charChanges.push(new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn));\n            }\n            return true;\n        }\n        return false;\n    }\n}\nfunction getFirstNonBlankColumn(txt, defaultValue) {\n    const r = strings.firstNonWhitespaceIndex(txt);\n    if (r === -1) {\n        return defaultValue;\n    }\n    return r + 1;\n}\nfunction getLastNonBlankColumn(txt, defaultValue) {\n    const r = strings.lastNonWhitespaceIndex(txt);\n    if (r === -1) {\n        return defaultValue;\n    }\n    return r + 2;\n}\nfunction createContinueProcessingPredicate(maximumRuntime) {\n    if (maximumRuntime === 0) {\n        return () => true;\n    }\n    const startTime = Date.now();\n    return () => {\n        return Date.now() - startTime < maximumRuntime;\n    };\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { BugIndicatingError } from '../../../base/common/errors.js';\n/**\n * A range of offsets (0-based).\n*/\nexport class OffsetRange {\n    static addRange(range, sortedRanges) {\n        let i = 0;\n        while (i < sortedRanges.length && sortedRanges[i].endExclusive < range.start) {\n            i++;\n        }\n        let j = i;\n        while (j < sortedRanges.length && sortedRanges[j].start <= range.endExclusive) {\n            j++;\n        }\n        if (i === j) {\n            sortedRanges.splice(i, 0, range);\n        }\n        else {\n            const start = Math.min(range.start, sortedRanges[i].start);\n            const end = Math.max(range.endExclusive, sortedRanges[j - 1].endExclusive);\n            sortedRanges.splice(i, j - i, new OffsetRange(start, end));\n        }\n    }\n    static tryCreate(start, endExclusive) {\n        if (start > endExclusive) {\n            return undefined;\n        }\n        return new OffsetRange(start, endExclusive);\n    }\n    constructor(start, endExclusive) {\n        this.start = start;\n        this.endExclusive = endExclusive;\n        if (start > endExclusive) {\n            throw new BugIndicatingError(`Invalid range: ${this.toString()}`);\n        }\n    }\n    get isEmpty() {\n        return this.start === this.endExclusive;\n    }\n    delta(offset) {\n        return new OffsetRange(this.start + offset, this.endExclusive + offset);\n    }\n    get length() {\n        return this.endExclusive - this.start;\n    }\n    toString() {\n        return `[${this.start}, ${this.endExclusive})`;\n    }\n    equals(other) {\n        return this.start === other.start && this.endExclusive === other.endExclusive;\n    }\n    containsRange(other) {\n        return this.start <= other.start && other.endExclusive <= this.endExclusive;\n    }\n    /**\n     * for all numbers n: range1.contains(n) or range2.contains(n) => range1.join(range2).contains(n)\n     * The joined range is the smallest range that contains both ranges.\n     */\n    join(other) {\n        return new OffsetRange(Math.min(this.start, other.start), Math.max(this.endExclusive, other.endExclusive));\n    }\n    /**\n     * for all numbers n: range1.contains(n) and range2.contains(n) <=> range1.intersect(range2).contains(n)\n     *\n     * The resulting range is empty if the ranges do not intersect, but touch.\n     * If the ranges don't even touch, the result is undefined.\n     */\n    intersect(other) {\n        const start = Math.max(this.start, other.start);\n        const end = Math.min(this.endExclusive, other.endExclusive);\n        if (start <= end) {\n            return new OffsetRange(start, end);\n        }\n        return undefined;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { BugIndicatingError } from '../../../../base/common/errors.js';\nimport { OffsetRange } from '../../core/offsetRange.js';\nexport class DiffAlgorithmResult {\n    static trivial(seq1, seq2) {\n        return new DiffAlgorithmResult([new SequenceDiff(new OffsetRange(0, seq1.length), new OffsetRange(0, seq2.length))], false);\n    }\n    static trivialTimedOut(seq1, seq2) {\n        return new DiffAlgorithmResult([new SequenceDiff(new OffsetRange(0, seq1.length), new OffsetRange(0, seq2.length))], true);\n    }\n    constructor(diffs, \n    /**\n     * Indicates if the time out was reached.\n     * In that case, the diffs might be an approximation and the user should be asked to rerun the diff with more time.\n     */\n    hitTimeout) {\n        this.diffs = diffs;\n        this.hitTimeout = hitTimeout;\n    }\n}\nexport class SequenceDiff {\n    constructor(seq1Range, seq2Range) {\n        this.seq1Range = seq1Range;\n        this.seq2Range = seq2Range;\n    }\n    reverse() {\n        return new SequenceDiff(this.seq2Range, this.seq1Range);\n    }\n    toString() {\n        return `${this.seq1Range} <-> ${this.seq2Range}`;\n    }\n    join(other) {\n        return new SequenceDiff(this.seq1Range.join(other.seq1Range), this.seq2Range.join(other.seq2Range));\n    }\n    delta(offset) {\n        if (offset === 0) {\n            return this;\n        }\n        return new SequenceDiff(this.seq1Range.delta(offset), this.seq2Range.delta(offset));\n    }\n}\nexport class InfiniteTimeout {\n    isValid() {\n        return true;\n    }\n}\nInfiniteTimeout.instance = new InfiniteTimeout();\nexport class DateTimeout {\n    constructor(timeout) {\n        this.timeout = timeout;\n        this.startTime = Date.now();\n        this.valid = true;\n        if (timeout <= 0) {\n            throw new BugIndicatingError('timeout must be positive');\n        }\n    }\n    // Recommendation: Set a log-point `{this.disable()}` in the body\n    isValid() {\n        const valid = Date.now() - this.startTime < this.timeout;\n        if (!valid && this.valid) {\n            this.valid = false; // timeout reached\n            // eslint-disable-next-line no-debugger\n            debugger; // WARNING: Most likely debugging caused the timeout. Call `this.disable()` to continue without timing out.\n        }\n        return this.valid;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport class Array2D {\n    constructor(width, height) {\n        this.width = width;\n        this.height = height;\n        this.array = [];\n        this.array = new Array(width * height);\n    }\n    get(x, y) {\n        return this.array[x + y * this.width];\n    }\n    set(x, y, value) {\n        this.array[x + y * this.width] = value;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { OffsetRange } from '../../core/offsetRange.js';\nimport { SequenceDiff, InfiniteTimeout, DiffAlgorithmResult } from './diffAlgorithm.js';\nimport { Array2D } from './utils.js';\n/**\n * A O(MN) diffing algorithm that supports a score function.\n * The algorithm can be improved by processing the 2d array diagonally.\n*/\nexport class DynamicProgrammingDiffing {\n    compute(sequence1, sequence2, timeout = InfiniteTimeout.instance, equalityScore) {\n        if (sequence1.length === 0 || sequence2.length === 0) {\n            return DiffAlgorithmResult.trivial(sequence1, sequence2);\n        }\n        /**\n         * lcsLengths.get(i, j): Length of the longest common subsequence of sequence1.substring(0, i + 1) and sequence2.substring(0, j + 1).\n         */\n        const lcsLengths = new Array2D(sequence1.length, sequence2.length);\n        const directions = new Array2D(sequence1.length, sequence2.length);\n        const lengths = new Array2D(sequence1.length, sequence2.length);\n        // ==== Initializing lcsLengths ====\n        for (let s1 = 0; s1 < sequence1.length; s1++) {\n            for (let s2 = 0; s2 < sequence2.length; s2++) {\n                if (!timeout.isValid()) {\n                    return DiffAlgorithmResult.trivialTimedOut(sequence1, sequence2);\n                }\n                const horizontalLen = s1 === 0 ? 0 : lcsLengths.get(s1 - 1, s2);\n                const verticalLen = s2 === 0 ? 0 : lcsLengths.get(s1, s2 - 1);\n                let extendedSeqScore;\n                if (sequence1.getElement(s1) === sequence2.getElement(s2)) {\n                    if (s1 === 0 || s2 === 0) {\n                        extendedSeqScore = 0;\n                    }\n                    else {\n                        extendedSeqScore = lcsLengths.get(s1 - 1, s2 - 1);\n                    }\n                    if (s1 > 0 && s2 > 0 && directions.get(s1 - 1, s2 - 1) === 3) {\n                        // Prefer consecutive diagonals\n                        extendedSeqScore += lengths.get(s1 - 1, s2 - 1);\n                    }\n                    extendedSeqScore += (equalityScore ? equalityScore(s1, s2) : 1);\n                }\n                else {\n                    extendedSeqScore = -1;\n                }\n                const newValue = Math.max(horizontalLen, verticalLen, extendedSeqScore);\n                if (newValue === extendedSeqScore) {\n                    // Prefer diagonals\n                    const prevLen = s1 > 0 && s2 > 0 ? lengths.get(s1 - 1, s2 - 1) : 0;\n                    lengths.set(s1, s2, prevLen + 1);\n                    directions.set(s1, s2, 3);\n                }\n                else if (newValue === horizontalLen) {\n                    lengths.set(s1, s2, 0);\n                    directions.set(s1, s2, 1);\n                }\n                else if (newValue === verticalLen) {\n                    lengths.set(s1, s2, 0);\n                    directions.set(s1, s2, 2);\n                }\n                lcsLengths.set(s1, s2, newValue);\n            }\n        }\n        // ==== Backtracking ====\n        const result = [];\n        let lastAligningPosS1 = sequence1.length;\n        let lastAligningPosS2 = sequence2.length;\n        function reportDecreasingAligningPositions(s1, s2) {\n            if (s1 + 1 !== lastAligningPosS1 || s2 + 1 !== lastAligningPosS2) {\n                result.push(new SequenceDiff(new OffsetRange(s1 + 1, lastAligningPosS1), new OffsetRange(s2 + 1, lastAligningPosS2)));\n            }\n            lastAligningPosS1 = s1;\n            lastAligningPosS2 = s2;\n        }\n        let s1 = sequence1.length - 1;\n        let s2 = sequence2.length - 1;\n        while (s1 >= 0 && s2 >= 0) {\n            if (directions.get(s1, s2) === 3) {\n                reportDecreasingAligningPositions(s1, s2);\n                s1--;\n                s2--;\n            }\n            else {\n                if (directions.get(s1, s2) === 1) {\n                    s1--;\n                }\n                else {\n                    s2--;\n                }\n            }\n        }\n        reportDecreasingAligningPositions(-1, -1);\n        result.reverse();\n        return new DiffAlgorithmResult(result, false);\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { OffsetRange } from '../../core/offsetRange.js';\nimport { SequenceDiff } from './diffAlgorithm.js';\nexport function optimizeSequenceDiffs(sequence1, sequence2, sequenceDiffs) {\n    let result = sequenceDiffs;\n    result = joinSequenceDiffs(sequence1, sequence2, result);\n    result = shiftSequenceDiffs(sequence1, sequence2, result);\n    return result;\n}\nexport function smoothenSequenceDiffs(sequence1, sequence2, sequenceDiffs) {\n    const result = [];\n    for (const s of sequenceDiffs) {\n        const last = result[result.length - 1];\n        if (!last) {\n            result.push(s);\n            continue;\n        }\n        if (s.seq1Range.start - last.seq1Range.endExclusive <= 2 || s.seq2Range.start - last.seq2Range.endExclusive <= 2) {\n            result[result.length - 1] = new SequenceDiff(last.seq1Range.join(s.seq1Range), last.seq2Range.join(s.seq2Range));\n        }\n        else {\n            result.push(s);\n        }\n    }\n    return result;\n}\n/**\n * This function fixes issues like this:\n * ```\n * import { Baz, Bar } from \"foo\";\n * ```\n * <->\n * ```\n * import { Baz, Bar, Foo } from \"foo\";\n * ```\n * Computed diff: [ {Add \",\" after Bar}, {Add \"Foo \" after space} }\n * Improved diff: [{Add \", Foo\" after Bar}]\n */\nexport function joinSequenceDiffs(sequence1, sequence2, sequenceDiffs) {\n    const result = [];\n    if (sequenceDiffs.length > 0) {\n        result.push(sequenceDiffs[0]);\n    }\n    // First move them all to the left as much as possible and join them if possible\n    for (let i = 1; i < sequenceDiffs.length; i++) {\n        const prevResult = sequenceDiffs[i - 1];\n        let cur = sequenceDiffs[i];\n        if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {\n            const length = cur.seq1Range.start - prevResult.seq1Range.endExclusive;\n            let d;\n            for (d = 1; d <= length; d++) {\n                if (sequence1.getElement(cur.seq1Range.start - d) !== sequence1.getElement(cur.seq1Range.endExclusive - d) ||\n                    sequence2.getElement(cur.seq2Range.start - d) !== sequence2.getElement(cur.seq2Range.endExclusive - d)) {\n                    break;\n                }\n            }\n            d--;\n            if (d === length) {\n                // Merge previous and current diff\n                result[result.length - 1] = new SequenceDiff(new OffsetRange(prevResult.seq1Range.start, cur.seq1Range.endExclusive - length), new OffsetRange(prevResult.seq2Range.start, cur.seq2Range.endExclusive - length));\n                continue;\n            }\n            cur = cur.delta(-d);\n        }\n        result.push(cur);\n    }\n    const result2 = [];\n    // Then move them all to the right and join them again if possible\n    for (let i = 0; i < result.length - 1; i++) {\n        const nextResult = result[i + 1];\n        let cur = result[i];\n        if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {\n            const length = nextResult.seq1Range.start - cur.seq1Range.endExclusive;\n            let d;\n            for (d = 0; d < length; d++) {\n                if (sequence1.getElement(cur.seq1Range.start + d) !== sequence1.getElement(cur.seq1Range.endExclusive + d) ||\n                    sequence2.getElement(cur.seq2Range.start + d) !== sequence2.getElement(cur.seq2Range.endExclusive + d)) {\n                    break;\n                }\n            }\n            if (d === length) {\n                // Merge previous and current diff, write to result!\n                result[i + 1] = new SequenceDiff(new OffsetRange(cur.seq1Range.start + length, nextResult.seq1Range.endExclusive), new OffsetRange(cur.seq2Range.start + length, nextResult.seq2Range.endExclusive));\n                continue;\n            }\n            if (d > 0) {\n                cur = cur.delta(d);\n            }\n        }\n        result2.push(cur);\n    }\n    if (result.length > 0) {\n        result2.push(result[result.length - 1]);\n    }\n    return result2;\n}\n// align character level diffs at whitespace characters\n// import { IBar } from \"foo\";\n// import { I[Arr, I]Bar } from \"foo\";\n// ->\n// import { [IArr, ]IBar } from \"foo\";\n// import { ITransaction, observableValue, transaction } from 'vs/base/common/observable';\n// import { ITransaction, observable[FromEvent, observable]Value, transaction } from 'vs/base/common/observable';\n// ->\n// import { ITransaction, [observableFromEvent, ]observableValue, transaction } from 'vs/base/common/observable';\n// collectBrackets(level + 1, levelPerBracketType);\n// collectBrackets(level + 1, levelPerBracket[ + 1, levelPerBracket]Type);\n// ->\n// collectBrackets(level + 1, [levelPerBracket + 1, ]levelPerBracketType);\nexport function shiftSequenceDiffs(sequence1, sequence2, sequenceDiffs) {\n    if (!sequence1.getBoundaryScore || !sequence2.getBoundaryScore) {\n        return sequenceDiffs;\n    }\n    for (let i = 0; i < sequenceDiffs.length; i++) {\n        const prevDiff = (i > 0 ? sequenceDiffs[i - 1] : undefined);\n        const diff = sequenceDiffs[i];\n        const nextDiff = (i + 1 < sequenceDiffs.length ? sequenceDiffs[i + 1] : undefined);\n        const seq1ValidRange = new OffsetRange(prevDiff ? prevDiff.seq1Range.start + 1 : 0, nextDiff ? nextDiff.seq1Range.endExclusive - 1 : sequence1.length);\n        const seq2ValidRange = new OffsetRange(prevDiff ? prevDiff.seq2Range.start + 1 : 0, nextDiff ? nextDiff.seq2Range.endExclusive - 1 : sequence2.length);\n        if (diff.seq1Range.isEmpty) {\n            sequenceDiffs[i] = shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange);\n        }\n        else if (diff.seq2Range.isEmpty) {\n            sequenceDiffs[i] = shiftDiffToBetterPosition(diff.reverse(), sequence2, sequence1, seq2ValidRange, seq1ValidRange).reverse();\n        }\n    }\n    return sequenceDiffs;\n}\nfunction shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange) {\n    const maxShiftLimit = 100; // To prevent performance issues\n    // don't touch previous or next!\n    let deltaBefore = 1;\n    while (diff.seq1Range.start - deltaBefore >= seq1ValidRange.start &&\n        diff.seq2Range.start - deltaBefore >= seq2ValidRange.start &&\n        sequence2.getElement(diff.seq2Range.start - deltaBefore) ===\n            sequence2.getElement(diff.seq2Range.endExclusive - deltaBefore) && deltaBefore < maxShiftLimit) {\n        deltaBefore++;\n    }\n    deltaBefore--;\n    let deltaAfter = 0;\n    while (diff.seq1Range.start + deltaAfter < seq1ValidRange.endExclusive &&\n        diff.seq2Range.endExclusive + deltaAfter < seq2ValidRange.endExclusive &&\n        sequence2.getElement(diff.seq2Range.start + deltaAfter) ===\n            sequence2.getElement(diff.seq2Range.endExclusive + deltaAfter) && deltaAfter < maxShiftLimit) {\n        deltaAfter++;\n    }\n    if (deltaBefore === 0 && deltaAfter === 0) {\n        return diff;\n    }\n    // Visualize `[sequence1.text, diff.seq1Range.start + deltaAfter]`\n    // and `[sequence2.text, diff.seq2Range.start + deltaAfter, diff.seq2Range.endExclusive + deltaAfter]`\n    let bestDelta = 0;\n    let bestScore = -1;\n    // find best scored delta\n    for (let delta = -deltaBefore; delta <= deltaAfter; delta++) {\n        const seq2OffsetStart = diff.seq2Range.start + delta;\n        const seq2OffsetEndExclusive = diff.seq2Range.endExclusive + delta;\n        const seq1Offset = diff.seq1Range.start + delta;\n        const score = sequence1.getBoundaryScore(seq1Offset) + sequence2.getBoundaryScore(seq2OffsetStart) + sequence2.getBoundaryScore(seq2OffsetEndExclusive);\n        if (score > bestScore) {\n            bestScore = score;\n            bestDelta = delta;\n        }\n    }\n    return diff.delta(bestDelta);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { OffsetRange } from '../../core/offsetRange.js';\nimport { DiffAlgorithmResult, InfiniteTimeout, SequenceDiff } from './diffAlgorithm.js';\n/**\n * An O(ND) diff algorithm that has a quadratic space worst-case complexity.\n*/\nexport class MyersDiffAlgorithm {\n    compute(seq1, seq2, timeout = InfiniteTimeout.instance) {\n        // These are common special cases.\n        // The early return improves performance dramatically.\n        if (seq1.length === 0 || seq2.length === 0) {\n            return DiffAlgorithmResult.trivial(seq1, seq2);\n        }\n        function getXAfterSnake(x, y) {\n            while (x < seq1.length && y < seq2.length && seq1.getElement(x) === seq2.getElement(y)) {\n                x++;\n                y++;\n            }\n            return x;\n        }\n        let d = 0;\n        // V[k]: X value of longest d-line that ends in diagonal k.\n        // d-line: path from (0,0) to (x,y) that uses exactly d non-diagonals.\n        // diagonal k: Set of points (x,y) with x-y = k.\n        const V = new FastInt32Array();\n        V.set(0, getXAfterSnake(0, 0));\n        const paths = new FastArrayNegativeIndices();\n        paths.set(0, V.get(0) === 0 ? null : new SnakePath(null, 0, 0, V.get(0)));\n        let k = 0;\n        loop: while (true) {\n            d++;\n            if (!timeout.isValid()) {\n                return DiffAlgorithmResult.trivialTimedOut(seq1, seq2);\n            }\n            // The paper has `for (k = -d; k <= d; k += 2)`, but we can ignore diagonals that cannot influence the result.\n            const lowerBound = -Math.min(d, seq2.length + (d % 2));\n            const upperBound = Math.min(d, seq1.length + (d % 2));\n            for (k = lowerBound; k <= upperBound; k += 2) {\n                // We can use the X values of (d-1)-lines to compute X value of the longest d-lines.\n                const maxXofDLineTop = k === upperBound ? -1 : V.get(k + 1); // We take a vertical non-diagonal (add a symbol in seq1)\n                const maxXofDLineLeft = k === lowerBound ? -1 : V.get(k - 1) + 1; // We take a horizontal non-diagonal (+1 x) (delete a symbol in seq1)\n                const x = Math.min(Math.max(maxXofDLineTop, maxXofDLineLeft), seq1.length);\n                const y = x - k;\n                if (x > seq1.length || y > seq2.length) {\n                    // This diagonal is irrelevant for the result.\n                    // TODO: Don't pay the cost for this in the next iteration.\n                    continue;\n                }\n                const newMaxX = getXAfterSnake(x, y);\n                V.set(k, newMaxX);\n                const lastPath = x === maxXofDLineTop ? paths.get(k + 1) : paths.get(k - 1);\n                paths.set(k, newMaxX !== x ? new SnakePath(lastPath, x, y, newMaxX - x) : lastPath);\n                if (V.get(k) === seq1.length && V.get(k) - k === seq2.length) {\n                    break loop;\n                }\n            }\n        }\n        let path = paths.get(k);\n        const result = [];\n        let lastAligningPosS1 = seq1.length;\n        let lastAligningPosS2 = seq2.length;\n        while (true) {\n            const endX = path ? path.x + path.length : 0;\n            const endY = path ? path.y + path.length : 0;\n            if (endX !== lastAligningPosS1 || endY !== lastAligningPosS2) {\n                result.push(new SequenceDiff(new OffsetRange(endX, lastAligningPosS1), new OffsetRange(endY, lastAligningPosS2)));\n            }\n            if (!path) {\n                break;\n            }\n            lastAligningPosS1 = path.x;\n            lastAligningPosS2 = path.y;\n            path = path.prev;\n        }\n        result.reverse();\n        return new DiffAlgorithmResult(result, false);\n    }\n}\nclass SnakePath {\n    constructor(prev, x, y, length) {\n        this.prev = prev;\n        this.x = x;\n        this.y = y;\n        this.length = length;\n    }\n}\n/**\n * An array that supports fast negative indices.\n*/\nclass FastInt32Array {\n    constructor() {\n        this.positiveArr = new Int32Array(10);\n        this.negativeArr = new Int32Array(10);\n    }\n    get(idx) {\n        if (idx < 0) {\n            idx = -idx - 1;\n            return this.negativeArr[idx];\n        }\n        else {\n            return this.positiveArr[idx];\n        }\n    }\n    set(idx, value) {\n        if (idx < 0) {\n            idx = -idx - 1;\n            if (idx >= this.negativeArr.length) {\n                const arr = this.negativeArr;\n                this.negativeArr = new Int32Array(arr.length * 2);\n                this.negativeArr.set(arr);\n            }\n            this.negativeArr[idx] = value;\n        }\n        else {\n            if (idx >= this.positiveArr.length) {\n                const arr = this.positiveArr;\n                this.positiveArr = new Int32Array(arr.length * 2);\n                this.positiveArr.set(arr);\n            }\n            this.positiveArr[idx] = value;\n        }\n    }\n}\n/**\n * An array that supports fast negative indices.\n*/\nclass FastArrayNegativeIndices {\n    constructor() {\n        this.positiveArr = [];\n        this.negativeArr = [];\n    }\n    get(idx) {\n        if (idx < 0) {\n            idx = -idx - 1;\n            return this.negativeArr[idx];\n        }\n        else {\n            return this.positiveArr[idx];\n        }\n    }\n    set(idx, value) {\n        if (idx < 0) {\n            idx = -idx - 1;\n            this.negativeArr[idx] = value;\n        }\n        else {\n            this.positiveArr[idx] = value;\n        }\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { assertFn, checkAdjacentItems } from '../../../base/common/assert.js';\nimport { LineRange } from '../core/lineRange.js';\nimport { OffsetRange } from '../core/offsetRange.js';\nimport { Position } from '../core/position.js';\nimport { Range } from '../core/range.js';\nimport { DateTimeout, InfiniteTimeout, SequenceDiff } from './algorithms/diffAlgorithm.js';\nimport { DynamicProgrammingDiffing } from './algorithms/dynamicProgrammingDiffing.js';\nimport { optimizeSequenceDiffs, smoothenSequenceDiffs } from './algorithms/joinSequenceDiffs.js';\nimport { MyersDiffAlgorithm } from './algorithms/myersDiffAlgorithm.js';\nimport { LineRangeMapping, LinesDiff, MovedText, RangeMapping, SimpleLineRangeMapping } from './linesDiffComputer.js';\nexport class StandardLinesDiffComputer {\n    constructor() {\n        this.dynamicProgrammingDiffing = new DynamicProgrammingDiffing();\n        this.myersDiffingAlgorithm = new MyersDiffAlgorithm();\n    }\n    computeDiff(originalLines, modifiedLines, options) {\n        const timeout = options.maxComputationTimeMs === 0 ? InfiniteTimeout.instance : new DateTimeout(options.maxComputationTimeMs);\n        const considerWhitespaceChanges = !options.ignoreTrimWhitespace;\n        const perfectHashes = new Map();\n        function getOrCreateHash(text) {\n            let hash = perfectHashes.get(text);\n            if (hash === undefined) {\n                hash = perfectHashes.size;\n                perfectHashes.set(text, hash);\n            }\n            return hash;\n        }\n        const srcDocLines = originalLines.map((l) => getOrCreateHash(l.trim()));\n        const tgtDocLines = modifiedLines.map((l) => getOrCreateHash(l.trim()));\n        const sequence1 = new LineSequence(srcDocLines, originalLines);\n        const sequence2 = new LineSequence(tgtDocLines, modifiedLines);\n        const lineAlignmentResult = (() => {\n            if (sequence1.length + sequence2.length < 1500) {\n                // Use the improved algorithm for small files\n                return this.dynamicProgrammingDiffing.compute(sequence1, sequence2, timeout, (offset1, offset2) => originalLines[offset1] === modifiedLines[offset2]\n                    ? modifiedLines[offset2].length === 0\n                        ? 0.1\n                        : 1 + Math.log(1 + modifiedLines[offset2].length)\n                    : 0.99);\n            }\n            return this.myersDiffingAlgorithm.compute(sequence1, sequence2);\n        })();\n        let lineAlignments = lineAlignmentResult.diffs;\n        let hitTimeout = lineAlignmentResult.hitTimeout;\n        lineAlignments = optimizeSequenceDiffs(sequence1, sequence2, lineAlignments);\n        const alignments = [];\n        const scanForWhitespaceChanges = (equalLinesCount) => {\n            if (!considerWhitespaceChanges) {\n                return;\n            }\n            for (let i = 0; i < equalLinesCount; i++) {\n                const seq1Offset = seq1LastStart + i;\n                const seq2Offset = seq2LastStart + i;\n                if (originalLines[seq1Offset] !== modifiedLines[seq2Offset]) {\n                    // This is because of whitespace changes, diff these lines\n                    const characterDiffs = this.refineDiff(originalLines, modifiedLines, new SequenceDiff(new OffsetRange(seq1Offset, seq1Offset + 1), new OffsetRange(seq2Offset, seq2Offset + 1)), timeout, considerWhitespaceChanges);\n                    for (const a of characterDiffs.mappings) {\n                        alignments.push(a);\n                    }\n                    if (characterDiffs.hitTimeout) {\n                        hitTimeout = true;\n                    }\n                }\n            }\n        };\n        let seq1LastStart = 0;\n        let seq2LastStart = 0;\n        for (const diff of lineAlignments) {\n            assertFn(() => diff.seq1Range.start - seq1LastStart === diff.seq2Range.start - seq2LastStart);\n            const equalLinesCount = diff.seq1Range.start - seq1LastStart;\n            scanForWhitespaceChanges(equalLinesCount);\n            seq1LastStart = diff.seq1Range.endExclusive;\n            seq2LastStart = diff.seq2Range.endExclusive;\n            const characterDiffs = this.refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges);\n            if (characterDiffs.hitTimeout) {\n                hitTimeout = true;\n            }\n            for (const a of characterDiffs.mappings) {\n                alignments.push(a);\n            }\n        }\n        scanForWhitespaceChanges(originalLines.length - seq1LastStart);\n        const changes = lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines);\n        const moves = [];\n        if (options.computeMoves) {\n            const deletions = changes\n                .filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3)\n                .map(d => new LineRangeFragment(d.originalRange, originalLines));\n            const insertions = new Set(changes\n                .filter(c => c.originalRange.isEmpty && c.modifiedRange.length >= 3)\n                .map(d => new LineRangeFragment(d.modifiedRange, modifiedLines)));\n            for (const deletion of deletions) {\n                let highestSimilarity = -1;\n                let best;\n                for (const insertion of insertions) {\n                    const similarity = deletion.computeSimilarity(insertion);\n                    if (similarity > highestSimilarity) {\n                        highestSimilarity = similarity;\n                        best = insertion;\n                    }\n                }\n                if (highestSimilarity > 0.90 && best) {\n                    const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff(new OffsetRange(deletion.range.startLineNumber - 1, deletion.range.endLineNumberExclusive - 1), new OffsetRange(best.range.startLineNumber - 1, best.range.endLineNumberExclusive - 1)), timeout, considerWhitespaceChanges);\n                    const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true);\n                    insertions.delete(best);\n                    moves.push(new MovedText(new SimpleLineRangeMapping(deletion.range, best.range), mappings));\n                }\n            }\n        }\n        return new LinesDiff(changes, moves, hitTimeout);\n    }\n    refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges) {\n        const slice1 = new Slice(originalLines, diff.seq1Range, considerWhitespaceChanges);\n        const slice2 = new Slice(modifiedLines, diff.seq2Range, considerWhitespaceChanges);\n        const diffResult = slice1.length + slice2.length < 500\n            ? this.dynamicProgrammingDiffing.compute(slice1, slice2, timeout)\n            : this.myersDiffingAlgorithm.compute(slice1, slice2, timeout);\n        let diffs = diffResult.diffs;\n        diffs = optimizeSequenceDiffs(slice1, slice2, diffs);\n        diffs = coverFullWords(slice1, slice2, diffs);\n        diffs = smoothenSequenceDiffs(slice1, slice2, diffs);\n        const result = diffs.map((d) => new RangeMapping(slice1.translateRange(d.seq1Range), slice2.translateRange(d.seq2Range)));\n        // Assert: result applied on original should be the same as diff applied to original\n        return {\n            mappings: result,\n            hitTimeout: diffResult.hitTimeout,\n        };\n    }\n}\nfunction coverFullWords(sequence1, sequence2, sequenceDiffs) {\n    const additional = [];\n    let lastModifiedWord = undefined;\n    function maybePushWordToAdditional() {\n        if (!lastModifiedWord) {\n            return;\n        }\n        const originalLength1 = lastModifiedWord.s1Range.length - lastModifiedWord.deleted;\n        const originalLength2 = lastModifiedWord.s2Range.length - lastModifiedWord.added;\n        if (originalLength1 !== originalLength2) {\n            // TODO figure out why this happens\n        }\n        if (Math.max(lastModifiedWord.deleted, lastModifiedWord.added) + (lastModifiedWord.count - 1) > originalLength1) {\n            additional.push(new SequenceDiff(lastModifiedWord.s1Range, lastModifiedWord.s2Range));\n        }\n        lastModifiedWord = undefined;\n    }\n    for (const s of sequenceDiffs) {\n        function processWord(s1Range, s2Range) {\n            var _a, _b, _c, _d;\n            if (!lastModifiedWord || !lastModifiedWord.s1Range.containsRange(s1Range) || !lastModifiedWord.s2Range.containsRange(s2Range)) {\n                if (lastModifiedWord && !(lastModifiedWord.s1Range.endExclusive < s1Range.start && lastModifiedWord.s2Range.endExclusive < s2Range.start)) {\n                    const s1Added = OffsetRange.tryCreate(lastModifiedWord.s1Range.endExclusive, s1Range.start);\n                    const s2Added = OffsetRange.tryCreate(lastModifiedWord.s2Range.endExclusive, s2Range.start);\n                    lastModifiedWord.deleted += (_a = s1Added === null || s1Added === void 0 ? void 0 : s1Added.length) !== null && _a !== void 0 ? _a : 0;\n                    lastModifiedWord.added += (_b = s2Added === null || s2Added === void 0 ? void 0 : s2Added.length) !== null && _b !== void 0 ? _b : 0;\n                    lastModifiedWord.s1Range = lastModifiedWord.s1Range.join(s1Range);\n                    lastModifiedWord.s2Range = lastModifiedWord.s2Range.join(s2Range);\n                }\n                else {\n                    maybePushWordToAdditional();\n                    lastModifiedWord = { added: 0, deleted: 0, count: 0, s1Range: s1Range, s2Range: s2Range };\n                }\n            }\n            const changedS1 = s1Range.intersect(s.seq1Range);\n            const changedS2 = s2Range.intersect(s.seq2Range);\n            lastModifiedWord.count++;\n            lastModifiedWord.deleted += (_c = changedS1 === null || changedS1 === void 0 ? void 0 : changedS1.length) !== null && _c !== void 0 ? _c : 0;\n            lastModifiedWord.added += (_d = changedS2 === null || changedS2 === void 0 ? void 0 : changedS2.length) !== null && _d !== void 0 ? _d : 0;\n        }\n        const w1Before = sequence1.findWordContaining(s.seq1Range.start - 1);\n        const w2Before = sequence2.findWordContaining(s.seq2Range.start - 1);\n        const w1After = sequence1.findWordContaining(s.seq1Range.endExclusive);\n        const w2After = sequence2.findWordContaining(s.seq2Range.endExclusive);\n        if (w1Before && w1After && w2Before && w2After && w1Before.equals(w1After) && w2Before.equals(w2After)) {\n            processWord(w1Before, w2Before);\n        }\n        else {\n            if (w1Before && w2Before) {\n                processWord(w1Before, w2Before);\n            }\n            if (w1After && w2After) {\n                processWord(w1After, w2After);\n            }\n        }\n    }\n    maybePushWordToAdditional();\n    const merged = mergeSequenceDiffs(sequenceDiffs, additional);\n    return merged;\n}\nfunction mergeSequenceDiffs(sequenceDiffs1, sequenceDiffs2) {\n    const result = [];\n    while (sequenceDiffs1.length > 0 || sequenceDiffs2.length > 0) {\n        const sd1 = sequenceDiffs1[0];\n        const sd2 = sequenceDiffs2[0];\n        let next;\n        if (sd1 && (!sd2 || sd1.seq1Range.start < sd2.seq1Range.start)) {\n            next = sequenceDiffs1.shift();\n        }\n        else {\n            next = sequenceDiffs2.shift();\n        }\n        if (result.length > 0 && result[result.length - 1].seq1Range.endExclusive >= next.seq1Range.start) {\n            result[result.length - 1] = result[result.length - 1].join(next);\n        }\n        else {\n            result.push(next);\n        }\n    }\n    return result;\n}\nexport function lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines, dontAssertStartLine = false) {\n    const changes = [];\n    for (const g of group(alignments.map(a => getLineRangeMapping(a, originalLines, modifiedLines)), (a1, a2) => a1.originalRange.overlapOrTouch(a2.originalRange)\n        || a1.modifiedRange.overlapOrTouch(a2.modifiedRange))) {\n        const first = g[0];\n        const last = g[g.length - 1];\n        changes.push(new LineRangeMapping(first.originalRange.join(last.originalRange), first.modifiedRange.join(last.modifiedRange), g.map(a => a.innerChanges[0])));\n    }\n    assertFn(() => {\n        if (!dontAssertStartLine) {\n            if (changes.length > 0 && changes[0].originalRange.startLineNumber !== changes[0].modifiedRange.startLineNumber) {\n                return false;\n            }\n        }\n        return checkAdjacentItems(changes, (m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&\n            // There has to be an unchanged line in between (otherwise both diffs should have been joined)\n            m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&\n            m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber);\n    });\n    return changes;\n}\nexport function getLineRangeMapping(rangeMapping, originalLines, modifiedLines) {\n    let lineStartDelta = 0;\n    let lineEndDelta = 0;\n    // rangeMapping describes the edit that replaces `rangeMapping.originalRange` with `newText := getText(modifiedLines, rangeMapping.modifiedRange)`.\n    // original: ]xxx \\n <- this line is not modified\n    // modified: ]xx  \\n\n    if (rangeMapping.modifiedRange.endColumn === 1 && rangeMapping.originalRange.endColumn === 1\n        && rangeMapping.originalRange.startLineNumber + lineStartDelta <= rangeMapping.originalRange.endLineNumber\n        && rangeMapping.modifiedRange.startLineNumber + lineStartDelta <= rangeMapping.modifiedRange.endLineNumber) {\n        // We can only do this if the range is not empty yet\n        lineEndDelta = -1;\n    }\n    // original: xxx[ \\n <- this line is not modified\n    // modified: xxx[ \\n\n    if (rangeMapping.modifiedRange.startColumn - 1 >= modifiedLines[rangeMapping.modifiedRange.startLineNumber - 1].length\n        && rangeMapping.originalRange.startColumn - 1 >= originalLines[rangeMapping.originalRange.startLineNumber - 1].length\n        && rangeMapping.originalRange.startLineNumber <= rangeMapping.originalRange.endLineNumber + lineEndDelta\n        && rangeMapping.modifiedRange.startLineNumber <= rangeMapping.modifiedRange.endLineNumber + lineEndDelta) {\n        // We can only do this if the range is not empty yet\n        lineStartDelta = 1;\n    }\n    const originalLineRange = new LineRange(rangeMapping.originalRange.startLineNumber + lineStartDelta, rangeMapping.originalRange.endLineNumber + 1 + lineEndDelta);\n    const modifiedLineRange = new LineRange(rangeMapping.modifiedRange.startLineNumber + lineStartDelta, rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta);\n    return new LineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]);\n}\nfunction* group(items, shouldBeGrouped) {\n    let currentGroup;\n    let last;\n    for (const item of items) {\n        if (last !== undefined && shouldBeGrouped(last, item)) {\n            currentGroup.push(item);\n        }\n        else {\n            if (currentGroup) {\n                yield currentGroup;\n            }\n            currentGroup = [item];\n        }\n        last = item;\n    }\n    if (currentGroup) {\n        yield currentGroup;\n    }\n}\nexport class LineSequence {\n    constructor(trimmedHash, lines) {\n        this.trimmedHash = trimmedHash;\n        this.lines = lines;\n    }\n    getElement(offset) {\n        return this.trimmedHash[offset];\n    }\n    get length() {\n        return this.trimmedHash.length;\n    }\n    getBoundaryScore(length) {\n        const indentationBefore = length === 0 ? 0 : getIndentation(this.lines[length - 1]);\n        const indentationAfter = length === this.lines.length ? 0 : getIndentation(this.lines[length]);\n        return 1000 - (indentationBefore + indentationAfter);\n    }\n}\nfunction getIndentation(str) {\n    let i = 0;\n    while (i < str.length && (str.charCodeAt(i) === 32 /* CharCode.Space */ || str.charCodeAt(i) === 9 /* CharCode.Tab */)) {\n        i++;\n    }\n    return i;\n}\nclass Slice {\n    constructor(lines, lineRange, considerWhitespaceChanges) {\n        // This slice has to have lineRange.length many \\n! (otherwise diffing against an empty slice will be problematic)\n        // (Unless it covers the entire document, in that case the other slice also has to cover the entire document ands it's okay)\n        this.lines = lines;\n        this.considerWhitespaceChanges = considerWhitespaceChanges;\n        this.elements = [];\n        this.firstCharOffsetByLineMinusOne = [];\n        // To account for trimming\n        this.offsetByLine = [];\n        // If the slice covers the end, but does not start at the beginning, we include just the \\n of the previous line.\n        let trimFirstLineFully = false;\n        if (lineRange.start > 0 && lineRange.endExclusive >= lines.length) {\n            lineRange = new OffsetRange(lineRange.start - 1, lineRange.endExclusive);\n            trimFirstLineFully = true;\n        }\n        this.lineRange = lineRange;\n        for (let i = this.lineRange.start; i < this.lineRange.endExclusive; i++) {\n            let line = lines[i];\n            let offset = 0;\n            if (trimFirstLineFully) {\n                offset = line.length;\n                line = '';\n                trimFirstLineFully = false;\n            }\n            else if (!considerWhitespaceChanges) {\n                const trimmedStartLine = line.trimStart();\n                offset = line.length - trimmedStartLine.length;\n                line = trimmedStartLine.trimEnd();\n            }\n            this.offsetByLine.push(offset);\n            for (let i = 0; i < line.length; i++) {\n                this.elements.push(line.charCodeAt(i));\n            }\n            // Don't add an \\n that does not exist in the document.\n            if (i < lines.length - 1) {\n                this.elements.push('\\n'.charCodeAt(0));\n                this.firstCharOffsetByLineMinusOne[i - this.lineRange.start] = this.elements.length;\n            }\n        }\n        // To account for the last line\n        this.offsetByLine.push(0);\n    }\n    toString() {\n        return `Slice: \"${this.text}\"`;\n    }\n    get text() {\n        return [...this.elements].map(e => String.fromCharCode(e)).join('');\n    }\n    getElement(offset) {\n        return this.elements[offset];\n    }\n    get length() {\n        return this.elements.length;\n    }\n    getBoundaryScore(length) {\n        //   a   b   c   ,           d   e   f\n        // 11  0   0   12  15  6   13  0   0   11\n        const prevCategory = getCategory(length > 0 ? this.elements[length - 1] : -1);\n        const nextCategory = getCategory(length < this.elements.length ? this.elements[length] : -1);\n        if (prevCategory === 6 /* CharBoundaryCategory.LineBreakCR */ && nextCategory === 7 /* CharBoundaryCategory.LineBreakLF */) {\n            // don't break between \\r and \\n\n            return 0;\n        }\n        let score = 0;\n        if (prevCategory !== nextCategory) {\n            score += 10;\n            if (nextCategory === 1 /* CharBoundaryCategory.WordUpper */) {\n                score += 1;\n            }\n        }\n        score += getCategoryBoundaryScore(prevCategory);\n        score += getCategoryBoundaryScore(nextCategory);\n        return score;\n    }\n    translateOffset(offset) {\n        // find smallest i, so that lineBreakOffsets[i] <= offset using binary search\n        if (this.lineRange.isEmpty) {\n            return new Position(this.lineRange.start + 1, 1);\n        }\n        let i = 0;\n        let j = this.firstCharOffsetByLineMinusOne.length;\n        while (i < j) {\n            const k = Math.floor((i + j) / 2);\n            if (this.firstCharOffsetByLineMinusOne[k] > offset) {\n                j = k;\n            }\n            else {\n                i = k + 1;\n            }\n        }\n        const offsetOfFirstCharInLine = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1];\n        return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.offsetByLine[i]);\n    }\n    translateRange(range) {\n        return Range.fromPositions(this.translateOffset(range.start), this.translateOffset(range.endExclusive));\n    }\n    /**\n     * Finds the word that contains the character at the given offset\n     */\n    findWordContaining(offset) {\n        if (offset < 0 || offset >= this.elements.length) {\n            return undefined;\n        }\n        if (!isWordChar(this.elements[offset])) {\n            return undefined;\n        }\n        // find start\n        let start = offset;\n        while (start > 0 && isWordChar(this.elements[start - 1])) {\n            start--;\n        }\n        // find end\n        let end = offset;\n        while (end < this.elements.length && isWordChar(this.elements[end])) {\n            end++;\n        }\n        return new OffsetRange(start, end);\n    }\n}\nfunction isWordChar(charCode) {\n    return charCode >= 97 /* CharCode.a */ && charCode <= 122 /* CharCode.z */\n        || charCode >= 65 /* CharCode.A */ && charCode <= 90 /* CharCode.Z */\n        || charCode >= 48 /* CharCode.Digit0 */ && charCode <= 57 /* CharCode.Digit9 */;\n}\nconst score = {\n    [0 /* CharBoundaryCategory.WordLower */]: 0,\n    [1 /* CharBoundaryCategory.WordUpper */]: 0,\n    [2 /* CharBoundaryCategory.WordNumber */]: 0,\n    [3 /* CharBoundaryCategory.End */]: 10,\n    [4 /* CharBoundaryCategory.Other */]: 2,\n    [5 /* CharBoundaryCategory.Space */]: 3,\n    [6 /* CharBoundaryCategory.LineBreakCR */]: 10,\n    [7 /* CharBoundaryCategory.LineBreakLF */]: 10,\n};\nfunction getCategoryBoundaryScore(category) {\n    return score[category];\n}\nfunction getCategory(charCode) {\n    if (charCode === 10 /* CharCode.LineFeed */) {\n        return 7 /* CharBoundaryCategory.LineBreakLF */;\n    }\n    else if (charCode === 13 /* CharCode.CarriageReturn */) {\n        return 6 /* CharBoundaryCategory.LineBreakCR */;\n    }\n    else if (isSpace(charCode)) {\n        return 5 /* CharBoundaryCategory.Space */;\n    }\n    else if (charCode >= 97 /* CharCode.a */ && charCode <= 122 /* CharCode.z */) {\n        return 0 /* CharBoundaryCategory.WordLower */;\n    }\n    else if (charCode >= 65 /* CharCode.A */ && charCode <= 90 /* CharCode.Z */) {\n        return 1 /* CharBoundaryCategory.WordUpper */;\n    }\n    else if (charCode >= 48 /* CharCode.Digit0 */ && charCode <= 57 /* CharCode.Digit9 */) {\n        return 2 /* CharBoundaryCategory.WordNumber */;\n    }\n    else if (charCode === -1) {\n        return 3 /* CharBoundaryCategory.End */;\n    }\n    else {\n        return 4 /* CharBoundaryCategory.Other */;\n    }\n}\nfunction isSpace(charCode) {\n    return charCode === 32 /* CharCode.Space */ || charCode === 9 /* CharCode.Tab */;\n}\nconst chrKeys = new Map();\nfunction getKey(chr) {\n    let key = chrKeys.get(chr);\n    if (key === undefined) {\n        key = chrKeys.size;\n        chrKeys.set(chr, key);\n    }\n    return key;\n}\nclass LineRangeFragment {\n    constructor(range, lines) {\n        this.range = range;\n        this.lines = lines;\n        this.histogram = [];\n        let counter = 0;\n        for (let i = range.startLineNumber - 1; i < range.endLineNumberExclusive - 1; i++) {\n            const line = lines[i];\n            for (let j = 0; j < line.length; j++) {\n                counter++;\n                const chr = line[j];\n                const key = getKey(chr);\n                this.histogram[key] = (this.histogram[key] || 0) + 1;\n            }\n            counter++;\n            const key = getKey('\\n');\n            this.histogram[key] = (this.histogram[key] || 0) + 1;\n        }\n        this.totalCount = counter;\n    }\n    computeSimilarity(other) {\n        var _a, _b;\n        let sumDifferences = 0;\n        const maxLength = Math.max(this.histogram.length, other.histogram.length);\n        for (let i = 0; i < maxLength; i++) {\n            sumDifferences += Math.abs(((_a = this.histogram[i]) !== null && _a !== void 0 ? _a : 0) - ((_b = other.histogram[i]) !== null && _b !== void 0 ? _b : 0));\n        }\n        return 1 - (sumDifferences / (this.totalCount + other.totalCount));\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { SmartLinesDiffComputer } from './smartLinesDiffComputer.js';\nimport { StandardLinesDiffComputer } from './standardLinesDiffComputer.js';\nexport const linesDiffComputers = {\n    getLegacy: () => new SmartLinesDiffComputer(),\n    getAdvanced: () => new StandardLinesDiffComputer(),\n};\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nfunction roundFloat(number, decimalPoints) {\n    const decimal = Math.pow(10, decimalPoints);\n    return Math.round(number * decimal) / decimal;\n}\nexport class RGBA {\n    constructor(r, g, b, a = 1) {\n        this._rgbaBrand = undefined;\n        this.r = Math.min(255, Math.max(0, r)) | 0;\n        this.g = Math.min(255, Math.max(0, g)) | 0;\n        this.b = Math.min(255, Math.max(0, b)) | 0;\n        this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);\n    }\n    static equals(a, b) {\n        return a.r === b.r && a.g === b.g && a.b === b.b && a.a === b.a;\n    }\n}\nexport class HSLA {\n    constructor(h, s, l, a) {\n        this._hslaBrand = undefined;\n        this.h = Math.max(Math.min(360, h), 0) | 0;\n        this.s = roundFloat(Math.max(Math.min(1, s), 0), 3);\n        this.l = roundFloat(Math.max(Math.min(1, l), 0), 3);\n        this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);\n    }\n    static equals(a, b) {\n        return a.h === b.h && a.s === b.s && a.l === b.l && a.a === b.a;\n    }\n    /**\n     * Converts an RGB color value to HSL. Conversion formula\n     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.\n     * Assumes r, g, and b are contained in the set [0, 255] and\n     * returns h in the set [0, 360], s, and l in the set [0, 1].\n     */\n    static fromRGBA(rgba) {\n        const r = rgba.r / 255;\n        const g = rgba.g / 255;\n        const b = rgba.b / 255;\n        const a = rgba.a;\n        const max = Math.max(r, g, b);\n        const min = Math.min(r, g, b);\n        let h = 0;\n        let s = 0;\n        const l = (min + max) / 2;\n        const chroma = max - min;\n        if (chroma > 0) {\n            s = Math.min((l <= 0.5 ? chroma / (2 * l) : chroma / (2 - (2 * l))), 1);\n            switch (max) {\n                case r:\n                    h = (g - b) / chroma + (g < b ? 6 : 0);\n                    break;\n                case g:\n                    h = (b - r) / chroma + 2;\n                    break;\n                case b:\n                    h = (r - g) / chroma + 4;\n                    break;\n            }\n            h *= 60;\n            h = Math.round(h);\n        }\n        return new HSLA(h, s, l, a);\n    }\n    static _hue2rgb(p, q, t) {\n        if (t < 0) {\n            t += 1;\n        }\n        if (t > 1) {\n            t -= 1;\n        }\n        if (t < 1 / 6) {\n            return p + (q - p) * 6 * t;\n        }\n        if (t < 1 / 2) {\n            return q;\n        }\n        if (t < 2 / 3) {\n            return p + (q - p) * (2 / 3 - t) * 6;\n        }\n        return p;\n    }\n    /**\n     * Converts an HSL color value to RGB. Conversion formula\n     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.\n     * Assumes h in the set [0, 360] s, and l are contained in the set [0, 1] and\n     * returns r, g, and b in the set [0, 255].\n     */\n    static toRGBA(hsla) {\n        const h = hsla.h / 360;\n        const { s, l, a } = hsla;\n        let r, g, b;\n        if (s === 0) {\n            r = g = b = l; // achromatic\n        }\n        else {\n            const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n            const p = 2 * l - q;\n            r = HSLA._hue2rgb(p, q, h + 1 / 3);\n            g = HSLA._hue2rgb(p, q, h);\n            b = HSLA._hue2rgb(p, q, h - 1 / 3);\n        }\n        return new RGBA(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a);\n    }\n}\nexport class HSVA {\n    constructor(h, s, v, a) {\n        this._hsvaBrand = undefined;\n        this.h = Math.max(Math.min(360, h), 0) | 0;\n        this.s = roundFloat(Math.max(Math.min(1, s), 0), 3);\n        this.v = roundFloat(Math.max(Math.min(1, v), 0), 3);\n        this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);\n    }\n    static equals(a, b) {\n        return a.h === b.h && a.s === b.s && a.v === b.v && a.a === b.a;\n    }\n    // from http://www.rapidtables.com/convert/color/rgb-to-hsv.htm\n    static fromRGBA(rgba) {\n        const r = rgba.r / 255;\n        const g = rgba.g / 255;\n        const b = rgba.b / 255;\n        const cmax = Math.max(r, g, b);\n        const cmin = Math.min(r, g, b);\n        const delta = cmax - cmin;\n        const s = cmax === 0 ? 0 : (delta / cmax);\n        let m;\n        if (delta === 0) {\n            m = 0;\n        }\n        else if (cmax === r) {\n            m = ((((g - b) / delta) % 6) + 6) % 6;\n        }\n        else if (cmax === g) {\n            m = ((b - r) / delta) + 2;\n        }\n        else {\n            m = ((r - g) / delta) + 4;\n        }\n        return new HSVA(Math.round(m * 60), s, cmax, rgba.a);\n    }\n    // from http://www.rapidtables.com/convert/color/hsv-to-rgb.htm\n    static toRGBA(hsva) {\n        const { h, s, v, a } = hsva;\n        const c = v * s;\n        const x = c * (1 - Math.abs((h / 60) % 2 - 1));\n        const m = v - c;\n        let [r, g, b] = [0, 0, 0];\n        if (h < 60) {\n            r = c;\n            g = x;\n        }\n        else if (h < 120) {\n            r = x;\n            g = c;\n        }\n        else if (h < 180) {\n            g = c;\n            b = x;\n        }\n        else if (h < 240) {\n            g = x;\n            b = c;\n        }\n        else if (h < 300) {\n            r = x;\n            b = c;\n        }\n        else if (h <= 360) {\n            r = c;\n            b = x;\n        }\n        r = Math.round((r + m) * 255);\n        g = Math.round((g + m) * 255);\n        b = Math.round((b + m) * 255);\n        return new RGBA(r, g, b, a);\n    }\n}\nexport class Color {\n    static fromHex(hex) {\n        return Color.Format.CSS.parseHex(hex) || Color.red;\n    }\n    static equals(a, b) {\n        if (!a && !b) {\n            return true;\n        }\n        if (!a || !b) {\n            return false;\n        }\n        return a.equals(b);\n    }\n    get hsla() {\n        if (this._hsla) {\n            return this._hsla;\n        }\n        else {\n            return HSLA.fromRGBA(this.rgba);\n        }\n    }\n    get hsva() {\n        if (this._hsva) {\n            return this._hsva;\n        }\n        return HSVA.fromRGBA(this.rgba);\n    }\n    constructor(arg) {\n        if (!arg) {\n            throw new Error('Color needs a value');\n        }\n        else if (arg instanceof RGBA) {\n            this.rgba = arg;\n        }\n        else if (arg instanceof HSLA) {\n            this._hsla = arg;\n            this.rgba = HSLA.toRGBA(arg);\n        }\n        else if (arg instanceof HSVA) {\n            this._hsva = arg;\n            this.rgba = HSVA.toRGBA(arg);\n        }\n        else {\n            throw new Error('Invalid color ctor argument');\n        }\n    }\n    equals(other) {\n        return !!other && RGBA.equals(this.rgba, other.rgba) && HSLA.equals(this.hsla, other.hsla) && HSVA.equals(this.hsva, other.hsva);\n    }\n    /**\n     * http://www.w3.org/TR/WCAG20/#relativeluminancedef\n     * Returns the number in the set [0, 1]. O => Darkest Black. 1 => Lightest white.\n     */\n    getRelativeLuminance() {\n        const R = Color._relativeLuminanceForComponent(this.rgba.r);\n        const G = Color._relativeLuminanceForComponent(this.rgba.g);\n        const B = Color._relativeLuminanceForComponent(this.rgba.b);\n        const luminance = 0.2126 * R + 0.7152 * G + 0.0722 * B;\n        return roundFloat(luminance, 4);\n    }\n    static _relativeLuminanceForComponent(color) {\n        const c = color / 255;\n        return (c <= 0.03928) ? c / 12.92 : Math.pow(((c + 0.055) / 1.055), 2.4);\n    }\n    /**\n     *\thttp://24ways.org/2010/calculating-color-contrast\n     *  Return 'true' if lighter color otherwise 'false'\n     */\n    isLighter() {\n        const yiq = (this.rgba.r * 299 + this.rgba.g * 587 + this.rgba.b * 114) / 1000;\n        return yiq >= 128;\n    }\n    isLighterThan(another) {\n        const lum1 = this.getRelativeLuminance();\n        const lum2 = another.getRelativeLuminance();\n        return lum1 > lum2;\n    }\n    isDarkerThan(another) {\n        const lum1 = this.getRelativeLuminance();\n        const lum2 = another.getRelativeLuminance();\n        return lum1 < lum2;\n    }\n    lighten(factor) {\n        return new Color(new HSLA(this.hsla.h, this.hsla.s, this.hsla.l + this.hsla.l * factor, this.hsla.a));\n    }\n    darken(factor) {\n        return new Color(new HSLA(this.hsla.h, this.hsla.s, this.hsla.l - this.hsla.l * factor, this.hsla.a));\n    }\n    transparent(factor) {\n        const { r, g, b, a } = this.rgba;\n        return new Color(new RGBA(r, g, b, a * factor));\n    }\n    isTransparent() {\n        return this.rgba.a === 0;\n    }\n    isOpaque() {\n        return this.rgba.a === 1;\n    }\n    opposite() {\n        return new Color(new RGBA(255 - this.rgba.r, 255 - this.rgba.g, 255 - this.rgba.b, this.rgba.a));\n    }\n    makeOpaque(opaqueBackground) {\n        if (this.isOpaque() || opaqueBackground.rgba.a !== 1) {\n            // only allow to blend onto a non-opaque color onto a opaque color\n            return this;\n        }\n        const { r, g, b, a } = this.rgba;\n        // https://stackoverflow.com/questions/12228548/finding-equivalent-color-with-opacity\n        return new Color(new RGBA(opaqueBackground.rgba.r - a * (opaqueBackground.rgba.r - r), opaqueBackground.rgba.g - a * (opaqueBackground.rgba.g - g), opaqueBackground.rgba.b - a * (opaqueBackground.rgba.b - b), 1));\n    }\n    toString() {\n        if (!this._toString) {\n            this._toString = Color.Format.CSS.format(this);\n        }\n        return this._toString;\n    }\n    static getLighterColor(of, relative, factor) {\n        if (of.isLighterThan(relative)) {\n            return of;\n        }\n        factor = factor ? factor : 0.5;\n        const lum1 = of.getRelativeLuminance();\n        const lum2 = relative.getRelativeLuminance();\n        factor = factor * (lum2 - lum1) / lum2;\n        return of.lighten(factor);\n    }\n    static getDarkerColor(of, relative, factor) {\n        if (of.isDarkerThan(relative)) {\n            return of;\n        }\n        factor = factor ? factor : 0.5;\n        const lum1 = of.getRelativeLuminance();\n        const lum2 = relative.getRelativeLuminance();\n        factor = factor * (lum1 - lum2) / lum1;\n        return of.darken(factor);\n    }\n}\nColor.white = new Color(new RGBA(255, 255, 255, 1));\nColor.black = new Color(new RGBA(0, 0, 0, 1));\nColor.red = new Color(new RGBA(255, 0, 0, 1));\nColor.blue = new Color(new RGBA(0, 0, 255, 1));\nColor.green = new Color(new RGBA(0, 255, 0, 1));\nColor.cyan = new Color(new RGBA(0, 255, 255, 1));\nColor.lightgrey = new Color(new RGBA(211, 211, 211, 1));\nColor.transparent = new Color(new RGBA(0, 0, 0, 0));\n(function (Color) {\n    let Format;\n    (function (Format) {\n        let CSS;\n        (function (CSS) {\n            function formatRGB(color) {\n                if (color.rgba.a === 1) {\n                    return `rgb(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b})`;\n                }\n                return Color.Format.CSS.formatRGBA(color);\n            }\n            CSS.formatRGB = formatRGB;\n            function formatRGBA(color) {\n                return `rgba(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b}, ${+(color.rgba.a).toFixed(2)})`;\n            }\n            CSS.formatRGBA = formatRGBA;\n            function formatHSL(color) {\n                if (color.hsla.a === 1) {\n                    return `hsl(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%)`;\n                }\n                return Color.Format.CSS.formatHSLA(color);\n            }\n            CSS.formatHSL = formatHSL;\n            function formatHSLA(color) {\n                return `hsla(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%, ${color.hsla.a.toFixed(2)})`;\n            }\n            CSS.formatHSLA = formatHSLA;\n            function _toTwoDigitHex(n) {\n                const r = n.toString(16);\n                return r.length !== 2 ? '0' + r : r;\n            }\n            /**\n             * Formats the color as #RRGGBB\n             */\n            function formatHex(color) {\n                return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}`;\n            }\n            CSS.formatHex = formatHex;\n            /**\n             * Formats the color as #RRGGBBAA\n             * If 'compact' is set, colors without transparancy will be printed as #RRGGBB\n             */\n            function formatHexA(color, compact = false) {\n                if (compact && color.rgba.a === 1) {\n                    return Color.Format.CSS.formatHex(color);\n                }\n                return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}${_toTwoDigitHex(Math.round(color.rgba.a * 255))}`;\n            }\n            CSS.formatHexA = formatHexA;\n            /**\n             * The default format will use HEX if opaque and RGBA otherwise.\n             */\n            function format(color) {\n                if (color.isOpaque()) {\n                    return Color.Format.CSS.formatHex(color);\n                }\n                return Color.Format.CSS.formatRGBA(color);\n            }\n            CSS.format = format;\n            /**\n             * Converts an Hex color value to a Color.\n             * returns r, g, and b are contained in the set [0, 255]\n             * @param hex string (#RGB, #RGBA, #RRGGBB or #RRGGBBAA).\n             */\n            function parseHex(hex) {\n                const length = hex.length;\n                if (length === 0) {\n                    // Invalid color\n                    return null;\n                }\n                if (hex.charCodeAt(0) !== 35 /* CharCode.Hash */) {\n                    // Does not begin with a #\n                    return null;\n                }\n                if (length === 7) {\n                    // #RRGGBB format\n                    const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));\n                    const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));\n                    const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));\n                    return new Color(new RGBA(r, g, b, 1));\n                }\n                if (length === 9) {\n                    // #RRGGBBAA format\n                    const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));\n                    const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));\n                    const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));\n                    const a = 16 * _parseHexDigit(hex.charCodeAt(7)) + _parseHexDigit(hex.charCodeAt(8));\n                    return new Color(new RGBA(r, g, b, a / 255));\n                }\n                if (length === 4) {\n                    // #RGB format\n                    const r = _parseHexDigit(hex.charCodeAt(1));\n                    const g = _parseHexDigit(hex.charCodeAt(2));\n                    const b = _parseHexDigit(hex.charCodeAt(3));\n                    return new Color(new RGBA(16 * r + r, 16 * g + g, 16 * b + b));\n                }\n                if (length === 5) {\n                    // #RGBA format\n                    const r = _parseHexDigit(hex.charCodeAt(1));\n                    const g = _parseHexDigit(hex.charCodeAt(2));\n                    const b = _parseHexDigit(hex.charCodeAt(3));\n                    const a = _parseHexDigit(hex.charCodeAt(4));\n                    return new Color(new RGBA(16 * r + r, 16 * g + g, 16 * b + b, (16 * a + a) / 255));\n                }\n                // Invalid color\n                return null;\n            }\n            CSS.parseHex = parseHex;\n            function _parseHexDigit(charCode) {\n                switch (charCode) {\n                    case 48 /* CharCode.Digit0 */: return 0;\n                    case 49 /* CharCode.Digit1 */: return 1;\n                    case 50 /* CharCode.Digit2 */: return 2;\n                    case 51 /* CharCode.Digit3 */: return 3;\n                    case 52 /* CharCode.Digit4 */: return 4;\n                    case 53 /* CharCode.Digit5 */: return 5;\n                    case 54 /* CharCode.Digit6 */: return 6;\n                    case 55 /* CharCode.Digit7 */: return 7;\n                    case 56 /* CharCode.Digit8 */: return 8;\n                    case 57 /* CharCode.Digit9 */: return 9;\n                    case 97 /* CharCode.a */: return 10;\n                    case 65 /* CharCode.A */: return 10;\n                    case 98 /* CharCode.b */: return 11;\n                    case 66 /* CharCode.B */: return 11;\n                    case 99 /* CharCode.c */: return 12;\n                    case 67 /* CharCode.C */: return 12;\n                    case 100 /* CharCode.d */: return 13;\n                    case 68 /* CharCode.D */: return 13;\n                    case 101 /* CharCode.e */: return 14;\n                    case 69 /* CharCode.E */: return 14;\n                    case 102 /* CharCode.f */: return 15;\n                    case 70 /* CharCode.F */: return 15;\n                }\n                return 0;\n            }\n        })(CSS = Format.CSS || (Format.CSS = {}));\n    })(Format = Color.Format || (Color.Format = {}));\n})(Color || (Color = {}));\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Color, HSLA } from '../../../base/common/color.js';\nfunction _parseCaptureGroups(captureGroups) {\n    const values = [];\n    for (const captureGroup of captureGroups) {\n        const parsedNumber = Number(captureGroup);\n        if (parsedNumber || parsedNumber === 0 && captureGroup.replace(/\\s/g, '') !== '') {\n            values.push(parsedNumber);\n        }\n    }\n    return values;\n}\nfunction _toIColor(r, g, b, a) {\n    return {\n        red: r / 255,\n        blue: b / 255,\n        green: g / 255,\n        alpha: a\n    };\n}\nfunction _findRange(model, match) {\n    const index = match.index;\n    const length = match[0].length;\n    if (!index) {\n        return;\n    }\n    const startPosition = model.positionAt(index);\n    const range = {\n        startLineNumber: startPosition.lineNumber,\n        startColumn: startPosition.column,\n        endLineNumber: startPosition.lineNumber,\n        endColumn: startPosition.column + length\n    };\n    return range;\n}\nfunction _findHexColorInformation(range, hexValue) {\n    if (!range) {\n        return;\n    }\n    const parsedHexColor = Color.Format.CSS.parseHex(hexValue);\n    if (!parsedHexColor) {\n        return;\n    }\n    return {\n        range: range,\n        color: _toIColor(parsedHexColor.rgba.r, parsedHexColor.rgba.g, parsedHexColor.rgba.b, parsedHexColor.rgba.a)\n    };\n}\nfunction _findRGBColorInformation(range, matches, isAlpha) {\n    if (!range || matches.length !== 1) {\n        return;\n    }\n    const match = matches[0];\n    const captureGroups = match.values();\n    const parsedRegex = _parseCaptureGroups(captureGroups);\n    return {\n        range: range,\n        color: _toIColor(parsedRegex[0], parsedRegex[1], parsedRegex[2], isAlpha ? parsedRegex[3] : 1)\n    };\n}\nfunction _findHSLColorInformation(range, matches, isAlpha) {\n    if (!range || matches.length !== 1) {\n        return;\n    }\n    const match = matches[0];\n    const captureGroups = match.values();\n    const parsedRegex = _parseCaptureGroups(captureGroups);\n    const colorEquivalent = new Color(new HSLA(parsedRegex[0], parsedRegex[1] / 100, parsedRegex[2] / 100, isAlpha ? parsedRegex[3] : 1));\n    return {\n        range: range,\n        color: _toIColor(colorEquivalent.rgba.r, colorEquivalent.rgba.g, colorEquivalent.rgba.b, colorEquivalent.rgba.a)\n    };\n}\nfunction _findMatches(model, regex) {\n    if (typeof model === 'string') {\n        return [...model.matchAll(regex)];\n    }\n    else {\n        return model.findMatches(regex);\n    }\n}\nfunction computeColors(model) {\n    const result = [];\n    // Early validation for RGB and HSL\n    const initialValidationRegex = /\\b(rgb|rgba|hsl|hsla)(\\([0-9\\s,.\\%]*\\))|(#)([A-Fa-f0-9]{3})\\b|(#)([A-Fa-f0-9]{4})\\b|(#)([A-Fa-f0-9]{6})\\b|(#)([A-Fa-f0-9]{8})\\b/gm;\n    const initialValidationMatches = _findMatches(model, initialValidationRegex);\n    // Potential colors have been found, validate the parameters\n    if (initialValidationMatches.length > 0) {\n        for (const initialMatch of initialValidationMatches) {\n            const initialCaptureGroups = initialMatch.filter(captureGroup => captureGroup !== undefined);\n            const colorScheme = initialCaptureGroups[1];\n            const colorParameters = initialCaptureGroups[2];\n            if (!colorParameters) {\n                continue;\n            }\n            let colorInformation;\n            if (colorScheme === 'rgb') {\n                const regexParameters = /^\\(\\s*(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\s*,\\s*(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\s*,\\s*(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\s*\\)$/gm;\n                colorInformation = _findRGBColorInformation(_findRange(model, initialMatch), _findMatches(colorParameters, regexParameters), false);\n            }\n            else if (colorScheme === 'rgba') {\n                const regexParameters = /^\\(\\s*(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\s*,\\s*(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\s*,\\s*(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\s*,\\s*(0[.][0-9]+|[.][0-9]+|[01][.]|[01])\\s*\\)$/gm;\n                colorInformation = _findRGBColorInformation(_findRange(model, initialMatch), _findMatches(colorParameters, regexParameters), true);\n            }\n            else if (colorScheme === 'hsl') {\n                const regexParameters = /^\\(\\s*(36[0]|3[0-5][0-9]|[12][0-9][0-9]|[1-9]?[0-9])\\s*,\\s*(100|\\d{1,2}[.]\\d*|\\d{1,2})%\\s*,\\s*(100|\\d{1,2}[.]\\d*|\\d{1,2})%\\s*\\)$/gm;\n                colorInformation = _findHSLColorInformation(_findRange(model, initialMatch), _findMatches(colorParameters, regexParameters), false);\n            }\n            else if (colorScheme === 'hsla') {\n                const regexParameters = /^\\(\\s*(36[0]|3[0-5][0-9]|[12][0-9][0-9]|[1-9]?[0-9])\\s*,\\s*(100|\\d{1,2}[.]\\d*|\\d{1,2})%\\s*,\\s*(100|\\d{1,2}[.]\\d*|\\d{1,2})%\\s*,\\s*(0[.][0-9]+|[.][0-9]+|[01][.]|[01])\\s*\\)$/gm;\n                colorInformation = _findHSLColorInformation(_findRange(model, initialMatch), _findMatches(colorParameters, regexParameters), true);\n            }\n            else if (colorScheme === '#') {\n                colorInformation = _findHexColorInformation(_findRange(model, initialMatch), colorScheme + colorParameters);\n            }\n            if (colorInformation) {\n                result.push(colorInformation);\n            }\n        }\n    }\n    return result;\n}\n/**\n * Returns an array of all default document colors in the provided document\n */\nexport function computeDefaultDocumentColors(model) {\n    if (!model || typeof model.getValue !== 'function' || typeof model.positionAt !== 'function') {\n        // Unknown caller!\n        return [];\n    }\n    return computeColors(model);\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nimport { stringDiff } from '../../../base/common/diff/diff.js';\nimport { URI } from '../../../base/common/uri.js';\nimport { Position } from '../core/position.js';\nimport { Range } from '../core/range.js';\nimport { MirrorTextModel as BaseMirrorModel } from '../model/mirrorTextModel.js';\nimport { ensureValidWordDefinition, getWordAtText } from '../core/wordHelper.js';\nimport { computeLinks } from '../languages/linkComputer.js';\nimport { BasicInplaceReplace } from '../languages/supports/inplaceReplaceSupport.js';\nimport { createMonacoBaseAPI } from './editorBaseApi.js';\nimport { StopWatch } from '../../../base/common/stopwatch.js';\nimport { UnicodeTextModelHighlighter } from './unicodeTextModelHighlighter.js';\nimport { linesDiffComputers } from '../diff/linesDiffComputers.js';\nimport { createProxyObject, getAllMethodNames } from '../../../base/common/objects.js';\nimport { computeDefaultDocumentColors } from '../languages/defaultDocumentColorsComputer.js';\n/**\n * @internal\n */\nclass MirrorModel extends BaseMirrorModel {\n    get uri() {\n        return this._uri;\n    }\n    get eol() {\n        return this._eol;\n    }\n    getValue() {\n        return this.getText();\n    }\n    findMatches(regex) {\n        const matches = [];\n        for (let i = 0; i < this._lines.length; i++) {\n            const line = this._lines[i];\n            const offsetToAdd = this.offsetAt(new Position(i + 1, 1));\n            const iteratorOverMatches = line.matchAll(regex);\n            for (const match of iteratorOverMatches) {\n                if (match.index || match.index === 0) {\n                    match.index = match.index + offsetToAdd;\n                }\n                matches.push(match);\n            }\n        }\n        return matches;\n    }\n    getLinesContent() {\n        return this._lines.slice(0);\n    }\n    getLineCount() {\n        return this._lines.length;\n    }\n    getLineContent(lineNumber) {\n        return this._lines[lineNumber - 1];\n    }\n    getWordAtPosition(position, wordDefinition) {\n        const wordAtText = getWordAtText(position.column, ensureValidWordDefinition(wordDefinition), this._lines[position.lineNumber - 1], 0);\n        if (wordAtText) {\n            return new Range(position.lineNumber, wordAtText.startColumn, position.lineNumber, wordAtText.endColumn);\n        }\n        return null;\n    }\n    words(wordDefinition) {\n        const lines = this._lines;\n        const wordenize = this._wordenize.bind(this);\n        let lineNumber = 0;\n        let lineText = '';\n        let wordRangesIdx = 0;\n        let wordRanges = [];\n        return {\n            *[Symbol.iterator]() {\n                while (true) {\n                    if (wordRangesIdx < wordRanges.length) {\n                        const value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end);\n                        wordRangesIdx += 1;\n                        yield value;\n                    }\n                    else {\n                        if (lineNumber < lines.length) {\n                            lineText = lines[lineNumber];\n                            wordRanges = wordenize(lineText, wordDefinition);\n                            wordRangesIdx = 0;\n                            lineNumber += 1;\n                        }\n                        else {\n                            break;\n                        }\n                    }\n                }\n            }\n        };\n    }\n    getLineWords(lineNumber, wordDefinition) {\n        const content = this._lines[lineNumber - 1];\n        const ranges = this._wordenize(content, wordDefinition);\n        const words = [];\n        for (const range of ranges) {\n            words.push({\n                word: content.substring(range.start, range.end),\n                startColumn: range.start + 1,\n                endColumn: range.end + 1\n            });\n        }\n        return words;\n    }\n    _wordenize(content, wordDefinition) {\n        const result = [];\n        let match;\n        wordDefinition.lastIndex = 0; // reset lastIndex just to be sure\n        while (match = wordDefinition.exec(content)) {\n            if (match[0].length === 0) {\n                // it did match the empty string\n                break;\n            }\n            result.push({ start: match.index, end: match.index + match[0].length });\n        }\n        return result;\n    }\n    getValueInRange(range) {\n        range = this._validateRange(range);\n        if (range.startLineNumber === range.endLineNumber) {\n            return this._lines[range.startLineNumber - 1].substring(range.startColumn - 1, range.endColumn - 1);\n        }\n        const lineEnding = this._eol;\n        const startLineIndex = range.startLineNumber - 1;\n        const endLineIndex = range.endLineNumber - 1;\n        const resultLines = [];\n        resultLines.push(this._lines[startLineIndex].substring(range.startColumn - 1));\n        for (let i = startLineIndex + 1; i < endLineIndex; i++) {\n            resultLines.push(this._lines[i]);\n        }\n        resultLines.push(this._lines[endLineIndex].substring(0, range.endColumn - 1));\n        return resultLines.join(lineEnding);\n    }\n    offsetAt(position) {\n        position = this._validatePosition(position);\n        this._ensureLineStarts();\n        return this._lineStarts.getPrefixSum(position.lineNumber - 2) + (position.column - 1);\n    }\n    positionAt(offset) {\n        offset = Math.floor(offset);\n        offset = Math.max(0, offset);\n        this._ensureLineStarts();\n        const out = this._lineStarts.getIndexOf(offset);\n        const lineLength = this._lines[out.index].length;\n        // Ensure we return a valid position\n        return {\n            lineNumber: 1 + out.index,\n            column: 1 + Math.min(out.remainder, lineLength)\n        };\n    }\n    _validateRange(range) {\n        const start = this._validatePosition({ lineNumber: range.startLineNumber, column: range.startColumn });\n        const end = this._validatePosition({ lineNumber: range.endLineNumber, column: range.endColumn });\n        if (start.lineNumber !== range.startLineNumber\n            || start.column !== range.startColumn\n            || end.lineNumber !== range.endLineNumber\n            || end.column !== range.endColumn) {\n            return {\n                startLineNumber: start.lineNumber,\n                startColumn: start.column,\n                endLineNumber: end.lineNumber,\n                endColumn: end.column\n            };\n        }\n        return range;\n    }\n    _validatePosition(position) {\n        if (!Position.isIPosition(position)) {\n            throw new Error('bad position');\n        }\n        let { lineNumber, column } = position;\n        let hasChanged = false;\n        if (lineNumber < 1) {\n            lineNumber = 1;\n            column = 1;\n            hasChanged = true;\n        }\n        else if (lineNumber > this._lines.length) {\n            lineNumber = this._lines.length;\n            column = this._lines[lineNumber - 1].length + 1;\n            hasChanged = true;\n        }\n        else {\n            const maxCharacter = this._lines[lineNumber - 1].length + 1;\n            if (column < 1) {\n                column = 1;\n                hasChanged = true;\n            }\n            else if (column > maxCharacter) {\n                column = maxCharacter;\n                hasChanged = true;\n            }\n        }\n        if (!hasChanged) {\n            return position;\n        }\n        else {\n            return { lineNumber, column };\n        }\n    }\n}\n/**\n * @internal\n */\nexport class EditorSimpleWorker {\n    constructor(host, foreignModuleFactory) {\n        this._host = host;\n        this._models = Object.create(null);\n        this._foreignModuleFactory = foreignModuleFactory;\n        this._foreignModule = null;\n    }\n    dispose() {\n        this._models = Object.create(null);\n    }\n    _getModel(uri) {\n        return this._models[uri];\n    }\n    _getModels() {\n        const all = [];\n        Object.keys(this._models).forEach((key) => all.push(this._models[key]));\n        return all;\n    }\n    acceptNewModel(data) {\n        this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId);\n    }\n    acceptModelChanged(strURL, e) {\n        if (!this._models[strURL]) {\n            return;\n        }\n        const model = this._models[strURL];\n        model.onEvents(e);\n    }\n    acceptRemovedModel(strURL) {\n        if (!this._models[strURL]) {\n            return;\n        }\n        delete this._models[strURL];\n    }\n    computeUnicodeHighlights(url, options, range) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const model = this._getModel(url);\n            if (!model) {\n                return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 };\n            }\n            return UnicodeTextModelHighlighter.computeUnicodeHighlights(model, options, range);\n        });\n    }\n    // ---- BEGIN diff --------------------------------------------------------------------------\n    computeDiff(originalUrl, modifiedUrl, options, algorithm) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const original = this._getModel(originalUrl);\n            const modified = this._getModel(modifiedUrl);\n            if (!original || !modified) {\n                return null;\n            }\n            return EditorSimpleWorker.computeDiff(original, modified, options, algorithm);\n        });\n    }\n    static computeDiff(originalTextModel, modifiedTextModel, options, algorithm) {\n        const diffAlgorithm = algorithm === 'advanced' ? linesDiffComputers.getAdvanced() : linesDiffComputers.getLegacy();\n        const originalLines = originalTextModel.getLinesContent();\n        const modifiedLines = modifiedTextModel.getLinesContent();\n        const result = diffAlgorithm.computeDiff(originalLines, modifiedLines, options);\n        const identical = (result.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));\n        function getLineChanges(changes) {\n            return changes.map(m => {\n                var _a;\n                return ([m.originalRange.startLineNumber, m.originalRange.endLineNumberExclusive, m.modifiedRange.startLineNumber, m.modifiedRange.endLineNumberExclusive, (_a = m.innerChanges) === null || _a === void 0 ? void 0 : _a.map(m => [\n                        m.originalRange.startLineNumber,\n                        m.originalRange.startColumn,\n                        m.originalRange.endLineNumber,\n                        m.originalRange.endColumn,\n                        m.modifiedRange.startLineNumber,\n                        m.modifiedRange.startColumn,\n                        m.modifiedRange.endLineNumber,\n                        m.modifiedRange.endColumn,\n                    ])]);\n            });\n        }\n        return {\n            identical,\n            quitEarly: result.hitTimeout,\n            changes: getLineChanges(result.changes),\n            moves: result.moves.map(m => ([\n                m.lineRangeMapping.originalRange.startLineNumber,\n                m.lineRangeMapping.originalRange.endLineNumberExclusive,\n                m.lineRangeMapping.modifiedRange.startLineNumber,\n                m.lineRangeMapping.modifiedRange.endLineNumberExclusive,\n                getLineChanges(m.changes)\n            ])),\n        };\n    }\n    static _modelsAreIdentical(original, modified) {\n        const originalLineCount = original.getLineCount();\n        const modifiedLineCount = modified.getLineCount();\n        if (originalLineCount !== modifiedLineCount) {\n            return false;\n        }\n        for (let line = 1; line <= originalLineCount; line++) {\n            const originalLine = original.getLineContent(line);\n            const modifiedLine = modified.getLineContent(line);\n            if (originalLine !== modifiedLine) {\n                return false;\n            }\n        }\n        return true;\n    }\n    computeMoreMinimalEdits(modelUrl, edits, pretty) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const model = this._getModel(modelUrl);\n            if (!model) {\n                return edits;\n            }\n            const result = [];\n            let lastEol = undefined;\n            edits = edits.slice(0).sort((a, b) => {\n                if (a.range && b.range) {\n                    return Range.compareRangesUsingStarts(a.range, b.range);\n                }\n                // eol only changes should go to the end\n                const aRng = a.range ? 0 : 1;\n                const bRng = b.range ? 0 : 1;\n                return aRng - bRng;\n            });\n            for (let { range, text, eol } of edits) {\n                if (typeof eol === 'number') {\n                    lastEol = eol;\n                }\n                if (Range.isEmpty(range) && !text) {\n                    // empty change\n                    continue;\n                }\n                const original = model.getValueInRange(range);\n                text = text.replace(/\\r\\n|\\n|\\r/g, model.eol);\n                if (original === text) {\n                    // noop\n                    continue;\n                }\n                // make sure diff won't take too long\n                if (Math.max(text.length, original.length) > EditorSimpleWorker._diffLimit) {\n                    result.push({ range, text });\n                    continue;\n                }\n                // compute diff between original and edit.text\n                const changes = stringDiff(original, text, pretty);\n                const editOffset = model.offsetAt(Range.lift(range).getStartPosition());\n                for (const change of changes) {\n                    const start = model.positionAt(editOffset + change.originalStart);\n                    const end = model.positionAt(editOffset + change.originalStart + change.originalLength);\n                    const newEdit = {\n                        text: text.substr(change.modifiedStart, change.modifiedLength),\n                        range: { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column }\n                    };\n                    if (model.getValueInRange(newEdit.range) !== newEdit.text) {\n                        result.push(newEdit);\n                    }\n                }\n            }\n            if (typeof lastEol === 'number') {\n                result.push({ eol: lastEol, text: '', range: { startLineNumber: 0, startColumn: 0, endLineNumber: 0, endColumn: 0 } });\n            }\n            return result;\n        });\n    }\n    // ---- END minimal edits ---------------------------------------------------------------\n    computeLinks(modelUrl) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const model = this._getModel(modelUrl);\n            if (!model) {\n                return null;\n            }\n            return computeLinks(model);\n        });\n    }\n    // --- BEGIN default document colors -----------------------------------------------------------\n    computeDefaultDocumentColors(modelUrl) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const model = this._getModel(modelUrl);\n            if (!model) {\n                return null;\n            }\n            return computeDefaultDocumentColors(model);\n        });\n    }\n    textualSuggest(modelUrls, leadingWord, wordDef, wordDefFlags) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const sw = new StopWatch();\n            const wordDefRegExp = new RegExp(wordDef, wordDefFlags);\n            const seen = new Set();\n            outer: for (const url of modelUrls) {\n                const model = this._getModel(url);\n                if (!model) {\n                    continue;\n                }\n                for (const word of model.words(wordDefRegExp)) {\n                    if (word === leadingWord || !isNaN(Number(word))) {\n                        continue;\n                    }\n                    seen.add(word);\n                    if (seen.size > EditorSimpleWorker._suggestionsLimit) {\n                        break outer;\n                    }\n                }\n            }\n            return { words: Array.from(seen), duration: sw.elapsed() };\n        });\n    }\n    // ---- END suggest --------------------------------------------------------------------------\n    //#region -- word ranges --\n    computeWordRanges(modelUrl, range, wordDef, wordDefFlags) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const model = this._getModel(modelUrl);\n            if (!model) {\n                return Object.create(null);\n            }\n            const wordDefRegExp = new RegExp(wordDef, wordDefFlags);\n            const result = Object.create(null);\n            for (let line = range.startLineNumber; line < range.endLineNumber; line++) {\n                const words = model.getLineWords(line, wordDefRegExp);\n                for (const word of words) {\n                    if (!isNaN(Number(word.word))) {\n                        continue;\n                    }\n                    let array = result[word.word];\n                    if (!array) {\n                        array = [];\n                        result[word.word] = array;\n                    }\n                    array.push({\n                        startLineNumber: line,\n                        startColumn: word.startColumn,\n                        endLineNumber: line,\n                        endColumn: word.endColumn\n                    });\n                }\n            }\n            return result;\n        });\n    }\n    //#endregion\n    navigateValueSet(modelUrl, range, up, wordDef, wordDefFlags) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const model = this._getModel(modelUrl);\n            if (!model) {\n                return null;\n            }\n            const wordDefRegExp = new RegExp(wordDef, wordDefFlags);\n            if (range.startColumn === range.endColumn) {\n                range = {\n                    startLineNumber: range.startLineNumber,\n                    startColumn: range.startColumn,\n                    endLineNumber: range.endLineNumber,\n                    endColumn: range.endColumn + 1\n                };\n            }\n            const selectionText = model.getValueInRange(range);\n            const wordRange = model.getWordAtPosition({ lineNumber: range.startLineNumber, column: range.startColumn }, wordDefRegExp);\n            if (!wordRange) {\n                return null;\n            }\n            const word = model.getValueInRange(wordRange);\n            const result = BasicInplaceReplace.INSTANCE.navigateValueSet(range, selectionText, wordRange, word, up);\n            return result;\n        });\n    }\n    // ---- BEGIN foreign module support --------------------------------------------------------------------------\n    loadForeignModule(moduleId, createData, foreignHostMethods) {\n        const proxyMethodRequest = (method, args) => {\n            return this._host.fhr(method, args);\n        };\n        const foreignHost = createProxyObject(foreignHostMethods, proxyMethodRequest);\n        const ctx = {\n            host: foreignHost,\n            getMirrorModels: () => {\n                return this._getModels();\n            }\n        };\n        if (this._foreignModuleFactory) {\n            this._foreignModule = this._foreignModuleFactory(ctx, createData);\n            // static foreing module\n            return Promise.resolve(getAllMethodNames(this._foreignModule));\n        }\n        // ESM-comment-begin\n        // \t\treturn new Promise((resolve, reject) => {\n        // \t\t\trequire([moduleId], (foreignModule: { create: IForeignModuleFactory }) => {\n        // \t\t\t\tthis._foreignModule = foreignModule.create(ctx, createData);\n        // \n        // \t\t\t\tresolve(getAllMethodNames(this._foreignModule));\n        // \n        // \t\t\t}, reject);\n        // \t\t});\n        // ESM-comment-end\n        // ESM-uncomment-begin\n        return Promise.reject(new Error(`Unexpected usage`));\n        // ESM-uncomment-end\n    }\n    // foreign method request\n    fmr(method, args) {\n        if (!this._foreignModule || typeof this._foreignModule[method] !== 'function') {\n            return Promise.reject(new Error('Missing requestHandler or method: ' + method));\n        }\n        try {\n            return Promise.resolve(this._foreignModule[method].apply(this._foreignModule, args));\n        }\n        catch (e) {\n            return Promise.reject(e);\n        }\n    }\n}\n// ---- END diff --------------------------------------------------------------------------\n// ---- BEGIN minimal edits ---------------------------------------------------------------\nEditorSimpleWorker._diffLimit = 100000;\n// ---- BEGIN suggest --------------------------------------------------------------------------\nEditorSimpleWorker._suggestionsLimit = 10000;\n/**\n * Called on the worker side\n * @internal\n */\nexport function create(host) {\n    return new EditorSimpleWorker(host, null);\n}\nif (typeof importScripts === 'function') {\n    // Running in a web worker\n    globalThis.monaco = createMonacoBaseAPI();\n}\n","import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';\nexport const ITextResourceConfigurationService = createDecorator('textResourceConfigurationService');\nexport const ITextResourcePropertiesService = createDecorator('textResourcePropertiesService');\n","import { Emitter } from '../../../base/common/event.js';\nimport { Disposable } from '../../../base/common/lifecycle.js';\nimport { RawContextKey } from '../../contextkey/common/contextkey.js';\nimport { createDecorator } from '../../instantiation/common/instantiation.js';\nexport const ILogService = createDecorator('logService');\nexport var LogLevel;\n(function (LogLevel) {\n    LogLevel[LogLevel[\"Off\"] = 0] = \"Off\";\n    LogLevel[LogLevel[\"Trace\"] = 1] = \"Trace\";\n    LogLevel[LogLevel[\"Debug\"] = 2] = \"Debug\";\n    LogLevel[LogLevel[\"Info\"] = 3] = \"Info\";\n    LogLevel[LogLevel[\"Warning\"] = 4] = \"Warning\";\n    LogLevel[LogLevel[\"Error\"] = 5] = \"Error\";\n})(LogLevel || (LogLevel = {}));\nexport const DEFAULT_LOG_LEVEL = LogLevel.Info;\nexport class AbstractLogger extends Disposable {\n    constructor() {\n        super(...arguments);\n        this.level = DEFAULT_LOG_LEVEL;\n        this._onDidChangeLogLevel = this._register(new Emitter());\n        this.onDidChangeLogLevel = this._onDidChangeLogLevel.event;\n    }\n    setLevel(level) {\n        if (this.level !== level) {\n            this.level = level;\n            this._onDidChangeLogLevel.fire(this.level);\n        }\n    }\n    getLevel() {\n        return this.level;\n    }\n    checkLogLevel(level) {\n        return this.level !== LogLevel.Off && this.level <= level;\n    }\n}\nexport class ConsoleLogger extends AbstractLogger {\n    constructor(logLevel = DEFAULT_LOG_LEVEL, useColors = true) {\n        super();\n        this.useColors = useColors;\n        this.setLevel(logLevel);\n    }\n    trace(message, ...args) {\n        if (this.checkLogLevel(LogLevel.Trace)) {\n            if (this.useColors) {\n                console.log('%cTRACE', 'color: #888', message, ...args);\n            }\n            else {\n                console.log(message, ...args);\n            }\n        }\n    }\n    debug(message, ...args) {\n        if (this.checkLogLevel(LogLevel.Debug)) {\n            if (this.useColors) {\n                console.log('%cDEBUG', 'background: #eee; color: #888', message, ...args);\n            }\n            else {\n                console.log(message, ...args);\n            }\n        }\n    }\n    info(message, ...args) {\n        if (this.checkLogLevel(LogLevel.Info)) {\n            if (this.useColors) {\n                console.log('%c INFO', 'color: #33f', message, ...args);\n            }\n            else {\n                console.log(message, ...args);\n            }\n        }\n    }\n    warn(message, ...args) {\n        if (this.checkLogLevel(LogLevel.Warning)) {\n            if (this.useColors) {\n                console.log('%c WARN', 'color: #993', message, ...args);\n            }\n            else {\n                console.log(message, ...args);\n            }\n        }\n    }\n    error(message, ...args) {\n        if (this.checkLogLevel(LogLevel.Error)) {\n            if (this.useColors) {\n                console.log('%c  ERR', 'color: #f33', message, ...args);\n            }\n            else {\n                console.error(message, ...args);\n            }\n        }\n    }\n    dispose() {\n        // noop\n    }\n}\nexport class MultiplexLogger extends AbstractLogger {\n    constructor(loggers) {\n        super();\n        this.loggers = loggers;\n        if (loggers.length) {\n            this.setLevel(loggers[0].getLevel());\n        }\n    }\n    setLevel(level) {\n        for (const logger of this.loggers) {\n            logger.setLevel(level);\n        }\n        super.setLevel(level);\n    }\n    trace(message, ...args) {\n        for (const logger of this.loggers) {\n            logger.trace(message, ...args);\n        }\n    }\n    debug(message, ...args) {\n        for (const logger of this.loggers) {\n            logger.debug(message, ...args);\n        }\n    }\n    info(message, ...args) {\n        for (const logger of this.loggers) {\n            logger.info(message, ...args);\n        }\n    }\n    warn(message, ...args) {\n        for (const logger of this.loggers) {\n            logger.warn(message, ...args);\n        }\n    }\n    error(message, ...args) {\n        for (const logger of this.loggers) {\n            logger.error(message, ...args);\n        }\n    }\n    dispose() {\n        for (const logger of this.loggers) {\n            logger.dispose();\n        }\n    }\n}\nexport function LogLevelToString(logLevel) {\n    switch (logLevel) {\n        case LogLevel.Trace: return 'trace';\n        case LogLevel.Debug: return 'debug';\n        case LogLevel.Info: return 'info';\n        case LogLevel.Warning: return 'warn';\n        case LogLevel.Error: return 'error';\n        case LogLevel.Off: return 'off';\n    }\n}\n// Contexts\nexport const CONTEXT_LOG_LEVEL = new RawContextKey('logLevel', LogLevelToString(LogLevel.Info));\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { createDecorator } from '../../../platform/instantiation/common/instantiation.js';\nexport const ILanguageFeaturesService = createDecorator('ILanguageFeaturesService');\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\n};\nvar __param = (this && this.__param) || function (paramIndex, decorator) {\n    return function (target, key) { decorator(target, key, paramIndex); }\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nimport { IntervalTimer, timeout } from '../../../base/common/async.js';\nimport { Disposable, dispose, toDisposable, DisposableStore } from '../../../base/common/lifecycle.js';\nimport { SimpleWorkerClient, logOnceWebWorkerWarning } from '../../../base/common/worker/simpleWorker.js';\nimport { DefaultWorkerFactory } from '../../../base/browser/defaultWorkerFactory.js';\nimport { Range } from '../../common/core/range.js';\nimport { ILanguageConfigurationService } from '../../common/languages/languageConfigurationRegistry.js';\nimport { EditorSimpleWorker } from '../../common/services/editorSimpleWorker.js';\nimport { IModelService } from '../../common/services/model.js';\nimport { ITextResourceConfigurationService } from '../../common/services/textResourceConfiguration.js';\nimport { regExpFlags } from '../../../base/common/strings.js';\nimport { isNonEmptyArray } from '../../../base/common/arrays.js';\nimport { ILogService } from '../../../platform/log/common/log.js';\nimport { StopWatch } from '../../../base/common/stopwatch.js';\nimport { canceled } from '../../../base/common/errors.js';\nimport { ILanguageFeaturesService } from '../../common/services/languageFeatures.js';\nimport { LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from '../../common/diff/linesDiffComputer.js';\nimport { LineRange } from '../../common/core/lineRange.js';\n/**\n * Stop syncing a model to the worker if it was not needed for 1 min.\n */\nconst STOP_SYNC_MODEL_DELTA_TIME_MS = 60 * 1000;\n/**\n * Stop the worker if it was not needed for 5 min.\n */\nconst STOP_WORKER_DELTA_TIME_MS = 5 * 60 * 1000;\nfunction canSyncModel(modelService, resource) {\n    const model = modelService.getModel(resource);\n    if (!model) {\n        return false;\n    }\n    if (model.isTooLargeForSyncing()) {\n        return false;\n    }\n    return true;\n}\nexport let EditorWorkerService = class EditorWorkerService extends Disposable {\n    constructor(modelService, configurationService, logService, languageConfigurationService, languageFeaturesService) {\n        super();\n        this._modelService = modelService;\n        this._workerManager = this._register(new WorkerManager(this._modelService, languageConfigurationService));\n        this._logService = logService;\n        // register default link-provider and default completions-provider\n        this._register(languageFeaturesService.linkProvider.register({ language: '*', hasAccessToAllModels: true }, {\n            provideLinks: (model, token) => {\n                if (!canSyncModel(this._modelService, model.uri)) {\n                    return Promise.resolve({ links: [] }); // File too large\n                }\n                return this._workerManager.withWorker().then(client => client.computeLinks(model.uri)).then(links => {\n                    return links && { links };\n                });\n            }\n        }));\n        this._register(languageFeaturesService.completionProvider.register('*', new WordBasedCompletionItemProvider(this._workerManager, configurationService, this._modelService, languageConfigurationService)));\n    }\n    dispose() {\n        super.dispose();\n    }\n    canComputeUnicodeHighlights(uri) {\n        return canSyncModel(this._modelService, uri);\n    }\n    computedUnicodeHighlights(uri, options, range) {\n        return this._workerManager.withWorker().then(client => client.computedUnicodeHighlights(uri, options, range));\n    }\n    computeDiff(original, modified, options, algorithm) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const result = yield this._workerManager.withWorker().then(client => client.computeDiff(original, modified, options, algorithm));\n            if (!result) {\n                return null;\n            }\n            // Convert from space efficient JSON data to rich objects.\n            const diff = {\n                identical: result.identical,\n                quitEarly: result.quitEarly,\n                changes: toLineRangeMappings(result.changes),\n                moves: result.moves.map(m => new MovedText(new SimpleLineRangeMapping(new LineRange(m[0], m[1]), new LineRange(m[2], m[3])), toLineRangeMappings(m[4])))\n            };\n            return diff;\n            function toLineRangeMappings(changes) {\n                return changes.map((c) => {\n                    var _a;\n                    return new LineRangeMapping(new LineRange(c[0], c[1]), new LineRange(c[2], c[3]), (_a = c[4]) === null || _a === void 0 ? void 0 : _a.map((c) => new RangeMapping(new Range(c[0], c[1], c[2], c[3]), new Range(c[4], c[5], c[6], c[7]))));\n                });\n            }\n        });\n    }\n    computeMoreMinimalEdits(resource, edits, pretty = false) {\n        if (isNonEmptyArray(edits)) {\n            if (!canSyncModel(this._modelService, resource)) {\n                return Promise.resolve(edits); // File too large\n            }\n            const sw = StopWatch.create();\n            const result = this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits, pretty));\n            result.finally(() => this._logService.trace('FORMAT#computeMoreMinimalEdits', resource.toString(true), sw.elapsed()));\n            return Promise.race([result, timeout(1000).then(() => edits)]);\n        }\n        else {\n            return Promise.resolve(undefined);\n        }\n    }\n    canNavigateValueSet(resource) {\n        return (canSyncModel(this._modelService, resource));\n    }\n    navigateValueSet(resource, range, up) {\n        return this._workerManager.withWorker().then(client => client.navigateValueSet(resource, range, up));\n    }\n    canComputeWordRanges(resource) {\n        return canSyncModel(this._modelService, resource);\n    }\n    computeWordRanges(resource, range) {\n        return this._workerManager.withWorker().then(client => client.computeWordRanges(resource, range));\n    }\n};\nEditorWorkerService = __decorate([\n    __param(0, IModelService),\n    __param(1, ITextResourceConfigurationService),\n    __param(2, ILogService),\n    __param(3, ILanguageConfigurationService),\n    __param(4, ILanguageFeaturesService)\n], EditorWorkerService);\nclass WordBasedCompletionItemProvider {\n    constructor(workerManager, configurationService, modelService, languageConfigurationService) {\n        this.languageConfigurationService = languageConfigurationService;\n        this._debugDisplayName = 'wordbasedCompletions';\n        this._workerManager = workerManager;\n        this._configurationService = configurationService;\n        this._modelService = modelService;\n    }\n    provideCompletionItems(model, position) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const config = this._configurationService.getValue(model.uri, position, 'editor');\n            if (!config.wordBasedSuggestions) {\n                return undefined;\n            }\n            const models = [];\n            if (config.wordBasedSuggestionsMode === 'currentDocument') {\n                // only current file and only if not too large\n                if (canSyncModel(this._modelService, model.uri)) {\n                    models.push(model.uri);\n                }\n            }\n            else {\n                // either all files or files of same language\n                for (const candidate of this._modelService.getModels()) {\n                    if (!canSyncModel(this._modelService, candidate.uri)) {\n                        continue;\n                    }\n                    if (candidate === model) {\n                        models.unshift(candidate.uri);\n                    }\n                    else if (config.wordBasedSuggestionsMode === 'allDocuments' || candidate.getLanguageId() === model.getLanguageId()) {\n                        models.push(candidate.uri);\n                    }\n                }\n            }\n            if (models.length === 0) {\n                return undefined; // File too large, no other files\n            }\n            const wordDefRegExp = this.languageConfigurationService.getLanguageConfiguration(model.getLanguageId()).getWordDefinition();\n            const word = model.getWordAtPosition(position);\n            const replace = !word ? Range.fromPositions(position) : new Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);\n            const insert = replace.setEndPosition(position.lineNumber, position.column);\n            const client = yield this._workerManager.withWorker();\n            const data = yield client.textualSuggest(models, word === null || word === void 0 ? void 0 : word.word, wordDefRegExp);\n            if (!data) {\n                return undefined;\n            }\n            return {\n                duration: data.duration,\n                suggestions: data.words.map((word) => {\n                    return {\n                        kind: 18 /* languages.CompletionItemKind.Text */,\n                        label: word,\n                        insertText: word,\n                        range: { insert, replace }\n                    };\n                }),\n            };\n        });\n    }\n}\nclass WorkerManager extends Disposable {\n    constructor(modelService, languageConfigurationService) {\n        super();\n        this.languageConfigurationService = languageConfigurationService;\n        this._modelService = modelService;\n        this._editorWorkerClient = null;\n        this._lastWorkerUsedTime = (new Date()).getTime();\n        const stopWorkerInterval = this._register(new IntervalTimer());\n        stopWorkerInterval.cancelAndSet(() => this._checkStopIdleWorker(), Math.round(STOP_WORKER_DELTA_TIME_MS / 2));\n        this._register(this._modelService.onModelRemoved(_ => this._checkStopEmptyWorker()));\n    }\n    dispose() {\n        if (this._editorWorkerClient) {\n            this._editorWorkerClient.dispose();\n            this._editorWorkerClient = null;\n        }\n        super.dispose();\n    }\n    /**\n     * Check if the model service has no more models and stop the worker if that is the case.\n     */\n    _checkStopEmptyWorker() {\n        if (!this._editorWorkerClient) {\n            return;\n        }\n        const models = this._modelService.getModels();\n        if (models.length === 0) {\n            // There are no more models => nothing possible for me to do\n            this._editorWorkerClient.dispose();\n            this._editorWorkerClient = null;\n        }\n    }\n    /**\n     * Check if the worker has been idle for a while and then stop it.\n     */\n    _checkStopIdleWorker() {\n        if (!this._editorWorkerClient) {\n            return;\n        }\n        const timeSinceLastWorkerUsedTime = (new Date()).getTime() - this._lastWorkerUsedTime;\n        if (timeSinceLastWorkerUsedTime > STOP_WORKER_DELTA_TIME_MS) {\n            this._editorWorkerClient.dispose();\n            this._editorWorkerClient = null;\n        }\n    }\n    withWorker() {\n        this._lastWorkerUsedTime = (new Date()).getTime();\n        if (!this._editorWorkerClient) {\n            this._editorWorkerClient = new EditorWorkerClient(this._modelService, false, 'editorWorkerService', this.languageConfigurationService);\n        }\n        return Promise.resolve(this._editorWorkerClient);\n    }\n}\nclass EditorModelManager extends Disposable {\n    constructor(proxy, modelService, keepIdleModels) {\n        super();\n        this._syncedModels = Object.create(null);\n        this._syncedModelsLastUsedTime = Object.create(null);\n        this._proxy = proxy;\n        this._modelService = modelService;\n        if (!keepIdleModels) {\n            const timer = new IntervalTimer();\n            timer.cancelAndSet(() => this._checkStopModelSync(), Math.round(STOP_SYNC_MODEL_DELTA_TIME_MS / 2));\n            this._register(timer);\n        }\n    }\n    dispose() {\n        for (const modelUrl in this._syncedModels) {\n            dispose(this._syncedModels[modelUrl]);\n        }\n        this._syncedModels = Object.create(null);\n        this._syncedModelsLastUsedTime = Object.create(null);\n        super.dispose();\n    }\n    ensureSyncedResources(resources, forceLargeModels) {\n        for (const resource of resources) {\n            const resourceStr = resource.toString();\n            if (!this._syncedModels[resourceStr]) {\n                this._beginModelSync(resource, forceLargeModels);\n            }\n            if (this._syncedModels[resourceStr]) {\n                this._syncedModelsLastUsedTime[resourceStr] = (new Date()).getTime();\n            }\n        }\n    }\n    _checkStopModelSync() {\n        const currentTime = (new Date()).getTime();\n        const toRemove = [];\n        for (const modelUrl in this._syncedModelsLastUsedTime) {\n            const elapsedTime = currentTime - this._syncedModelsLastUsedTime[modelUrl];\n            if (elapsedTime > STOP_SYNC_MODEL_DELTA_TIME_MS) {\n                toRemove.push(modelUrl);\n            }\n        }\n        for (const e of toRemove) {\n            this._stopModelSync(e);\n        }\n    }\n    _beginModelSync(resource, forceLargeModels) {\n        const model = this._modelService.getModel(resource);\n        if (!model) {\n            return;\n        }\n        if (!forceLargeModels && model.isTooLargeForSyncing()) {\n            return;\n        }\n        const modelUrl = resource.toString();\n        this._proxy.acceptNewModel({\n            url: model.uri.toString(),\n            lines: model.getLinesContent(),\n            EOL: model.getEOL(),\n            versionId: model.getVersionId()\n        });\n        const toDispose = new DisposableStore();\n        toDispose.add(model.onDidChangeContent((e) => {\n            this._proxy.acceptModelChanged(modelUrl.toString(), e);\n        }));\n        toDispose.add(model.onWillDispose(() => {\n            this._stopModelSync(modelUrl);\n        }));\n        toDispose.add(toDisposable(() => {\n            this._proxy.acceptRemovedModel(modelUrl);\n        }));\n        this._syncedModels[modelUrl] = toDispose;\n    }\n    _stopModelSync(modelUrl) {\n        const toDispose = this._syncedModels[modelUrl];\n        delete this._syncedModels[modelUrl];\n        delete this._syncedModelsLastUsedTime[modelUrl];\n        dispose(toDispose);\n    }\n}\nclass SynchronousWorkerClient {\n    constructor(instance) {\n        this._instance = instance;\n        this._proxyObj = Promise.resolve(this._instance);\n    }\n    dispose() {\n        this._instance.dispose();\n    }\n    getProxyObject() {\n        return this._proxyObj;\n    }\n}\nexport class EditorWorkerHost {\n    constructor(workerClient) {\n        this._workerClient = workerClient;\n    }\n    // foreign host request\n    fhr(method, args) {\n        return this._workerClient.fhr(method, args);\n    }\n}\nexport class EditorWorkerClient extends Disposable {\n    constructor(modelService, keepIdleModels, label, languageConfigurationService) {\n        super();\n        this.languageConfigurationService = languageConfigurationService;\n        this._disposed = false;\n        this._modelService = modelService;\n        this._keepIdleModels = keepIdleModels;\n        this._workerFactory = new DefaultWorkerFactory(label);\n        this._worker = null;\n        this._modelManager = null;\n    }\n    // foreign host request\n    fhr(method, args) {\n        throw new Error(`Not implemented!`);\n    }\n    _getOrCreateWorker() {\n        if (!this._worker) {\n            try {\n                this._worker = this._register(new SimpleWorkerClient(this._workerFactory, 'vs/editor/common/services/editorSimpleWorker', new EditorWorkerHost(this)));\n            }\n            catch (err) {\n                logOnceWebWorkerWarning(err);\n                this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null));\n            }\n        }\n        return this._worker;\n    }\n    _getProxy() {\n        return this._getOrCreateWorker().getProxyObject().then(undefined, (err) => {\n            logOnceWebWorkerWarning(err);\n            this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null));\n            return this._getOrCreateWorker().getProxyObject();\n        });\n    }\n    _getOrCreateModelManager(proxy) {\n        if (!this._modelManager) {\n            this._modelManager = this._register(new EditorModelManager(proxy, this._modelService, this._keepIdleModels));\n        }\n        return this._modelManager;\n    }\n    _withSyncedResources(resources, forceLargeModels = false) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (this._disposed) {\n                return Promise.reject(canceled());\n            }\n            return this._getProxy().then((proxy) => {\n                this._getOrCreateModelManager(proxy).ensureSyncedResources(resources, forceLargeModels);\n                return proxy;\n            });\n        });\n    }\n    computedUnicodeHighlights(uri, options, range) {\n        return this._withSyncedResources([uri]).then(proxy => {\n            return proxy.computeUnicodeHighlights(uri.toString(), options, range);\n        });\n    }\n    computeDiff(original, modified, options, algorithm) {\n        return this._withSyncedResources([original, modified], /* forceLargeModels */ true).then(proxy => {\n            return proxy.computeDiff(original.toString(), modified.toString(), options, algorithm);\n        });\n    }\n    computeMoreMinimalEdits(resource, edits, pretty) {\n        return this._withSyncedResources([resource]).then(proxy => {\n            return proxy.computeMoreMinimalEdits(resource.toString(), edits, pretty);\n        });\n    }\n    computeLinks(resource) {\n        return this._withSyncedResources([resource]).then(proxy => {\n            return proxy.computeLinks(resource.toString());\n        });\n    }\n    computeDefaultDocumentColors(resource) {\n        return this._withSyncedResources([resource]).then(proxy => {\n            return proxy.computeDefaultDocumentColors(resource.toString());\n        });\n    }\n    textualSuggest(resources, leadingWord, wordDefRegExp) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const proxy = yield this._withSyncedResources(resources);\n            const wordDef = wordDefRegExp.source;\n            const wordDefFlags = regExpFlags(wordDefRegExp);\n            return proxy.textualSuggest(resources.map(r => r.toString()), leadingWord, wordDef, wordDefFlags);\n        });\n    }\n    computeWordRanges(resource, range) {\n        return this._withSyncedResources([resource]).then(proxy => {\n            const model = this._modelService.getModel(resource);\n            if (!model) {\n                return Promise.resolve(null);\n            }\n            const wordDefRegExp = this.languageConfigurationService.getLanguageConfiguration(model.getLanguageId()).getWordDefinition();\n            const wordDef = wordDefRegExp.source;\n            const wordDefFlags = regExpFlags(wordDefRegExp);\n            return proxy.computeWordRanges(resource.toString(), range, wordDef, wordDefFlags);\n        });\n    }\n    navigateValueSet(resource, range, up) {\n        return this._withSyncedResources([resource]).then(proxy => {\n            const model = this._modelService.getModel(resource);\n            if (!model) {\n                return null;\n            }\n            const wordDefRegExp = this.languageConfigurationService.getLanguageConfiguration(model.getLanguageId()).getWordDefinition();\n            const wordDef = wordDefRegExp.source;\n            const wordDefFlags = regExpFlags(wordDefRegExp);\n            return proxy.navigateValueSet(resource.toString(), range, up, wordDef, wordDefFlags);\n        });\n    }\n    dispose() {\n        super.dispose();\n        this._disposed = true;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { getAllMethodNames } from '../../../base/common/objects.js';\nimport { EditorWorkerClient } from './editorWorkerService.js';\n/**\n * Create a new web worker that has model syncing capabilities built in.\n * Specify an AMD module to load that will `create` an object that will be proxied.\n */\nexport function createWebWorker(modelService, languageConfigurationService, opts) {\n    return new MonacoWebWorkerImpl(modelService, languageConfigurationService, opts);\n}\nclass MonacoWebWorkerImpl extends EditorWorkerClient {\n    constructor(modelService, languageConfigurationService, opts) {\n        super(modelService, opts.keepIdleModels || false, opts.label, languageConfigurationService);\n        this._foreignModuleId = opts.moduleId;\n        this._foreignModuleCreateData = opts.createData || null;\n        this._foreignModuleHost = opts.host || null;\n        this._foreignProxy = null;\n    }\n    // foreign host request\n    fhr(method, args) {\n        if (!this._foreignModuleHost || typeof this._foreignModuleHost[method] !== 'function') {\n            return Promise.reject(new Error('Missing method ' + method + ' or missing main thread foreign host.'));\n        }\n        try {\n            return Promise.resolve(this._foreignModuleHost[method].apply(this._foreignModuleHost, args));\n        }\n        catch (e) {\n            return Promise.reject(e);\n        }\n    }\n    _getForeignProxy() {\n        if (!this._foreignProxy) {\n            this._foreignProxy = this._getProxy().then((proxy) => {\n                const foreignHostMethods = this._foreignModuleHost ? getAllMethodNames(this._foreignModuleHost) : [];\n                return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData, foreignHostMethods).then((foreignMethods) => {\n                    this._foreignModuleCreateData = null;\n                    const proxyMethodRequest = (method, args) => {\n                        return proxy.fmr(method, args);\n                    };\n                    const createProxyMethod = (method, proxyMethodRequest) => {\n                        return function () {\n                            const args = Array.prototype.slice.call(arguments, 0);\n                            return proxyMethodRequest(method, args);\n                        };\n                    };\n                    const foreignProxy = {};\n                    for (const foreignMethod of foreignMethods) {\n                        foreignProxy[foreignMethod] = createProxyMethod(foreignMethod, proxyMethodRequest);\n                    }\n                    return foreignProxy;\n                });\n            });\n        }\n        return this._foreignProxy;\n    }\n    getProxy() {\n        return this._getForeignProxy();\n    }\n    withSyncedResources(resources) {\n        return this._withSyncedResources(resources).then(_ => this.getProxy());\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n */\nexport class TokenMetadata {\n    static getLanguageId(metadata) {\n        return (metadata & 255 /* MetadataConsts.LANGUAGEID_MASK */) >>> 0 /* MetadataConsts.LANGUAGEID_OFFSET */;\n    }\n    static getTokenType(metadata) {\n        return (metadata & 768 /* MetadataConsts.TOKEN_TYPE_MASK */) >>> 8 /* MetadataConsts.TOKEN_TYPE_OFFSET */;\n    }\n    static containsBalancedBrackets(metadata) {\n        return (metadata & 1024 /* MetadataConsts.BALANCED_BRACKETS_MASK */) !== 0;\n    }\n    static getFontStyle(metadata) {\n        return (metadata & 30720 /* MetadataConsts.FONT_STYLE_MASK */) >>> 11 /* MetadataConsts.FONT_STYLE_OFFSET */;\n    }\n    static getForeground(metadata) {\n        return (metadata & 16744448 /* MetadataConsts.FOREGROUND_MASK */) >>> 15 /* MetadataConsts.FOREGROUND_OFFSET */;\n    }\n    static getBackground(metadata) {\n        return (metadata & 4278190080 /* MetadataConsts.BACKGROUND_MASK */) >>> 24 /* MetadataConsts.BACKGROUND_OFFSET */;\n    }\n    static getClassNameFromMetadata(metadata) {\n        const foreground = this.getForeground(metadata);\n        let className = 'mtk' + foreground;\n        const fontStyle = this.getFontStyle(metadata);\n        if (fontStyle & 1 /* FontStyle.Italic */) {\n            className += ' mtki';\n        }\n        if (fontStyle & 2 /* FontStyle.Bold */) {\n            className += ' mtkb';\n        }\n        if (fontStyle & 4 /* FontStyle.Underline */) {\n            className += ' mtku';\n        }\n        if (fontStyle & 8 /* FontStyle.Strikethrough */) {\n            className += ' mtks';\n        }\n        return className;\n    }\n    static getInlineStyleFromMetadata(metadata, colorMap) {\n        const foreground = this.getForeground(metadata);\n        const fontStyle = this.getFontStyle(metadata);\n        let result = `color: ${colorMap[foreground]};`;\n        if (fontStyle & 1 /* FontStyle.Italic */) {\n            result += 'font-style: italic;';\n        }\n        if (fontStyle & 2 /* FontStyle.Bold */) {\n            result += 'font-weight: bold;';\n        }\n        let textDecoration = '';\n        if (fontStyle & 4 /* FontStyle.Underline */) {\n            textDecoration += ' underline';\n        }\n        if (fontStyle & 8 /* FontStyle.Strikethrough */) {\n            textDecoration += ' line-through';\n        }\n        if (textDecoration) {\n            result += `text-decoration:${textDecoration};`;\n        }\n        return result;\n    }\n    static getPresentationFromMetadata(metadata) {\n        const foreground = this.getForeground(metadata);\n        const fontStyle = this.getFontStyle(metadata);\n        return {\n            foreground: foreground,\n            italic: Boolean(fontStyle & 1 /* FontStyle.Italic */),\n            bold: Boolean(fontStyle & 2 /* FontStyle.Bold */),\n            underline: Boolean(fontStyle & 4 /* FontStyle.Underline */),\n            strikethrough: Boolean(fontStyle & 8 /* FontStyle.Strikethrough */),\n        };\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { TokenMetadata } from '../encodedTokenAttributes.js';\nexport class LineTokens {\n    static createEmpty(lineContent, decoder) {\n        const defaultMetadata = LineTokens.defaultTokenMetadata;\n        const tokens = new Uint32Array(2);\n        tokens[0] = lineContent.length;\n        tokens[1] = defaultMetadata;\n        return new LineTokens(tokens, lineContent, decoder);\n    }\n    constructor(tokens, text, decoder) {\n        this._lineTokensBrand = undefined;\n        this._tokens = tokens;\n        this._tokensCount = (this._tokens.length >>> 1);\n        this._text = text;\n        this._languageIdCodec = decoder;\n    }\n    equals(other) {\n        if (other instanceof LineTokens) {\n            return this.slicedEquals(other, 0, this._tokensCount);\n        }\n        return false;\n    }\n    slicedEquals(other, sliceFromTokenIndex, sliceTokenCount) {\n        if (this._text !== other._text) {\n            return false;\n        }\n        if (this._tokensCount !== other._tokensCount) {\n            return false;\n        }\n        const from = (sliceFromTokenIndex << 1);\n        const to = from + (sliceTokenCount << 1);\n        for (let i = from; i < to; i++) {\n            if (this._tokens[i] !== other._tokens[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n    getLineContent() {\n        return this._text;\n    }\n    getCount() {\n        return this._tokensCount;\n    }\n    getStartOffset(tokenIndex) {\n        if (tokenIndex > 0) {\n            return this._tokens[(tokenIndex - 1) << 1];\n        }\n        return 0;\n    }\n    getMetadata(tokenIndex) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        return metadata;\n    }\n    getLanguageId(tokenIndex) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        const languageId = TokenMetadata.getLanguageId(metadata);\n        return this._languageIdCodec.decodeLanguageId(languageId);\n    }\n    getStandardTokenType(tokenIndex) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        return TokenMetadata.getTokenType(metadata);\n    }\n    getForeground(tokenIndex) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        return TokenMetadata.getForeground(metadata);\n    }\n    getClassName(tokenIndex) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        return TokenMetadata.getClassNameFromMetadata(metadata);\n    }\n    getInlineStyle(tokenIndex, colorMap) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        return TokenMetadata.getInlineStyleFromMetadata(metadata, colorMap);\n    }\n    getPresentation(tokenIndex) {\n        const metadata = this._tokens[(tokenIndex << 1) + 1];\n        return TokenMetadata.getPresentationFromMetadata(metadata);\n    }\n    getEndOffset(tokenIndex) {\n        return this._tokens[tokenIndex << 1];\n    }\n    /**\n     * Find the token containing offset `offset`.\n     * @param offset The search offset\n     * @return The index of the token containing the offset.\n     */\n    findTokenIndexAtOffset(offset) {\n        return LineTokens.findIndexInTokensArray(this._tokens, offset);\n    }\n    inflate() {\n        return this;\n    }\n    sliceAndInflate(startOffset, endOffset, deltaOffset) {\n        return new SliceLineTokens(this, startOffset, endOffset, deltaOffset);\n    }\n    static convertToEndOffset(tokens, lineTextLength) {\n        const tokenCount = (tokens.length >>> 1);\n        const lastTokenIndex = tokenCount - 1;\n        for (let tokenIndex = 0; tokenIndex < lastTokenIndex; tokenIndex++) {\n            tokens[tokenIndex << 1] = tokens[(tokenIndex + 1) << 1];\n        }\n        tokens[lastTokenIndex << 1] = lineTextLength;\n    }\n    static findIndexInTokensArray(tokens, desiredIndex) {\n        if (tokens.length <= 2) {\n            return 0;\n        }\n        let low = 0;\n        let high = (tokens.length >>> 1) - 1;\n        while (low < high) {\n            const mid = low + Math.floor((high - low) / 2);\n            const endOffset = tokens[(mid << 1)];\n            if (endOffset === desiredIndex) {\n                return mid + 1;\n            }\n            else if (endOffset < desiredIndex) {\n                low = mid + 1;\n            }\n            else if (endOffset > desiredIndex) {\n                high = mid;\n            }\n        }\n        return low;\n    }\n    /**\n     * @pure\n     * @param insertTokens Must be sorted by offset.\n    */\n    withInserted(insertTokens) {\n        if (insertTokens.length === 0) {\n            return this;\n        }\n        let nextOriginalTokenIdx = 0;\n        let nextInsertTokenIdx = 0;\n        let text = '';\n        const newTokens = new Array();\n        let originalEndOffset = 0;\n        while (true) {\n            const nextOriginalTokenEndOffset = nextOriginalTokenIdx < this._tokensCount ? this._tokens[nextOriginalTokenIdx << 1] : -1;\n            const nextInsertToken = nextInsertTokenIdx < insertTokens.length ? insertTokens[nextInsertTokenIdx] : null;\n            if (nextOriginalTokenEndOffset !== -1 && (nextInsertToken === null || nextOriginalTokenEndOffset <= nextInsertToken.offset)) {\n                // original token ends before next insert token\n                text += this._text.substring(originalEndOffset, nextOriginalTokenEndOffset);\n                const metadata = this._tokens[(nextOriginalTokenIdx << 1) + 1];\n                newTokens.push(text.length, metadata);\n                nextOriginalTokenIdx++;\n                originalEndOffset = nextOriginalTokenEndOffset;\n            }\n            else if (nextInsertToken) {\n                if (nextInsertToken.offset > originalEndOffset) {\n                    // insert token is in the middle of the next token.\n                    text += this._text.substring(originalEndOffset, nextInsertToken.offset);\n                    const metadata = this._tokens[(nextOriginalTokenIdx << 1) + 1];\n                    newTokens.push(text.length, metadata);\n                    originalEndOffset = nextInsertToken.offset;\n                }\n                text += nextInsertToken.text;\n                newTokens.push(text.length, nextInsertToken.tokenMetadata);\n                nextInsertTokenIdx++;\n            }\n            else {\n                break;\n            }\n        }\n        return new LineTokens(new Uint32Array(newTokens), text, this._languageIdCodec);\n    }\n}\nLineTokens.defaultTokenMetadata = ((0 /* FontStyle.None */ << 11 /* MetadataConsts.FONT_STYLE_OFFSET */)\n    | (1 /* ColorId.DefaultForeground */ << 15 /* MetadataConsts.FOREGROUND_OFFSET */)\n    | (2 /* ColorId.DefaultBackground */ << 24 /* MetadataConsts.BACKGROUND_OFFSET */)) >>> 0;\nclass SliceLineTokens {\n    constructor(source, startOffset, endOffset, deltaOffset) {\n        this._source = source;\n        this._startOffset = startOffset;\n        this._endOffset = endOffset;\n        this._deltaOffset = deltaOffset;\n        this._firstTokenIndex = source.findTokenIndexAtOffset(startOffset);\n        this._tokensCount = 0;\n        for (let i = this._firstTokenIndex, len = source.getCount(); i < len; i++) {\n            const tokenStartOffset = source.getStartOffset(i);\n            if (tokenStartOffset >= endOffset) {\n                break;\n            }\n            this._tokensCount++;\n        }\n    }\n    getMetadata(tokenIndex) {\n        return this._source.getMetadata(this._firstTokenIndex + tokenIndex);\n    }\n    getLanguageId(tokenIndex) {\n        return this._source.getLanguageId(this._firstTokenIndex + tokenIndex);\n    }\n    getLineContent() {\n        return this._source.getLineContent().substring(this._startOffset, this._endOffset);\n    }\n    equals(other) {\n        if (other instanceof SliceLineTokens) {\n            return (this._startOffset === other._startOffset\n                && this._endOffset === other._endOffset\n                && this._deltaOffset === other._deltaOffset\n                && this._source.slicedEquals(other._source, this._firstTokenIndex, this._tokensCount));\n        }\n        return false;\n    }\n    getCount() {\n        return this._tokensCount;\n    }\n    getForeground(tokenIndex) {\n        return this._source.getForeground(this._firstTokenIndex + tokenIndex);\n    }\n    getEndOffset(tokenIndex) {\n        const tokenEndOffset = this._source.getEndOffset(this._firstTokenIndex + tokenIndex);\n        return Math.min(this._endOffset, tokenEndOffset) - this._startOffset + this._deltaOffset;\n    }\n    getClassName(tokenIndex) {\n        return this._source.getClassName(this._firstTokenIndex + tokenIndex);\n    }\n    getInlineStyle(tokenIndex, colorMap) {\n        return this._source.getInlineStyle(this._firstTokenIndex + tokenIndex, colorMap);\n    }\n    getPresentation(tokenIndex) {\n        return this._source.getPresentation(this._firstTokenIndex + tokenIndex);\n    }\n    findTokenIndexAtOffset(offset) {\n        return this._source.findTokenIndexAtOffset(offset + this._startOffset - this._deltaOffset) - this._firstTokenIndex;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../../base/common/strings.js';\nexport class LineDecoration {\n    constructor(startColumn, endColumn, className, type) {\n        this.startColumn = startColumn;\n        this.endColumn = endColumn;\n        this.className = className;\n        this.type = type;\n        this._lineDecorationBrand = undefined;\n    }\n    static _equals(a, b) {\n        return (a.startColumn === b.startColumn\n            && a.endColumn === b.endColumn\n            && a.className === b.className\n            && a.type === b.type);\n    }\n    static equalsArr(a, b) {\n        const aLen = a.length;\n        const bLen = b.length;\n        if (aLen !== bLen) {\n            return false;\n        }\n        for (let i = 0; i < aLen; i++) {\n            if (!LineDecoration._equals(a[i], b[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n    static extractWrapped(arr, startOffset, endOffset) {\n        if (arr.length === 0) {\n            return arr;\n        }\n        const startColumn = startOffset + 1;\n        const endColumn = endOffset + 1;\n        const lineLength = endOffset - startOffset;\n        const r = [];\n        let rLength = 0;\n        for (const dec of arr) {\n            if (dec.endColumn <= startColumn || dec.startColumn >= endColumn) {\n                continue;\n            }\n            r[rLength++] = new LineDecoration(Math.max(1, dec.startColumn - startColumn + 1), Math.min(lineLength + 1, dec.endColumn - startColumn + 1), dec.className, dec.type);\n        }\n        return r;\n    }\n    static filter(lineDecorations, lineNumber, minLineColumn, maxLineColumn) {\n        if (lineDecorations.length === 0) {\n            return [];\n        }\n        const result = [];\n        let resultLen = 0;\n        for (let i = 0, len = lineDecorations.length; i < len; i++) {\n            const d = lineDecorations[i];\n            const range = d.range;\n            if (range.endLineNumber < lineNumber || range.startLineNumber > lineNumber) {\n                // Ignore decorations that sit outside this line\n                continue;\n            }\n            if (range.isEmpty() && (d.type === 0 /* InlineDecorationType.Regular */ || d.type === 3 /* InlineDecorationType.RegularAffectingLetterSpacing */)) {\n                // Ignore empty range decorations\n                continue;\n            }\n            const startColumn = (range.startLineNumber === lineNumber ? range.startColumn : minLineColumn);\n            const endColumn = (range.endLineNumber === lineNumber ? range.endColumn : maxLineColumn);\n            result[resultLen++] = new LineDecoration(startColumn, endColumn, d.inlineClassName, d.type);\n        }\n        return result;\n    }\n    static _typeCompare(a, b) {\n        const ORDER = [2, 0, 1, 3];\n        return ORDER[a] - ORDER[b];\n    }\n    static compare(a, b) {\n        if (a.startColumn !== b.startColumn) {\n            return a.startColumn - b.startColumn;\n        }\n        if (a.endColumn !== b.endColumn) {\n            return a.endColumn - b.endColumn;\n        }\n        const typeCmp = LineDecoration._typeCompare(a.type, b.type);\n        if (typeCmp !== 0) {\n            return typeCmp;\n        }\n        if (a.className !== b.className) {\n            return a.className < b.className ? -1 : 1;\n        }\n        return 0;\n    }\n}\nexport class DecorationSegment {\n    constructor(startOffset, endOffset, className, metadata) {\n        this.startOffset = startOffset;\n        this.endOffset = endOffset;\n        this.className = className;\n        this.metadata = metadata;\n    }\n}\nclass Stack {\n    constructor() {\n        this.stopOffsets = [];\n        this.classNames = [];\n        this.metadata = [];\n        this.count = 0;\n    }\n    static _metadata(metadata) {\n        let result = 0;\n        for (let i = 0, len = metadata.length; i < len; i++) {\n            result |= metadata[i];\n        }\n        return result;\n    }\n    consumeLowerThan(maxStopOffset, nextStartOffset, result) {\n        while (this.count > 0 && this.stopOffsets[0] < maxStopOffset) {\n            let i = 0;\n            // Take all equal stopping offsets\n            while (i + 1 < this.count && this.stopOffsets[i] === this.stopOffsets[i + 1]) {\n                i++;\n            }\n            // Basically we are consuming the first i + 1 elements of the stack\n            result.push(new DecorationSegment(nextStartOffset, this.stopOffsets[i], this.classNames.join(' '), Stack._metadata(this.metadata)));\n            nextStartOffset = this.stopOffsets[i] + 1;\n            // Consume them\n            this.stopOffsets.splice(0, i + 1);\n            this.classNames.splice(0, i + 1);\n            this.metadata.splice(0, i + 1);\n            this.count -= (i + 1);\n        }\n        if (this.count > 0 && nextStartOffset < maxStopOffset) {\n            result.push(new DecorationSegment(nextStartOffset, maxStopOffset - 1, this.classNames.join(' '), Stack._metadata(this.metadata)));\n            nextStartOffset = maxStopOffset;\n        }\n        return nextStartOffset;\n    }\n    insert(stopOffset, className, metadata) {\n        if (this.count === 0 || this.stopOffsets[this.count - 1] <= stopOffset) {\n            // Insert at the end\n            this.stopOffsets.push(stopOffset);\n            this.classNames.push(className);\n            this.metadata.push(metadata);\n        }\n        else {\n            // Find the insertion position for `stopOffset`\n            for (let i = 0; i < this.count; i++) {\n                if (this.stopOffsets[i] >= stopOffset) {\n                    this.stopOffsets.splice(i, 0, stopOffset);\n                    this.classNames.splice(i, 0, className);\n                    this.metadata.splice(i, 0, metadata);\n                    break;\n                }\n            }\n        }\n        this.count++;\n        return;\n    }\n}\nexport class LineDecorationsNormalizer {\n    /**\n     * Normalize line decorations. Overlapping decorations will generate multiple segments\n     */\n    static normalize(lineContent, lineDecorations) {\n        if (lineDecorations.length === 0) {\n            return [];\n        }\n        const result = [];\n        const stack = new Stack();\n        let nextStartOffset = 0;\n        for (let i = 0, len = lineDecorations.length; i < len; i++) {\n            const d = lineDecorations[i];\n            let startColumn = d.startColumn;\n            let endColumn = d.endColumn;\n            const className = d.className;\n            const metadata = (d.type === 1 /* InlineDecorationType.Before */\n                ? 2 /* LinePartMetadata.PSEUDO_BEFORE */\n                : d.type === 2 /* InlineDecorationType.After */\n                    ? 4 /* LinePartMetadata.PSEUDO_AFTER */\n                    : 0);\n            // If the position would end up in the middle of a high-low surrogate pair, we move it to before the pair\n            if (startColumn > 1) {\n                const charCodeBefore = lineContent.charCodeAt(startColumn - 2);\n                if (strings.isHighSurrogate(charCodeBefore)) {\n                    startColumn--;\n                }\n            }\n            if (endColumn > 1) {\n                const charCodeBefore = lineContent.charCodeAt(endColumn - 2);\n                if (strings.isHighSurrogate(charCodeBefore)) {\n                    endColumn--;\n                }\n            }\n            const currentStartOffset = startColumn - 1;\n            const currentEndOffset = endColumn - 2;\n            nextStartOffset = stack.consumeLowerThan(currentStartOffset, nextStartOffset, result);\n            if (stack.count === 0) {\n                nextStartOffset = currentStartOffset;\n            }\n            stack.insert(currentEndOffset, className, metadata);\n        }\n        stack.consumeLowerThan(1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */, nextStartOffset, result);\n        return result;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport class LinePart {\n    constructor(\n    /**\n     * last char index of this token (not inclusive).\n     */\n    endIndex, type, metadata, containsRTL) {\n        this.endIndex = endIndex;\n        this.type = type;\n        this.metadata = metadata;\n        this.containsRTL = containsRTL;\n        this._linePartBrand = undefined;\n    }\n    isWhitespace() {\n        return (this.metadata & 1 /* LinePartMetadata.IS_WHITESPACE_MASK */ ? true : false);\n    }\n    isPseudoAfter() {\n        return (this.metadata & 4 /* LinePartMetadata.PSEUDO_AFTER_MASK */ ? true : false);\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as nls from '../../../nls.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { StringBuilder } from '../core/stringBuilder.js';\nimport { LineDecoration, LineDecorationsNormalizer } from './lineDecorations.js';\nimport { LinePart } from './linePart.js';\nexport class LineRange {\n    constructor(startIndex, endIndex) {\n        this.startOffset = startIndex;\n        this.endOffset = endIndex;\n    }\n    equals(otherLineRange) {\n        return this.startOffset === otherLineRange.startOffset\n            && this.endOffset === otherLineRange.endOffset;\n    }\n}\nexport class RenderLineInput {\n    constructor(useMonospaceOptimizations, canUseHalfwidthRightwardsArrow, lineContent, continuesWithWrappedLine, isBasicASCII, containsRTL, fauxIndentLength, lineTokens, lineDecorations, tabSize, startVisibleColumn, spaceWidth, middotWidth, wsmiddotWidth, stopRenderingLineAfter, renderWhitespace, renderControlCharacters, fontLigatures, selectionsOnLine) {\n        this.useMonospaceOptimizations = useMonospaceOptimizations;\n        this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow;\n        this.lineContent = lineContent;\n        this.continuesWithWrappedLine = continuesWithWrappedLine;\n        this.isBasicASCII = isBasicASCII;\n        this.containsRTL = containsRTL;\n        this.fauxIndentLength = fauxIndentLength;\n        this.lineTokens = lineTokens;\n        this.lineDecorations = lineDecorations.sort(LineDecoration.compare);\n        this.tabSize = tabSize;\n        this.startVisibleColumn = startVisibleColumn;\n        this.spaceWidth = spaceWidth;\n        this.stopRenderingLineAfter = stopRenderingLineAfter;\n        this.renderWhitespace = (renderWhitespace === 'all'\n            ? 4 /* RenderWhitespace.All */\n            : renderWhitespace === 'boundary'\n                ? 1 /* RenderWhitespace.Boundary */\n                : renderWhitespace === 'selection'\n                    ? 2 /* RenderWhitespace.Selection */\n                    : renderWhitespace === 'trailing'\n                        ? 3 /* RenderWhitespace.Trailing */\n                        : 0 /* RenderWhitespace.None */);\n        this.renderControlCharacters = renderControlCharacters;\n        this.fontLigatures = fontLigatures;\n        this.selectionsOnLine = selectionsOnLine && selectionsOnLine.sort((a, b) => a.startOffset < b.startOffset ? -1 : 1);\n        const wsmiddotDiff = Math.abs(wsmiddotWidth - spaceWidth);\n        const middotDiff = Math.abs(middotWidth - spaceWidth);\n        if (wsmiddotDiff < middotDiff) {\n            this.renderSpaceWidth = wsmiddotWidth;\n            this.renderSpaceCharCode = 0x2E31; // U+2E31 - WORD SEPARATOR MIDDLE DOT\n        }\n        else {\n            this.renderSpaceWidth = middotWidth;\n            this.renderSpaceCharCode = 0xB7; // U+00B7 - MIDDLE DOT\n        }\n    }\n    sameSelection(otherSelections) {\n        if (this.selectionsOnLine === null) {\n            return otherSelections === null;\n        }\n        if (otherSelections === null) {\n            return false;\n        }\n        if (otherSelections.length !== this.selectionsOnLine.length) {\n            return false;\n        }\n        for (let i = 0; i < this.selectionsOnLine.length; i++) {\n            if (!this.selectionsOnLine[i].equals(otherSelections[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n    equals(other) {\n        return (this.useMonospaceOptimizations === other.useMonospaceOptimizations\n            && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow\n            && this.lineContent === other.lineContent\n            && this.continuesWithWrappedLine === other.continuesWithWrappedLine\n            && this.isBasicASCII === other.isBasicASCII\n            && this.containsRTL === other.containsRTL\n            && this.fauxIndentLength === other.fauxIndentLength\n            && this.tabSize === other.tabSize\n            && this.startVisibleColumn === other.startVisibleColumn\n            && this.spaceWidth === other.spaceWidth\n            && this.renderSpaceWidth === other.renderSpaceWidth\n            && this.renderSpaceCharCode === other.renderSpaceCharCode\n            && this.stopRenderingLineAfter === other.stopRenderingLineAfter\n            && this.renderWhitespace === other.renderWhitespace\n            && this.renderControlCharacters === other.renderControlCharacters\n            && this.fontLigatures === other.fontLigatures\n            && LineDecoration.equalsArr(this.lineDecorations, other.lineDecorations)\n            && this.lineTokens.equals(other.lineTokens)\n            && this.sameSelection(other.selectionsOnLine));\n    }\n}\nexport class DomPosition {\n    constructor(partIndex, charIndex) {\n        this.partIndex = partIndex;\n        this.charIndex = charIndex;\n    }\n}\n/**\n * Provides a both direction mapping between a line's character and its rendered position.\n */\nexport class CharacterMapping {\n    static getPartIndex(partData) {\n        return (partData & 4294901760 /* CharacterMappingConstants.PART_INDEX_MASK */) >>> 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */;\n    }\n    static getCharIndex(partData) {\n        return (partData & 65535 /* CharacterMappingConstants.CHAR_INDEX_MASK */) >>> 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */;\n    }\n    constructor(length, partCount) {\n        this.length = length;\n        this._data = new Uint32Array(this.length);\n        this._horizontalOffset = new Uint32Array(this.length);\n    }\n    setColumnInfo(column, partIndex, charIndex, horizontalOffset) {\n        const partData = ((partIndex << 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */)\n            | (charIndex << 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */)) >>> 0;\n        this._data[column - 1] = partData;\n        this._horizontalOffset[column - 1] = horizontalOffset;\n    }\n    getHorizontalOffset(column) {\n        if (this._horizontalOffset.length === 0) {\n            // No characters on this line\n            return 0;\n        }\n        return this._horizontalOffset[column - 1];\n    }\n    charOffsetToPartData(charOffset) {\n        if (this.length === 0) {\n            return 0;\n        }\n        if (charOffset < 0) {\n            return this._data[0];\n        }\n        if (charOffset >= this.length) {\n            return this._data[this.length - 1];\n        }\n        return this._data[charOffset];\n    }\n    getDomPosition(column) {\n        const partData = this.charOffsetToPartData(column - 1);\n        const partIndex = CharacterMapping.getPartIndex(partData);\n        const charIndex = CharacterMapping.getCharIndex(partData);\n        return new DomPosition(partIndex, charIndex);\n    }\n    getColumn(domPosition, partLength) {\n        const charOffset = this.partDataToCharOffset(domPosition.partIndex, partLength, domPosition.charIndex);\n        return charOffset + 1;\n    }\n    partDataToCharOffset(partIndex, partLength, charIndex) {\n        if (this.length === 0) {\n            return 0;\n        }\n        const searchEntry = ((partIndex << 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */)\n            | (charIndex << 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */)) >>> 0;\n        let min = 0;\n        let max = this.length - 1;\n        while (min + 1 < max) {\n            const mid = ((min + max) >>> 1);\n            const midEntry = this._data[mid];\n            if (midEntry === searchEntry) {\n                return mid;\n            }\n            else if (midEntry > searchEntry) {\n                max = mid;\n            }\n            else {\n                min = mid;\n            }\n        }\n        if (min === max) {\n            return min;\n        }\n        const minEntry = this._data[min];\n        const maxEntry = this._data[max];\n        if (minEntry === searchEntry) {\n            return min;\n        }\n        if (maxEntry === searchEntry) {\n            return max;\n        }\n        const minPartIndex = CharacterMapping.getPartIndex(minEntry);\n        const minCharIndex = CharacterMapping.getCharIndex(minEntry);\n        const maxPartIndex = CharacterMapping.getPartIndex(maxEntry);\n        let maxCharIndex;\n        if (minPartIndex !== maxPartIndex) {\n            // sitting between parts\n            maxCharIndex = partLength;\n        }\n        else {\n            maxCharIndex = CharacterMapping.getCharIndex(maxEntry);\n        }\n        const minEntryDistance = charIndex - minCharIndex;\n        const maxEntryDistance = maxCharIndex - charIndex;\n        if (minEntryDistance <= maxEntryDistance) {\n            return min;\n        }\n        return max;\n    }\n}\nexport class RenderLineOutput {\n    constructor(characterMapping, containsRTL, containsForeignElements) {\n        this._renderLineOutputBrand = undefined;\n        this.characterMapping = characterMapping;\n        this.containsRTL = containsRTL;\n        this.containsForeignElements = containsForeignElements;\n    }\n}\nexport function renderViewLine(input, sb) {\n    if (input.lineContent.length === 0) {\n        if (input.lineDecorations.length > 0) {\n            // This line is empty, but it contains inline decorations\n            sb.appendString(``);\n            let beforeCount = 0;\n            let afterCount = 0;\n            let containsForeignElements = 0 /* ForeignElementType.None */;\n            for (const lineDecoration of input.lineDecorations) {\n                if (lineDecoration.type === 1 /* InlineDecorationType.Before */ || lineDecoration.type === 2 /* InlineDecorationType.After */) {\n                    sb.appendString(``);\n                    if (lineDecoration.type === 1 /* InlineDecorationType.Before */) {\n                        containsForeignElements |= 1 /* ForeignElementType.Before */;\n                        beforeCount++;\n                    }\n                    if (lineDecoration.type === 2 /* InlineDecorationType.After */) {\n                        containsForeignElements |= 2 /* ForeignElementType.After */;\n                        afterCount++;\n                    }\n                }\n            }\n            sb.appendString(``);\n            const characterMapping = new CharacterMapping(1, beforeCount + afterCount);\n            characterMapping.setColumnInfo(1, beforeCount, 0, 0);\n            return new RenderLineOutput(characterMapping, false, containsForeignElements);\n        }\n        // completely empty line\n        sb.appendString('');\n        return new RenderLineOutput(new CharacterMapping(0, 0), false, 0 /* ForeignElementType.None */);\n    }\n    return _renderLine(resolveRenderLineInput(input), sb);\n}\nexport class RenderLineOutput2 {\n    constructor(characterMapping, html, containsRTL, containsForeignElements) {\n        this.characterMapping = characterMapping;\n        this.html = html;\n        this.containsRTL = containsRTL;\n        this.containsForeignElements = containsForeignElements;\n    }\n}\nexport function renderViewLine2(input) {\n    const sb = new StringBuilder(10000);\n    const out = renderViewLine(input, sb);\n    return new RenderLineOutput2(out.characterMapping, sb.build(), out.containsRTL, out.containsForeignElements);\n}\nclass ResolvedRenderLineInput {\n    constructor(fontIsMonospace, canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, overflowingCharCount, parts, containsForeignElements, fauxIndentLength, tabSize, startVisibleColumn, containsRTL, spaceWidth, renderSpaceCharCode, renderWhitespace, renderControlCharacters) {\n        this.fontIsMonospace = fontIsMonospace;\n        this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow;\n        this.lineContent = lineContent;\n        this.len = len;\n        this.isOverflowing = isOverflowing;\n        this.overflowingCharCount = overflowingCharCount;\n        this.parts = parts;\n        this.containsForeignElements = containsForeignElements;\n        this.fauxIndentLength = fauxIndentLength;\n        this.tabSize = tabSize;\n        this.startVisibleColumn = startVisibleColumn;\n        this.containsRTL = containsRTL;\n        this.spaceWidth = spaceWidth;\n        this.renderSpaceCharCode = renderSpaceCharCode;\n        this.renderWhitespace = renderWhitespace;\n        this.renderControlCharacters = renderControlCharacters;\n        //\n    }\n}\nfunction resolveRenderLineInput(input) {\n    const lineContent = input.lineContent;\n    let isOverflowing;\n    let overflowingCharCount;\n    let len;\n    if (input.stopRenderingLineAfter !== -1 && input.stopRenderingLineAfter < lineContent.length) {\n        isOverflowing = true;\n        overflowingCharCount = lineContent.length - input.stopRenderingLineAfter;\n        len = input.stopRenderingLineAfter;\n    }\n    else {\n        isOverflowing = false;\n        overflowingCharCount = 0;\n        len = lineContent.length;\n    }\n    let tokens = transformAndRemoveOverflowing(lineContent, input.containsRTL, input.lineTokens, input.fauxIndentLength, len);\n    if (input.renderControlCharacters && !input.isBasicASCII) {\n        // Calling `extractControlCharacters` before adding (possibly empty) line parts\n        // for inline decorations. `extractControlCharacters` removes empty line parts.\n        tokens = extractControlCharacters(lineContent, tokens);\n    }\n    if (input.renderWhitespace === 4 /* RenderWhitespace.All */ ||\n        input.renderWhitespace === 1 /* RenderWhitespace.Boundary */ ||\n        (input.renderWhitespace === 2 /* RenderWhitespace.Selection */ && !!input.selectionsOnLine) ||\n        (input.renderWhitespace === 3 /* RenderWhitespace.Trailing */ && !input.continuesWithWrappedLine)) {\n        tokens = _applyRenderWhitespace(input, lineContent, len, tokens);\n    }\n    let containsForeignElements = 0 /* ForeignElementType.None */;\n    if (input.lineDecorations.length > 0) {\n        for (let i = 0, len = input.lineDecorations.length; i < len; i++) {\n            const lineDecoration = input.lineDecorations[i];\n            if (lineDecoration.type === 3 /* InlineDecorationType.RegularAffectingLetterSpacing */) {\n                // Pretend there are foreign elements... although not 100% accurate.\n                containsForeignElements |= 1 /* ForeignElementType.Before */;\n            }\n            else if (lineDecoration.type === 1 /* InlineDecorationType.Before */) {\n                containsForeignElements |= 1 /* ForeignElementType.Before */;\n            }\n            else if (lineDecoration.type === 2 /* InlineDecorationType.After */) {\n                containsForeignElements |= 2 /* ForeignElementType.After */;\n            }\n        }\n        tokens = _applyInlineDecorations(lineContent, len, tokens, input.lineDecorations);\n    }\n    if (!input.containsRTL) {\n        // We can never split RTL text, as it ruins the rendering\n        tokens = splitLargeTokens(lineContent, tokens, !input.isBasicASCII || input.fontLigatures);\n    }\n    return new ResolvedRenderLineInput(input.useMonospaceOptimizations, input.canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, overflowingCharCount, tokens, containsForeignElements, input.fauxIndentLength, input.tabSize, input.startVisibleColumn, input.containsRTL, input.spaceWidth, input.renderSpaceCharCode, input.renderWhitespace, input.renderControlCharacters);\n}\n/**\n * In the rendering phase, characters are always looped until token.endIndex.\n * Ensure that all tokens end before `len` and the last one ends precisely at `len`.\n */\nfunction transformAndRemoveOverflowing(lineContent, lineContainsRTL, tokens, fauxIndentLength, len) {\n    const result = [];\n    let resultLen = 0;\n    // The faux indent part of the line should have no token type\n    if (fauxIndentLength > 0) {\n        result[resultLen++] = new LinePart(fauxIndentLength, '', 0, false);\n    }\n    let startOffset = fauxIndentLength;\n    for (let tokenIndex = 0, tokensLen = tokens.getCount(); tokenIndex < tokensLen; tokenIndex++) {\n        const endIndex = tokens.getEndOffset(tokenIndex);\n        if (endIndex <= fauxIndentLength) {\n            // The faux indent part of the line should have no token type\n            continue;\n        }\n        const type = tokens.getClassName(tokenIndex);\n        if (endIndex >= len) {\n            const tokenContainsRTL = (lineContainsRTL ? strings.containsRTL(lineContent.substring(startOffset, len)) : false);\n            result[resultLen++] = new LinePart(len, type, 0, tokenContainsRTL);\n            break;\n        }\n        const tokenContainsRTL = (lineContainsRTL ? strings.containsRTL(lineContent.substring(startOffset, endIndex)) : false);\n        result[resultLen++] = new LinePart(endIndex, type, 0, tokenContainsRTL);\n        startOffset = endIndex;\n    }\n    return result;\n}\n/**\n * See https://github.com/microsoft/vscode/issues/6885.\n * It appears that having very large spans causes very slow reading of character positions.\n * So here we try to avoid that.\n */\nfunction splitLargeTokens(lineContent, tokens, onlyAtSpaces) {\n    let lastTokenEndIndex = 0;\n    const result = [];\n    let resultLen = 0;\n    if (onlyAtSpaces) {\n        // Split only at spaces => we need to walk each character\n        for (let i = 0, len = tokens.length; i < len; i++) {\n            const token = tokens[i];\n            const tokenEndIndex = token.endIndex;\n            if (lastTokenEndIndex + 50 /* Constants.LongToken */ < tokenEndIndex) {\n                const tokenType = token.type;\n                const tokenMetadata = token.metadata;\n                const tokenContainsRTL = token.containsRTL;\n                let lastSpaceOffset = -1;\n                let currTokenStart = lastTokenEndIndex;\n                for (let j = lastTokenEndIndex; j < tokenEndIndex; j++) {\n                    if (lineContent.charCodeAt(j) === 32 /* CharCode.Space */) {\n                        lastSpaceOffset = j;\n                    }\n                    if (lastSpaceOffset !== -1 && j - currTokenStart >= 50 /* Constants.LongToken */) {\n                        // Split at `lastSpaceOffset` + 1\n                        result[resultLen++] = new LinePart(lastSpaceOffset + 1, tokenType, tokenMetadata, tokenContainsRTL);\n                        currTokenStart = lastSpaceOffset + 1;\n                        lastSpaceOffset = -1;\n                    }\n                }\n                if (currTokenStart !== tokenEndIndex) {\n                    result[resultLen++] = new LinePart(tokenEndIndex, tokenType, tokenMetadata, tokenContainsRTL);\n                }\n            }\n            else {\n                result[resultLen++] = token;\n            }\n            lastTokenEndIndex = tokenEndIndex;\n        }\n    }\n    else {\n        // Split anywhere => we don't need to walk each character\n        for (let i = 0, len = tokens.length; i < len; i++) {\n            const token = tokens[i];\n            const tokenEndIndex = token.endIndex;\n            const diff = (tokenEndIndex - lastTokenEndIndex);\n            if (diff > 50 /* Constants.LongToken */) {\n                const tokenType = token.type;\n                const tokenMetadata = token.metadata;\n                const tokenContainsRTL = token.containsRTL;\n                const piecesCount = Math.ceil(diff / 50 /* Constants.LongToken */);\n                for (let j = 1; j < piecesCount; j++) {\n                    const pieceEndIndex = lastTokenEndIndex + (j * 50 /* Constants.LongToken */);\n                    result[resultLen++] = new LinePart(pieceEndIndex, tokenType, tokenMetadata, tokenContainsRTL);\n                }\n                result[resultLen++] = new LinePart(tokenEndIndex, tokenType, tokenMetadata, tokenContainsRTL);\n            }\n            else {\n                result[resultLen++] = token;\n            }\n            lastTokenEndIndex = tokenEndIndex;\n        }\n    }\n    return result;\n}\nfunction isControlCharacter(charCode) {\n    if (charCode < 32) {\n        return (charCode !== 9 /* CharCode.Tab */);\n    }\n    if (charCode === 127) {\n        // DEL\n        return true;\n    }\n    if ((charCode >= 0x202A && charCode <= 0x202E)\n        || (charCode >= 0x2066 && charCode <= 0x2069)\n        || (charCode >= 0x200E && charCode <= 0x200F)\n        || charCode === 0x061C) {\n        // Unicode Directional Formatting Characters\n        // LRE\tU+202A\tLEFT-TO-RIGHT EMBEDDING\n        // RLE\tU+202B\tRIGHT-TO-LEFT EMBEDDING\n        // PDF\tU+202C\tPOP DIRECTIONAL FORMATTING\n        // LRO\tU+202D\tLEFT-TO-RIGHT OVERRIDE\n        // RLO\tU+202E\tRIGHT-TO-LEFT OVERRIDE\n        // LRI\tU+2066\tLEFT-TO-RIGHT ISOLATE\n        // RLI\tU+2067\tRIGHT-TO-LEFT ISOLATE\n        // FSI\tU+2068\tFIRST STRONG ISOLATE\n        // PDI\tU+2069\tPOP DIRECTIONAL ISOLATE\n        // LRM\tU+200E\tLEFT-TO-RIGHT MARK\n        // RLM\tU+200F\tRIGHT-TO-LEFT MARK\n        // ALM\tU+061C\tARABIC LETTER MARK\n        return true;\n    }\n    return false;\n}\nfunction extractControlCharacters(lineContent, tokens) {\n    const result = [];\n    let lastLinePart = new LinePart(0, '', 0, false);\n    let charOffset = 0;\n    for (const token of tokens) {\n        const tokenEndIndex = token.endIndex;\n        for (; charOffset < tokenEndIndex; charOffset++) {\n            const charCode = lineContent.charCodeAt(charOffset);\n            if (isControlCharacter(charCode)) {\n                if (charOffset > lastLinePart.endIndex) {\n                    // emit previous part if it has text\n                    lastLinePart = new LinePart(charOffset, token.type, token.metadata, token.containsRTL);\n                    result.push(lastLinePart);\n                }\n                lastLinePart = new LinePart(charOffset + 1, 'mtkcontrol', token.metadata, false);\n                result.push(lastLinePart);\n            }\n        }\n        if (charOffset > lastLinePart.endIndex) {\n            // emit previous part if it has text\n            lastLinePart = new LinePart(tokenEndIndex, token.type, token.metadata, token.containsRTL);\n            result.push(lastLinePart);\n        }\n    }\n    return result;\n}\n/**\n * Whitespace is rendered by \"replacing\" tokens with a special-purpose `mtkw` type that is later recognized in the rendering phase.\n * Moreover, a token is created for every visual indent because on some fonts the glyphs used for rendering whitespace (→ or ·) do not have the same width as  .\n * The rendering phase will generate `style=\"width:...\"` for these tokens.\n */\nfunction _applyRenderWhitespace(input, lineContent, len, tokens) {\n    const continuesWithWrappedLine = input.continuesWithWrappedLine;\n    const fauxIndentLength = input.fauxIndentLength;\n    const tabSize = input.tabSize;\n    const startVisibleColumn = input.startVisibleColumn;\n    const useMonospaceOptimizations = input.useMonospaceOptimizations;\n    const selections = input.selectionsOnLine;\n    const onlyBoundary = (input.renderWhitespace === 1 /* RenderWhitespace.Boundary */);\n    const onlyTrailing = (input.renderWhitespace === 3 /* RenderWhitespace.Trailing */);\n    const generateLinePartForEachWhitespace = (input.renderSpaceWidth !== input.spaceWidth);\n    const result = [];\n    let resultLen = 0;\n    let tokenIndex = 0;\n    let tokenType = tokens[tokenIndex].type;\n    let tokenContainsRTL = tokens[tokenIndex].containsRTL;\n    let tokenEndIndex = tokens[tokenIndex].endIndex;\n    const tokensLength = tokens.length;\n    let lineIsEmptyOrWhitespace = false;\n    let firstNonWhitespaceIndex = strings.firstNonWhitespaceIndex(lineContent);\n    let lastNonWhitespaceIndex;\n    if (firstNonWhitespaceIndex === -1) {\n        lineIsEmptyOrWhitespace = true;\n        firstNonWhitespaceIndex = len;\n        lastNonWhitespaceIndex = len;\n    }\n    else {\n        lastNonWhitespaceIndex = strings.lastNonWhitespaceIndex(lineContent);\n    }\n    let wasInWhitespace = false;\n    let currentSelectionIndex = 0;\n    let currentSelection = selections && selections[currentSelectionIndex];\n    let tmpIndent = startVisibleColumn % tabSize;\n    for (let charIndex = fauxIndentLength; charIndex < len; charIndex++) {\n        const chCode = lineContent.charCodeAt(charIndex);\n        if (currentSelection && charIndex >= currentSelection.endOffset) {\n            currentSelectionIndex++;\n            currentSelection = selections && selections[currentSelectionIndex];\n        }\n        let isInWhitespace;\n        if (charIndex < firstNonWhitespaceIndex || charIndex > lastNonWhitespaceIndex) {\n            // in leading or trailing whitespace\n            isInWhitespace = true;\n        }\n        else if (chCode === 9 /* CharCode.Tab */) {\n            // a tab character is rendered both in all and boundary cases\n            isInWhitespace = true;\n        }\n        else if (chCode === 32 /* CharCode.Space */) {\n            // hit a space character\n            if (onlyBoundary) {\n                // rendering only boundary whitespace\n                if (wasInWhitespace) {\n                    isInWhitespace = true;\n                }\n                else {\n                    const nextChCode = (charIndex + 1 < len ? lineContent.charCodeAt(charIndex + 1) : 0 /* CharCode.Null */);\n                    isInWhitespace = (nextChCode === 32 /* CharCode.Space */ || nextChCode === 9 /* CharCode.Tab */);\n                }\n            }\n            else {\n                isInWhitespace = true;\n            }\n        }\n        else {\n            isInWhitespace = false;\n        }\n        // If rendering whitespace on selection, check that the charIndex falls within a selection\n        if (isInWhitespace && selections) {\n            isInWhitespace = !!currentSelection && currentSelection.startOffset <= charIndex && currentSelection.endOffset > charIndex;\n        }\n        // If rendering only trailing whitespace, check that the charIndex points to trailing whitespace.\n        if (isInWhitespace && onlyTrailing) {\n            isInWhitespace = lineIsEmptyOrWhitespace || charIndex > lastNonWhitespaceIndex;\n        }\n        if (isInWhitespace && tokenContainsRTL) {\n            // If the token contains RTL text, breaking it up into multiple line parts\n            // to render whitespace might affect the browser's bidi layout.\n            //\n            // We render whitespace in such tokens only if the whitespace\n            // is the leading or the trailing whitespace of the line,\n            // which doesn't affect the browser's bidi layout.\n            if (charIndex >= firstNonWhitespaceIndex && charIndex <= lastNonWhitespaceIndex) {\n                isInWhitespace = false;\n            }\n        }\n        if (wasInWhitespace) {\n            // was in whitespace token\n            if (!isInWhitespace || (!useMonospaceOptimizations && tmpIndent >= tabSize)) {\n                // leaving whitespace token or entering a new indent\n                if (generateLinePartForEachWhitespace) {\n                    const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength);\n                    for (let i = lastEndIndex + 1; i <= charIndex; i++) {\n                        result[resultLen++] = new LinePart(i, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);\n                    }\n                }\n                else {\n                    result[resultLen++] = new LinePart(charIndex, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);\n                }\n                tmpIndent = tmpIndent % tabSize;\n            }\n        }\n        else {\n            // was in regular token\n            if (charIndex === tokenEndIndex || (isInWhitespace && charIndex > fauxIndentLength)) {\n                result[resultLen++] = new LinePart(charIndex, tokenType, 0, tokenContainsRTL);\n                tmpIndent = tmpIndent % tabSize;\n            }\n        }\n        if (chCode === 9 /* CharCode.Tab */) {\n            tmpIndent = tabSize;\n        }\n        else if (strings.isFullWidthCharacter(chCode)) {\n            tmpIndent += 2;\n        }\n        else {\n            tmpIndent++;\n        }\n        wasInWhitespace = isInWhitespace;\n        while (charIndex === tokenEndIndex) {\n            tokenIndex++;\n            if (tokenIndex < tokensLength) {\n                tokenType = tokens[tokenIndex].type;\n                tokenContainsRTL = tokens[tokenIndex].containsRTL;\n                tokenEndIndex = tokens[tokenIndex].endIndex;\n            }\n            else {\n                break;\n            }\n        }\n    }\n    let generateWhitespace = false;\n    if (wasInWhitespace) {\n        // was in whitespace token\n        if (continuesWithWrappedLine && onlyBoundary) {\n            const lastCharCode = (len > 0 ? lineContent.charCodeAt(len - 1) : 0 /* CharCode.Null */);\n            const prevCharCode = (len > 1 ? lineContent.charCodeAt(len - 2) : 0 /* CharCode.Null */);\n            const isSingleTrailingSpace = (lastCharCode === 32 /* CharCode.Space */ && (prevCharCode !== 32 /* CharCode.Space */ && prevCharCode !== 9 /* CharCode.Tab */));\n            if (!isSingleTrailingSpace) {\n                generateWhitespace = true;\n            }\n        }\n        else {\n            generateWhitespace = true;\n        }\n    }\n    if (generateWhitespace) {\n        if (generateLinePartForEachWhitespace) {\n            const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength);\n            for (let i = lastEndIndex + 1; i <= len; i++) {\n                result[resultLen++] = new LinePart(i, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);\n            }\n        }\n        else {\n            result[resultLen++] = new LinePart(len, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);\n        }\n    }\n    else {\n        result[resultLen++] = new LinePart(len, tokenType, 0, tokenContainsRTL);\n    }\n    return result;\n}\n/**\n * Inline decorations are \"merged\" on top of tokens.\n * Special care must be taken when multiple inline decorations are at play and they overlap.\n */\nfunction _applyInlineDecorations(lineContent, len, tokens, _lineDecorations) {\n    _lineDecorations.sort(LineDecoration.compare);\n    const lineDecorations = LineDecorationsNormalizer.normalize(lineContent, _lineDecorations);\n    const lineDecorationsLen = lineDecorations.length;\n    let lineDecorationIndex = 0;\n    const result = [];\n    let resultLen = 0;\n    let lastResultEndIndex = 0;\n    for (let tokenIndex = 0, len = tokens.length; tokenIndex < len; tokenIndex++) {\n        const token = tokens[tokenIndex];\n        const tokenEndIndex = token.endIndex;\n        const tokenType = token.type;\n        const tokenMetadata = token.metadata;\n        const tokenContainsRTL = token.containsRTL;\n        while (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset < tokenEndIndex) {\n            const lineDecoration = lineDecorations[lineDecorationIndex];\n            if (lineDecoration.startOffset > lastResultEndIndex) {\n                lastResultEndIndex = lineDecoration.startOffset;\n                result[resultLen++] = new LinePart(lastResultEndIndex, tokenType, tokenMetadata, tokenContainsRTL);\n            }\n            if (lineDecoration.endOffset + 1 <= tokenEndIndex) {\n                // This line decoration ends before this token ends\n                lastResultEndIndex = lineDecoration.endOffset + 1;\n                result[resultLen++] = new LinePart(lastResultEndIndex, tokenType + ' ' + lineDecoration.className, tokenMetadata | lineDecoration.metadata, tokenContainsRTL);\n                lineDecorationIndex++;\n            }\n            else {\n                // This line decoration continues on to the next token\n                lastResultEndIndex = tokenEndIndex;\n                result[resultLen++] = new LinePart(lastResultEndIndex, tokenType + ' ' + lineDecoration.className, tokenMetadata | lineDecoration.metadata, tokenContainsRTL);\n                break;\n            }\n        }\n        if (tokenEndIndex > lastResultEndIndex) {\n            lastResultEndIndex = tokenEndIndex;\n            result[resultLen++] = new LinePart(lastResultEndIndex, tokenType, tokenMetadata, tokenContainsRTL);\n        }\n    }\n    const lastTokenEndIndex = tokens[tokens.length - 1].endIndex;\n    if (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset === lastTokenEndIndex) {\n        while (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset === lastTokenEndIndex) {\n            const lineDecoration = lineDecorations[lineDecorationIndex];\n            result[resultLen++] = new LinePart(lastResultEndIndex, lineDecoration.className, lineDecoration.metadata, false);\n            lineDecorationIndex++;\n        }\n    }\n    return result;\n}\n/**\n * This function is on purpose not split up into multiple functions to allow runtime type inference (i.e. performance reasons).\n * Notice how all the needed data is fully resolved and passed in (i.e. no other calls).\n */\nfunction _renderLine(input, sb) {\n    const fontIsMonospace = input.fontIsMonospace;\n    const canUseHalfwidthRightwardsArrow = input.canUseHalfwidthRightwardsArrow;\n    const containsForeignElements = input.containsForeignElements;\n    const lineContent = input.lineContent;\n    const len = input.len;\n    const isOverflowing = input.isOverflowing;\n    const overflowingCharCount = input.overflowingCharCount;\n    const parts = input.parts;\n    const fauxIndentLength = input.fauxIndentLength;\n    const tabSize = input.tabSize;\n    const startVisibleColumn = input.startVisibleColumn;\n    const containsRTL = input.containsRTL;\n    const spaceWidth = input.spaceWidth;\n    const renderSpaceCharCode = input.renderSpaceCharCode;\n    const renderWhitespace = input.renderWhitespace;\n    const renderControlCharacters = input.renderControlCharacters;\n    const characterMapping = new CharacterMapping(len + 1, parts.length);\n    let lastCharacterMappingDefined = false;\n    let charIndex = 0;\n    let visibleColumn = startVisibleColumn;\n    let charOffsetInPart = 0; // the character offset in the current part\n    let charHorizontalOffset = 0; // the character horizontal position in terms of chars relative to line start\n    let partDisplacement = 0;\n    if (containsRTL) {\n        sb.appendString('');\n    }\n    else {\n        sb.appendString('');\n    }\n    for (let partIndex = 0, tokensLen = parts.length; partIndex < tokensLen; partIndex++) {\n        const part = parts[partIndex];\n        const partEndIndex = part.endIndex;\n        const partType = part.type;\n        const partContainsRTL = part.containsRTL;\n        const partRendersWhitespace = (renderWhitespace !== 0 /* RenderWhitespace.None */ && part.isWhitespace());\n        const partRendersWhitespaceWithWidth = partRendersWhitespace && !fontIsMonospace && (partType === 'mtkw' /*only whitespace*/ || !containsForeignElements);\n        const partIsEmptyAndHasPseudoAfter = (charIndex === partEndIndex && part.isPseudoAfter());\n        charOffsetInPart = 0;\n        sb.appendString('= fauxIndentLength) {\n                        _visibleColumn += charWidth;\n                    }\n                }\n            }\n            if (partRendersWhitespaceWithWidth) {\n                sb.appendString(' style=\"width:');\n                sb.appendString(String(spaceWidth * partWidth));\n                sb.appendString('px\"');\n            }\n            sb.appendASCIICharCode(62 /* CharCode.GreaterThan */);\n            for (; charIndex < partEndIndex; charIndex++) {\n                characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, charHorizontalOffset);\n                partDisplacement = 0;\n                const charCode = lineContent.charCodeAt(charIndex);\n                let producedCharacters;\n                let charWidth;\n                if (charCode === 9 /* CharCode.Tab */) {\n                    producedCharacters = (tabSize - (visibleColumn % tabSize)) | 0;\n                    charWidth = producedCharacters;\n                    if (!canUseHalfwidthRightwardsArrow || charWidth > 1) {\n                        sb.appendCharCode(0x2192); // RIGHTWARDS ARROW\n                    }\n                    else {\n                        sb.appendCharCode(0xFFEB); // HALFWIDTH RIGHTWARDS ARROW\n                    }\n                    for (let space = 2; space <= charWidth; space++) {\n                        sb.appendCharCode(0xA0); //  \n                    }\n                }\n                else { // must be CharCode.Space\n                    producedCharacters = 2;\n                    charWidth = 1;\n                    sb.appendCharCode(renderSpaceCharCode); // · or word separator middle dot\n                    sb.appendCharCode(0x200C); // ZERO WIDTH NON-JOINER\n                }\n                charOffsetInPart += producedCharacters;\n                charHorizontalOffset += charWidth;\n                if (charIndex >= fauxIndentLength) {\n                    visibleColumn += charWidth;\n                }\n            }\n        }\n        else {\n            sb.appendASCIICharCode(62 /* CharCode.GreaterThan */);\n            for (; charIndex < partEndIndex; charIndex++) {\n                characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, charHorizontalOffset);\n                partDisplacement = 0;\n                const charCode = lineContent.charCodeAt(charIndex);\n                let producedCharacters = 1;\n                let charWidth = 1;\n                switch (charCode) {\n                    case 9 /* CharCode.Tab */:\n                        producedCharacters = (tabSize - (visibleColumn % tabSize));\n                        charWidth = producedCharacters;\n                        for (let space = 1; space <= producedCharacters; space++) {\n                            sb.appendCharCode(0xA0); //  \n                        }\n                        break;\n                    case 32 /* CharCode.Space */:\n                        sb.appendCharCode(0xA0); //  \n                        break;\n                    case 60 /* CharCode.LessThan */:\n                        sb.appendString('<');\n                        break;\n                    case 62 /* CharCode.GreaterThan */:\n                        sb.appendString('>');\n                        break;\n                    case 38 /* CharCode.Ampersand */:\n                        sb.appendString('&');\n                        break;\n                    case 0 /* CharCode.Null */:\n                        if (renderControlCharacters) {\n                            // See https://unicode-table.com/en/blocks/control-pictures/\n                            sb.appendCharCode(9216);\n                        }\n                        else {\n                            sb.appendString('�');\n                        }\n                        break;\n                    case 65279 /* CharCode.UTF8_BOM */:\n                    case 8232 /* CharCode.LINE_SEPARATOR */:\n                    case 8233 /* CharCode.PARAGRAPH_SEPARATOR */:\n                    case 133 /* CharCode.NEXT_LINE */:\n                        sb.appendCharCode(0xFFFD);\n                        break;\n                    default:\n                        if (strings.isFullWidthCharacter(charCode)) {\n                            charWidth++;\n                        }\n                        // See https://unicode-table.com/en/blocks/control-pictures/\n                        if (renderControlCharacters && charCode < 32) {\n                            sb.appendCharCode(9216 + charCode);\n                        }\n                        else if (renderControlCharacters && charCode === 127) {\n                            // DEL\n                            sb.appendCharCode(9249);\n                        }\n                        else if (renderControlCharacters && isControlCharacter(charCode)) {\n                            sb.appendString('[U+');\n                            sb.appendString(to4CharHex(charCode));\n                            sb.appendString(']');\n                            producedCharacters = 8;\n                            charWidth = producedCharacters;\n                        }\n                        else {\n                            sb.appendCharCode(charCode);\n                        }\n                }\n                charOffsetInPart += producedCharacters;\n                charHorizontalOffset += charWidth;\n                if (charIndex >= fauxIndentLength) {\n                    visibleColumn += charWidth;\n                }\n            }\n        }\n        if (partIsEmptyAndHasPseudoAfter) {\n            partDisplacement++;\n        }\n        else {\n            partDisplacement = 0;\n        }\n        if (charIndex >= len && !lastCharacterMappingDefined && part.isPseudoAfter()) {\n            lastCharacterMappingDefined = true;\n            characterMapping.setColumnInfo(charIndex + 1, partIndex, charOffsetInPart, charHorizontalOffset);\n        }\n        sb.appendString('');\n    }\n    if (!lastCharacterMappingDefined) {\n        // When getting client rects for the last character, we will position the\n        // text range at the end of the span, insteaf of at the beginning of next span\n        characterMapping.setColumnInfo(len + 1, parts.length - 1, charOffsetInPart, charHorizontalOffset);\n    }\n    if (isOverflowing) {\n        sb.appendString('');\n        sb.appendString(nls.localize('showMore', \"Show more ({0})\", renderOverflowingCharCount(overflowingCharCount)));\n        sb.appendString('');\n    }\n    sb.appendString('');\n    return new RenderLineOutput(characterMapping, containsRTL, containsForeignElements);\n}\nfunction to4CharHex(n) {\n    return n.toString(16).toUpperCase().padStart(4, '0');\n}\nfunction renderOverflowingCharCount(n) {\n    if (n < 1024) {\n        return nls.localize('overflow.chars', \"{0} chars\", n);\n    }\n    if (n < 1024 * 1024) {\n        return `${(n / 1024).toFixed(1)} KB`;\n    }\n    return `${(n / 1024 / 1024).toFixed(1)} MB`;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../base/common/strings.js';\nimport { Range } from './core/range.js';\nexport class Viewport {\n    constructor(top, left, width, height) {\n        this._viewportBrand = undefined;\n        this.top = top | 0;\n        this.left = left | 0;\n        this.width = width | 0;\n        this.height = height | 0;\n    }\n}\nexport class MinimapLinesRenderingData {\n    constructor(tabSize, data) {\n        this.tabSize = tabSize;\n        this.data = data;\n    }\n}\nexport class ViewLineData {\n    constructor(content, continuesWithWrappedLine, minColumn, maxColumn, startVisibleColumn, tokens, inlineDecorations) {\n        this._viewLineDataBrand = undefined;\n        this.content = content;\n        this.continuesWithWrappedLine = continuesWithWrappedLine;\n        this.minColumn = minColumn;\n        this.maxColumn = maxColumn;\n        this.startVisibleColumn = startVisibleColumn;\n        this.tokens = tokens;\n        this.inlineDecorations = inlineDecorations;\n    }\n}\nexport class ViewLineRenderingData {\n    constructor(minColumn, maxColumn, content, continuesWithWrappedLine, mightContainRTL, mightContainNonBasicASCII, tokens, inlineDecorations, tabSize, startVisibleColumn) {\n        this.minColumn = minColumn;\n        this.maxColumn = maxColumn;\n        this.content = content;\n        this.continuesWithWrappedLine = continuesWithWrappedLine;\n        this.isBasicASCII = ViewLineRenderingData.isBasicASCII(content, mightContainNonBasicASCII);\n        this.containsRTL = ViewLineRenderingData.containsRTL(content, this.isBasicASCII, mightContainRTL);\n        this.tokens = tokens;\n        this.inlineDecorations = inlineDecorations;\n        this.tabSize = tabSize;\n        this.startVisibleColumn = startVisibleColumn;\n    }\n    static isBasicASCII(lineContent, mightContainNonBasicASCII) {\n        if (mightContainNonBasicASCII) {\n            return strings.isBasicASCII(lineContent);\n        }\n        return true;\n    }\n    static containsRTL(lineContent, isBasicASCII, mightContainRTL) {\n        if (!isBasicASCII && mightContainRTL) {\n            return strings.containsRTL(lineContent);\n        }\n        return false;\n    }\n}\nexport class InlineDecoration {\n    constructor(range, inlineClassName, type) {\n        this.range = range;\n        this.inlineClassName = inlineClassName;\n        this.type = type;\n    }\n}\nexport class SingleLineInlineDecoration {\n    constructor(startOffset, endOffset, inlineClassName, inlineClassNameAffectsLetterSpacing) {\n        this.startOffset = startOffset;\n        this.endOffset = endOffset;\n        this.inlineClassName = inlineClassName;\n        this.inlineClassNameAffectsLetterSpacing = inlineClassNameAffectsLetterSpacing;\n    }\n    toInlineDecoration(lineNumber) {\n        return new InlineDecoration(new Range(lineNumber, this.startOffset + 1, lineNumber, this.endOffset + 1), this.inlineClassName, this.inlineClassNameAffectsLetterSpacing ? 3 /* InlineDecorationType.RegularAffectingLetterSpacing */ : 0 /* InlineDecorationType.Regular */);\n    }\n}\nexport class ViewModelDecoration {\n    constructor(range, options) {\n        this._viewModelDecorationBrand = undefined;\n        this.range = range;\n        this.options = options;\n    }\n}\nexport class OverviewRulerDecorationsGroup {\n    constructor(color, zIndex, \n    /**\n     * Decorations are encoded in a number array using the following scheme:\n     *  - 3*i = lane\n     *  - 3*i+1 = startLineNumber\n     *  - 3*i+2 = endLineNumber\n     */\n    data) {\n        this.color = color;\n        this.zIndex = zIndex;\n        this.data = data;\n    }\n    static cmp(a, b) {\n        if (a.zIndex === b.zIndex) {\n            if (a.color < b.color) {\n                return -1;\n            }\n            if (a.color > b.color) {\n                return 1;\n            }\n            return 0;\n        }\n        return a.zIndex - b.zIndex;\n    }\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport function isFuzzyActionArr(what) {\n    return (Array.isArray(what));\n}\nexport function isFuzzyAction(what) {\n    return !isFuzzyActionArr(what);\n}\nexport function isString(what) {\n    return (typeof what === 'string');\n}\nexport function isIAction(what) {\n    return !isString(what);\n}\n// Small helper functions\n/**\n * Is a string null, undefined, or empty?\n */\nexport function empty(s) {\n    return (s ? false : true);\n}\n/**\n * Puts a string to lower case if 'ignoreCase' is set.\n */\nexport function fixCase(lexer, str) {\n    return (lexer.ignoreCase && str ? str.toLowerCase() : str);\n}\n/**\n * Ensures there are no bad characters in a CSS token class.\n */\nexport function sanitize(s) {\n    return s.replace(/[&<>'\"_]/g, '-'); // used on all output token CSS classes\n}\n// Logging\n/**\n * Logs a message.\n */\nexport function log(lexer, msg) {\n    console.log(`${lexer.languageId}: ${msg}`);\n}\n// Throwing errors\nexport function createError(lexer, msg) {\n    return new Error(`${lexer.languageId}: ${msg}`);\n}\n// Helper functions for rule finding and substitution\n/**\n * substituteMatches is used on lexer strings and can substitutes predefined patterns:\n * \t\t$$  => $\n * \t\t$#  => id\n * \t\t$n  => matched entry n\n * \t\t@attr => contents of lexer[attr]\n *\n * See documentation for more info\n */\nexport function substituteMatches(lexer, str, id, matches, state) {\n    const re = /\\$((\\$)|(#)|(\\d\\d?)|[sS](\\d\\d?)|@(\\w+))/g;\n    let stateMatches = null;\n    return str.replace(re, function (full, sub, dollar, hash, n, s, attr, ofs, total) {\n        if (!empty(dollar)) {\n            return '$'; // $$\n        }\n        if (!empty(hash)) {\n            return fixCase(lexer, id); // default $#\n        }\n        if (!empty(n) && n < matches.length) {\n            return fixCase(lexer, matches[n]); // $n\n        }\n        if (!empty(attr) && lexer && typeof (lexer[attr]) === 'string') {\n            return lexer[attr]; //@attribute\n        }\n        if (stateMatches === null) { // split state on demand\n            stateMatches = state.split('.');\n            stateMatches.unshift(state);\n        }\n        if (!empty(s) && s < stateMatches.length) {\n            return fixCase(lexer, stateMatches[s]); //$Sn\n        }\n        return '';\n    });\n}\n/**\n * Find the tokenizer rules for a specific state (i.e. next action)\n */\nexport function findRules(lexer, inState) {\n    let state = inState;\n    while (state && state.length > 0) {\n        const rules = lexer.tokenizer[state];\n        if (rules) {\n            return rules;\n        }\n        const idx = state.lastIndexOf('.');\n        if (idx < 0) {\n            state = null; // no further parent\n        }\n        else {\n            state = state.substr(0, idx);\n        }\n    }\n    return null;\n}\n/**\n * Is a certain state defined? In contrast to 'findRules' this works on a ILexerMin.\n * This is used during compilation where we may know the defined states\n * but not yet whether the corresponding rules are correct.\n */\nexport function stateExists(lexer, inState) {\n    let state = inState;\n    while (state && state.length > 0) {\n        const exist = lexer.stateNames[state];\n        if (exist) {\n            return true;\n        }\n        const idx = state.lastIndexOf('.');\n        if (idx < 0) {\n            state = null; // no further parent\n        }\n        else {\n            state = state.substr(0, idx);\n        }\n    }\n    return false;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\n};\nvar __param = (this && this.__param) || function (paramIndex, decorator) {\n    return function (target, key) { decorator(target, key, paramIndex); }\n};\nimport * as languages from '../../../common/languages.js';\nimport { NullState, nullTokenizeEncoded, nullTokenize } from '../../../common/languages/nullTokenize.js';\nimport * as monarchCommon from './monarchCommon.js';\nimport { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';\nconst CACHE_STACK_DEPTH = 5;\n/**\n * Reuse the same stack elements up to a certain depth.\n */\nclass MonarchStackElementFactory {\n    static create(parent, state) {\n        return this._INSTANCE.create(parent, state);\n    }\n    constructor(maxCacheDepth) {\n        this._maxCacheDepth = maxCacheDepth;\n        this._entries = Object.create(null);\n    }\n    create(parent, state) {\n        if (parent !== null && parent.depth >= this._maxCacheDepth) {\n            // no caching above a certain depth\n            return new MonarchStackElement(parent, state);\n        }\n        let stackElementId = MonarchStackElement.getStackElementId(parent);\n        if (stackElementId.length > 0) {\n            stackElementId += '|';\n        }\n        stackElementId += state;\n        let result = this._entries[stackElementId];\n        if (result) {\n            return result;\n        }\n        result = new MonarchStackElement(parent, state);\n        this._entries[stackElementId] = result;\n        return result;\n    }\n}\nMonarchStackElementFactory._INSTANCE = new MonarchStackElementFactory(CACHE_STACK_DEPTH);\nclass MonarchStackElement {\n    constructor(parent, state) {\n        this.parent = parent;\n        this.state = state;\n        this.depth = (this.parent ? this.parent.depth : 0) + 1;\n    }\n    static getStackElementId(element) {\n        let result = '';\n        while (element !== null) {\n            if (result.length > 0) {\n                result += '|';\n            }\n            result += element.state;\n            element = element.parent;\n        }\n        return result;\n    }\n    static _equals(a, b) {\n        while (a !== null && b !== null) {\n            if (a === b) {\n                return true;\n            }\n            if (a.state !== b.state) {\n                return false;\n            }\n            a = a.parent;\n            b = b.parent;\n        }\n        if (a === null && b === null) {\n            return true;\n        }\n        return false;\n    }\n    equals(other) {\n        return MonarchStackElement._equals(this, other);\n    }\n    push(state) {\n        return MonarchStackElementFactory.create(this, state);\n    }\n    pop() {\n        return this.parent;\n    }\n    popall() {\n        let result = this;\n        while (result.parent) {\n            result = result.parent;\n        }\n        return result;\n    }\n    switchTo(state) {\n        return MonarchStackElementFactory.create(this.parent, state);\n    }\n}\nclass EmbeddedLanguageData {\n    constructor(languageId, state) {\n        this.languageId = languageId;\n        this.state = state;\n    }\n    equals(other) {\n        return (this.languageId === other.languageId\n            && this.state.equals(other.state));\n    }\n    clone() {\n        const stateClone = this.state.clone();\n        // save an object\n        if (stateClone === this.state) {\n            return this;\n        }\n        return new EmbeddedLanguageData(this.languageId, this.state);\n    }\n}\n/**\n * Reuse the same line states up to a certain depth.\n */\nclass MonarchLineStateFactory {\n    static create(stack, embeddedLanguageData) {\n        return this._INSTANCE.create(stack, embeddedLanguageData);\n    }\n    constructor(maxCacheDepth) {\n        this._maxCacheDepth = maxCacheDepth;\n        this._entries = Object.create(null);\n    }\n    create(stack, embeddedLanguageData) {\n        if (embeddedLanguageData !== null) {\n            // no caching when embedding\n            return new MonarchLineState(stack, embeddedLanguageData);\n        }\n        if (stack !== null && stack.depth >= this._maxCacheDepth) {\n            // no caching above a certain depth\n            return new MonarchLineState(stack, embeddedLanguageData);\n        }\n        const stackElementId = MonarchStackElement.getStackElementId(stack);\n        let result = this._entries[stackElementId];\n        if (result) {\n            return result;\n        }\n        result = new MonarchLineState(stack, null);\n        this._entries[stackElementId] = result;\n        return result;\n    }\n}\nMonarchLineStateFactory._INSTANCE = new MonarchLineStateFactory(CACHE_STACK_DEPTH);\nclass MonarchLineState {\n    constructor(stack, embeddedLanguageData) {\n        this.stack = stack;\n        this.embeddedLanguageData = embeddedLanguageData;\n    }\n    clone() {\n        const embeddedlanguageDataClone = this.embeddedLanguageData ? this.embeddedLanguageData.clone() : null;\n        // save an object\n        if (embeddedlanguageDataClone === this.embeddedLanguageData) {\n            return this;\n        }\n        return MonarchLineStateFactory.create(this.stack, this.embeddedLanguageData);\n    }\n    equals(other) {\n        if (!(other instanceof MonarchLineState)) {\n            return false;\n        }\n        if (!this.stack.equals(other.stack)) {\n            return false;\n        }\n        if (this.embeddedLanguageData === null && other.embeddedLanguageData === null) {\n            return true;\n        }\n        if (this.embeddedLanguageData === null || other.embeddedLanguageData === null) {\n            return false;\n        }\n        return this.embeddedLanguageData.equals(other.embeddedLanguageData);\n    }\n}\nclass MonarchClassicTokensCollector {\n    constructor() {\n        this._tokens = [];\n        this._languageId = null;\n        this._lastTokenType = null;\n        this._lastTokenLanguage = null;\n    }\n    enterLanguage(languageId) {\n        this._languageId = languageId;\n    }\n    emit(startOffset, type) {\n        if (this._lastTokenType === type && this._lastTokenLanguage === this._languageId) {\n            return;\n        }\n        this._lastTokenType = type;\n        this._lastTokenLanguage = this._languageId;\n        this._tokens.push(new languages.Token(startOffset, type, this._languageId));\n    }\n    nestedLanguageTokenize(embeddedLanguageLine, hasEOL, embeddedLanguageData, offsetDelta) {\n        const nestedLanguageId = embeddedLanguageData.languageId;\n        const embeddedModeState = embeddedLanguageData.state;\n        const nestedLanguageTokenizationSupport = languages.TokenizationRegistry.get(nestedLanguageId);\n        if (!nestedLanguageTokenizationSupport) {\n            this.enterLanguage(nestedLanguageId);\n            this.emit(offsetDelta, '');\n            return embeddedModeState;\n        }\n        const nestedResult = nestedLanguageTokenizationSupport.tokenize(embeddedLanguageLine, hasEOL, embeddedModeState);\n        if (offsetDelta !== 0) {\n            for (const token of nestedResult.tokens) {\n                this._tokens.push(new languages.Token(token.offset + offsetDelta, token.type, token.language));\n            }\n        }\n        else {\n            this._tokens = this._tokens.concat(nestedResult.tokens);\n        }\n        this._lastTokenType = null;\n        this._lastTokenLanguage = null;\n        this._languageId = null;\n        return nestedResult.endState;\n    }\n    finalize(endState) {\n        return new languages.TokenizationResult(this._tokens, endState);\n    }\n}\nclass MonarchModernTokensCollector {\n    constructor(languageService, theme) {\n        this._languageService = languageService;\n        this._theme = theme;\n        this._prependTokens = null;\n        this._tokens = [];\n        this._currentLanguageId = 0 /* LanguageId.Null */;\n        this._lastTokenMetadata = 0;\n    }\n    enterLanguage(languageId) {\n        this._currentLanguageId = this._languageService.languageIdCodec.encodeLanguageId(languageId);\n    }\n    emit(startOffset, type) {\n        const metadata = this._theme.match(this._currentLanguageId, type) | 1024 /* MetadataConsts.BALANCED_BRACKETS_MASK */;\n        if (this._lastTokenMetadata === metadata) {\n            return;\n        }\n        this._lastTokenMetadata = metadata;\n        this._tokens.push(startOffset);\n        this._tokens.push(metadata);\n    }\n    static _merge(a, b, c) {\n        const aLen = (a !== null ? a.length : 0);\n        const bLen = b.length;\n        const cLen = (c !== null ? c.length : 0);\n        if (aLen === 0 && bLen === 0 && cLen === 0) {\n            return new Uint32Array(0);\n        }\n        if (aLen === 0 && bLen === 0) {\n            return c;\n        }\n        if (bLen === 0 && cLen === 0) {\n            return a;\n        }\n        const result = new Uint32Array(aLen + bLen + cLen);\n        if (a !== null) {\n            result.set(a);\n        }\n        for (let i = 0; i < bLen; i++) {\n            result[aLen + i] = b[i];\n        }\n        if (c !== null) {\n            result.set(c, aLen + bLen);\n        }\n        return result;\n    }\n    nestedLanguageTokenize(embeddedLanguageLine, hasEOL, embeddedLanguageData, offsetDelta) {\n        const nestedLanguageId = embeddedLanguageData.languageId;\n        const embeddedModeState = embeddedLanguageData.state;\n        const nestedLanguageTokenizationSupport = languages.TokenizationRegistry.get(nestedLanguageId);\n        if (!nestedLanguageTokenizationSupport) {\n            this.enterLanguage(nestedLanguageId);\n            this.emit(offsetDelta, '');\n            return embeddedModeState;\n        }\n        const nestedResult = nestedLanguageTokenizationSupport.tokenizeEncoded(embeddedLanguageLine, hasEOL, embeddedModeState);\n        if (offsetDelta !== 0) {\n            for (let i = 0, len = nestedResult.tokens.length; i < len; i += 2) {\n                nestedResult.tokens[i] += offsetDelta;\n            }\n        }\n        this._prependTokens = MonarchModernTokensCollector._merge(this._prependTokens, this._tokens, nestedResult.tokens);\n        this._tokens = [];\n        this._currentLanguageId = 0;\n        this._lastTokenMetadata = 0;\n        return nestedResult.endState;\n    }\n    finalize(endState) {\n        return new languages.EncodedTokenizationResult(MonarchModernTokensCollector._merge(this._prependTokens, this._tokens, null), endState);\n    }\n}\nexport let MonarchTokenizer = class MonarchTokenizer {\n    constructor(languageService, standaloneThemeService, languageId, lexer, _configurationService) {\n        this._configurationService = _configurationService;\n        this._languageService = languageService;\n        this._standaloneThemeService = standaloneThemeService;\n        this._languageId = languageId;\n        this._lexer = lexer;\n        this._embeddedLanguages = Object.create(null);\n        this.embeddedLoaded = Promise.resolve(undefined);\n        // Set up listening for embedded modes\n        let emitting = false;\n        this._tokenizationRegistryListener = languages.TokenizationRegistry.onDidChange((e) => {\n            if (emitting) {\n                return;\n            }\n            let isOneOfMyEmbeddedModes = false;\n            for (let i = 0, len = e.changedLanguages.length; i < len; i++) {\n                const language = e.changedLanguages[i];\n                if (this._embeddedLanguages[language]) {\n                    isOneOfMyEmbeddedModes = true;\n                    break;\n                }\n            }\n            if (isOneOfMyEmbeddedModes) {\n                emitting = true;\n                languages.TokenizationRegistry.handleChange([this._languageId]);\n                emitting = false;\n            }\n        });\n        this._maxTokenizationLineLength = this._configurationService.getValue('editor.maxTokenizationLineLength', {\n            overrideIdentifier: this._languageId\n        });\n        this._configurationService.onDidChangeConfiguration(e => {\n            if (e.affectsConfiguration('editor.maxTokenizationLineLength')) {\n                this._maxTokenizationLineLength = this._configurationService.getValue('editor.maxTokenizationLineLength', {\n                    overrideIdentifier: this._languageId\n                });\n            }\n        });\n    }\n    dispose() {\n        this._tokenizationRegistryListener.dispose();\n    }\n    getLoadStatus() {\n        const promises = [];\n        for (const nestedLanguageId in this._embeddedLanguages) {\n            const tokenizationSupport = languages.TokenizationRegistry.get(nestedLanguageId);\n            if (tokenizationSupport) {\n                // The nested language is already loaded\n                if (tokenizationSupport instanceof MonarchTokenizer) {\n                    const nestedModeStatus = tokenizationSupport.getLoadStatus();\n                    if (nestedModeStatus.loaded === false) {\n                        promises.push(nestedModeStatus.promise);\n                    }\n                }\n                continue;\n            }\n            if (!languages.TokenizationRegistry.isResolved(nestedLanguageId)) {\n                // The nested language is in the process of being loaded\n                promises.push(languages.TokenizationRegistry.getOrCreate(nestedLanguageId));\n            }\n        }\n        if (promises.length === 0) {\n            return {\n                loaded: true\n            };\n        }\n        return {\n            loaded: false,\n            promise: Promise.all(promises).then(_ => undefined)\n        };\n    }\n    getInitialState() {\n        const rootState = MonarchStackElementFactory.create(null, this._lexer.start);\n        return MonarchLineStateFactory.create(rootState, null);\n    }\n    tokenize(line, hasEOL, lineState) {\n        if (line.length >= this._maxTokenizationLineLength) {\n            return nullTokenize(this._languageId, lineState);\n        }\n        const tokensCollector = new MonarchClassicTokensCollector();\n        const endLineState = this._tokenize(line, hasEOL, lineState, tokensCollector);\n        return tokensCollector.finalize(endLineState);\n    }\n    tokenizeEncoded(line, hasEOL, lineState) {\n        if (line.length >= this._maxTokenizationLineLength) {\n            return nullTokenizeEncoded(this._languageService.languageIdCodec.encodeLanguageId(this._languageId), lineState);\n        }\n        const tokensCollector = new MonarchModernTokensCollector(this._languageService, this._standaloneThemeService.getColorTheme().tokenTheme);\n        const endLineState = this._tokenize(line, hasEOL, lineState, tokensCollector);\n        return tokensCollector.finalize(endLineState);\n    }\n    _tokenize(line, hasEOL, lineState, collector) {\n        if (lineState.embeddedLanguageData) {\n            return this._nestedTokenize(line, hasEOL, lineState, 0, collector);\n        }\n        else {\n            return this._myTokenize(line, hasEOL, lineState, 0, collector);\n        }\n    }\n    _findLeavingNestedLanguageOffset(line, state) {\n        let rules = this._lexer.tokenizer[state.stack.state];\n        if (!rules) {\n            rules = monarchCommon.findRules(this._lexer, state.stack.state); // do parent matching\n            if (!rules) {\n                throw monarchCommon.createError(this._lexer, 'tokenizer state is not defined: ' + state.stack.state);\n            }\n        }\n        let popOffset = -1;\n        let hasEmbeddedPopRule = false;\n        for (const rule of rules) {\n            if (!monarchCommon.isIAction(rule.action) || rule.action.nextEmbedded !== '@pop') {\n                continue;\n            }\n            hasEmbeddedPopRule = true;\n            let regex = rule.regex;\n            const regexSource = rule.regex.source;\n            if (regexSource.substr(0, 4) === '^(?:' && regexSource.substr(regexSource.length - 1, 1) === ')') {\n                const flags = (regex.ignoreCase ? 'i' : '') + (regex.unicode ? 'u' : '');\n                regex = new RegExp(regexSource.substr(4, regexSource.length - 5), flags);\n            }\n            const result = line.search(regex);\n            if (result === -1 || (result !== 0 && rule.matchOnlyAtLineStart)) {\n                continue;\n            }\n            if (popOffset === -1 || result < popOffset) {\n                popOffset = result;\n            }\n        }\n        if (!hasEmbeddedPopRule) {\n            throw monarchCommon.createError(this._lexer, 'no rule containing nextEmbedded: \"@pop\" in tokenizer embedded state: ' + state.stack.state);\n        }\n        return popOffset;\n    }\n    _nestedTokenize(line, hasEOL, lineState, offsetDelta, tokensCollector) {\n        const popOffset = this._findLeavingNestedLanguageOffset(line, lineState);\n        if (popOffset === -1) {\n            // tokenization will not leave nested language\n            const nestedEndState = tokensCollector.nestedLanguageTokenize(line, hasEOL, lineState.embeddedLanguageData, offsetDelta);\n            return MonarchLineStateFactory.create(lineState.stack, new EmbeddedLanguageData(lineState.embeddedLanguageData.languageId, nestedEndState));\n        }\n        const nestedLanguageLine = line.substring(0, popOffset);\n        if (nestedLanguageLine.length > 0) {\n            // tokenize with the nested language\n            tokensCollector.nestedLanguageTokenize(nestedLanguageLine, false, lineState.embeddedLanguageData, offsetDelta);\n        }\n        const restOfTheLine = line.substring(popOffset);\n        return this._myTokenize(restOfTheLine, hasEOL, lineState, offsetDelta + popOffset, tokensCollector);\n    }\n    _safeRuleName(rule) {\n        if (rule) {\n            return rule.name;\n        }\n        return '(unknown)';\n    }\n    _myTokenize(lineWithoutLF, hasEOL, lineState, offsetDelta, tokensCollector) {\n        tokensCollector.enterLanguage(this._languageId);\n        const lineWithoutLFLength = lineWithoutLF.length;\n        const line = (hasEOL && this._lexer.includeLF ? lineWithoutLF + '\\n' : lineWithoutLF);\n        const lineLength = line.length;\n        let embeddedLanguageData = lineState.embeddedLanguageData;\n        let stack = lineState.stack;\n        let pos = 0;\n        let groupMatching = null;\n        // See https://github.com/microsoft/monaco-editor/issues/1235\n        // Evaluate rules at least once for an empty line\n        let forceEvaluation = true;\n        while (forceEvaluation || pos < lineLength) {\n            const pos0 = pos;\n            const stackLen0 = stack.depth;\n            const groupLen0 = groupMatching ? groupMatching.groups.length : 0;\n            const state = stack.state;\n            let matches = null;\n            let matched = null;\n            let action = null;\n            let rule = null;\n            let enteringEmbeddedLanguage = null;\n            // check if we need to process group matches first\n            if (groupMatching) {\n                matches = groupMatching.matches;\n                const groupEntry = groupMatching.groups.shift();\n                matched = groupEntry.matched;\n                action = groupEntry.action;\n                rule = groupMatching.rule;\n                // cleanup if necessary\n                if (groupMatching.groups.length === 0) {\n                    groupMatching = null;\n                }\n            }\n            else {\n                // otherwise we match on the token stream\n                if (!forceEvaluation && pos >= lineLength) {\n                    // nothing to do\n                    break;\n                }\n                forceEvaluation = false;\n                // get the rules for this state\n                let rules = this._lexer.tokenizer[state];\n                if (!rules) {\n                    rules = monarchCommon.findRules(this._lexer, state); // do parent matching\n                    if (!rules) {\n                        throw monarchCommon.createError(this._lexer, 'tokenizer state is not defined: ' + state);\n                    }\n                }\n                // try each rule until we match\n                const restOfLine = line.substr(pos);\n                for (const rule of rules) {\n                    if (pos === 0 || !rule.matchOnlyAtLineStart) {\n                        matches = restOfLine.match(rule.regex);\n                        if (matches) {\n                            matched = matches[0];\n                            action = rule.action;\n                            break;\n                        }\n                    }\n                }\n            }\n            // We matched 'rule' with 'matches' and 'action'\n            if (!matches) {\n                matches = [''];\n                matched = '';\n            }\n            if (!action) {\n                // bad: we didn't match anything, and there is no action to take\n                // we need to advance the stream or we get progress trouble\n                if (pos < lineLength) {\n                    matches = [line.charAt(pos)];\n                    matched = matches[0];\n                }\n                action = this._lexer.defaultToken;\n            }\n            if (matched === null) {\n                // should never happen, needed for strict null checking\n                break;\n            }\n            // advance stream\n            pos += matched.length;\n            // maybe call action function (used for 'cases')\n            while (monarchCommon.isFuzzyAction(action) && monarchCommon.isIAction(action) && action.test) {\n                action = action.test(matched, matches, state, pos === lineLength);\n            }\n            let result = null;\n            // set the result: either a string or an array of actions\n            if (typeof action === 'string' || Array.isArray(action)) {\n                result = action;\n            }\n            else if (action.group) {\n                result = action.group;\n            }\n            else if (action.token !== null && action.token !== undefined) {\n                // do $n replacements?\n                if (action.tokenSubst) {\n                    result = monarchCommon.substituteMatches(this._lexer, action.token, matched, matches, state);\n                }\n                else {\n                    result = action.token;\n                }\n                // enter embedded language?\n                if (action.nextEmbedded) {\n                    if (action.nextEmbedded === '@pop') {\n                        if (!embeddedLanguageData) {\n                            throw monarchCommon.createError(this._lexer, 'cannot pop embedded language if not inside one');\n                        }\n                        embeddedLanguageData = null;\n                    }\n                    else if (embeddedLanguageData) {\n                        throw monarchCommon.createError(this._lexer, 'cannot enter embedded language from within an embedded language');\n                    }\n                    else {\n                        enteringEmbeddedLanguage = monarchCommon.substituteMatches(this._lexer, action.nextEmbedded, matched, matches, state);\n                    }\n                }\n                // state transformations\n                if (action.goBack) { // back up the stream..\n                    pos = Math.max(0, pos - action.goBack);\n                }\n                if (action.switchTo && typeof action.switchTo === 'string') {\n                    let nextState = monarchCommon.substituteMatches(this._lexer, action.switchTo, matched, matches, state); // switch state without a push...\n                    if (nextState[0] === '@') {\n                        nextState = nextState.substr(1); // peel off starting '@'\n                    }\n                    if (!monarchCommon.findRules(this._lexer, nextState)) {\n                        throw monarchCommon.createError(this._lexer, 'trying to switch to a state \\'' + nextState + '\\' that is undefined in rule: ' + this._safeRuleName(rule));\n                    }\n                    else {\n                        stack = stack.switchTo(nextState);\n                    }\n                }\n                else if (action.transform && typeof action.transform === 'function') {\n                    throw monarchCommon.createError(this._lexer, 'action.transform not supported');\n                }\n                else if (action.next) {\n                    if (action.next === '@push') {\n                        if (stack.depth >= this._lexer.maxStack) {\n                            throw monarchCommon.createError(this._lexer, 'maximum tokenizer stack size reached: [' +\n                                stack.state + ',' + stack.parent.state + ',...]');\n                        }\n                        else {\n                            stack = stack.push(state);\n                        }\n                    }\n                    else if (action.next === '@pop') {\n                        if (stack.depth <= 1) {\n                            throw monarchCommon.createError(this._lexer, 'trying to pop an empty stack in rule: ' + this._safeRuleName(rule));\n                        }\n                        else {\n                            stack = stack.pop();\n                        }\n                    }\n                    else if (action.next === '@popall') {\n                        stack = stack.popall();\n                    }\n                    else {\n                        let nextState = monarchCommon.substituteMatches(this._lexer, action.next, matched, matches, state);\n                        if (nextState[0] === '@') {\n                            nextState = nextState.substr(1); // peel off starting '@'\n                        }\n                        if (!monarchCommon.findRules(this._lexer, nextState)) {\n                            throw monarchCommon.createError(this._lexer, 'trying to set a next state \\'' + nextState + '\\' that is undefined in rule: ' + this._safeRuleName(rule));\n                        }\n                        else {\n                            stack = stack.push(nextState);\n                        }\n                    }\n                }\n                if (action.log && typeof (action.log) === 'string') {\n                    monarchCommon.log(this._lexer, this._lexer.languageId + ': ' + monarchCommon.substituteMatches(this._lexer, action.log, matched, matches, state));\n                }\n            }\n            // check result\n            if (result === null) {\n                throw monarchCommon.createError(this._lexer, 'lexer rule has no well-defined action in rule: ' + this._safeRuleName(rule));\n            }\n            const computeNewStateForEmbeddedLanguage = (enteringEmbeddedLanguage) => {\n                // support language names, mime types, and language ids\n                const languageId = (this._languageService.getLanguageIdByLanguageName(enteringEmbeddedLanguage)\n                    || this._languageService.getLanguageIdByMimeType(enteringEmbeddedLanguage)\n                    || enteringEmbeddedLanguage);\n                const embeddedLanguageData = this._getNestedEmbeddedLanguageData(languageId);\n                if (pos < lineLength) {\n                    // there is content from the embedded language on this line\n                    const restOfLine = lineWithoutLF.substr(pos);\n                    return this._nestedTokenize(restOfLine, hasEOL, MonarchLineStateFactory.create(stack, embeddedLanguageData), offsetDelta + pos, tokensCollector);\n                }\n                else {\n                    return MonarchLineStateFactory.create(stack, embeddedLanguageData);\n                }\n            };\n            // is the result a group match?\n            if (Array.isArray(result)) {\n                if (groupMatching && groupMatching.groups.length > 0) {\n                    throw monarchCommon.createError(this._lexer, 'groups cannot be nested: ' + this._safeRuleName(rule));\n                }\n                if (matches.length !== result.length + 1) {\n                    throw monarchCommon.createError(this._lexer, 'matched number of groups does not match the number of actions in rule: ' + this._safeRuleName(rule));\n                }\n                let totalLen = 0;\n                for (let i = 1; i < matches.length; i++) {\n                    totalLen += matches[i].length;\n                }\n                if (totalLen !== matched.length) {\n                    throw monarchCommon.createError(this._lexer, 'with groups, all characters should be matched in consecutive groups in rule: ' + this._safeRuleName(rule));\n                }\n                groupMatching = {\n                    rule: rule,\n                    matches: matches,\n                    groups: []\n                };\n                for (let i = 0; i < result.length; i++) {\n                    groupMatching.groups[i] = {\n                        action: result[i],\n                        matched: matches[i + 1]\n                    };\n                }\n                pos -= matched.length;\n                // call recursively to initiate first result match\n                continue;\n            }\n            else {\n                // regular result\n                // check for '@rematch'\n                if (result === '@rematch') {\n                    pos -= matched.length;\n                    matched = ''; // better set the next state too..\n                    matches = null;\n                    result = '';\n                    // Even though `@rematch` was specified, if `nextEmbedded` also specified,\n                    // a state transition should occur.\n                    if (enteringEmbeddedLanguage !== null) {\n                        return computeNewStateForEmbeddedLanguage(enteringEmbeddedLanguage);\n                    }\n                }\n                // check progress\n                if (matched.length === 0) {\n                    if (lineLength === 0 || stackLen0 !== stack.depth || state !== stack.state || (!groupMatching ? 0 : groupMatching.groups.length) !== groupLen0) {\n                        continue;\n                    }\n                    else {\n                        throw monarchCommon.createError(this._lexer, 'no progress in tokenizer in rule: ' + this._safeRuleName(rule));\n                    }\n                }\n                // return the result (and check for brace matching)\n                // todo: for efficiency we could pre-sanitize tokenPostfix and substitutions\n                let tokenType = null;\n                if (monarchCommon.isString(result) && result.indexOf('@brackets') === 0) {\n                    const rest = result.substr('@brackets'.length);\n                    const bracket = findBracket(this._lexer, matched);\n                    if (!bracket) {\n                        throw monarchCommon.createError(this._lexer, '@brackets token returned but no bracket defined as: ' + matched);\n                    }\n                    tokenType = monarchCommon.sanitize(bracket.token + rest);\n                }\n                else {\n                    const token = (result === '' ? '' : result + this._lexer.tokenPostfix);\n                    tokenType = monarchCommon.sanitize(token);\n                }\n                if (pos0 < lineWithoutLFLength) {\n                    tokensCollector.emit(pos0 + offsetDelta, tokenType);\n                }\n            }\n            if (enteringEmbeddedLanguage !== null) {\n                return computeNewStateForEmbeddedLanguage(enteringEmbeddedLanguage);\n            }\n        }\n        return MonarchLineStateFactory.create(stack, embeddedLanguageData);\n    }\n    _getNestedEmbeddedLanguageData(languageId) {\n        if (!this._languageService.isRegisteredLanguageId(languageId)) {\n            return new EmbeddedLanguageData(languageId, NullState);\n        }\n        if (languageId !== this._languageId) {\n            // Fire language loading event\n            this._languageService.requestBasicLanguageFeatures(languageId);\n            languages.TokenizationRegistry.getOrCreate(languageId);\n            this._embeddedLanguages[languageId] = true;\n        }\n        const tokenizationSupport = languages.TokenizationRegistry.get(languageId);\n        if (tokenizationSupport) {\n            return new EmbeddedLanguageData(languageId, tokenizationSupport.getInitialState());\n        }\n        return new EmbeddedLanguageData(languageId, NullState);\n    }\n};\nMonarchTokenizer = __decorate([\n    __param(4, IConfigurationService)\n], MonarchTokenizer);\n/**\n * Searches for a bracket in the 'brackets' attribute that matches the input.\n */\nfunction findBracket(lexer, matched) {\n    if (!matched) {\n        return null;\n    }\n    matched = monarchCommon.fixCase(lexer, matched);\n    const brackets = lexer.brackets;\n    for (const bracket of brackets) {\n        if (bracket.open === matched) {\n            return { token: bracket.token, bracketType: 1 /* monarchCommon.MonarchBracket.Open */ };\n        }\n        else if (bracket.close === matched) {\n            return { token: bracket.token, bracketType: -1 /* monarchCommon.MonarchBracket.Close */ };\n        }\n    }\n    return null;\n}\n","/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nimport { createTrustedTypesPolicy } from '../../../base/browser/trustedTypes.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { TokenizationRegistry } from '../../common/languages.js';\nimport { LineTokens } from '../../common/tokens/lineTokens.js';\nimport { RenderLineInput, renderViewLine2 as renderViewLine } from '../../common/viewLayout/viewLineRenderer.js';\nimport { ViewLineRenderingData } from '../../common/viewModel.js';\nimport { MonarchTokenizer } from '../common/monarch/monarchLexer.js';\nconst ttPolicy = createTrustedTypesPolicy('standaloneColorizer', { createHTML: value => value });\nexport class Colorizer {\n    static colorizeElement(themeService, languageService, domNode, options) {\n        options = options || {};\n        const theme = options.theme || 'vs';\n        const mimeType = options.mimeType || domNode.getAttribute('lang') || domNode.getAttribute('data-lang');\n        if (!mimeType) {\n            console.error('Mode not detected');\n            return Promise.resolve();\n        }\n        const languageId = languageService.getLanguageIdByMimeType(mimeType) || mimeType;\n        themeService.setTheme(theme);\n        const text = domNode.firstChild ? domNode.firstChild.nodeValue : '';\n        domNode.className += ' ' + theme;\n        const render = (str) => {\n            var _a;\n            const trustedhtml = (_a = ttPolicy === null || ttPolicy === void 0 ? void 0 : ttPolicy.createHTML(str)) !== null && _a !== void 0 ? _a : str;\n            domNode.innerHTML = trustedhtml;\n        };\n        return this.colorize(languageService, text || '', languageId, options).then(render, (err) => console.error(err));\n    }\n    static colorize(languageService, text, languageId, options) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const languageIdCodec = languageService.languageIdCodec;\n            let tabSize = 4;\n            if (options && typeof options.tabSize === 'number') {\n                tabSize = options.tabSize;\n            }\n            if (strings.startsWithUTF8BOM(text)) {\n                text = text.substr(1);\n            }\n            const lines = strings.splitLines(text);\n            if (!languageService.isRegisteredLanguageId(languageId)) {\n                return _fakeColorize(lines, tabSize, languageIdCodec);\n            }\n            const tokenizationSupport = yield TokenizationRegistry.getOrCreate(languageId);\n            if (tokenizationSupport) {\n                return _colorize(lines, tabSize, tokenizationSupport, languageIdCodec);\n            }\n            return _fakeColorize(lines, tabSize, languageIdCodec);\n        });\n    }\n    static colorizeLine(line, mightContainNonBasicASCII, mightContainRTL, tokens, tabSize = 4) {\n        const isBasicASCII = ViewLineRenderingData.isBasicASCII(line, mightContainNonBasicASCII);\n        const containsRTL = ViewLineRenderingData.containsRTL(line, isBasicASCII, mightContainRTL);\n        const renderResult = renderViewLine(new RenderLineInput(false, true, line, false, isBasicASCII, containsRTL, 0, tokens, [], tabSize, 0, 0, 0, 0, -1, 'none', false, false, null));\n        return renderResult.html;\n    }\n    static colorizeModelLine(model, lineNumber, tabSize = 4) {\n        const content = model.getLineContent(lineNumber);\n        model.tokenization.forceTokenization(lineNumber);\n        const tokens = model.tokenization.getLineTokens(lineNumber);\n        const inflatedTokens = tokens.inflate();\n        return this.colorizeLine(content, model.mightContainNonBasicASCII(), model.mightContainRTL(), inflatedTokens, tabSize);\n    }\n}\nfunction _colorize(lines, tabSize, tokenizationSupport, languageIdCodec) {\n    return new Promise((c, e) => {\n        const execute = () => {\n            const result = _actualColorize(lines, tabSize, tokenizationSupport, languageIdCodec);\n            if (tokenizationSupport instanceof MonarchTokenizer) {\n                const status = tokenizationSupport.getLoadStatus();\n                if (status.loaded === false) {\n                    status.promise.then(execute, e);\n                    return;\n                }\n            }\n            c(result);\n        };\n        execute();\n    });\n}\nfunction _fakeColorize(lines, tabSize, languageIdCodec) {\n    let html = [];\n    const defaultMetadata = ((0 /* FontStyle.None */ << 11 /* MetadataConsts.FONT_STYLE_OFFSET */)\n        | (1 /* ColorId.DefaultForeground */ << 15 /* MetadataConsts.FOREGROUND_OFFSET */)\n        | (2 /* ColorId.DefaultBackground */ << 24 /* MetadataConsts.BACKGROUND_OFFSET */)) >>> 0;\n    const tokens = new Uint32Array(2);\n    tokens[0] = 0;\n    tokens[1] = defaultMetadata;\n    for (let i = 0, length = lines.length; i < length; i++) {\n        const line = lines[i];\n        tokens[0] = line.length;\n        const lineTokens = new LineTokens(tokens, line, languageIdCodec);\n        const isBasicASCII = ViewLineRenderingData.isBasicASCII(line, /* check for basic ASCII */ true);\n        const containsRTL = ViewLineRenderingData.containsRTL(line, isBasicASCII, /* check for RTL */ true);\n        const renderResult = renderViewLine(new RenderLineInput(false, true, line, false, isBasicASCII, containsRTL, 0, lineTokens, [], tabSize, 0, 0, 0, 0, -1, 'none', false, false, null));\n        html = html.concat(renderResult.html);\n        html.push('
');\n }\n return html.join('');\n}\nfunction _actualColorize(lines, tabSize, tokenizationSupport, languageIdCodec) {\n let html = [];\n let state = tokenizationSupport.getInitialState();\n for (let i = 0, length = lines.length; i < length; i++) {\n const line = lines[i];\n const tokenizeResult = tokenizationSupport.tokenizeEncoded(line, true, state);\n LineTokens.convertToEndOffset(tokenizeResult.tokens, line.length);\n const lineTokens = new LineTokens(tokenizeResult.tokens, line, languageIdCodec);\n const isBasicASCII = ViewLineRenderingData.isBasicASCII(line, /* check for basic ASCII */ true);\n const containsRTL = ViewLineRenderingData.containsRTL(line, isBasicASCII, /* check for RTL */ true);\n const renderResult = renderViewLine(new RenderLineInput(false, true, line, false, isBasicASCII, containsRTL, 0, lineTokens.inflate(), [], tabSize, 0, 0, 0, 0, -1, 'none', false, false, null));\n html = html.concat(renderResult.html);\n html.push('
');\n state = tokenizeResult.endState;\n }\n return html.join('');\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as browser from './browser.js';\nimport * as platform from '../common/platform.js';\n/**\n * Browser feature we can support in current platform, browser and environment.\n */\nexport const BrowserFeatures = {\n clipboard: {\n writeText: (platform.isNative\n || (document.queryCommandSupported && document.queryCommandSupported('copy'))\n || !!(navigator && navigator.clipboard && navigator.clipboard.writeText)),\n readText: (platform.isNative\n || !!(navigator && navigator.clipboard && navigator.clipboard.readText))\n },\n keyboard: (() => {\n if (platform.isNative || browser.isStandalone()) {\n return 0 /* KeyboardSupport.Always */;\n }\n if (navigator.keyboard || browser.isSafari) {\n return 1 /* KeyboardSupport.FullScreen */;\n }\n return 2 /* KeyboardSupport.None */;\n })(),\n // 'ontouchstart' in window always evaluates to true with typescript's modern typings. This causes `window` to be\n // `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast\n touch: 'ontouchstart' in window || navigator.maxTouchPoints > 0,\n pointerEvents: window.PointerEvent && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0 || navigator.maxTouchPoints > 0)\n};\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { illegalArgument } from './errors.js';\nexport function decodeKeybinding(keybinding, OS) {\n if (typeof keybinding === 'number') {\n if (keybinding === 0) {\n return null;\n }\n const firstChord = (keybinding & 0x0000FFFF) >>> 0;\n const secondChord = (keybinding & 0xFFFF0000) >>> 16;\n if (secondChord !== 0) {\n return new Keybinding([\n createSimpleKeybinding(firstChord, OS),\n createSimpleKeybinding(secondChord, OS)\n ]);\n }\n return new Keybinding([createSimpleKeybinding(firstChord, OS)]);\n }\n else {\n const chords = [];\n for (let i = 0; i < keybinding.length; i++) {\n chords.push(createSimpleKeybinding(keybinding[i], OS));\n }\n return new Keybinding(chords);\n }\n}\nexport function createSimpleKeybinding(keybinding, OS) {\n const ctrlCmd = (keybinding & 2048 /* BinaryKeybindingsMask.CtrlCmd */ ? true : false);\n const winCtrl = (keybinding & 256 /* BinaryKeybindingsMask.WinCtrl */ ? true : false);\n const ctrlKey = (OS === 2 /* OperatingSystem.Macintosh */ ? winCtrl : ctrlCmd);\n const shiftKey = (keybinding & 1024 /* BinaryKeybindingsMask.Shift */ ? true : false);\n const altKey = (keybinding & 512 /* BinaryKeybindingsMask.Alt */ ? true : false);\n const metaKey = (OS === 2 /* OperatingSystem.Macintosh */ ? ctrlCmd : winCtrl);\n const keyCode = (keybinding & 255 /* BinaryKeybindingsMask.KeyCode */);\n return new KeyCodeChord(ctrlKey, shiftKey, altKey, metaKey, keyCode);\n}\n/**\n * Represents a chord which uses the `keyCode` field of keyboard events.\n * A chord is a combination of keys pressed simultaneously.\n */\nexport class KeyCodeChord {\n constructor(ctrlKey, shiftKey, altKey, metaKey, keyCode) {\n this.ctrlKey = ctrlKey;\n this.shiftKey = shiftKey;\n this.altKey = altKey;\n this.metaKey = metaKey;\n this.keyCode = keyCode;\n }\n equals(other) {\n return (other instanceof KeyCodeChord\n && this.ctrlKey === other.ctrlKey\n && this.shiftKey === other.shiftKey\n && this.altKey === other.altKey\n && this.metaKey === other.metaKey\n && this.keyCode === other.keyCode);\n }\n isModifierKey() {\n return (this.keyCode === 0 /* KeyCode.Unknown */\n || this.keyCode === 5 /* KeyCode.Ctrl */\n || this.keyCode === 57 /* KeyCode.Meta */\n || this.keyCode === 6 /* KeyCode.Alt */\n || this.keyCode === 4 /* KeyCode.Shift */);\n }\n /**\n * Does this keybinding refer to the key code of a modifier and it also has the modifier flag?\n */\n isDuplicateModifierCase() {\n return ((this.ctrlKey && this.keyCode === 5 /* KeyCode.Ctrl */)\n || (this.shiftKey && this.keyCode === 4 /* KeyCode.Shift */)\n || (this.altKey && this.keyCode === 6 /* KeyCode.Alt */)\n || (this.metaKey && this.keyCode === 57 /* KeyCode.Meta */));\n }\n}\n/**\n * Represents a chord which uses the `code` field of keyboard events.\n * A chord is a combination of keys pressed simultaneously.\n */\nexport class ScanCodeChord {\n constructor(ctrlKey, shiftKey, altKey, metaKey, scanCode) {\n this.ctrlKey = ctrlKey;\n this.shiftKey = shiftKey;\n this.altKey = altKey;\n this.metaKey = metaKey;\n this.scanCode = scanCode;\n }\n /**\n * Does this keybinding refer to the key code of a modifier and it also has the modifier flag?\n */\n isDuplicateModifierCase() {\n return ((this.ctrlKey && (this.scanCode === 157 /* ScanCode.ControlLeft */ || this.scanCode === 161 /* ScanCode.ControlRight */))\n || (this.shiftKey && (this.scanCode === 158 /* ScanCode.ShiftLeft */ || this.scanCode === 162 /* ScanCode.ShiftRight */))\n || (this.altKey && (this.scanCode === 159 /* ScanCode.AltLeft */ || this.scanCode === 163 /* ScanCode.AltRight */))\n || (this.metaKey && (this.scanCode === 160 /* ScanCode.MetaLeft */ || this.scanCode === 164 /* ScanCode.MetaRight */)));\n }\n}\n/**\n * A keybinding is a sequence of chords.\n */\nexport class Keybinding {\n constructor(chords) {\n if (chords.length === 0) {\n throw illegalArgument(`chords`);\n }\n this.chords = chords;\n }\n}\nexport class ResolvedChord {\n constructor(ctrlKey, shiftKey, altKey, metaKey, keyLabel, keyAriaLabel) {\n this.ctrlKey = ctrlKey;\n this.shiftKey = shiftKey;\n this.altKey = altKey;\n this.metaKey = metaKey;\n this.keyLabel = keyLabel;\n this.keyAriaLabel = keyAriaLabel;\n }\n}\n/**\n * A resolved keybinding. Consists of one or multiple chords.\n */\nexport class ResolvedKeybinding {\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as browser from './browser.js';\nimport { EVENT_KEY_CODE_MAP, KeyCodeUtils } from '../common/keyCodes.js';\nimport { KeyCodeChord } from '../common/keybindings.js';\nimport * as platform from '../common/platform.js';\nfunction extractKeyCode(e) {\n if (e.charCode) {\n // \"keypress\" events mostly\n const char = String.fromCharCode(e.charCode).toUpperCase();\n return KeyCodeUtils.fromString(char);\n }\n const keyCode = e.keyCode;\n // browser quirks\n if (keyCode === 3) {\n return 7 /* KeyCode.PauseBreak */;\n }\n else if (browser.isFirefox) {\n switch (keyCode) {\n case 59: return 85 /* KeyCode.Semicolon */;\n case 60:\n if (platform.isLinux) {\n return 97 /* KeyCode.IntlBackslash */;\n }\n break;\n case 61: return 86 /* KeyCode.Equal */;\n // based on: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#numpad_keys\n case 107: return 109 /* KeyCode.NumpadAdd */;\n case 109: return 111 /* KeyCode.NumpadSubtract */;\n case 173: return 88 /* KeyCode.Minus */;\n case 224:\n if (platform.isMacintosh) {\n return 57 /* KeyCode.Meta */;\n }\n break;\n }\n }\n else if (browser.isWebKit) {\n if (platform.isMacintosh && keyCode === 93) {\n // the two meta keys in the Mac have different key codes (91 and 93)\n return 57 /* KeyCode.Meta */;\n }\n else if (!platform.isMacintosh && keyCode === 92) {\n return 57 /* KeyCode.Meta */;\n }\n }\n // cross browser keycodes:\n return EVENT_KEY_CODE_MAP[keyCode] || 0 /* KeyCode.Unknown */;\n}\nconst ctrlKeyMod = (platform.isMacintosh ? 256 /* KeyMod.WinCtrl */ : 2048 /* KeyMod.CtrlCmd */);\nconst altKeyMod = 512 /* KeyMod.Alt */;\nconst shiftKeyMod = 1024 /* KeyMod.Shift */;\nconst metaKeyMod = (platform.isMacintosh ? 2048 /* KeyMod.CtrlCmd */ : 256 /* KeyMod.WinCtrl */);\nexport class StandardKeyboardEvent {\n constructor(source) {\n this._standardKeyboardEventBrand = true;\n const e = source;\n this.browserEvent = e;\n this.target = e.target;\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n this.altGraphKey = e.getModifierState('AltGraph');\n this.keyCode = extractKeyCode(e);\n this.code = e.code;\n // console.info(e.type + \": keyCode: \" + e.keyCode + \", which: \" + e.which + \", charCode: \" + e.charCode + \", detail: \" + e.detail + \" ====> \" + this.keyCode + ' -- ' + KeyCode[this.keyCode]);\n this.ctrlKey = this.ctrlKey || this.keyCode === 5 /* KeyCode.Ctrl */;\n this.altKey = this.altKey || this.keyCode === 6 /* KeyCode.Alt */;\n this.shiftKey = this.shiftKey || this.keyCode === 4 /* KeyCode.Shift */;\n this.metaKey = this.metaKey || this.keyCode === 57 /* KeyCode.Meta */;\n this._asKeybinding = this._computeKeybinding();\n this._asKeyCodeChord = this._computeKeyCodeChord();\n // console.log(`code: ${e.code}, keyCode: ${e.keyCode}, key: ${e.key}`);\n }\n preventDefault() {\n if (this.browserEvent && this.browserEvent.preventDefault) {\n this.browserEvent.preventDefault();\n }\n }\n stopPropagation() {\n if (this.browserEvent && this.browserEvent.stopPropagation) {\n this.browserEvent.stopPropagation();\n }\n }\n toKeyCodeChord() {\n return this._asKeyCodeChord;\n }\n equals(other) {\n return this._asKeybinding === other;\n }\n _computeKeybinding() {\n let key = 0 /* KeyCode.Unknown */;\n if (this.keyCode !== 5 /* KeyCode.Ctrl */ && this.keyCode !== 4 /* KeyCode.Shift */ && this.keyCode !== 6 /* KeyCode.Alt */ && this.keyCode !== 57 /* KeyCode.Meta */) {\n key = this.keyCode;\n }\n let result = 0;\n if (this.ctrlKey) {\n result |= ctrlKeyMod;\n }\n if (this.altKey) {\n result |= altKeyMod;\n }\n if (this.shiftKey) {\n result |= shiftKeyMod;\n }\n if (this.metaKey) {\n result |= metaKeyMod;\n }\n result |= key;\n return result;\n }\n _computeKeyCodeChord() {\n let key = 0 /* KeyCode.Unknown */;\n if (this.keyCode !== 5 /* KeyCode.Ctrl */ && this.keyCode !== 4 /* KeyCode.Shift */ && this.keyCode !== 6 /* KeyCode.Alt */ && this.keyCode !== 57 /* KeyCode.Meta */) {\n key = this.keyCode;\n }\n return new KeyCodeChord(this.ctrlKey, this.shiftKey, this.altKey, this.metaKey, key);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nlet hasDifferentOriginAncestorFlag = false;\nlet sameOriginWindowChainCache = null;\nfunction getParentWindowIfSameOrigin(w) {\n if (!w.parent || w.parent === w) {\n return null;\n }\n // Cannot really tell if we have access to the parent window unless we try to access something in it\n try {\n const location = w.location;\n const parentLocation = w.parent.location;\n if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {\n hasDifferentOriginAncestorFlag = true;\n return null;\n }\n }\n catch (e) {\n hasDifferentOriginAncestorFlag = true;\n return null;\n }\n return w.parent;\n}\nexport class IframeUtils {\n /**\n * Returns a chain of embedded windows with the same origin (which can be accessed programmatically).\n * Having a chain of length 1 might mean that the current execution environment is running outside of an iframe or inside an iframe embedded in a window with a different origin.\n * To distinguish if at one point the current execution environment is running inside a window with a different origin, see hasDifferentOriginAncestor()\n */\n static getSameOriginWindowChain() {\n if (!sameOriginWindowChainCache) {\n sameOriginWindowChainCache = [];\n let w = window;\n let parent;\n do {\n parent = getParentWindowIfSameOrigin(w);\n if (parent) {\n sameOriginWindowChainCache.push({\n window: w,\n iframeElement: w.frameElement || null\n });\n }\n else {\n sameOriginWindowChainCache.push({\n window: w,\n iframeElement: null\n });\n }\n w = parent;\n } while (w);\n }\n return sameOriginWindowChainCache.slice(0);\n }\n /**\n * Returns the position of `childWindow` relative to `ancestorWindow`\n */\n static getPositionOfChildWindowRelativeToAncestorWindow(childWindow, ancestorWindow) {\n if (!ancestorWindow || childWindow === ancestorWindow) {\n return {\n top: 0,\n left: 0\n };\n }\n let top = 0, left = 0;\n const windowChain = this.getSameOriginWindowChain();\n for (const windowChainEl of windowChain) {\n top += windowChainEl.window.scrollY;\n left += windowChainEl.window.scrollX;\n if (windowChainEl.window === ancestorWindow) {\n break;\n }\n if (!windowChainEl.iframeElement) {\n break;\n }\n const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();\n top += boundingRect.top;\n left += boundingRect.left;\n }\n return {\n top: top,\n left: left\n };\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as browser from './browser.js';\nimport { IframeUtils } from './iframe.js';\nimport * as platform from '../common/platform.js';\nexport class StandardMouseEvent {\n constructor(e) {\n this.timestamp = Date.now();\n this.browserEvent = e;\n this.leftButton = e.button === 0;\n this.middleButton = e.button === 1;\n this.rightButton = e.button === 2;\n this.buttons = e.buttons;\n this.target = e.target;\n this.detail = e.detail || 1;\n if (e.type === 'dblclick') {\n this.detail = 2;\n }\n this.ctrlKey = e.ctrlKey;\n this.shiftKey = e.shiftKey;\n this.altKey = e.altKey;\n this.metaKey = e.metaKey;\n if (typeof e.pageX === 'number') {\n this.posx = e.pageX;\n this.posy = e.pageY;\n }\n else {\n // Probably hit by MSGestureEvent\n this.posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;\n this.posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;\n }\n // Find the position of the iframe this code is executing in relative to the iframe where the event was captured.\n const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(window, e.view);\n this.posx -= iframeOffsets.left;\n this.posy -= iframeOffsets.top;\n }\n preventDefault() {\n this.browserEvent.preventDefault();\n }\n stopPropagation() {\n this.browserEvent.stopPropagation();\n }\n}\nexport class StandardWheelEvent {\n constructor(e, deltaX = 0, deltaY = 0) {\n this.browserEvent = e || null;\n this.target = e ? (e.target || e.targetNode || e.srcElement) : null;\n this.deltaY = deltaY;\n this.deltaX = deltaX;\n if (e) {\n // Old (deprecated) wheel events\n const e1 = e;\n const e2 = e;\n // vertical delta scroll\n if (typeof e1.wheelDeltaY !== 'undefined') {\n this.deltaY = e1.wheelDeltaY / 120;\n }\n else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {\n this.deltaY = -e2.detail / 3;\n }\n else if (e.type === 'wheel') {\n // Modern wheel event\n // https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent\n const ev = e;\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n // the deltas are expressed in lines\n if (browser.isFirefox && !platform.isMacintosh) {\n this.deltaY = -e.deltaY / 3;\n }\n else {\n this.deltaY = -e.deltaY;\n }\n }\n else {\n this.deltaY = -e.deltaY / 40;\n }\n }\n // horizontal delta scroll\n if (typeof e1.wheelDeltaX !== 'undefined') {\n if (browser.isSafari && platform.isWindows) {\n this.deltaX = -(e1.wheelDeltaX / 120);\n }\n else {\n this.deltaX = e1.wheelDeltaX / 120;\n }\n }\n else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {\n this.deltaX = -e.detail / 3;\n }\n else if (e.type === 'wheel') {\n // Modern wheel event\n // https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent\n const ev = e;\n if (ev.deltaMode === ev.DOM_DELTA_LINE) {\n // the deltas are expressed in lines\n if (browser.isFirefox && !platform.isMacintosh) {\n this.deltaX = -e.deltaX / 3;\n }\n else {\n this.deltaX = -e.deltaX;\n }\n }\n else {\n this.deltaX = -e.deltaX / 40;\n }\n }\n // Assume a vertical scroll if nothing else worked\n if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {\n this.deltaY = e.wheelDelta / 120;\n }\n }\n }\n preventDefault() {\n var _a;\n (_a = this.browserEvent) === null || _a === void 0 ? void 0 : _a.preventDefault();\n }\n stopPropagation() {\n var _a;\n (_a = this.browserEvent) === null || _a === void 0 ? void 0 : _a.stopPropagation();\n }\n}\n","/*! @license DOMPurify 2.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.1/LICENSE */\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar hasOwnProperty = Object.hasOwnProperty,\n setPrototypeOf = Object.setPrototypeOf,\n isFrozen = Object.isFrozen,\n getPrototypeOf = Object.getPrototypeOf,\n getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar freeze = Object.freeze,\n seal = Object.seal,\n create = Object.create; // eslint-disable-line import/no-mutable-exports\n\nvar _ref = typeof Reflect !== 'undefined' && Reflect,\n apply = _ref.apply,\n construct = _ref.construct;\n\nif (!apply) {\n apply = function apply(fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\n\nif (!construct) {\n construct = function construct(Func, args) {\n return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))();\n };\n}\n\nvar arrayForEach = unapply(Array.prototype.forEach);\nvar arrayPop = unapply(Array.prototype.pop);\nvar arrayPush = unapply(Array.prototype.push);\n\nvar stringToLowerCase = unapply(String.prototype.toLowerCase);\nvar stringMatch = unapply(String.prototype.match);\nvar stringReplace = unapply(String.prototype.replace);\nvar stringIndexOf = unapply(String.prototype.indexOf);\nvar stringTrim = unapply(String.prototype.trim);\n\nvar regExpTest = unapply(RegExp.prototype.test);\n\nvar typeErrorCreate = unconstruct(TypeError);\n\nfunction unapply(func) {\n return function (thisArg) {\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return apply(func, thisArg, args);\n };\n}\n\nfunction unconstruct(func) {\n return function () {\n for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n return construct(func, args);\n };\n}\n\n/* Add properties to a lookup table */\nfunction addToSet(set, array) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n var l = array.length;\n while (l--) {\n var element = array[l];\n if (typeof element === 'string') {\n var lcElement = stringToLowerCase(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/* Shallow clone an object */\nfunction clone(object) {\n var newObject = create(null);\n\n var property = void 0;\n for (property in object) {\n if (apply(hasOwnProperty, object, [property])) {\n newObject[property] = object[property];\n }\n }\n\n return newObject;\n}\n\n/* IE10 doesn't support __lookupGetter__ so lets'\n * simulate it. It also automatically checks\n * if the prop is function or getter and behaves\n * accordingly. */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n var desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(element) {\n console.warn('fallback value for', element);\n return null;\n }\n\n return fallbackValue;\n}\n\nvar html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\n\n// SVG\nvar svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\n\nvar svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nvar svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'feimage', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\n\nvar mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nvar mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\n\nvar text = freeze(['#text']);\n\nvar html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']);\n\nvar svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\n\nvar mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\n\nvar xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nvar MUSTACHE_EXPR = seal(/\\{\\{[\\s\\S]*|[\\s\\S]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nvar ERB_EXPR = seal(/<%[\\s\\S]*|[\\s\\S]*%>/gm);\nvar DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nvar ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nvar IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nvar IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nvar ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {Document} document The document object (to determine policy name suffix)\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported).\n */\nvar _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {\n if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n var suffix = null;\n var ATTR_NAME = 'data-tt-policy-suffix';\n if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {\n suffix = document.currentScript.getAttribute(ATTR_NAME);\n }\n\n var policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML: function createHTML(html$$1) {\n return html$$1;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\n\nfunction createDOMPurify() {\n var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n\n var DOMPurify = function DOMPurify(root) {\n return createDOMPurify(root);\n };\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = '2.3.1';\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n var originalDocument = window.document;\n\n var document = window.document;\n var DocumentFragment = window.DocumentFragment,\n HTMLTemplateElement = window.HTMLTemplateElement,\n Node = window.Node,\n Element = window.Element,\n NodeFilter = window.NodeFilter,\n _window$NamedNodeMap = window.NamedNodeMap,\n NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,\n Text = window.Text,\n Comment = window.Comment,\n DOMParser = window.DOMParser,\n trustedTypes = window.trustedTypes;\n\n\n var ElementPrototype = Element.prototype;\n\n var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n var getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n var template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);\n var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : '';\n\n var _document = document,\n implementation = _document.implementation,\n createNodeIterator = _document.createNodeIterator,\n createDocumentFragment = _document.createDocumentFragment,\n getElementsByTagName = _document.getElementsByTagName;\n var importNode = originalDocument.importNode;\n\n\n var documentMode = {};\n try {\n documentMode = clone(document).documentMode ? document.documentMode : {};\n } catch (_) {}\n\n var hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;\n\n var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,\n ERB_EXPR$$1 = ERB_EXPR,\n DATA_ATTR$$1 = DATA_ATTR,\n ARIA_ATTR$$1 = ARIA_ATTR,\n IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE$$1 = ATTR_WHITESPACE;\n var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n\n var ALLOWED_TAGS = null;\n var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text)));\n\n /* Allowed attribute names */\n var ALLOWED_ATTR = null;\n var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n var FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n var FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n var ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n var ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n var ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n var SAFE_FOR_TEMPLATES = false;\n\n /* Decide if document with ... should be returned */\n var WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n var SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n var FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n var RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n var RETURN_DOM_FRAGMENT = false;\n\n /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM\n * `Node` is imported into the current `Document`. If this flag is not enabled the\n * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by\n * DOMPurify.\n *\n * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`\n * might cause XSS from attacks hidden in closed shadowroots in case the browser\n * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/\n */\n var RETURN_DOM_IMPORT = true;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n var RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks? */\n var SANITIZE_DOM = true;\n\n /* Keep element content when removing element? */\n var KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n var IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n var USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n var FORBID_CONTENTS = null;\n var DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n\n /* Tags that are safe for data: URIs */\n var DATA_URI_TAGS = null;\n var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n\n /* Attributes safe for values like \"javascript:\" */\n var URI_SAFE_ATTRIBUTES = null;\n var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n\n var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n var NAMESPACE = HTML_NAMESPACE;\n var IS_EMPTY_INPUT = false;\n\n /* Keep a reference to config to pass to hooks */\n var CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n var formElement = document.createElement('form');\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n var _parseConfig = function _parseConfig(cfg) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n /* Set configuration parameters */\n ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;\n URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text)));\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html);\n addToSet(ALLOWED_ATTR, html$1);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg);\n addToSet(ALLOWED_ATTR, svg$1);\n addToSet(ALLOWED_ATTR, xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg$1);\n addToSet(ALLOWED_ATTR, xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl);\n addToSet(ALLOWED_ATTR, mathMl$1);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n\n var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n var ALL_SVG_TAGS = addToSet({}, svg);\n addToSet(ALL_SVG_TAGS, svgFilters);\n addToSet(ALL_SVG_TAGS, svgDisallowed);\n\n var ALL_MATHML_TAGS = addToSet({}, mathMl);\n addToSet(ALL_MATHML_TAGS, mathMlDisallowed);\n\n /**\n *\n *\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n var _checkValidNamespace = function _checkValidNamespace(element) {\n var parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: HTML_NAMESPACE,\n tagName: 'template'\n };\n }\n\n var tagName = stringToLowerCase(element.tagName);\n var parentTagName = stringToLowerCase(parent.tagName);\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via\n // svg if parent is either or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erronously deleted from\n // HTML namespace.\n var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG or MathML). Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n var _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, { element: node });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n node.parentNode.removeChild(node);\n } catch (_) {\n try {\n node.outerHTML = emptyHTML;\n } catch (_) {\n node.remove();\n }\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n var _removeAttribute = function _removeAttribute(name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node\n });\n }\n\n node.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\"\" attributes\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n var _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n var doc = void 0;\n var leadingWhitespace = void 0;\n\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n var matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n var body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * _createIterator\n *\n * @param {Document} root document/fragment to create iterator for\n * @return {Iterator} iterator instance\n */\n var _createIterator = function _createIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n var _isClobbered = function _isClobbered(elm) {\n if (elm instanceof Text || elm instanceof Comment) {\n return false;\n }\n\n if (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function') {\n return true;\n }\n\n return false;\n };\n\n /**\n * _isNode\n *\n * @param {Node} obj object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n var _isNode = function _isNode(object) {\n return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n var _executeHook = function _executeHook(entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], function (hook) {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n var _sanitizeElements = function _sanitizeElements(currentNode) {\n var content = void 0;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check if tagname contains Unicode */\n if (stringMatch(currentNode.nodeName, /[\\u0080-\\uFFFF]/)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n var tagName = stringToLowerCase(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName: tagName,\n allowedTags: ALLOWED_TAGS\n });\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\\w]/g, currentNode.innerHTML) && regExpTest(/<[/\\w]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Mitigate a problem with templates inside select */\n if (tagName === 'select' && regExpTest(/\n // To cover cases of empty s, avoid using a range and use the 's bounding box\n const clientRects = domNode.children[startChildIndex].getClientRects();\n context.markDidDomLayout();\n return this._createHorizontalRangesFromClientRects(clientRects, context.clientRectDeltaLeft, context.clientRectScale);\n }\n // If crossing over to a span only to select offset 0, then use the previous span's maximum offset\n // Chrome is buggy and doesn't handle 0 offsets well sometimes.\n if (startChildIndex !== endChildIndex) {\n if (endChildIndex > 0 && endOffset === 0) {\n endChildIndex--;\n endOffset = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n }\n }\n let startElement = domNode.children[startChildIndex].firstChild;\n let endElement = domNode.children[endChildIndex].firstChild;\n if (!startElement || !endElement) {\n // When having an empty (without any text content), try to move to the previous \n if (!startElement && startOffset === 0 && startChildIndex > 0) {\n startElement = domNode.children[startChildIndex - 1].firstChild;\n startOffset = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n }\n if (!endElement && endOffset === 0 && endChildIndex > 0) {\n endElement = domNode.children[endChildIndex - 1].firstChild;\n endOffset = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;\n }\n }\n if (!startElement || !endElement) {\n return null;\n }\n startOffset = Math.min(startElement.textContent.length, Math.max(0, startOffset));\n endOffset = Math.min(endElement.textContent.length, Math.max(0, endOffset));\n const clientRects = this._readClientRects(startElement, startOffset, endElement, endOffset, context.endNode);\n context.markDidDomLayout();\n return this._createHorizontalRangesFromClientRects(clientRects, context.clientRectDeltaLeft, context.clientRectScale);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * Color scheme used by the OS and by color themes.\n */\nexport var ColorScheme;\n(function (ColorScheme) {\n ColorScheme[\"DARK\"] = \"dark\";\n ColorScheme[\"LIGHT\"] = \"light\";\n ColorScheme[\"HIGH_CONTRAST_DARK\"] = \"hcDark\";\n ColorScheme[\"HIGH_CONTRAST_LIGHT\"] = \"hcLight\";\n})(ColorScheme || (ColorScheme = {}));\nexport function isHighContrast(scheme) {\n return scheme === ColorScheme.HIGH_CONTRAST_DARK || scheme === ColorScheme.HIGH_CONTRAST_LIGHT;\n}\nexport function isDark(scheme) {\n return scheme === ColorScheme.DARK || scheme === ColorScheme.HIGH_CONTRAST_DARK;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as browser from '../../../../base/browser/browser.js';\nimport { createFastDomNode } from '../../../../base/browser/fastDomNode.js';\nimport * as platform from '../../../../base/common/platform.js';\nimport { RangeUtil } from './rangeUtil.js';\nimport { FloatHorizontalRange, VisibleRanges } from '../../view/renderingContext.js';\nimport { LineDecoration } from '../../../common/viewLayout/lineDecorations.js';\nimport { RenderLineInput, renderViewLine, LineRange, DomPosition } from '../../../common/viewLayout/viewLineRenderer.js';\nimport { isHighContrast } from '../../../../platform/theme/common/theme.js';\nimport { EditorFontLigatures } from '../../../common/config/editorOptions.js';\nconst canUseFastRenderedViewLine = (function () {\n if (platform.isNative) {\n // In VSCode we know very well when the zoom level changes\n return true;\n }\n if (platform.isLinux || browser.isFirefox || browser.isSafari) {\n // On Linux, it appears that zooming affects char widths (in pixels), which is unexpected.\n // --\n // Even though we read character widths correctly, having read them at a specific zoom level\n // does not mean they are the same at the current zoom level.\n // --\n // This could be improved if we ever figure out how to get an event when browsers zoom,\n // but until then we have to stick with reading client rects.\n // --\n // The same has been observed with Firefox on Windows7\n // --\n // The same has been oversved with Safari\n return false;\n }\n return true;\n})();\nlet monospaceAssumptionsAreValid = true;\nexport class ViewLineOptions {\n constructor(config, themeType) {\n this.themeType = themeType;\n const options = config.options;\n const fontInfo = options.get(48 /* EditorOption.fontInfo */);\n const experimentalWhitespaceRendering = options.get(36 /* EditorOption.experimentalWhitespaceRendering */);\n if (experimentalWhitespaceRendering === 'off') {\n this.renderWhitespace = options.get(96 /* EditorOption.renderWhitespace */);\n }\n else {\n // whitespace is rendered in a different layer\n this.renderWhitespace = 'none';\n }\n this.renderControlCharacters = options.get(91 /* EditorOption.renderControlCharacters */);\n this.spaceWidth = fontInfo.spaceWidth;\n this.middotWidth = fontInfo.middotWidth;\n this.wsmiddotWidth = fontInfo.wsmiddotWidth;\n this.useMonospaceOptimizations = (fontInfo.isMonospace\n && !options.get(31 /* EditorOption.disableMonospaceOptimizations */));\n this.canUseHalfwidthRightwardsArrow = fontInfo.canUseHalfwidthRightwardsArrow;\n this.lineHeight = options.get(64 /* EditorOption.lineHeight */);\n this.stopRenderingLineAfter = options.get(114 /* EditorOption.stopRenderingLineAfter */);\n this.fontLigatures = options.get(49 /* EditorOption.fontLigatures */);\n }\n equals(other) {\n return (this.themeType === other.themeType\n && this.renderWhitespace === other.renderWhitespace\n && this.renderControlCharacters === other.renderControlCharacters\n && this.spaceWidth === other.spaceWidth\n && this.middotWidth === other.middotWidth\n && this.wsmiddotWidth === other.wsmiddotWidth\n && this.useMonospaceOptimizations === other.useMonospaceOptimizations\n && this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow\n && this.lineHeight === other.lineHeight\n && this.stopRenderingLineAfter === other.stopRenderingLineAfter\n && this.fontLigatures === other.fontLigatures);\n }\n}\nexport class ViewLine {\n constructor(options) {\n this._options = options;\n this._isMaybeInvalid = true;\n this._renderedViewLine = null;\n }\n // --- begin IVisibleLineData\n getDomNode() {\n if (this._renderedViewLine && this._renderedViewLine.domNode) {\n return this._renderedViewLine.domNode.domNode;\n }\n return null;\n }\n setDomNode(domNode) {\n if (this._renderedViewLine) {\n this._renderedViewLine.domNode = createFastDomNode(domNode);\n }\n else {\n throw new Error('I have no rendered view line to set the dom node to...');\n }\n }\n onContentChanged() {\n this._isMaybeInvalid = true;\n }\n onTokensChanged() {\n this._isMaybeInvalid = true;\n }\n onDecorationsChanged() {\n this._isMaybeInvalid = true;\n }\n onOptionsChanged(newOptions) {\n this._isMaybeInvalid = true;\n this._options = newOptions;\n }\n onSelectionChanged() {\n if (isHighContrast(this._options.themeType) || this._options.renderWhitespace === 'selection') {\n this._isMaybeInvalid = true;\n return true;\n }\n return false;\n }\n renderLine(lineNumber, deltaTop, viewportData, sb) {\n if (this._isMaybeInvalid === false) {\n // it appears that nothing relevant has changed\n return false;\n }\n this._isMaybeInvalid = false;\n const lineData = viewportData.getViewLineRenderingData(lineNumber);\n const options = this._options;\n const actualInlineDecorations = LineDecoration.filter(lineData.inlineDecorations, lineNumber, lineData.minColumn, lineData.maxColumn);\n // Only send selection information when needed for rendering whitespace\n let selectionsOnLine = null;\n if (isHighContrast(options.themeType) || this._options.renderWhitespace === 'selection') {\n const selections = viewportData.selections;\n for (const selection of selections) {\n if (selection.endLineNumber < lineNumber || selection.startLineNumber > lineNumber) {\n // Selection does not intersect line\n continue;\n }\n const startColumn = (selection.startLineNumber === lineNumber ? selection.startColumn : lineData.minColumn);\n const endColumn = (selection.endLineNumber === lineNumber ? selection.endColumn : lineData.maxColumn);\n if (startColumn < endColumn) {\n if (isHighContrast(options.themeType)) {\n actualInlineDecorations.push(new LineDecoration(startColumn, endColumn, 'inline-selected-text', 0 /* InlineDecorationType.Regular */));\n }\n if (this._options.renderWhitespace === 'selection') {\n if (!selectionsOnLine) {\n selectionsOnLine = [];\n }\n selectionsOnLine.push(new LineRange(startColumn - 1, endColumn - 1));\n }\n }\n }\n }\n const renderLineInput = new RenderLineInput(options.useMonospaceOptimizations, options.canUseHalfwidthRightwardsArrow, lineData.content, lineData.continuesWithWrappedLine, lineData.isBasicASCII, lineData.containsRTL, lineData.minColumn - 1, lineData.tokens, actualInlineDecorations, lineData.tabSize, lineData.startVisibleColumn, options.spaceWidth, options.middotWidth, options.wsmiddotWidth, options.stopRenderingLineAfter, options.renderWhitespace, options.renderControlCharacters, options.fontLigatures !== EditorFontLigatures.OFF, selectionsOnLine);\n if (this._renderedViewLine && this._renderedViewLine.input.equals(renderLineInput)) {\n // no need to do anything, we have the same render input\n return false;\n }\n sb.appendString('
');\n const output = renderViewLine(renderLineInput, sb);\n sb.appendString('
');\n let renderedViewLine = null;\n if (monospaceAssumptionsAreValid && canUseFastRenderedViewLine && lineData.isBasicASCII && options.useMonospaceOptimizations && output.containsForeignElements === 0 /* ForeignElementType.None */) {\n renderedViewLine = new FastRenderedViewLine(this._renderedViewLine ? this._renderedViewLine.domNode : null, renderLineInput, output.characterMapping);\n }\n if (!renderedViewLine) {\n renderedViewLine = createRenderedLine(this._renderedViewLine ? this._renderedViewLine.domNode : null, renderLineInput, output.characterMapping, output.containsRTL, output.containsForeignElements);\n }\n this._renderedViewLine = renderedViewLine;\n return true;\n }\n layoutLine(lineNumber, deltaTop) {\n if (this._renderedViewLine && this._renderedViewLine.domNode) {\n this._renderedViewLine.domNode.setTop(deltaTop);\n this._renderedViewLine.domNode.setHeight(this._options.lineHeight);\n }\n }\n // --- end IVisibleLineData\n getWidth(context) {\n if (!this._renderedViewLine) {\n return 0;\n }\n return this._renderedViewLine.getWidth(context);\n }\n getWidthIsFast() {\n if (!this._renderedViewLine) {\n return true;\n }\n return this._renderedViewLine.getWidthIsFast();\n }\n needsMonospaceFontCheck() {\n if (!this._renderedViewLine) {\n return false;\n }\n return (this._renderedViewLine instanceof FastRenderedViewLine);\n }\n monospaceAssumptionsAreValid() {\n if (!this._renderedViewLine) {\n return monospaceAssumptionsAreValid;\n }\n if (this._renderedViewLine instanceof FastRenderedViewLine) {\n return this._renderedViewLine.monospaceAssumptionsAreValid();\n }\n return monospaceAssumptionsAreValid;\n }\n onMonospaceAssumptionsInvalidated() {\n if (this._renderedViewLine && this._renderedViewLine instanceof FastRenderedViewLine) {\n this._renderedViewLine = this._renderedViewLine.toSlowRenderedLine();\n }\n }\n getVisibleRangesForRange(lineNumber, startColumn, endColumn, context) {\n if (!this._renderedViewLine) {\n return null;\n }\n startColumn = Math.min(this._renderedViewLine.input.lineContent.length + 1, Math.max(1, startColumn));\n endColumn = Math.min(this._renderedViewLine.input.lineContent.length + 1, Math.max(1, endColumn));\n const stopRenderingLineAfter = this._renderedViewLine.input.stopRenderingLineAfter;\n if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter + 1 && endColumn > stopRenderingLineAfter + 1) {\n // This range is obviously not visible\n return new VisibleRanges(true, [new FloatHorizontalRange(this.getWidth(context), 0)]);\n }\n if (stopRenderingLineAfter !== -1 && startColumn > stopRenderingLineAfter + 1) {\n startColumn = stopRenderingLineAfter + 1;\n }\n if (stopRenderingLineAfter !== -1 && endColumn > stopRenderingLineAfter + 1) {\n endColumn = stopRenderingLineAfter + 1;\n }\n const horizontalRanges = this._renderedViewLine.getVisibleRangesForRange(lineNumber, startColumn, endColumn, context);\n if (horizontalRanges && horizontalRanges.length > 0) {\n return new VisibleRanges(false, horizontalRanges);\n }\n return null;\n }\n getColumnOfNodeOffset(lineNumber, spanNode, offset) {\n if (!this._renderedViewLine) {\n return 1;\n }\n return this._renderedViewLine.getColumnOfNodeOffset(lineNumber, spanNode, offset);\n }\n}\nViewLine.CLASS_NAME = 'view-line';\n/**\n * A rendered line which is guaranteed to contain only regular ASCII and is rendered with a monospace font.\n */\nclass FastRenderedViewLine {\n constructor(domNode, renderLineInput, characterMapping) {\n this._cachedWidth = -1;\n this.domNode = domNode;\n this.input = renderLineInput;\n const keyColumnCount = Math.floor(renderLineInput.lineContent.length / 300 /* Constants.MaxMonospaceDistance */);\n if (keyColumnCount > 0) {\n this._keyColumnPixelOffsetCache = new Float32Array(keyColumnCount);\n for (let i = 0; i < keyColumnCount; i++) {\n this._keyColumnPixelOffsetCache[i] = -1;\n }\n }\n else {\n this._keyColumnPixelOffsetCache = null;\n }\n this._characterMapping = characterMapping;\n this._charWidth = renderLineInput.spaceWidth;\n }\n getWidth(context) {\n if (!this.domNode || this.input.lineContent.length < 300 /* Constants.MaxMonospaceDistance */) {\n const horizontalOffset = this._characterMapping.getHorizontalOffset(this._characterMapping.length);\n return Math.round(this._charWidth * horizontalOffset);\n }\n if (this._cachedWidth === -1) {\n this._cachedWidth = this._getReadingTarget(this.domNode).offsetWidth;\n context === null || context === void 0 ? void 0 : context.markDidDomLayout();\n }\n return this._cachedWidth;\n }\n getWidthIsFast() {\n return (this.input.lineContent.length < 300 /* Constants.MaxMonospaceDistance */) || this._cachedWidth !== -1;\n }\n monospaceAssumptionsAreValid() {\n if (!this.domNode) {\n return monospaceAssumptionsAreValid;\n }\n if (this.input.lineContent.length < 300 /* Constants.MaxMonospaceDistance */) {\n const expectedWidth = this.getWidth(null);\n const actualWidth = this.domNode.domNode.firstChild.offsetWidth;\n if (Math.abs(expectedWidth - actualWidth) >= 2) {\n // more than 2px off\n console.warn(`monospace assumptions have been violated, therefore disabling monospace optimizations!`);\n monospaceAssumptionsAreValid = false;\n }\n }\n return monospaceAssumptionsAreValid;\n }\n toSlowRenderedLine() {\n return createRenderedLine(this.domNode, this.input, this._characterMapping, false, 0 /* ForeignElementType.None */);\n }\n getVisibleRangesForRange(lineNumber, startColumn, endColumn, context) {\n const startPosition = this._getColumnPixelOffset(lineNumber, startColumn, context);\n const endPosition = this._getColumnPixelOffset(lineNumber, endColumn, context);\n return [new FloatHorizontalRange(startPosition, endPosition - startPosition)];\n }\n _getColumnPixelOffset(lineNumber, column, context) {\n if (column <= 300 /* Constants.MaxMonospaceDistance */) {\n const horizontalOffset = this._characterMapping.getHorizontalOffset(column);\n return this._charWidth * horizontalOffset;\n }\n const keyColumnOrdinal = Math.floor((column - 1) / 300 /* Constants.MaxMonospaceDistance */) - 1;\n const keyColumn = (keyColumnOrdinal + 1) * 300 /* Constants.MaxMonospaceDistance */ + 1;\n let keyColumnPixelOffset = -1;\n if (this._keyColumnPixelOffsetCache) {\n keyColumnPixelOffset = this._keyColumnPixelOffsetCache[keyColumnOrdinal];\n if (keyColumnPixelOffset === -1) {\n keyColumnPixelOffset = this._actualReadPixelOffset(lineNumber, keyColumn, context);\n this._keyColumnPixelOffsetCache[keyColumnOrdinal] = keyColumnPixelOffset;\n }\n }\n if (keyColumnPixelOffset === -1) {\n // Could not read actual key column pixel offset\n const horizontalOffset = this._characterMapping.getHorizontalOffset(column);\n return this._charWidth * horizontalOffset;\n }\n const keyColumnHorizontalOffset = this._characterMapping.getHorizontalOffset(keyColumn);\n const horizontalOffset = this._characterMapping.getHorizontalOffset(column);\n return keyColumnPixelOffset + this._charWidth * (horizontalOffset - keyColumnHorizontalOffset);\n }\n _getReadingTarget(myDomNode) {\n return myDomNode.domNode.firstChild;\n }\n _actualReadPixelOffset(lineNumber, column, context) {\n if (!this.domNode) {\n return -1;\n }\n const domPosition = this._characterMapping.getDomPosition(column);\n const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(this.domNode), domPosition.partIndex, domPosition.charIndex, domPosition.partIndex, domPosition.charIndex, context);\n if (!r || r.length === 0) {\n return -1;\n }\n return r[0].left;\n }\n getColumnOfNodeOffset(lineNumber, spanNode, offset) {\n const spanNodeTextContentLength = spanNode.textContent.length;\n let spanIndex = -1;\n while (spanNode) {\n spanNode = spanNode.previousSibling;\n spanIndex++;\n }\n return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength);\n }\n}\n/**\n * Every time we render a line, we save what we have rendered in an instance of this class.\n */\nclass RenderedViewLine {\n constructor(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements) {\n this.domNode = domNode;\n this.input = renderLineInput;\n this._characterMapping = characterMapping;\n this._isWhitespaceOnly = /^\\s*$/.test(renderLineInput.lineContent);\n this._containsForeignElements = containsForeignElements;\n this._cachedWidth = -1;\n this._pixelOffsetCache = null;\n if (!containsRTL || this._characterMapping.length === 0 /* the line is empty */) {\n this._pixelOffsetCache = new Float32Array(Math.max(2, this._characterMapping.length + 1));\n for (let column = 0, len = this._characterMapping.length; column <= len; column++) {\n this._pixelOffsetCache[column] = -1;\n }\n }\n }\n // --- Reading from the DOM methods\n _getReadingTarget(myDomNode) {\n return myDomNode.domNode.firstChild;\n }\n /**\n * Width of the line in pixels\n */\n getWidth(context) {\n if (!this.domNode) {\n return 0;\n }\n if (this._cachedWidth === -1) {\n this._cachedWidth = this._getReadingTarget(this.domNode).offsetWidth;\n context === null || context === void 0 ? void 0 : context.markDidDomLayout();\n }\n return this._cachedWidth;\n }\n getWidthIsFast() {\n if (this._cachedWidth === -1) {\n return false;\n }\n return true;\n }\n /**\n * Visible ranges for a model range\n */\n getVisibleRangesForRange(lineNumber, startColumn, endColumn, context) {\n if (!this.domNode) {\n return null;\n }\n if (this._pixelOffsetCache !== null) {\n // the text is LTR\n const startOffset = this._readPixelOffset(this.domNode, lineNumber, startColumn, context);\n if (startOffset === -1) {\n return null;\n }\n const endOffset = this._readPixelOffset(this.domNode, lineNumber, endColumn, context);\n if (endOffset === -1) {\n return null;\n }\n return [new FloatHorizontalRange(startOffset, endOffset - startOffset)];\n }\n return this._readVisibleRangesForRange(this.domNode, lineNumber, startColumn, endColumn, context);\n }\n _readVisibleRangesForRange(domNode, lineNumber, startColumn, endColumn, context) {\n if (startColumn === endColumn) {\n const pixelOffset = this._readPixelOffset(domNode, lineNumber, startColumn, context);\n if (pixelOffset === -1) {\n return null;\n }\n else {\n return [new FloatHorizontalRange(pixelOffset, 0)];\n }\n }\n else {\n return this._readRawVisibleRangesForRange(domNode, startColumn, endColumn, context);\n }\n }\n _readPixelOffset(domNode, lineNumber, column, context) {\n if (this._characterMapping.length === 0) {\n // This line has no content\n if (this._containsForeignElements === 0 /* ForeignElementType.None */) {\n // We can assume the line is really empty\n return 0;\n }\n if (this._containsForeignElements === 2 /* ForeignElementType.After */) {\n // We have foreign elements after the (empty) line\n return 0;\n }\n if (this._containsForeignElements === 1 /* ForeignElementType.Before */) {\n // We have foreign elements before the (empty) line\n return this.getWidth(context);\n }\n // We have foreign elements before & after the (empty) line\n const readingTarget = this._getReadingTarget(domNode);\n if (readingTarget.firstChild) {\n context.markDidDomLayout();\n return readingTarget.firstChild.offsetWidth;\n }\n else {\n return 0;\n }\n }\n if (this._pixelOffsetCache !== null) {\n // the text is LTR\n const cachedPixelOffset = this._pixelOffsetCache[column];\n if (cachedPixelOffset !== -1) {\n return cachedPixelOffset;\n }\n const result = this._actualReadPixelOffset(domNode, lineNumber, column, context);\n this._pixelOffsetCache[column] = result;\n return result;\n }\n return this._actualReadPixelOffset(domNode, lineNumber, column, context);\n }\n _actualReadPixelOffset(domNode, lineNumber, column, context) {\n if (this._characterMapping.length === 0) {\n // This line has no content\n const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), 0, 0, 0, 0, context);\n if (!r || r.length === 0) {\n return -1;\n }\n return r[0].left;\n }\n if (column === this._characterMapping.length && this._isWhitespaceOnly && this._containsForeignElements === 0 /* ForeignElementType.None */) {\n // This branch helps in the case of whitespace only lines which have a width set\n return this.getWidth(context);\n }\n const domPosition = this._characterMapping.getDomPosition(column);\n const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), domPosition.partIndex, domPosition.charIndex, domPosition.partIndex, domPosition.charIndex, context);\n if (!r || r.length === 0) {\n return -1;\n }\n const result = r[0].left;\n if (this.input.isBasicASCII) {\n const horizontalOffset = this._characterMapping.getHorizontalOffset(column);\n const expectedResult = Math.round(this.input.spaceWidth * horizontalOffset);\n if (Math.abs(expectedResult - result) <= 1) {\n return expectedResult;\n }\n }\n return result;\n }\n _readRawVisibleRangesForRange(domNode, startColumn, endColumn, context) {\n if (startColumn === 1 && endColumn === this._characterMapping.length) {\n // This branch helps IE with bidi text & gives a performance boost to other browsers when reading visible ranges for an entire line\n return [new FloatHorizontalRange(0, this.getWidth(context))];\n }\n const startDomPosition = this._characterMapping.getDomPosition(startColumn);\n const endDomPosition = this._characterMapping.getDomPosition(endColumn);\n return RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), startDomPosition.partIndex, startDomPosition.charIndex, endDomPosition.partIndex, endDomPosition.charIndex, context);\n }\n /**\n * Returns the column for the text found at a specific offset inside a rendered dom node\n */\n getColumnOfNodeOffset(lineNumber, spanNode, offset) {\n const spanNodeTextContentLength = spanNode.textContent.length;\n let spanIndex = -1;\n while (spanNode) {\n spanNode = spanNode.previousSibling;\n spanIndex++;\n }\n return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength);\n }\n}\nclass WebKitRenderedViewLine extends RenderedViewLine {\n _readVisibleRangesForRange(domNode, lineNumber, startColumn, endColumn, context) {\n const output = super._readVisibleRangesForRange(domNode, lineNumber, startColumn, endColumn, context);\n if (!output || output.length === 0 || startColumn === endColumn || (startColumn === 1 && endColumn === this._characterMapping.length)) {\n return output;\n }\n // WebKit is buggy and returns an expanded range (to contain words in some cases)\n // The last client rect is enlarged (I think)\n if (!this.input.containsRTL) {\n // This is an attempt to patch things up\n // Find position of last column\n const endPixelOffset = this._readPixelOffset(domNode, lineNumber, endColumn, context);\n if (endPixelOffset !== -1) {\n const lastRange = output[output.length - 1];\n if (lastRange.left < endPixelOffset) {\n // Trim down the width of the last visible range to not go after the last column's position\n lastRange.width = endPixelOffset - lastRange.left;\n }\n }\n }\n return output;\n }\n}\nconst createRenderedLine = (function () {\n if (browser.isWebKit) {\n return createWebKitRenderedLine;\n }\n return createNormalRenderedLine;\n})();\nfunction createWebKitRenderedLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements) {\n return new WebKitRenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements);\n}\nfunction createNormalRenderedLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements) {\n return new RenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL, containsForeignElements);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../../base/common/strings.js';\n/**\n * A column in a position is the gap between two adjacent characters. The methods here\n * work with a concept called \"visible column\". A visible column is a very rough approximation\n * of the horizontal screen position of a column. For example, using a tab size of 4:\n * ```txt\n * |||T|ext\n * | | | \\---- column = 4, visible column = 9\n * | | \\------ column = 3, visible column = 8\n * | \\------------ column = 2, visible column = 4\n * \\------------------ column = 1, visible column = 0\n * ```\n *\n * **NOTE**: Visual columns do not work well for RTL text or variable-width fonts or characters.\n *\n * **NOTE**: These methods work and make sense both on the model and on the view model.\n */\nexport class CursorColumns {\n static _nextVisibleColumn(codePoint, visibleColumn, tabSize) {\n if (codePoint === 9 /* CharCode.Tab */) {\n return CursorColumns.nextRenderTabStop(visibleColumn, tabSize);\n }\n if (strings.isFullWidthCharacter(codePoint) || strings.isEmojiImprecise(codePoint)) {\n return visibleColumn + 2;\n }\n return visibleColumn + 1;\n }\n /**\n * Returns a visible column from a column.\n * @see {@link CursorColumns}\n */\n static visibleColumnFromColumn(lineContent, column, tabSize) {\n const textLen = Math.min(column - 1, lineContent.length);\n const text = lineContent.substring(0, textLen);\n const iterator = new strings.GraphemeIterator(text);\n let result = 0;\n while (!iterator.eol()) {\n const codePoint = strings.getNextCodePoint(text, textLen, iterator.offset);\n iterator.nextGraphemeLength();\n result = this._nextVisibleColumn(codePoint, result, tabSize);\n }\n return result;\n }\n /**\n * Returns a column from a visible column.\n * @see {@link CursorColumns}\n */\n static columnFromVisibleColumn(lineContent, visibleColumn, tabSize) {\n if (visibleColumn <= 0) {\n return 1;\n }\n const lineContentLength = lineContent.length;\n const iterator = new strings.GraphemeIterator(lineContent);\n let beforeVisibleColumn = 0;\n let beforeColumn = 1;\n while (!iterator.eol()) {\n const codePoint = strings.getNextCodePoint(lineContent, lineContentLength, iterator.offset);\n iterator.nextGraphemeLength();\n const afterVisibleColumn = this._nextVisibleColumn(codePoint, beforeVisibleColumn, tabSize);\n const afterColumn = iterator.offset + 1;\n if (afterVisibleColumn >= visibleColumn) {\n const beforeDelta = visibleColumn - beforeVisibleColumn;\n const afterDelta = afterVisibleColumn - visibleColumn;\n if (afterDelta < beforeDelta) {\n return afterColumn;\n }\n else {\n return beforeColumn;\n }\n }\n beforeVisibleColumn = afterVisibleColumn;\n beforeColumn = afterColumn;\n }\n // walked the entire string\n return lineContentLength + 1;\n }\n /**\n * ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)\n * @see {@link CursorColumns}\n */\n static nextRenderTabStop(visibleColumn, tabSize) {\n return visibleColumn + tabSize - visibleColumn % tabSize;\n }\n /**\n * ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns)\n * @see {@link CursorColumns}\n */\n static nextIndentTabStop(visibleColumn, indentSize) {\n return visibleColumn + indentSize - visibleColumn % indentSize;\n }\n /**\n * ATTENTION: This works with 0-based columns (as opposed to the regular 1-based columns)\n * @see {@link CursorColumns}\n */\n static prevRenderTabStop(column, tabSize) {\n return Math.max(0, column - 1 - (column - 1) % tabSize);\n }\n /**\n * ATTENTION: This works with 0-based columns (as opposed to the regular 1-based columns)\n * @see {@link CursorColumns}\n */\n static prevIndentTabStop(column, indentSize) {\n return Math.max(0, column - 1 - (column - 1) % indentSize);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { CursorColumns } from '../core/cursorColumns.js';\nexport class AtomicTabMoveOperations {\n /**\n * Get the visible column at the position. If we get to a non-whitespace character first\n * or past the end of string then return -1.\n *\n * **Note** `position` and the return value are 0-based.\n */\n static whitespaceVisibleColumn(lineContent, position, tabSize) {\n const lineLength = lineContent.length;\n let visibleColumn = 0;\n let prevTabStopPosition = -1;\n let prevTabStopVisibleColumn = -1;\n for (let i = 0; i < lineLength; i++) {\n if (i === position) {\n return [prevTabStopPosition, prevTabStopVisibleColumn, visibleColumn];\n }\n if (visibleColumn % tabSize === 0) {\n prevTabStopPosition = i;\n prevTabStopVisibleColumn = visibleColumn;\n }\n const chCode = lineContent.charCodeAt(i);\n switch (chCode) {\n case 32 /* CharCode.Space */:\n visibleColumn += 1;\n break;\n case 9 /* CharCode.Tab */:\n // Skip to the next multiple of tabSize.\n visibleColumn = CursorColumns.nextRenderTabStop(visibleColumn, tabSize);\n break;\n default:\n return [-1, -1, -1];\n }\n }\n if (position === lineLength) {\n return [prevTabStopPosition, prevTabStopVisibleColumn, visibleColumn];\n }\n return [-1, -1, -1];\n }\n /**\n * Return the position that should result from a move left, right or to the\n * nearest tab, if atomic tabs are enabled. Left and right are used for the\n * arrow key movements, nearest is used for mouse selection. It returns\n * -1 if atomic tabs are not relevant and you should fall back to normal\n * behaviour.\n *\n * **Note**: `position` and the return value are 0-based.\n */\n static atomicPosition(lineContent, position, tabSize, direction) {\n const lineLength = lineContent.length;\n // Get the 0-based visible column corresponding to the position, or return\n // -1 if it is not in the initial whitespace.\n const [prevTabStopPosition, prevTabStopVisibleColumn, visibleColumn] = AtomicTabMoveOperations.whitespaceVisibleColumn(lineContent, position, tabSize);\n if (visibleColumn === -1) {\n return -1;\n }\n // Is the output left or right of the current position. The case for nearest\n // where it is the same as the current position is handled in the switch.\n let left;\n switch (direction) {\n case 0 /* Direction.Left */:\n left = true;\n break;\n case 1 /* Direction.Right */:\n left = false;\n break;\n case 2 /* Direction.Nearest */:\n // The code below assumes the output position is either left or right\n // of the input position. If it is the same, return immediately.\n if (visibleColumn % tabSize === 0) {\n return position;\n }\n // Go to the nearest indentation.\n left = visibleColumn % tabSize <= (tabSize / 2);\n break;\n }\n // If going left, we can just use the info about the last tab stop position and\n // last tab stop visible column that we computed in the first walk over the whitespace.\n if (left) {\n if (prevTabStopPosition === -1) {\n return -1;\n }\n // If the direction is left, we need to keep scanning right to ensure\n // that targetVisibleColumn + tabSize is before non-whitespace.\n // This is so that when we press left at the end of a partial\n // indentation it only goes one character. For example ' foo' with\n // tabSize 4, should jump from position 6 to position 5, not 4.\n let currentVisibleColumn = prevTabStopVisibleColumn;\n for (let i = prevTabStopPosition; i < lineLength; ++i) {\n if (currentVisibleColumn === prevTabStopVisibleColumn + tabSize) {\n // It is a full indentation.\n return prevTabStopPosition;\n }\n const chCode = lineContent.charCodeAt(i);\n switch (chCode) {\n case 32 /* CharCode.Space */:\n currentVisibleColumn += 1;\n break;\n case 9 /* CharCode.Tab */:\n currentVisibleColumn = CursorColumns.nextRenderTabStop(currentVisibleColumn, tabSize);\n break;\n default:\n return -1;\n }\n }\n if (currentVisibleColumn === prevTabStopVisibleColumn + tabSize) {\n return prevTabStopPosition;\n }\n // It must have been a partial indentation.\n return -1;\n }\n // We are going right.\n const targetVisibleColumn = CursorColumns.nextRenderTabStop(visibleColumn, tabSize);\n // We can just continue from where whitespaceVisibleColumn got to.\n let currentVisibleColumn = visibleColumn;\n for (let i = position; i < lineLength; i++) {\n if (currentVisibleColumn === targetVisibleColumn) {\n return i;\n }\n const chCode = lineContent.charCodeAt(i);\n switch (chCode) {\n case 32 /* CharCode.Space */:\n currentVisibleColumn += 1;\n break;\n case 9 /* CharCode.Tab */:\n currentVisibleColumn = CursorColumns.nextRenderTabStop(currentVisibleColumn, tabSize);\n break;\n default:\n return -1;\n }\n }\n // This condition handles when the target column is at the end of the line.\n if (currentVisibleColumn === targetVisibleColumn) {\n return lineLength;\n }\n return -1;\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { PageCoordinates } from '../editorDom.js';\nimport { PartFingerprints } from '../view/viewPart.js';\nimport { ViewLine } from '../viewParts/lines/viewLine.js';\nimport { Position } from '../../common/core/position.js';\nimport { Range as EditorRange } from '../../common/core/range.js';\nimport { CursorColumns } from '../../common/core/cursorColumns.js';\nimport * as dom from '../../../base/browser/dom.js';\nimport { AtomicTabMoveOperations } from '../../common/cursor/cursorAtomicMoveOperations.js';\nclass UnknownHitTestResult {\n constructor(hitTarget = null) {\n this.hitTarget = hitTarget;\n this.type = 0 /* HitTestResultType.Unknown */;\n }\n}\nclass ContentHitTestResult {\n constructor(position, spanNode, injectedText) {\n this.position = position;\n this.spanNode = spanNode;\n this.injectedText = injectedText;\n this.type = 1 /* HitTestResultType.Content */;\n }\n}\nvar HitTestResult;\n(function (HitTestResult) {\n function createFromDOMInfo(ctx, spanNode, offset) {\n const position = ctx.getPositionFromDOMInfo(spanNode, offset);\n if (position) {\n return new ContentHitTestResult(position, spanNode, null);\n }\n return new UnknownHitTestResult(spanNode);\n }\n HitTestResult.createFromDOMInfo = createFromDOMInfo;\n})(HitTestResult || (HitTestResult = {}));\nexport class PointerHandlerLastRenderData {\n constructor(lastViewCursorsRenderData, lastTextareaPosition) {\n this.lastViewCursorsRenderData = lastViewCursorsRenderData;\n this.lastTextareaPosition = lastTextareaPosition;\n }\n}\nexport class MouseTarget {\n static _deduceRage(position, range = null) {\n if (!range && position) {\n return new EditorRange(position.lineNumber, position.column, position.lineNumber, position.column);\n }\n return range !== null && range !== void 0 ? range : null;\n }\n static createUnknown(element, mouseColumn, position) {\n return { type: 0 /* MouseTargetType.UNKNOWN */, element, mouseColumn, position, range: this._deduceRage(position) };\n }\n static createTextarea(element, mouseColumn) {\n return { type: 1 /* MouseTargetType.TEXTAREA */, element, mouseColumn, position: null, range: null };\n }\n static createMargin(type, element, mouseColumn, position, range, detail) {\n return { type, element, mouseColumn, position, range, detail };\n }\n static createViewZone(type, element, mouseColumn, position, detail) {\n return { type, element, mouseColumn, position, range: this._deduceRage(position), detail };\n }\n static createContentText(element, mouseColumn, position, range, detail) {\n return { type: 6 /* MouseTargetType.CONTENT_TEXT */, element, mouseColumn, position, range: this._deduceRage(position, range), detail };\n }\n static createContentEmpty(element, mouseColumn, position, detail) {\n return { type: 7 /* MouseTargetType.CONTENT_EMPTY */, element, mouseColumn, position, range: this._deduceRage(position), detail };\n }\n static createContentWidget(element, mouseColumn, detail) {\n return { type: 9 /* MouseTargetType.CONTENT_WIDGET */, element, mouseColumn, position: null, range: null, detail };\n }\n static createScrollbar(element, mouseColumn, position) {\n return { type: 11 /* MouseTargetType.SCROLLBAR */, element, mouseColumn, position, range: this._deduceRage(position) };\n }\n static createOverlayWidget(element, mouseColumn, detail) {\n return { type: 12 /* MouseTargetType.OVERLAY_WIDGET */, element, mouseColumn, position: null, range: null, detail };\n }\n static createOutsideEditor(mouseColumn, position, outsidePosition, outsideDistance) {\n return { type: 13 /* MouseTargetType.OUTSIDE_EDITOR */, element: null, mouseColumn, position, range: this._deduceRage(position), outsidePosition, outsideDistance };\n }\n static _typeToString(type) {\n if (type === 1 /* MouseTargetType.TEXTAREA */) {\n return 'TEXTAREA';\n }\n if (type === 2 /* MouseTargetType.GUTTER_GLYPH_MARGIN */) {\n return 'GUTTER_GLYPH_MARGIN';\n }\n if (type === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */) {\n return 'GUTTER_LINE_NUMBERS';\n }\n if (type === 4 /* MouseTargetType.GUTTER_LINE_DECORATIONS */) {\n return 'GUTTER_LINE_DECORATIONS';\n }\n if (type === 5 /* MouseTargetType.GUTTER_VIEW_ZONE */) {\n return 'GUTTER_VIEW_ZONE';\n }\n if (type === 6 /* MouseTargetType.CONTENT_TEXT */) {\n return 'CONTENT_TEXT';\n }\n if (type === 7 /* MouseTargetType.CONTENT_EMPTY */) {\n return 'CONTENT_EMPTY';\n }\n if (type === 8 /* MouseTargetType.CONTENT_VIEW_ZONE */) {\n return 'CONTENT_VIEW_ZONE';\n }\n if (type === 9 /* MouseTargetType.CONTENT_WIDGET */) {\n return 'CONTENT_WIDGET';\n }\n if (type === 10 /* MouseTargetType.OVERVIEW_RULER */) {\n return 'OVERVIEW_RULER';\n }\n if (type === 11 /* MouseTargetType.SCROLLBAR */) {\n return 'SCROLLBAR';\n }\n if (type === 12 /* MouseTargetType.OVERLAY_WIDGET */) {\n return 'OVERLAY_WIDGET';\n }\n return 'UNKNOWN';\n }\n static toString(target) {\n return this._typeToString(target.type) + ': ' + target.position + ' - ' + target.range + ' - ' + JSON.stringify(target.detail);\n }\n}\nclass ElementPath {\n static isTextArea(path) {\n return (path.length === 2\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[1] === 6 /* PartFingerprint.TextArea */);\n }\n static isChildOfViewLines(path) {\n return (path.length >= 4\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[3] === 7 /* PartFingerprint.ViewLines */);\n }\n static isStrictChildOfViewLines(path) {\n return (path.length > 4\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[3] === 7 /* PartFingerprint.ViewLines */);\n }\n static isChildOfScrollableElement(path) {\n return (path.length >= 2\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[1] === 5 /* PartFingerprint.ScrollableElement */);\n }\n static isChildOfMinimap(path) {\n return (path.length >= 2\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[1] === 8 /* PartFingerprint.Minimap */);\n }\n static isChildOfContentWidgets(path) {\n return (path.length >= 4\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[3] === 1 /* PartFingerprint.ContentWidgets */);\n }\n static isChildOfOverflowingContentWidgets(path) {\n return (path.length >= 1\n && path[0] === 2 /* PartFingerprint.OverflowingContentWidgets */);\n }\n static isChildOfOverlayWidgets(path) {\n return (path.length >= 2\n && path[0] === 3 /* PartFingerprint.OverflowGuard */\n && path[1] === 4 /* PartFingerprint.OverlayWidgets */);\n }\n}\nexport class HitTestContext {\n constructor(context, viewHelper, lastRenderData) {\n this.viewModel = context.viewModel;\n const options = context.configuration.options;\n this.layoutInfo = options.get(141 /* EditorOption.layoutInfo */);\n this.viewDomNode = viewHelper.viewDomNode;\n this.lineHeight = options.get(64 /* EditorOption.lineHeight */);\n this.stickyTabStops = options.get(113 /* EditorOption.stickyTabStops */);\n this.typicalHalfwidthCharacterWidth = options.get(48 /* EditorOption.fontInfo */).typicalHalfwidthCharacterWidth;\n this.lastRenderData = lastRenderData;\n this._context = context;\n this._viewHelper = viewHelper;\n }\n getZoneAtCoord(mouseVerticalOffset) {\n return HitTestContext.getZoneAtCoord(this._context, mouseVerticalOffset);\n }\n static getZoneAtCoord(context, mouseVerticalOffset) {\n // The target is either a view zone or the empty space after the last view-line\n const viewZoneWhitespace = context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset);\n if (viewZoneWhitespace) {\n const viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2;\n const lineCount = context.viewModel.getLineCount();\n let positionBefore = null;\n let position;\n let positionAfter = null;\n if (viewZoneWhitespace.afterLineNumber !== lineCount) {\n // There are more lines after this view zone\n positionAfter = new Position(viewZoneWhitespace.afterLineNumber + 1, 1);\n }\n if (viewZoneWhitespace.afterLineNumber > 0) {\n // There are more lines above this view zone\n positionBefore = new Position(viewZoneWhitespace.afterLineNumber, context.viewModel.getLineMaxColumn(viewZoneWhitespace.afterLineNumber));\n }\n if (positionAfter === null) {\n position = positionBefore;\n }\n else if (positionBefore === null) {\n position = positionAfter;\n }\n else if (mouseVerticalOffset < viewZoneMiddle) {\n position = positionBefore;\n }\n else {\n position = positionAfter;\n }\n return {\n viewZoneId: viewZoneWhitespace.id,\n afterLineNumber: viewZoneWhitespace.afterLineNumber,\n positionBefore: positionBefore,\n positionAfter: positionAfter,\n position: position\n };\n }\n return null;\n }\n getFullLineRangeAtCoord(mouseVerticalOffset) {\n if (this._context.viewLayout.isAfterLines(mouseVerticalOffset)) {\n // Below the last line\n const lineNumber = this._context.viewModel.getLineCount();\n const maxLineColumn = this._context.viewModel.getLineMaxColumn(lineNumber);\n return {\n range: new EditorRange(lineNumber, maxLineColumn, lineNumber, maxLineColumn),\n isAfterLines: true\n };\n }\n const lineNumber = this._context.viewLayout.getLineNumberAtVerticalOffset(mouseVerticalOffset);\n const maxLineColumn = this._context.viewModel.getLineMaxColumn(lineNumber);\n return {\n range: new EditorRange(lineNumber, 1, lineNumber, maxLineColumn),\n isAfterLines: false\n };\n }\n getLineNumberAtVerticalOffset(mouseVerticalOffset) {\n return this._context.viewLayout.getLineNumberAtVerticalOffset(mouseVerticalOffset);\n }\n isAfterLines(mouseVerticalOffset) {\n return this._context.viewLayout.isAfterLines(mouseVerticalOffset);\n }\n isInTopPadding(mouseVerticalOffset) {\n return this._context.viewLayout.isInTopPadding(mouseVerticalOffset);\n }\n isInBottomPadding(mouseVerticalOffset) {\n return this._context.viewLayout.isInBottomPadding(mouseVerticalOffset);\n }\n getVerticalOffsetForLineNumber(lineNumber) {\n return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber);\n }\n findAttribute(element, attr) {\n return HitTestContext._findAttribute(element, attr, this._viewHelper.viewDomNode);\n }\n static _findAttribute(element, attr, stopAt) {\n while (element && element !== document.body) {\n if (element.hasAttribute && element.hasAttribute(attr)) {\n return element.getAttribute(attr);\n }\n if (element === stopAt) {\n return null;\n }\n element = element.parentNode;\n }\n return null;\n }\n getLineWidth(lineNumber) {\n return this._viewHelper.getLineWidth(lineNumber);\n }\n visibleRangeForPosition(lineNumber, column) {\n return this._viewHelper.visibleRangeForPosition(lineNumber, column);\n }\n getPositionFromDOMInfo(spanNode, offset) {\n return this._viewHelper.getPositionFromDOMInfo(spanNode, offset);\n }\n getCurrentScrollTop() {\n return this._context.viewLayout.getCurrentScrollTop();\n }\n getCurrentScrollLeft() {\n return this._context.viewLayout.getCurrentScrollLeft();\n }\n}\nclass BareHitTestRequest {\n constructor(ctx, editorPos, pos, relativePos) {\n this.editorPos = editorPos;\n this.pos = pos;\n this.relativePos = relativePos;\n this.mouseVerticalOffset = Math.max(0, ctx.getCurrentScrollTop() + this.relativePos.y);\n this.mouseContentHorizontalOffset = ctx.getCurrentScrollLeft() + this.relativePos.x - ctx.layoutInfo.contentLeft;\n this.isInMarginArea = (this.relativePos.x < ctx.layoutInfo.contentLeft && this.relativePos.x >= ctx.layoutInfo.glyphMarginLeft);\n this.isInContentArea = !this.isInMarginArea;\n this.mouseColumn = Math.max(0, MouseTargetFactory._getMouseColumn(this.mouseContentHorizontalOffset, ctx.typicalHalfwidthCharacterWidth));\n }\n}\nclass HitTestRequest extends BareHitTestRequest {\n constructor(ctx, editorPos, pos, relativePos, target) {\n super(ctx, editorPos, pos, relativePos);\n this._ctx = ctx;\n if (target) {\n this.target = target;\n this.targetPath = PartFingerprints.collect(target, ctx.viewDomNode);\n }\n else {\n this.target = null;\n this.targetPath = new Uint8Array(0);\n }\n }\n toString() {\n return `pos(${this.pos.x},${this.pos.y}), editorPos(${this.editorPos.x},${this.editorPos.y}), relativePos(${this.relativePos.x},${this.relativePos.y}), mouseVerticalOffset: ${this.mouseVerticalOffset}, mouseContentHorizontalOffset: ${this.mouseContentHorizontalOffset}\\n\\ttarget: ${this.target ? this.target.outerHTML : null}`;\n }\n _getMouseColumn(position = null) {\n if (position && position.column < this._ctx.viewModel.getLineMaxColumn(position.lineNumber)) {\n // Most likely, the line contains foreign decorations...\n return CursorColumns.visibleColumnFromColumn(this._ctx.viewModel.getLineContent(position.lineNumber), position.column, this._ctx.viewModel.model.getOptions().tabSize) + 1;\n }\n return this.mouseColumn;\n }\n fulfillUnknown(position = null) {\n return MouseTarget.createUnknown(this.target, this._getMouseColumn(position), position);\n }\n fulfillTextarea() {\n return MouseTarget.createTextarea(this.target, this._getMouseColumn());\n }\n fulfillMargin(type, position, range, detail) {\n return MouseTarget.createMargin(type, this.target, this._getMouseColumn(position), position, range, detail);\n }\n fulfillViewZone(type, position, detail) {\n return MouseTarget.createViewZone(type, this.target, this._getMouseColumn(position), position, detail);\n }\n fulfillContentText(position, range, detail) {\n return MouseTarget.createContentText(this.target, this._getMouseColumn(position), position, range, detail);\n }\n fulfillContentEmpty(position, detail) {\n return MouseTarget.createContentEmpty(this.target, this._getMouseColumn(position), position, detail);\n }\n fulfillContentWidget(detail) {\n return MouseTarget.createContentWidget(this.target, this._getMouseColumn(), detail);\n }\n fulfillScrollbar(position) {\n return MouseTarget.createScrollbar(this.target, this._getMouseColumn(position), position);\n }\n fulfillOverlayWidget(detail) {\n return MouseTarget.createOverlayWidget(this.target, this._getMouseColumn(), detail);\n }\n withTarget(target) {\n return new HitTestRequest(this._ctx, this.editorPos, this.pos, this.relativePos, target);\n }\n}\nconst EMPTY_CONTENT_AFTER_LINES = { isAfterLines: true };\nfunction createEmptyContentDataInLines(horizontalDistanceToText) {\n return {\n isAfterLines: false,\n horizontalDistanceToText: horizontalDistanceToText\n };\n}\nexport class MouseTargetFactory {\n constructor(context, viewHelper) {\n this._context = context;\n this._viewHelper = viewHelper;\n }\n mouseTargetIsWidget(e) {\n const t = e.target;\n const path = PartFingerprints.collect(t, this._viewHelper.viewDomNode);\n // Is it a content widget?\n if (ElementPath.isChildOfContentWidgets(path) || ElementPath.isChildOfOverflowingContentWidgets(path)) {\n return true;\n }\n // Is it an overlay widget?\n if (ElementPath.isChildOfOverlayWidgets(path)) {\n return true;\n }\n return false;\n }\n createMouseTarget(lastRenderData, editorPos, pos, relativePos, target) {\n const ctx = new HitTestContext(this._context, this._viewHelper, lastRenderData);\n const request = new HitTestRequest(ctx, editorPos, pos, relativePos, target);\n try {\n const r = MouseTargetFactory._createMouseTarget(ctx, request, false);\n if (r.type === 6 /* MouseTargetType.CONTENT_TEXT */) {\n // Snap to the nearest soft tab boundary if atomic soft tabs are enabled.\n if (ctx.stickyTabStops && r.position !== null) {\n const position = MouseTargetFactory._snapToSoftTabBoundary(r.position, ctx.viewModel);\n const range = EditorRange.fromPositions(position, position).plusRange(r.range);\n return request.fulfillContentText(position, range, r.detail);\n }\n }\n // console.log(MouseTarget.toString(r));\n return r;\n }\n catch (err) {\n // console.log(err);\n return request.fulfillUnknown();\n }\n }\n static _createMouseTarget(ctx, request, domHitTestExecuted) {\n // console.log(`${domHitTestExecuted ? '=>' : ''}CAME IN REQUEST: ${request}`);\n // First ensure the request has a target\n if (request.target === null) {\n if (domHitTestExecuted) {\n // Still no target... and we have already executed hit test...\n return request.fulfillUnknown();\n }\n const hitTestResult = MouseTargetFactory._doHitTest(ctx, request);\n if (hitTestResult.type === 1 /* HitTestResultType.Content */) {\n return MouseTargetFactory.createMouseTargetFromHitTestPosition(ctx, request, hitTestResult.spanNode, hitTestResult.position, hitTestResult.injectedText);\n }\n return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);\n }\n // we know for a fact that request.target is not null\n const resolvedRequest = request;\n let result = null;\n result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestViewZone(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestMargin(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestViewCursor(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestTextArea(ctx, resolvedRequest);\n result = result || MouseTargetFactory._hitTestViewLines(ctx, resolvedRequest, domHitTestExecuted);\n result = result || MouseTargetFactory._hitTestScrollbar(ctx, resolvedRequest);\n return (result || request.fulfillUnknown());\n }\n static _hitTestContentWidget(ctx, request) {\n // Is it a content widget?\n if (ElementPath.isChildOfContentWidgets(request.targetPath) || ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) {\n const widgetId = ctx.findAttribute(request.target, 'widgetId');\n if (widgetId) {\n return request.fulfillContentWidget(widgetId);\n }\n else {\n return request.fulfillUnknown();\n }\n }\n return null;\n }\n static _hitTestOverlayWidget(ctx, request) {\n // Is it an overlay widget?\n if (ElementPath.isChildOfOverlayWidgets(request.targetPath)) {\n const widgetId = ctx.findAttribute(request.target, 'widgetId');\n if (widgetId) {\n return request.fulfillOverlayWidget(widgetId);\n }\n else {\n return request.fulfillUnknown();\n }\n }\n return null;\n }\n static _hitTestViewCursor(ctx, request) {\n if (request.target) {\n // Check if we've hit a painted cursor\n const lastViewCursorsRenderData = ctx.lastRenderData.lastViewCursorsRenderData;\n for (const d of lastViewCursorsRenderData) {\n if (request.target === d.domNode) {\n return request.fulfillContentText(d.position, null, { mightBeForeignElement: false, injectedText: null });\n }\n }\n }\n if (request.isInContentArea) {\n // Edge has a bug when hit-testing the exact position of a cursor,\n // instead of returning the correct dom node, it returns the\n // first or last rendered view line dom node, therefore help it out\n // and first check if we are on top of a cursor\n const lastViewCursorsRenderData = ctx.lastRenderData.lastViewCursorsRenderData;\n const mouseContentHorizontalOffset = request.mouseContentHorizontalOffset;\n const mouseVerticalOffset = request.mouseVerticalOffset;\n for (const d of lastViewCursorsRenderData) {\n if (mouseContentHorizontalOffset < d.contentLeft) {\n // mouse position is to the left of the cursor\n continue;\n }\n if (mouseContentHorizontalOffset > d.contentLeft + d.width) {\n // mouse position is to the right of the cursor\n continue;\n }\n const cursorVerticalOffset = ctx.getVerticalOffsetForLineNumber(d.position.lineNumber);\n if (cursorVerticalOffset <= mouseVerticalOffset\n && mouseVerticalOffset <= cursorVerticalOffset + d.height) {\n return request.fulfillContentText(d.position, null, { mightBeForeignElement: false, injectedText: null });\n }\n }\n }\n return null;\n }\n static _hitTestViewZone(ctx, request) {\n const viewZoneData = ctx.getZoneAtCoord(request.mouseVerticalOffset);\n if (viewZoneData) {\n const mouseTargetType = (request.isInContentArea ? 8 /* MouseTargetType.CONTENT_VIEW_ZONE */ : 5 /* MouseTargetType.GUTTER_VIEW_ZONE */);\n return request.fulfillViewZone(mouseTargetType, viewZoneData.position, viewZoneData);\n }\n return null;\n }\n static _hitTestTextArea(ctx, request) {\n // Is it the textarea?\n if (ElementPath.isTextArea(request.targetPath)) {\n if (ctx.lastRenderData.lastTextareaPosition) {\n return request.fulfillContentText(ctx.lastRenderData.lastTextareaPosition, null, { mightBeForeignElement: false, injectedText: null });\n }\n return request.fulfillTextarea();\n }\n return null;\n }\n static _hitTestMargin(ctx, request) {\n if (request.isInMarginArea) {\n const res = ctx.getFullLineRangeAtCoord(request.mouseVerticalOffset);\n const pos = res.range.getStartPosition();\n let offset = Math.abs(request.relativePos.x);\n const detail = {\n isAfterLines: res.isAfterLines,\n glyphMarginLeft: ctx.layoutInfo.glyphMarginLeft,\n glyphMarginWidth: ctx.layoutInfo.glyphMarginWidth,\n lineNumbersWidth: ctx.layoutInfo.lineNumbersWidth,\n offsetX: offset\n };\n offset -= ctx.layoutInfo.glyphMarginLeft;\n if (offset <= ctx.layoutInfo.glyphMarginWidth) {\n // On the glyph margin\n return request.fulfillMargin(2 /* MouseTargetType.GUTTER_GLYPH_MARGIN */, pos, res.range, detail);\n }\n offset -= ctx.layoutInfo.glyphMarginWidth;\n if (offset <= ctx.layoutInfo.lineNumbersWidth) {\n // On the line numbers\n return request.fulfillMargin(3 /* MouseTargetType.GUTTER_LINE_NUMBERS */, pos, res.range, detail);\n }\n offset -= ctx.layoutInfo.lineNumbersWidth;\n // On the line decorations\n return request.fulfillMargin(4 /* MouseTargetType.GUTTER_LINE_DECORATIONS */, pos, res.range, detail);\n }\n return null;\n }\n static _hitTestViewLines(ctx, request, domHitTestExecuted) {\n if (!ElementPath.isChildOfViewLines(request.targetPath)) {\n return null;\n }\n if (ctx.isInTopPadding(request.mouseVerticalOffset)) {\n return request.fulfillContentEmpty(new Position(1, 1), EMPTY_CONTENT_AFTER_LINES);\n }\n // Check if it is below any lines and any view zones\n if (ctx.isAfterLines(request.mouseVerticalOffset) || ctx.isInBottomPadding(request.mouseVerticalOffset)) {\n // This most likely indicates it happened after the last view-line\n const lineCount = ctx.viewModel.getLineCount();\n const maxLineColumn = ctx.viewModel.getLineMaxColumn(lineCount);\n return request.fulfillContentEmpty(new Position(lineCount, maxLineColumn), EMPTY_CONTENT_AFTER_LINES);\n }\n if (domHitTestExecuted) {\n // Check if we are hitting a view-line (can happen in the case of inline decorations on empty lines)\n // See https://github.com/microsoft/vscode/issues/46942\n if (ElementPath.isStrictChildOfViewLines(request.targetPath)) {\n const lineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);\n if (ctx.viewModel.getLineLength(lineNumber) === 0) {\n const lineWidth = ctx.getLineWidth(lineNumber);\n const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth);\n return request.fulfillContentEmpty(new Position(lineNumber, 1), detail);\n }\n const lineWidth = ctx.getLineWidth(lineNumber);\n if (request.mouseContentHorizontalOffset >= lineWidth) {\n const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth);\n const pos = new Position(lineNumber, ctx.viewModel.getLineMaxColumn(lineNumber));\n return request.fulfillContentEmpty(pos, detail);\n }\n }\n // We have already executed hit test...\n return request.fulfillUnknown();\n }\n const hitTestResult = MouseTargetFactory._doHitTest(ctx, request);\n if (hitTestResult.type === 1 /* HitTestResultType.Content */) {\n return MouseTargetFactory.createMouseTargetFromHitTestPosition(ctx, request, hitTestResult.spanNode, hitTestResult.position, hitTestResult.injectedText);\n }\n return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);\n }\n static _hitTestMinimap(ctx, request) {\n if (ElementPath.isChildOfMinimap(request.targetPath)) {\n const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);\n const maxColumn = ctx.viewModel.getLineMaxColumn(possibleLineNumber);\n return request.fulfillScrollbar(new Position(possibleLineNumber, maxColumn));\n }\n return null;\n }\n static _hitTestScrollbarSlider(ctx, request) {\n if (ElementPath.isChildOfScrollableElement(request.targetPath)) {\n if (request.target && request.target.nodeType === 1) {\n const className = request.target.className;\n if (className && /\\b(slider|scrollbar)\\b/.test(className)) {\n const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);\n const maxColumn = ctx.viewModel.getLineMaxColumn(possibleLineNumber);\n return request.fulfillScrollbar(new Position(possibleLineNumber, maxColumn));\n }\n }\n }\n return null;\n }\n static _hitTestScrollbar(ctx, request) {\n // Is it the overview ruler?\n // Is it a child of the scrollable element?\n if (ElementPath.isChildOfScrollableElement(request.targetPath)) {\n const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);\n const maxColumn = ctx.viewModel.getLineMaxColumn(possibleLineNumber);\n return request.fulfillScrollbar(new Position(possibleLineNumber, maxColumn));\n }\n return null;\n }\n getMouseColumn(relativePos) {\n const options = this._context.configuration.options;\n const layoutInfo = options.get(141 /* EditorOption.layoutInfo */);\n const mouseContentHorizontalOffset = this._context.viewLayout.getCurrentScrollLeft() + relativePos.x - layoutInfo.contentLeft;\n return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, options.get(48 /* EditorOption.fontInfo */).typicalHalfwidthCharacterWidth);\n }\n static _getMouseColumn(mouseContentHorizontalOffset, typicalHalfwidthCharacterWidth) {\n if (mouseContentHorizontalOffset < 0) {\n return 1;\n }\n const chars = Math.round(mouseContentHorizontalOffset / typicalHalfwidthCharacterWidth);\n return (chars + 1);\n }\n static createMouseTargetFromHitTestPosition(ctx, request, spanNode, pos, injectedText) {\n const lineNumber = pos.lineNumber;\n const column = pos.column;\n const lineWidth = ctx.getLineWidth(lineNumber);\n if (request.mouseContentHorizontalOffset > lineWidth) {\n const detail = createEmptyContentDataInLines(request.mouseContentHorizontalOffset - lineWidth);\n return request.fulfillContentEmpty(pos, detail);\n }\n const visibleRange = ctx.visibleRangeForPosition(lineNumber, column);\n if (!visibleRange) {\n return request.fulfillUnknown(pos);\n }\n const columnHorizontalOffset = visibleRange.left;\n if (Math.abs(request.mouseContentHorizontalOffset - columnHorizontalOffset) < 1) {\n return request.fulfillContentText(pos, null, { mightBeForeignElement: !!injectedText, injectedText });\n }\n const points = [];\n points.push({ offset: visibleRange.left, column: column });\n if (column > 1) {\n const visibleRange = ctx.visibleRangeForPosition(lineNumber, column - 1);\n if (visibleRange) {\n points.push({ offset: visibleRange.left, column: column - 1 });\n }\n }\n const lineMaxColumn = ctx.viewModel.getLineMaxColumn(lineNumber);\n if (column < lineMaxColumn) {\n const visibleRange = ctx.visibleRangeForPosition(lineNumber, column + 1);\n if (visibleRange) {\n points.push({ offset: visibleRange.left, column: column + 1 });\n }\n }\n points.sort((a, b) => a.offset - b.offset);\n const mouseCoordinates = request.pos.toClientCoordinates();\n const spanNodeClientRect = spanNode.getBoundingClientRect();\n const mouseIsOverSpanNode = (spanNodeClientRect.left <= mouseCoordinates.clientX && mouseCoordinates.clientX <= spanNodeClientRect.right);\n let rng = null;\n for (let i = 1; i < points.length; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n if (prev.offset <= request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset <= curr.offset) {\n rng = new EditorRange(lineNumber, prev.column, lineNumber, curr.column);\n // See https://github.com/microsoft/vscode/issues/152819\n // Due to the use of zwj, the browser's hit test result is skewed towards the left\n // Here we try to correct that if the mouse horizontal offset is closer to the right than the left\n const prevDelta = Math.abs(prev.offset - request.mouseContentHorizontalOffset);\n const nextDelta = Math.abs(curr.offset - request.mouseContentHorizontalOffset);\n pos = (prevDelta < nextDelta\n ? new Position(lineNumber, prev.column)\n : new Position(lineNumber, curr.column));\n break;\n }\n }\n return request.fulfillContentText(pos, rng, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText });\n }\n /**\n * Most probably WebKit browsers and Edge\n */\n static _doHitTestWithCaretRangeFromPoint(ctx, request) {\n // In Chrome, especially on Linux it is possible to click between lines,\n // so try to adjust the `hity` below so that it lands in the center of a line\n const lineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);\n const lineStartVerticalOffset = ctx.getVerticalOffsetForLineNumber(lineNumber);\n const lineEndVerticalOffset = lineStartVerticalOffset + ctx.lineHeight;\n const isBelowLastLine = (lineNumber === ctx.viewModel.getLineCount()\n && request.mouseVerticalOffset > lineEndVerticalOffset);\n if (!isBelowLastLine) {\n const lineCenteredVerticalOffset = Math.floor((lineStartVerticalOffset + lineEndVerticalOffset) / 2);\n let adjustedPageY = request.pos.y + (lineCenteredVerticalOffset - request.mouseVerticalOffset);\n if (adjustedPageY <= request.editorPos.y) {\n adjustedPageY = request.editorPos.y + 1;\n }\n if (adjustedPageY >= request.editorPos.y + request.editorPos.height) {\n adjustedPageY = request.editorPos.y + request.editorPos.height - 1;\n }\n const adjustedPage = new PageCoordinates(request.pos.x, adjustedPageY);\n const r = this._actualDoHitTestWithCaretRangeFromPoint(ctx, adjustedPage.toClientCoordinates());\n if (r.type === 1 /* HitTestResultType.Content */) {\n return r;\n }\n }\n // Also try to hit test without the adjustment (for the edge cases that we are near the top or bottom)\n return this._actualDoHitTestWithCaretRangeFromPoint(ctx, request.pos.toClientCoordinates());\n }\n static _actualDoHitTestWithCaretRangeFromPoint(ctx, coords) {\n const shadowRoot = dom.getShadowRoot(ctx.viewDomNode);\n let range;\n if (shadowRoot) {\n if (typeof shadowRoot.caretRangeFromPoint === 'undefined') {\n range = shadowCaretRangeFromPoint(shadowRoot, coords.clientX, coords.clientY);\n }\n else {\n range = shadowRoot.caretRangeFromPoint(coords.clientX, coords.clientY);\n }\n }\n else {\n range = document.caretRangeFromPoint(coords.clientX, coords.clientY);\n }\n if (!range || !range.startContainer) {\n return new UnknownHitTestResult();\n }\n // Chrome always hits a TEXT_NODE, while Edge sometimes hits a token span\n const startContainer = range.startContainer;\n if (startContainer.nodeType === startContainer.TEXT_NODE) {\n // startContainer is expected to be the token text\n const parent1 = startContainer.parentNode; // expected to be the token span\n const parent2 = parent1 ? parent1.parentNode : null; // expected to be the view line container span\n const parent3 = parent2 ? parent2.parentNode : null; // expected to be the view line div\n const parent3ClassName = parent3 && parent3.nodeType === parent3.ELEMENT_NODE ? parent3.className : null;\n if (parent3ClassName === ViewLine.CLASS_NAME) {\n return HitTestResult.createFromDOMInfo(ctx, parent1, range.startOffset);\n }\n else {\n return new UnknownHitTestResult(startContainer.parentNode);\n }\n }\n else if (startContainer.nodeType === startContainer.ELEMENT_NODE) {\n // startContainer is expected to be the token span\n const parent1 = startContainer.parentNode; // expected to be the view line container span\n const parent2 = parent1 ? parent1.parentNode : null; // expected to be the view line div\n const parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? parent2.className : null;\n if (parent2ClassName === ViewLine.CLASS_NAME) {\n return HitTestResult.createFromDOMInfo(ctx, startContainer, startContainer.textContent.length);\n }\n else {\n return new UnknownHitTestResult(startContainer);\n }\n }\n return new UnknownHitTestResult();\n }\n /**\n * Most probably Gecko\n */\n static _doHitTestWithCaretPositionFromPoint(ctx, coords) {\n const hitResult = document.caretPositionFromPoint(coords.clientX, coords.clientY);\n if (hitResult.offsetNode.nodeType === hitResult.offsetNode.TEXT_NODE) {\n // offsetNode is expected to be the token text\n const parent1 = hitResult.offsetNode.parentNode; // expected to be the token span\n const parent2 = parent1 ? parent1.parentNode : null; // expected to be the view line container span\n const parent3 = parent2 ? parent2.parentNode : null; // expected to be the view line div\n const parent3ClassName = parent3 && parent3.nodeType === parent3.ELEMENT_NODE ? parent3.className : null;\n if (parent3ClassName === ViewLine.CLASS_NAME) {\n return HitTestResult.createFromDOMInfo(ctx, hitResult.offsetNode.parentNode, hitResult.offset);\n }\n else {\n return new UnknownHitTestResult(hitResult.offsetNode.parentNode);\n }\n }\n // For inline decorations, Gecko sometimes returns the `` of the line and the offset is the `` with the inline decoration\n // Some other times, it returns the `` with the inline decoration\n if (hitResult.offsetNode.nodeType === hitResult.offsetNode.ELEMENT_NODE) {\n const parent1 = hitResult.offsetNode.parentNode;\n const parent1ClassName = parent1 && parent1.nodeType === parent1.ELEMENT_NODE ? parent1.className : null;\n const parent2 = parent1 ? parent1.parentNode : null;\n const parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? parent2.className : null;\n if (parent1ClassName === ViewLine.CLASS_NAME) {\n // it returned the `` of the line and the offset is the `` with the inline decoration\n const tokenSpan = hitResult.offsetNode.childNodes[Math.min(hitResult.offset, hitResult.offsetNode.childNodes.length - 1)];\n if (tokenSpan) {\n return HitTestResult.createFromDOMInfo(ctx, tokenSpan, 0);\n }\n }\n else if (parent2ClassName === ViewLine.CLASS_NAME) {\n // it returned the `` with the inline decoration\n return HitTestResult.createFromDOMInfo(ctx, hitResult.offsetNode, 0);\n }\n }\n return new UnknownHitTestResult(hitResult.offsetNode);\n }\n static _snapToSoftTabBoundary(position, viewModel) {\n const lineContent = viewModel.getLineContent(position.lineNumber);\n const { tabSize } = viewModel.model.getOptions();\n const newPosition = AtomicTabMoveOperations.atomicPosition(lineContent, position.column - 1, tabSize, 2 /* Direction.Nearest */);\n if (newPosition !== -1) {\n return new Position(position.lineNumber, newPosition + 1);\n }\n return position;\n }\n static _doHitTest(ctx, request) {\n let result = new UnknownHitTestResult();\n if (typeof document.caretRangeFromPoint === 'function') {\n result = this._doHitTestWithCaretRangeFromPoint(ctx, request);\n }\n else if (document.caretPositionFromPoint) {\n result = this._doHitTestWithCaretPositionFromPoint(ctx, request.pos.toClientCoordinates());\n }\n if (result.type === 1 /* HitTestResultType.Content */) {\n const injectedText = ctx.viewModel.getInjectedTextAt(result.position);\n const normalizedPosition = ctx.viewModel.normalizePosition(result.position, 2 /* PositionAffinity.None */);\n if (injectedText || !normalizedPosition.equals(result.position)) {\n result = new ContentHitTestResult(normalizedPosition, result.spanNode, injectedText);\n }\n }\n return result;\n }\n}\nfunction shadowCaretRangeFromPoint(shadowRoot, x, y) {\n const range = document.createRange();\n // Get the element under the point\n let el = shadowRoot.elementFromPoint(x, y);\n if (el !== null) {\n // Get the last child of the element until its firstChild is a text node\n // This assumes that the pointer is on the right of the line, out of the tokens\n // and that we want to get the offset of the last token of the line\n while (el && el.firstChild && el.firstChild.nodeType !== el.firstChild.TEXT_NODE && el.lastChild && el.lastChild.firstChild) {\n el = el.lastChild;\n }\n // Grab its rect\n const rect = el.getBoundingClientRect();\n // And its font (the computed shorthand font property might be empty, see #3217)\n const fontStyle = window.getComputedStyle(el, null).getPropertyValue('font-style');\n const fontVariant = window.getComputedStyle(el, null).getPropertyValue('font-variant');\n const fontWeight = window.getComputedStyle(el, null).getPropertyValue('font-weight');\n const fontSize = window.getComputedStyle(el, null).getPropertyValue('font-size');\n const lineHeight = window.getComputedStyle(el, null).getPropertyValue('line-height');\n const fontFamily = window.getComputedStyle(el, null).getPropertyValue('font-family');\n const font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`;\n // And also its txt content\n const text = el.innerText;\n // Position the pixel cursor at the left of the element\n let pixelCursor = rect.left;\n let offset = 0;\n let step;\n // If the point is on the right of the box put the cursor after the last character\n if (x > rect.left + rect.width) {\n offset = text.length;\n }\n else {\n const charWidthReader = CharWidthReader.getInstance();\n // Goes through all the characters of the innerText, and checks if the x of the point\n // belongs to the character.\n for (let i = 0; i < text.length + 1; i++) {\n // The step is half the width of the character\n step = charWidthReader.getCharWidth(text.charAt(i), font) / 2;\n // Move to the center of the character\n pixelCursor += step;\n // If the x of the point is smaller that the position of the cursor, the point is over that character\n if (x < pixelCursor) {\n offset = i;\n break;\n }\n // Move between the current character and the next\n pixelCursor += step;\n }\n }\n // Creates a range with the text node of the element and set the offset found\n range.setStart(el.firstChild, offset);\n range.setEnd(el.firstChild, offset);\n }\n return range;\n}\nclass CharWidthReader {\n static getInstance() {\n if (!CharWidthReader._INSTANCE) {\n CharWidthReader._INSTANCE = new CharWidthReader();\n }\n return CharWidthReader._INSTANCE;\n }\n constructor() {\n this._cache = {};\n this._canvas = document.createElement('canvas');\n }\n getCharWidth(char, font) {\n const cacheKey = char + font;\n if (this._cache[cacheKey]) {\n return this._cache[cacheKey];\n }\n const context = this._canvas.getContext('2d');\n context.font = font;\n const metrics = context.measureText(char);\n const width = metrics.width;\n this._cache[cacheKey] = width;\n return width;\n }\n}\nCharWidthReader._INSTANCE = null;\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as dom from '../dom.js';\nimport { StandardKeyboardEvent } from '../keyboardEvent.js';\nimport { StandardMouseEvent } from '../mouseEvent.js';\nimport { Gesture } from '../touch.js';\nimport { Disposable } from '../../common/lifecycle.js';\nexport class Widget extends Disposable {\n onclick(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.CLICK, (e) => listener(new StandardMouseEvent(e))));\n }\n onmousedown(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.MOUSE_DOWN, (e) => listener(new StandardMouseEvent(e))));\n }\n onmouseover(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.MOUSE_OVER, (e) => listener(new StandardMouseEvent(e))));\n }\n onmouseleave(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.MOUSE_LEAVE, (e) => listener(new StandardMouseEvent(e))));\n }\n onkeydown(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.KEY_DOWN, (e) => listener(new StandardKeyboardEvent(e))));\n }\n onkeyup(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.KEY_UP, (e) => listener(new StandardKeyboardEvent(e))));\n }\n oninput(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.INPUT, listener));\n }\n onblur(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.BLUR, listener));\n }\n onfocus(domNode, listener) {\n this._register(dom.addDisposableListener(domNode, dom.EventType.FOCUS, listener));\n }\n ignoreGesture(domNode) {\n return Gesture.ignoreTarget(domNode);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { GlobalPointerMoveMonitor } from '../../globalPointerMoveMonitor.js';\nimport { Widget } from '../widget.js';\nimport { IntervalTimer, TimeoutTimer } from '../../../common/async.js';\nimport { ThemeIcon } from '../../../common/themables.js';\nimport * as dom from '../../dom.js';\n/**\n * The arrow image size.\n */\nexport const ARROW_IMG_SIZE = 11;\nexport class ScrollbarArrow extends Widget {\n constructor(opts) {\n super();\n this._onActivate = opts.onActivate;\n this.bgDomNode = document.createElement('div');\n this.bgDomNode.className = 'arrow-background';\n this.bgDomNode.style.position = 'absolute';\n this.bgDomNode.style.width = opts.bgWidth + 'px';\n this.bgDomNode.style.height = opts.bgHeight + 'px';\n if (typeof opts.top !== 'undefined') {\n this.bgDomNode.style.top = '0px';\n }\n if (typeof opts.left !== 'undefined') {\n this.bgDomNode.style.left = '0px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.bgDomNode.style.bottom = '0px';\n }\n if (typeof opts.right !== 'undefined') {\n this.bgDomNode.style.right = '0px';\n }\n this.domNode = document.createElement('div');\n this.domNode.className = opts.className;\n this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));\n this.domNode.style.position = 'absolute';\n this.domNode.style.width = ARROW_IMG_SIZE + 'px';\n this.domNode.style.height = ARROW_IMG_SIZE + 'px';\n if (typeof opts.top !== 'undefined') {\n this.domNode.style.top = opts.top + 'px';\n }\n if (typeof opts.left !== 'undefined') {\n this.domNode.style.left = opts.left + 'px';\n }\n if (typeof opts.bottom !== 'undefined') {\n this.domNode.style.bottom = opts.bottom + 'px';\n }\n if (typeof opts.right !== 'undefined') {\n this.domNode.style.right = opts.right + 'px';\n }\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.EventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._register(dom.addStandardDisposableListener(this.domNode, dom.EventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));\n this._pointerdownRepeatTimer = this._register(new IntervalTimer());\n this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());\n }\n _arrowPointerDown(e) {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const scheduleRepeater = () => {\n this._pointerdownRepeatTimer.cancelAndSet(() => this._onActivate(), 1000 / 24);\n };\n this._onActivate();\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);\n this._pointerMoveMonitor.startMonitoring(e.target, e.pointerId, e.buttons, (pointerMoveData) => { }, () => {\n this._pointerdownRepeatTimer.cancel();\n this._pointerdownScheduleRepeatTimer.cancel();\n });\n e.preventDefault();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { TimeoutTimer } from '../../../common/async.js';\nimport { Disposable } from '../../../common/lifecycle.js';\nexport class ScrollbarVisibilityController extends Disposable {\n constructor(visibility, visibleClassName, invisibleClassName) {\n super();\n this._visibility = visibility;\n this._visibleClassName = visibleClassName;\n this._invisibleClassName = invisibleClassName;\n this._domNode = null;\n this._isVisible = false;\n this._isNeeded = false;\n this._rawShouldBeVisible = false;\n this._shouldBeVisible = false;\n this._revealTimer = this._register(new TimeoutTimer());\n }\n setVisibility(visibility) {\n if (this._visibility !== visibility) {\n this._visibility = visibility;\n this._updateShouldBeVisible();\n }\n }\n // ----------------- Hide / Reveal\n setShouldBeVisible(rawShouldBeVisible) {\n this._rawShouldBeVisible = rawShouldBeVisible;\n this._updateShouldBeVisible();\n }\n _applyVisibilitySetting() {\n if (this._visibility === 2 /* ScrollbarVisibility.Hidden */) {\n return false;\n }\n if (this._visibility === 3 /* ScrollbarVisibility.Visible */) {\n return true;\n }\n return this._rawShouldBeVisible;\n }\n _updateShouldBeVisible() {\n const shouldBeVisible = this._applyVisibilitySetting();\n if (this._shouldBeVisible !== shouldBeVisible) {\n this._shouldBeVisible = shouldBeVisible;\n this.ensureVisibility();\n }\n }\n setIsNeeded(isNeeded) {\n if (this._isNeeded !== isNeeded) {\n this._isNeeded = isNeeded;\n this.ensureVisibility();\n }\n }\n setDomNode(domNode) {\n this._domNode = domNode;\n this._domNode.setClassName(this._invisibleClassName);\n // Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration\n this.setShouldBeVisible(false);\n }\n ensureVisibility() {\n if (!this._isNeeded) {\n // Nothing to be rendered\n this._hide(false);\n return;\n }\n if (this._shouldBeVisible) {\n this._reveal();\n }\n else {\n this._hide(true);\n }\n }\n _reveal() {\n if (this._isVisible) {\n return;\n }\n this._isVisible = true;\n // The CSS animation doesn't play otherwise\n this._revealTimer.setIfNotSet(() => {\n var _a;\n (_a = this._domNode) === null || _a === void 0 ? void 0 : _a.setClassName(this._visibleClassName);\n }, 0);\n }\n _hide(withFadeAway) {\n var _a;\n this._revealTimer.cancel();\n if (!this._isVisible) {\n return;\n }\n this._isVisible = false;\n (_a = this._domNode) === null || _a === void 0 ? void 0 : _a.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as dom from '../../dom.js';\nimport { createFastDomNode } from '../../fastDomNode.js';\nimport { GlobalPointerMoveMonitor } from '../../globalPointerMoveMonitor.js';\nimport { ScrollbarArrow } from './scrollbarArrow.js';\nimport { ScrollbarVisibilityController } from './scrollbarVisibilityController.js';\nimport { Widget } from '../widget.js';\nimport * as platform from '../../../common/platform.js';\n/**\n * The orthogonal distance to the slider at which dragging \"resets\". This implements \"snapping\"\n */\nconst POINTER_DRAG_RESET_DISTANCE = 140;\nexport class AbstractScrollbar extends Widget {\n constructor(opts) {\n super();\n this._lazyRender = opts.lazyRender;\n this._host = opts.host;\n this._scrollable = opts.scrollable;\n this._scrollByPage = opts.scrollByPage;\n this._scrollbarState = opts.scrollbarState;\n this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName));\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());\n this._shouldRender = true;\n this.domNode = createFastDomNode(document.createElement('div'));\n this.domNode.setAttribute('role', 'presentation');\n this.domNode.setAttribute('aria-hidden', 'true');\n this._visibilityController.setDomNode(this.domNode);\n this.domNode.setPosition('absolute');\n this._register(dom.addDisposableListener(this.domNode.domNode, dom.EventType.POINTER_DOWN, (e) => this._domNodePointerDown(e)));\n }\n // ----------------- creation\n /**\n * Creates the dom node for an arrow & adds it to the container\n */\n _createArrow(opts) {\n const arrow = this._register(new ScrollbarArrow(opts));\n this.domNode.domNode.appendChild(arrow.bgDomNode);\n this.domNode.domNode.appendChild(arrow.domNode);\n }\n /**\n * Creates the slider dom node, adds it to the container & hooks up the events\n */\n _createSlider(top, left, width, height) {\n this.slider = createFastDomNode(document.createElement('div'));\n this.slider.setClassName('slider');\n this.slider.setPosition('absolute');\n this.slider.setTop(top);\n this.slider.setLeft(left);\n if (typeof width === 'number') {\n this.slider.setWidth(width);\n }\n if (typeof height === 'number') {\n this.slider.setHeight(height);\n }\n this.slider.setLayerHinting(true);\n this.slider.setContain('strict');\n this.domNode.domNode.appendChild(this.slider.domNode);\n this._register(dom.addDisposableListener(this.slider.domNode, dom.EventType.POINTER_DOWN, (e) => {\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }));\n this.onclick(this.slider.domNode, e => {\n if (e.leftButton) {\n e.stopPropagation();\n }\n });\n }\n // ----------------- Update state\n _onElementSize(visibleSize) {\n if (this._scrollbarState.setVisibleSize(visibleSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n _onElementScrollSize(elementScrollSize) {\n if (this._scrollbarState.setScrollSize(elementScrollSize)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n _onElementScrollPosition(elementScrollPosition) {\n if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {\n this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n return this._shouldRender;\n }\n // ----------------- rendering\n beginReveal() {\n this._visibilityController.setShouldBeVisible(true);\n }\n beginHide() {\n this._visibilityController.setShouldBeVisible(false);\n }\n render() {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());\n this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());\n }\n // ----------------- DOM events\n _domNodePointerDown(e) {\n if (e.target !== this.domNode.domNode) {\n return;\n }\n this._onPointerDown(e);\n }\n delegatePointerDown(e) {\n const domTop = this.domNode.domNode.getClientRects()[0].top;\n const sliderStart = domTop + this._scrollbarState.getSliderPosition();\n const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();\n const pointerPos = this._sliderPointerPosition(e);\n if (sliderStart <= pointerPos && pointerPos <= sliderStop) {\n // Act as if it was a pointer down on the slider\n if (e.button === 0) {\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n else {\n // Act as if it was a pointer down on the scrollbar\n this._onPointerDown(e);\n }\n }\n _onPointerDown(e) {\n let offsetX;\n let offsetY;\n if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {\n offsetX = e.offsetX;\n offsetY = e.offsetY;\n }\n else {\n const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);\n offsetX = e.pageX - domNodePosition.left;\n offsetY = e.pageY - domNodePosition.top;\n }\n const offset = this._pointerDownRelativePosition(offsetX, offsetY);\n this._setDesiredScrollPositionNow(this._scrollByPage\n ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)\n : this._scrollbarState.getDesiredScrollPositionFromOffset(offset));\n if (e.button === 0) {\n // left button\n e.preventDefault();\n this._sliderPointerDown(e);\n }\n }\n _sliderPointerDown(e) {\n if (!e.target || !(e.target instanceof Element)) {\n return;\n }\n const initialPointerPosition = this._sliderPointerPosition(e);\n const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);\n const initialScrollbarState = this._scrollbarState.clone();\n this.slider.toggleClassName('active', true);\n this._pointerMoveMonitor.startMonitoring(e.target, e.pointerId, e.buttons, (pointerMoveData) => {\n const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);\n const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);\n if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {\n // The pointer has wondered away from the scrollbar => reset dragging\n this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());\n return;\n }\n const pointerPosition = this._sliderPointerPosition(pointerMoveData);\n const pointerDelta = pointerPosition - initialPointerPosition;\n this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));\n }, () => {\n this.slider.toggleClassName('active', false);\n this._host.onDragEnd();\n });\n this._host.onDragStart();\n }\n _setDesiredScrollPositionNow(_desiredScrollPosition) {\n const desiredScrollPosition = {};\n this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n updateScrollbarSize(scrollbarSize) {\n this._updateScrollbarSize(scrollbarSize);\n this._scrollbarState.setScrollbarSize(scrollbarSize);\n this._shouldRender = true;\n if (!this._lazyRender) {\n this.render();\n }\n }\n isNeeded() {\n return this._scrollbarState.isNeeded();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/**\n * The minimal size of the slider (such that it can still be clickable) -- it is artificially enlarged.\n */\nconst MINIMUM_SLIDER_SIZE = 20;\nexport class ScrollbarState {\n constructor(arrowSize, scrollbarSize, oppositeScrollbarSize, visibleSize, scrollSize, scrollPosition) {\n this._scrollbarSize = Math.round(scrollbarSize);\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n this._arrowSize = Math.round(arrowSize);\n this._visibleSize = visibleSize;\n this._scrollSize = scrollSize;\n this._scrollPosition = scrollPosition;\n this._computedAvailableSize = 0;\n this._computedIsNeeded = false;\n this._computedSliderSize = 0;\n this._computedSliderRatio = 0;\n this._computedSliderPosition = 0;\n this._refreshComputedValues();\n }\n clone() {\n return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n }\n setVisibleSize(visibleSize) {\n const iVisibleSize = Math.round(visibleSize);\n if (this._visibleSize !== iVisibleSize) {\n this._visibleSize = iVisibleSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n setScrollSize(scrollSize) {\n const iScrollSize = Math.round(scrollSize);\n if (this._scrollSize !== iScrollSize) {\n this._scrollSize = iScrollSize;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n setScrollPosition(scrollPosition) {\n const iScrollPosition = Math.round(scrollPosition);\n if (this._scrollPosition !== iScrollPosition) {\n this._scrollPosition = iScrollPosition;\n this._refreshComputedValues();\n return true;\n }\n return false;\n }\n setScrollbarSize(scrollbarSize) {\n this._scrollbarSize = Math.round(scrollbarSize);\n }\n setOppositeScrollbarSize(oppositeScrollbarSize) {\n this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);\n }\n static _computeValues(oppositeScrollbarSize, arrowSize, visibleSize, scrollSize, scrollPosition) {\n const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);\n const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);\n const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);\n if (!computedIsNeeded) {\n // There is no need for a slider\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedRepresentableSize),\n computedSliderRatio: 0,\n computedSliderPosition: 0,\n };\n }\n // We must artificially increase the size of the slider if needed, since the slider would be too small to grab with the mouse otherwise\n const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));\n // The slider can move from 0 to `computedRepresentableSize` - `computedSliderSize`\n // in the same way `scrollPosition` can move from 0 to `scrollSize` - `visibleSize`.\n const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);\n const computedSliderPosition = (scrollPosition * computedSliderRatio);\n return {\n computedAvailableSize: Math.round(computedAvailableSize),\n computedIsNeeded: computedIsNeeded,\n computedSliderSize: Math.round(computedSliderSize),\n computedSliderRatio: computedSliderRatio,\n computedSliderPosition: Math.round(computedSliderPosition),\n };\n }\n _refreshComputedValues() {\n const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);\n this._computedAvailableSize = r.computedAvailableSize;\n this._computedIsNeeded = r.computedIsNeeded;\n this._computedSliderSize = r.computedSliderSize;\n this._computedSliderRatio = r.computedSliderRatio;\n this._computedSliderPosition = r.computedSliderPosition;\n }\n getArrowSize() {\n return this._arrowSize;\n }\n getScrollPosition() {\n return this._scrollPosition;\n }\n getRectangleLargeSize() {\n return this._computedAvailableSize;\n }\n getRectangleSmallSize() {\n return this._scrollbarSize;\n }\n isNeeded() {\n return this._computedIsNeeded;\n }\n getSliderSize() {\n return this._computedSliderSize;\n }\n getSliderPosition() {\n return this._computedSliderPosition;\n }\n /**\n * Compute a desired `scrollPosition` such that `offset` ends up in the center of the slider.\n * `offset` is based on the same coordinate system as the `sliderPosition`.\n */\n getDesiredScrollPositionFromOffset(offset) {\n if (!this._computedIsNeeded) {\n // no need for a slider\n return 0;\n }\n const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n /**\n * Compute a desired `scrollPosition` from if offset is before or after the slider position.\n * If offset is before slider, treat as a page up (or left). If after, page down (or right).\n * `offset` and `_computedSliderPosition` are based on the same coordinate system.\n * `_visibleSize` corresponds to a \"page\" of lines in the returned coordinate system.\n */\n getDesiredScrollPositionFromOffsetPaged(offset) {\n if (!this._computedIsNeeded) {\n // no need for a slider\n return 0;\n }\n const correctedOffset = offset - this._arrowSize; // compensate if has arrows\n let desiredScrollPosition = this._scrollPosition;\n if (correctedOffset < this._computedSliderPosition) {\n desiredScrollPosition -= this._visibleSize; // page up/left\n }\n else {\n desiredScrollPosition += this._visibleSize; // page down/right\n }\n return desiredScrollPosition;\n }\n /**\n * Compute a desired `scrollPosition` such that the slider moves by `delta`.\n */\n getDesiredScrollPositionFromDelta(delta) {\n if (!this._computedIsNeeded) {\n // no need for a slider\n return 0;\n }\n const desiredSliderPosition = this._computedSliderPosition + delta;\n return Math.round(desiredSliderPosition / this._computedSliderRatio);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { StandardWheelEvent } from '../../mouseEvent.js';\nimport { AbstractScrollbar } from './abstractScrollbar.js';\nimport { ARROW_IMG_SIZE } from './scrollbarArrow.js';\nimport { ScrollbarState } from './scrollbarState.js';\nimport { Codicon } from '../../../common/codicons.js';\nexport class HorizontalScrollbar extends AbstractScrollbar {\n constructor(scrollable, options, host) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState((options.horizontalHasArrows ? options.arrowSize : 0), (options.horizontal === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.horizontalScrollbarSize), (options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize), scrollDimensions.width, scrollDimensions.scrollWidth, scrollPosition.scrollLeft),\n visibility: options.horizontal,\n extraScrollbarClassName: 'horizontal',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n if (options.horizontalHasArrows) {\n const arrowDelta = (options.arrowSize - ARROW_IMG_SIZE) / 2;\n const scrollbarDelta = (options.horizontalScrollbarSize - ARROW_IMG_SIZE) / 2;\n this._createArrow({\n className: 'scra',\n icon: Codicon.scrollbarButtonLeft,\n top: scrollbarDelta,\n left: arrowDelta,\n bottom: undefined,\n right: undefined,\n bgWidth: options.arrowSize,\n bgHeight: options.horizontalScrollbarSize,\n onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, 1, 0)),\n });\n this._createArrow({\n className: 'scra',\n icon: Codicon.scrollbarButtonRight,\n top: scrollbarDelta,\n left: undefined,\n bottom: undefined,\n right: arrowDelta,\n bgWidth: options.arrowSize,\n bgHeight: options.horizontalScrollbarSize,\n onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, -1, 0)),\n });\n }\n this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);\n }\n _updateSlider(sliderSize, sliderPosition) {\n this.slider.setWidth(sliderSize);\n this.slider.setLeft(sliderPosition);\n }\n _renderDomNode(largeSize, smallSize) {\n this.domNode.setWidth(largeSize);\n this.domNode.setHeight(smallSize);\n this.domNode.setLeft(0);\n this.domNode.setBottom(0);\n }\n onDidScroll(e) {\n this._shouldRender = this._onElementScrollSize(e.scrollWidth) || this._shouldRender;\n this._shouldRender = this._onElementScrollPosition(e.scrollLeft) || this._shouldRender;\n this._shouldRender = this._onElementSize(e.width) || this._shouldRender;\n return this._shouldRender;\n }\n _pointerDownRelativePosition(offsetX, offsetY) {\n return offsetX;\n }\n _sliderPointerPosition(e) {\n return e.pageX;\n }\n _sliderOrthogonalPointerPosition(e) {\n return e.pageY;\n }\n _updateScrollbarSize(size) {\n this.slider.setHeight(size);\n }\n writeScrollPosition(target, scrollPosition) {\n target.scrollLeft = scrollPosition;\n }\n updateOptions(options) {\n this.updateScrollbarSize(options.horizontal === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.horizontalScrollbarSize);\n this._scrollbarState.setOppositeScrollbarSize(options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize);\n this._visibilityController.setVisibility(options.horizontal);\n this._scrollByPage = options.scrollByPage;\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { StandardWheelEvent } from '../../mouseEvent.js';\nimport { AbstractScrollbar } from './abstractScrollbar.js';\nimport { ARROW_IMG_SIZE } from './scrollbarArrow.js';\nimport { ScrollbarState } from './scrollbarState.js';\nimport { Codicon } from '../../../common/codicons.js';\nexport class VerticalScrollbar extends AbstractScrollbar {\n constructor(scrollable, options, host) {\n const scrollDimensions = scrollable.getScrollDimensions();\n const scrollPosition = scrollable.getCurrentScrollPosition();\n super({\n lazyRender: options.lazyRender,\n host: host,\n scrollbarState: new ScrollbarState((options.verticalHasArrows ? options.arrowSize : 0), (options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize), \n // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom\n 0, scrollDimensions.height, scrollDimensions.scrollHeight, scrollPosition.scrollTop),\n visibility: options.vertical,\n extraScrollbarClassName: 'vertical',\n scrollable: scrollable,\n scrollByPage: options.scrollByPage\n });\n if (options.verticalHasArrows) {\n const arrowDelta = (options.arrowSize - ARROW_IMG_SIZE) / 2;\n const scrollbarDelta = (options.verticalScrollbarSize - ARROW_IMG_SIZE) / 2;\n this._createArrow({\n className: 'scra',\n icon: Codicon.scrollbarButtonUp,\n top: arrowDelta,\n left: scrollbarDelta,\n bottom: undefined,\n right: undefined,\n bgWidth: options.verticalScrollbarSize,\n bgHeight: options.arrowSize,\n onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, 0, 1)),\n });\n this._createArrow({\n className: 'scra',\n icon: Codicon.scrollbarButtonDown,\n top: undefined,\n left: scrollbarDelta,\n bottom: arrowDelta,\n right: undefined,\n bgWidth: options.verticalScrollbarSize,\n bgHeight: options.arrowSize,\n onActivate: () => this._host.onMouseWheel(new StandardWheelEvent(null, 0, -1)),\n });\n }\n this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);\n }\n _updateSlider(sliderSize, sliderPosition) {\n this.slider.setHeight(sliderSize);\n this.slider.setTop(sliderPosition);\n }\n _renderDomNode(largeSize, smallSize) {\n this.domNode.setWidth(smallSize);\n this.domNode.setHeight(largeSize);\n this.domNode.setRight(0);\n this.domNode.setTop(0);\n }\n onDidScroll(e) {\n this._shouldRender = this._onElementScrollSize(e.scrollHeight) || this._shouldRender;\n this._shouldRender = this._onElementScrollPosition(e.scrollTop) || this._shouldRender;\n this._shouldRender = this._onElementSize(e.height) || this._shouldRender;\n return this._shouldRender;\n }\n _pointerDownRelativePosition(offsetX, offsetY) {\n return offsetY;\n }\n _sliderPointerPosition(e) {\n return e.pageY;\n }\n _sliderOrthogonalPointerPosition(e) {\n return e.pageX;\n }\n _updateScrollbarSize(size) {\n this.slider.setWidth(size);\n }\n writeScrollPosition(target, scrollPosition) {\n target.scrollTop = scrollPosition;\n }\n updateOptions(options) {\n this.updateScrollbarSize(options.vertical === 2 /* ScrollbarVisibility.Hidden */ ? 0 : options.verticalScrollbarSize);\n // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom\n this._scrollbarState.setOppositeScrollbarSize(0);\n this._visibilityController.setVisibility(options.vertical);\n this._scrollByPage = options.scrollByPage;\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Emitter } from './event.js';\nimport { Disposable } from './lifecycle.js';\nexport class ScrollState {\n constructor(_forceIntegerValues, width, scrollWidth, scrollLeft, height, scrollHeight, scrollTop) {\n this._forceIntegerValues = _forceIntegerValues;\n this._scrollStateBrand = undefined;\n if (this._forceIntegerValues) {\n width = width | 0;\n scrollWidth = scrollWidth | 0;\n scrollLeft = scrollLeft | 0;\n height = height | 0;\n scrollHeight = scrollHeight | 0;\n scrollTop = scrollTop | 0;\n }\n this.rawScrollLeft = scrollLeft; // before validation\n this.rawScrollTop = scrollTop; // before validation\n if (width < 0) {\n width = 0;\n }\n if (scrollLeft + width > scrollWidth) {\n scrollLeft = scrollWidth - width;\n }\n if (scrollLeft < 0) {\n scrollLeft = 0;\n }\n if (height < 0) {\n height = 0;\n }\n if (scrollTop + height > scrollHeight) {\n scrollTop = scrollHeight - height;\n }\n if (scrollTop < 0) {\n scrollTop = 0;\n }\n this.width = width;\n this.scrollWidth = scrollWidth;\n this.scrollLeft = scrollLeft;\n this.height = height;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n }\n equals(other) {\n return (this.rawScrollLeft === other.rawScrollLeft\n && this.rawScrollTop === other.rawScrollTop\n && this.width === other.width\n && this.scrollWidth === other.scrollWidth\n && this.scrollLeft === other.scrollLeft\n && this.height === other.height\n && this.scrollHeight === other.scrollHeight\n && this.scrollTop === other.scrollTop);\n }\n withScrollDimensions(update, useRawScrollPositions) {\n return new ScrollState(this._forceIntegerValues, (typeof update.width !== 'undefined' ? update.width : this.width), (typeof update.scrollWidth !== 'undefined' ? update.scrollWidth : this.scrollWidth), useRawScrollPositions ? this.rawScrollLeft : this.scrollLeft, (typeof update.height !== 'undefined' ? update.height : this.height), (typeof update.scrollHeight !== 'undefined' ? update.scrollHeight : this.scrollHeight), useRawScrollPositions ? this.rawScrollTop : this.scrollTop);\n }\n withScrollPosition(update) {\n return new ScrollState(this._forceIntegerValues, this.width, this.scrollWidth, (typeof update.scrollLeft !== 'undefined' ? update.scrollLeft : this.rawScrollLeft), this.height, this.scrollHeight, (typeof update.scrollTop !== 'undefined' ? update.scrollTop : this.rawScrollTop));\n }\n createScrollEvent(previous, inSmoothScrolling) {\n const widthChanged = (this.width !== previous.width);\n const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth);\n const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft);\n const heightChanged = (this.height !== previous.height);\n const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight);\n const scrollTopChanged = (this.scrollTop !== previous.scrollTop);\n return {\n inSmoothScrolling: inSmoothScrolling,\n oldWidth: previous.width,\n oldScrollWidth: previous.scrollWidth,\n oldScrollLeft: previous.scrollLeft,\n width: this.width,\n scrollWidth: this.scrollWidth,\n scrollLeft: this.scrollLeft,\n oldHeight: previous.height,\n oldScrollHeight: previous.scrollHeight,\n oldScrollTop: previous.scrollTop,\n height: this.height,\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n widthChanged: widthChanged,\n scrollWidthChanged: scrollWidthChanged,\n scrollLeftChanged: scrollLeftChanged,\n heightChanged: heightChanged,\n scrollHeightChanged: scrollHeightChanged,\n scrollTopChanged: scrollTopChanged,\n };\n }\n}\nexport class Scrollable extends Disposable {\n constructor(options) {\n super();\n this._scrollableBrand = undefined;\n this._onScroll = this._register(new Emitter());\n this.onScroll = this._onScroll.event;\n this._smoothScrollDuration = options.smoothScrollDuration;\n this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame;\n this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0);\n this._smoothScrolling = null;\n }\n dispose() {\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n super.dispose();\n }\n setSmoothScrollDuration(smoothScrollDuration) {\n this._smoothScrollDuration = smoothScrollDuration;\n }\n validateScrollPosition(scrollPosition) {\n return this._state.withScrollPosition(scrollPosition);\n }\n getScrollDimensions() {\n return this._state;\n }\n setScrollDimensions(dimensions, useRawScrollPositions) {\n var _a;\n const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions);\n this._setState(newState, Boolean(this._smoothScrolling));\n // Validate outstanding animated scroll position target\n (_a = this._smoothScrolling) === null || _a === void 0 ? void 0 : _a.acceptScrollDimensions(this._state);\n }\n /**\n * Returns the final scroll position that the instance will have once the smooth scroll animation concludes.\n * If no scroll animation is occurring, it will return the current scroll position instead.\n */\n getFutureScrollPosition() {\n if (this._smoothScrolling) {\n return this._smoothScrolling.to;\n }\n return this._state;\n }\n /**\n * Returns the current scroll position.\n * Note: This result might be an intermediate scroll position, as there might be an ongoing smooth scroll animation.\n */\n getCurrentScrollPosition() {\n return this._state;\n }\n setScrollPositionNow(update) {\n // no smooth scrolling requested\n const newState = this._state.withScrollPosition(update);\n // Terminate any outstanding smooth scrolling\n if (this._smoothScrolling) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n }\n this._setState(newState, false);\n }\n setScrollPositionSmooth(update, reuseAnimation) {\n if (this._smoothScrollDuration === 0) {\n // Smooth scrolling not supported.\n return this.setScrollPositionNow(update);\n }\n if (this._smoothScrolling) {\n // Combine our pending scrollLeft/scrollTop with incoming scrollLeft/scrollTop\n update = {\n scrollLeft: (typeof update.scrollLeft === 'undefined' ? this._smoothScrolling.to.scrollLeft : update.scrollLeft),\n scrollTop: (typeof update.scrollTop === 'undefined' ? this._smoothScrolling.to.scrollTop : update.scrollTop)\n };\n // Validate `update`\n const validTarget = this._state.withScrollPosition(update);\n if (this._smoothScrolling.to.scrollLeft === validTarget.scrollLeft && this._smoothScrolling.to.scrollTop === validTarget.scrollTop) {\n // No need to interrupt or extend the current animation since we're going to the same place\n return;\n }\n let newSmoothScrolling;\n if (reuseAnimation) {\n newSmoothScrolling = new SmoothScrollingOperation(this._smoothScrolling.from, validTarget, this._smoothScrolling.startTime, this._smoothScrolling.duration);\n }\n else {\n newSmoothScrolling = this._smoothScrolling.combine(this._state, validTarget, this._smoothScrollDuration);\n }\n this._smoothScrolling.dispose();\n this._smoothScrolling = newSmoothScrolling;\n }\n else {\n // Validate `update`\n const validTarget = this._state.withScrollPosition(update);\n this._smoothScrolling = SmoothScrollingOperation.start(this._state, validTarget, this._smoothScrollDuration);\n }\n // Begin smooth scrolling animation\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n hasPendingScrollAnimation() {\n return Boolean(this._smoothScrolling);\n }\n _performSmoothScrolling() {\n if (!this._smoothScrolling) {\n return;\n }\n const update = this._smoothScrolling.tick();\n const newState = this._state.withScrollPosition(update);\n this._setState(newState, true);\n if (!this._smoothScrolling) {\n // Looks like someone canceled the smooth scrolling\n // from the scroll event handler\n return;\n }\n if (update.isDone) {\n this._smoothScrolling.dispose();\n this._smoothScrolling = null;\n return;\n }\n // Continue smooth scrolling animation\n this._smoothScrolling.animationFrameDisposable = this._scheduleAtNextAnimationFrame(() => {\n if (!this._smoothScrolling) {\n return;\n }\n this._smoothScrolling.animationFrameDisposable = null;\n this._performSmoothScrolling();\n });\n }\n _setState(newState, inSmoothScrolling) {\n const oldState = this._state;\n if (oldState.equals(newState)) {\n // no change\n return;\n }\n this._state = newState;\n this._onScroll.fire(this._state.createScrollEvent(oldState, inSmoothScrolling));\n }\n}\nexport class SmoothScrollingUpdate {\n constructor(scrollLeft, scrollTop, isDone) {\n this.scrollLeft = scrollLeft;\n this.scrollTop = scrollTop;\n this.isDone = isDone;\n }\n}\nfunction createEaseOutCubic(from, to) {\n const delta = to - from;\n return function (completion) {\n return from + delta * easeOutCubic(completion);\n };\n}\nfunction createComposed(a, b, cut) {\n return function (completion) {\n if (completion < cut) {\n return a(completion / cut);\n }\n return b((completion - cut) / (1 - cut));\n };\n}\nexport class SmoothScrollingOperation {\n constructor(from, to, startTime, duration) {\n this.from = from;\n this.to = to;\n this.duration = duration;\n this.startTime = startTime;\n this.animationFrameDisposable = null;\n this._initAnimations();\n }\n _initAnimations() {\n this.scrollLeft = this._initAnimation(this.from.scrollLeft, this.to.scrollLeft, this.to.width);\n this.scrollTop = this._initAnimation(this.from.scrollTop, this.to.scrollTop, this.to.height);\n }\n _initAnimation(from, to, viewportSize) {\n const delta = Math.abs(from - to);\n if (delta > 2.5 * viewportSize) {\n let stop1, stop2;\n if (from < to) {\n // scroll to 75% of the viewportSize\n stop1 = from + 0.75 * viewportSize;\n stop2 = to - 0.75 * viewportSize;\n }\n else {\n stop1 = from - 0.75 * viewportSize;\n stop2 = to + 0.75 * viewportSize;\n }\n return createComposed(createEaseOutCubic(from, stop1), createEaseOutCubic(stop2, to), 0.33);\n }\n return createEaseOutCubic(from, to);\n }\n dispose() {\n if (this.animationFrameDisposable !== null) {\n this.animationFrameDisposable.dispose();\n this.animationFrameDisposable = null;\n }\n }\n acceptScrollDimensions(state) {\n this.to = state.withScrollPosition(this.to);\n this._initAnimations();\n }\n tick() {\n return this._tick(Date.now());\n }\n _tick(now) {\n const completion = (now - this.startTime) / this.duration;\n if (completion < 1) {\n const newScrollLeft = this.scrollLeft(completion);\n const newScrollTop = this.scrollTop(completion);\n return new SmoothScrollingUpdate(newScrollLeft, newScrollTop, false);\n }\n return new SmoothScrollingUpdate(this.to.scrollLeft, this.to.scrollTop, true);\n }\n combine(from, to, duration) {\n return SmoothScrollingOperation.start(from, to, duration);\n }\n static start(from, to, duration) {\n // +10 / -10 : pretend the animation already started for a quicker response to a scroll request\n duration = duration + 10;\n const startTime = Date.now() - 10;\n return new SmoothScrollingOperation(from, to, startTime, duration);\n }\n}\nfunction easeInCubic(t) {\n return Math.pow(t, 3);\n}\nfunction easeOutCubic(t) {\n return 1 - easeInCubic(1 - t);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { getZoomFactor } from '../../browser.js';\nimport * as dom from '../../dom.js';\nimport { createFastDomNode } from '../../fastDomNode.js';\nimport { StandardWheelEvent } from '../../mouseEvent.js';\nimport { HorizontalScrollbar } from './horizontalScrollbar.js';\nimport { VerticalScrollbar } from './verticalScrollbar.js';\nimport { Widget } from '../widget.js';\nimport { TimeoutTimer } from '../../../common/async.js';\nimport { Emitter } from '../../../common/event.js';\nimport { dispose } from '../../../common/lifecycle.js';\nimport * as platform from '../../../common/platform.js';\nimport { Scrollable } from '../../../common/scrollable.js';\nimport './media/scrollbars.css';\nconst HIDE_TIMEOUT = 500;\nconst SCROLL_WHEEL_SENSITIVITY = 50;\nconst SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED = true;\nclass MouseWheelClassifierItem {\n constructor(timestamp, deltaX, deltaY) {\n this.timestamp = timestamp;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.score = 0;\n }\n}\nexport class MouseWheelClassifier {\n constructor() {\n this._capacity = 5;\n this._memory = [];\n this._front = -1;\n this._rear = -1;\n }\n isPhysicalMouseWheel() {\n if (this._front === -1 && this._rear === -1) {\n // no elements\n return false;\n }\n // 0.5 * last + 0.25 * 2nd last + 0.125 * 3rd last + ...\n let remainingInfluence = 1;\n let score = 0;\n let iteration = 1;\n let index = this._rear;\n do {\n const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));\n remainingInfluence -= influence;\n score += this._memory[index].score * influence;\n if (index === this._front) {\n break;\n }\n index = (this._capacity + index - 1) % this._capacity;\n iteration++;\n } while (true);\n return (score <= 0.5);\n }\n acceptStandardWheelEvent(e) {\n const osZoomFactor = window.devicePixelRatio / getZoomFactor();\n if (platform.isWindows || platform.isLinux) {\n // On Windows and Linux, the incoming delta events are multiplied with the OS zoom factor.\n // The OS zoom factor can be reverse engineered by using the device pixel ratio and the configured zoom factor into account.\n this.accept(Date.now(), e.deltaX / osZoomFactor, e.deltaY / osZoomFactor);\n }\n else {\n this.accept(Date.now(), e.deltaX, e.deltaY);\n }\n }\n accept(timestamp, deltaX, deltaY) {\n const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);\n item.score = this._computeScore(item);\n if (this._front === -1 && this._rear === -1) {\n this._memory[0] = item;\n this._front = 0;\n this._rear = 0;\n }\n else {\n this._rear = (this._rear + 1) % this._capacity;\n if (this._rear === this._front) {\n // Drop oldest\n this._front = (this._front + 1) % this._capacity;\n }\n this._memory[this._rear] = item;\n }\n }\n /**\n * A score between 0 and 1 for `item`.\n * - a score towards 0 indicates that the source appears to be a physical mouse wheel\n * - a score towards 1 indicates that the source appears to be a touchpad or magic mouse, etc.\n */\n _computeScore(item) {\n if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {\n // both axes exercised => definitely not a physical mouse wheel\n return 1;\n }\n let score = 0.5;\n const prev = (this._front === -1 && this._rear === -1 ? null : this._memory[this._rear]);\n if (prev) {\n // const deltaT = item.timestamp - prev.timestamp;\n // if (deltaT < 1000 / 30) {\n // \t// sooner than X times per second => indicator that this is not a physical mouse wheel\n // \tscore += 0.25;\n // }\n // if (item.deltaX === prev.deltaX && item.deltaY === prev.deltaY) {\n // \t// equal amplitude => indicator that this is a physical mouse wheel\n // \tscore -= 0.25;\n // }\n }\n if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {\n // non-integer deltas => indicator that this is not a physical mouse wheel\n score += 0.25;\n }\n return Math.min(Math.max(score, 0), 1);\n }\n _isAlmostInt(value) {\n const delta = Math.abs(Math.round(value) - value);\n return (delta < 0.01);\n }\n}\nMouseWheelClassifier.INSTANCE = new MouseWheelClassifier();\nexport class AbstractScrollableElement extends Widget {\n get options() {\n return this._options;\n }\n constructor(element, options, scrollable) {\n super();\n this._onScroll = this._register(new Emitter());\n this.onScroll = this._onScroll.event;\n this._onWillScroll = this._register(new Emitter());\n element.style.overflow = 'hidden';\n this._options = resolveOptions(options);\n this._scrollable = scrollable;\n this._register(this._scrollable.onScroll((e) => {\n this._onWillScroll.fire(e);\n this._onDidScroll(e);\n this._onScroll.fire(e);\n }));\n const scrollbarHost = {\n onMouseWheel: (mouseWheelEvent) => this._onMouseWheel(mouseWheelEvent),\n onDragStart: () => this._onDragStart(),\n onDragEnd: () => this._onDragEnd(),\n };\n this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));\n this._domNode = document.createElement('div');\n this._domNode.className = 'monaco-scrollable-element ' + this._options.className;\n this._domNode.setAttribute('role', 'presentation');\n this._domNode.style.position = 'relative';\n this._domNode.style.overflow = 'hidden';\n this._domNode.appendChild(element);\n this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);\n this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);\n if (this._options.useShadows) {\n this._leftShadowDomNode = createFastDomNode(document.createElement('div'));\n this._leftShadowDomNode.setClassName('shadow');\n this._domNode.appendChild(this._leftShadowDomNode.domNode);\n this._topShadowDomNode = createFastDomNode(document.createElement('div'));\n this._topShadowDomNode.setClassName('shadow');\n this._domNode.appendChild(this._topShadowDomNode.domNode);\n this._topLeftShadowDomNode = createFastDomNode(document.createElement('div'));\n this._topLeftShadowDomNode.setClassName('shadow');\n this._domNode.appendChild(this._topLeftShadowDomNode.domNode);\n }\n else {\n this._leftShadowDomNode = null;\n this._topShadowDomNode = null;\n this._topLeftShadowDomNode = null;\n }\n this._listenOnDomNode = this._options.listenOnDomNode || this._domNode;\n this._mouseWheelToDispose = [];\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n this.onmouseover(this._listenOnDomNode, (e) => this._onMouseOver(e));\n this.onmouseleave(this._listenOnDomNode, (e) => this._onMouseLeave(e));\n this._hideTimeout = this._register(new TimeoutTimer());\n this._isDragging = false;\n this._mouseIsOver = false;\n this._shouldRender = true;\n this._revealOnScroll = true;\n }\n dispose() {\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n super.dispose();\n }\n /**\n * Get the generated 'scrollable' dom node\n */\n getDomNode() {\n return this._domNode;\n }\n getOverviewRulerLayoutInfo() {\n return {\n parent: this._domNode,\n insertBefore: this._verticalScrollbar.domNode.domNode,\n };\n }\n /**\n * Delegate a pointer down event to the vertical scrollbar.\n * This is to help with clicking somewhere else and having the scrollbar react.\n */\n delegateVerticalScrollbarPointerDown(browserEvent) {\n this._verticalScrollbar.delegatePointerDown(browserEvent);\n }\n getScrollDimensions() {\n return this._scrollable.getScrollDimensions();\n }\n setScrollDimensions(dimensions) {\n this._scrollable.setScrollDimensions(dimensions, false);\n }\n /**\n * Update the class name of the scrollable element.\n */\n updateClassName(newClassName) {\n this._options.className = newClassName;\n // Defaults are different on Macs\n if (platform.isMacintosh) {\n this._options.className += ' mac';\n }\n this._domNode.className = 'monaco-scrollable-element ' + this._options.className;\n }\n /**\n * Update configuration options for the scrollbar.\n */\n updateOptions(newOptions) {\n if (typeof newOptions.handleMouseWheel !== 'undefined') {\n this._options.handleMouseWheel = newOptions.handleMouseWheel;\n this._setListeningToMouseWheel(this._options.handleMouseWheel);\n }\n if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {\n this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;\n }\n if (typeof newOptions.fastScrollSensitivity !== 'undefined') {\n this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;\n }\n if (typeof newOptions.scrollPredominantAxis !== 'undefined') {\n this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;\n }\n if (typeof newOptions.horizontal !== 'undefined') {\n this._options.horizontal = newOptions.horizontal;\n }\n if (typeof newOptions.vertical !== 'undefined') {\n this._options.vertical = newOptions.vertical;\n }\n if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {\n this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;\n }\n if (typeof newOptions.verticalScrollbarSize !== 'undefined') {\n this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;\n }\n if (typeof newOptions.scrollByPage !== 'undefined') {\n this._options.scrollByPage = newOptions.scrollByPage;\n }\n this._horizontalScrollbar.updateOptions(this._options);\n this._verticalScrollbar.updateOptions(this._options);\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n delegateScrollFromMouseWheelEvent(browserEvent) {\n this._onMouseWheel(new StandardWheelEvent(browserEvent));\n }\n // -------------------- mouse wheel scrolling --------------------\n _setListeningToMouseWheel(shouldListen) {\n const isListening = (this._mouseWheelToDispose.length > 0);\n if (isListening === shouldListen) {\n // No change\n return;\n }\n // Stop listening (if necessary)\n this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);\n // Start listening (if necessary)\n if (shouldListen) {\n const onMouseWheel = (browserEvent) => {\n this._onMouseWheel(new StandardWheelEvent(browserEvent));\n };\n this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.EventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));\n }\n }\n _onMouseWheel(e) {\n var _a;\n if ((_a = e.browserEvent) === null || _a === void 0 ? void 0 : _a.defaultPrevented) {\n return;\n }\n const classifier = MouseWheelClassifier.INSTANCE;\n if (SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED) {\n classifier.acceptStandardWheelEvent(e);\n }\n // console.log(`${Date.now()}, ${e.deltaY}, ${e.deltaX}`);\n let didScroll = false;\n if (e.deltaY || e.deltaX) {\n let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;\n let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;\n if (this._options.scrollPredominantAxis) {\n if (Math.abs(deltaY) >= Math.abs(deltaX)) {\n deltaX = 0;\n }\n else {\n deltaY = 0;\n }\n }\n if (this._options.flipAxes) {\n [deltaY, deltaX] = [deltaX, deltaY];\n }\n // Convert vertical scrolling to horizontal if shift is held, this\n // is handled at a higher level on Mac\n const shiftConvert = !platform.isMacintosh && e.browserEvent && e.browserEvent.shiftKey;\n if ((this._options.scrollYToX || shiftConvert) && !deltaX) {\n deltaX = deltaY;\n deltaY = 0;\n }\n if (e.browserEvent && e.browserEvent.altKey) {\n // fastScrolling\n deltaX = deltaX * this._options.fastScrollSensitivity;\n deltaY = deltaY * this._options.fastScrollSensitivity;\n }\n const futureScrollPosition = this._scrollable.getFutureScrollPosition();\n let desiredScrollPosition = {};\n if (deltaY) {\n const deltaScrollTop = SCROLL_WHEEL_SENSITIVITY * deltaY;\n // Here we convert values such as -0.3 to -1 or 0.3 to 1, otherwise low speed scrolling will never scroll\n const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));\n this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);\n }\n if (deltaX) {\n const deltaScrollLeft = SCROLL_WHEEL_SENSITIVITY * deltaX;\n // Here we convert values such as -0.3 to -1 or 0.3 to 1, otherwise low speed scrolling will never scroll\n const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));\n this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);\n }\n // Check that we are scrolling towards a location which is valid\n desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);\n if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {\n const canPerformSmoothScroll = (SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED\n && this._options.mouseWheelSmoothScroll\n && classifier.isPhysicalMouseWheel());\n if (canPerformSmoothScroll) {\n this._scrollable.setScrollPositionSmooth(desiredScrollPosition);\n }\n else {\n this._scrollable.setScrollPositionNow(desiredScrollPosition);\n }\n didScroll = true;\n }\n }\n let consumeMouseWheel = didScroll;\n if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {\n consumeMouseWheel = true;\n }\n if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {\n consumeMouseWheel = true;\n }\n if (consumeMouseWheel) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n _onDidScroll(e) {\n this._shouldRender = this._horizontalScrollbar.onDidScroll(e) || this._shouldRender;\n this._shouldRender = this._verticalScrollbar.onDidScroll(e) || this._shouldRender;\n if (this._options.useShadows) {\n this._shouldRender = true;\n }\n if (this._revealOnScroll) {\n this._reveal();\n }\n if (!this._options.lazyRender) {\n this._render();\n }\n }\n /**\n * Render / mutate the DOM now.\n * Should be used together with the ctor option `lazyRender`.\n */\n renderNow() {\n if (!this._options.lazyRender) {\n throw new Error('Please use `lazyRender` together with `renderNow`!');\n }\n this._render();\n }\n _render() {\n if (!this._shouldRender) {\n return;\n }\n this._shouldRender = false;\n this._horizontalScrollbar.render();\n this._verticalScrollbar.render();\n if (this._options.useShadows) {\n const scrollState = this._scrollable.getCurrentScrollPosition();\n const enableTop = scrollState.scrollTop > 0;\n const enableLeft = scrollState.scrollLeft > 0;\n const leftClassName = (enableLeft ? ' left' : '');\n const topClassName = (enableTop ? ' top' : '');\n const topLeftClassName = (enableLeft || enableTop ? ' top-left-corner' : '');\n this._leftShadowDomNode.setClassName(`shadow${leftClassName}`);\n this._topShadowDomNode.setClassName(`shadow${topClassName}`);\n this._topLeftShadowDomNode.setClassName(`shadow${topLeftClassName}${topClassName}${leftClassName}`);\n }\n }\n // -------------------- fade in / fade out --------------------\n _onDragStart() {\n this._isDragging = true;\n this._reveal();\n }\n _onDragEnd() {\n this._isDragging = false;\n this._hide();\n }\n _onMouseLeave(e) {\n this._mouseIsOver = false;\n this._hide();\n }\n _onMouseOver(e) {\n this._mouseIsOver = true;\n this._reveal();\n }\n _reveal() {\n this._verticalScrollbar.beginReveal();\n this._horizontalScrollbar.beginReveal();\n this._scheduleHide();\n }\n _hide() {\n if (!this._mouseIsOver && !this._isDragging) {\n this._verticalScrollbar.beginHide();\n this._horizontalScrollbar.beginHide();\n }\n }\n _scheduleHide() {\n if (!this._mouseIsOver && !this._isDragging) {\n this._hideTimeout.cancelAndSet(() => this._hide(), HIDE_TIMEOUT);\n }\n }\n}\nexport class ScrollableElement extends AbstractScrollableElement {\n constructor(element, options) {\n options = options || {};\n options.mouseWheelSmoothScroll = false;\n const scrollable = new Scrollable({\n forceIntegerValues: true,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback)\n });\n super(element, options, scrollable);\n this._register(scrollable);\n }\n setScrollPosition(update) {\n this._scrollable.setScrollPositionNow(update);\n }\n}\nexport class SmoothScrollableElement extends AbstractScrollableElement {\n constructor(element, options, scrollable) {\n super(element, options, scrollable);\n }\n setScrollPosition(update) {\n if (update.reuseAnimation) {\n this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);\n }\n else {\n this._scrollable.setScrollPositionNow(update);\n }\n }\n getScrollPosition() {\n return this._scrollable.getCurrentScrollPosition();\n }\n}\nexport class DomScrollableElement extends AbstractScrollableElement {\n constructor(element, options) {\n options = options || {};\n options.mouseWheelSmoothScroll = false;\n const scrollable = new Scrollable({\n forceIntegerValues: false,\n smoothScrollDuration: 0,\n scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback)\n });\n super(element, options, scrollable);\n this._register(scrollable);\n this._element = element;\n this.onScroll((e) => {\n if (e.scrollTopChanged) {\n this._element.scrollTop = e.scrollTop;\n }\n if (e.scrollLeftChanged) {\n this._element.scrollLeft = e.scrollLeft;\n }\n });\n this.scanDomNode();\n }\n setScrollPosition(update) {\n this._scrollable.setScrollPositionNow(update);\n }\n getScrollPosition() {\n return this._scrollable.getCurrentScrollPosition();\n }\n scanDomNode() {\n // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight\n this.setScrollDimensions({\n width: this._element.clientWidth,\n scrollWidth: this._element.scrollWidth,\n height: this._element.clientHeight,\n scrollHeight: this._element.scrollHeight\n });\n this.setScrollPosition({\n scrollLeft: this._element.scrollLeft,\n scrollTop: this._element.scrollTop,\n });\n }\n}\nfunction resolveOptions(opts) {\n const result = {\n lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),\n className: (typeof opts.className !== 'undefined' ? opts.className : ''),\n useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),\n handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),\n flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),\n consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),\n alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),\n scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),\n mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),\n fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),\n scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),\n mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),\n arrowSize: (typeof opts.arrowSize !== 'undefined' ? opts.arrowSize : 11),\n listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),\n horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : 1 /* ScrollbarVisibility.Auto */),\n horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),\n horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),\n horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),\n vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : 1 /* ScrollbarVisibility.Auto */),\n verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),\n verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),\n verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),\n scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)\n };\n result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);\n result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);\n // Defaults are different on Macs\n if (platform.isMacintosh) {\n result.className += ' mac';\n }\n return result;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as dom from '../../../base/browser/dom.js';\nimport { StandardWheelEvent } from '../../../base/browser/mouseEvent.js';\nimport { Disposable } from '../../../base/common/lifecycle.js';\nimport * as platform from '../../../base/common/platform.js';\nimport { HitTestContext, MouseTarget, MouseTargetFactory } from './mouseTarget.js';\nimport { ClientCoordinates, EditorMouseEvent, EditorMouseEventFactory, GlobalEditorPointerMoveMonitor, createEditorPagePosition, createCoordinatesRelativeToEditor, PageCoordinates } from '../editorDom.js';\nimport { EditorZoom } from '../../common/config/editorZoom.js';\nimport { Position } from '../../common/core/position.js';\nimport { Selection } from '../../common/core/selection.js';\nimport { ViewEventHandler } from '../../common/viewEventHandler.js';\nimport { MouseWheelClassifier } from '../../../base/browser/ui/scrollbar/scrollableElement.js';\nexport class MouseHandler extends ViewEventHandler {\n constructor(context, viewController, viewHelper) {\n super();\n this._mouseLeaveMonitor = null;\n this._context = context;\n this.viewController = viewController;\n this.viewHelper = viewHelper;\n this.mouseTargetFactory = new MouseTargetFactory(this._context, viewHelper);\n this._mouseDownOperation = this._register(new MouseDownOperation(this._context, this.viewController, this.viewHelper, this.mouseTargetFactory, (e, testEventTarget) => this._createMouseTarget(e, testEventTarget), (e) => this._getMouseColumn(e)));\n this.lastMouseLeaveTime = -1;\n this._height = this._context.configuration.options.get(141 /* EditorOption.layoutInfo */).height;\n const mouseEvents = new EditorMouseEventFactory(this.viewHelper.viewDomNode);\n this._register(mouseEvents.onContextMenu(this.viewHelper.viewDomNode, (e) => this._onContextMenu(e, true)));\n this._register(mouseEvents.onMouseMove(this.viewHelper.viewDomNode, (e) => {\n this._onMouseMove(e);\n // See https://github.com/microsoft/vscode/issues/138789\n // When moving the mouse really quickly, the browser sometimes forgets to\n // send us a `mouseleave` or `mouseout` event. We therefore install here\n // a global `mousemove` listener to manually recover if the mouse goes outside\n // the editor. As soon as the mouse leaves outside of the editor, we\n // remove this listener\n if (!this._mouseLeaveMonitor) {\n this._mouseLeaveMonitor = dom.addDisposableListener(document, 'mousemove', (e) => {\n if (!this.viewHelper.viewDomNode.contains(e.target)) {\n // went outside the editor!\n this._onMouseLeave(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode));\n }\n });\n }\n }));\n this._register(mouseEvents.onMouseUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e)));\n this._register(mouseEvents.onMouseLeave(this.viewHelper.viewDomNode, (e) => this._onMouseLeave(e)));\n // `pointerdown` events can't be used to determine if there's a double click, or triple click\n // because their `e.detail` is always 0.\n // We will therefore save the pointer id for the mouse and then reuse it in the `mousedown` event\n // for `element.setPointerCapture`.\n let capturePointerId = 0;\n this._register(mouseEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => {\n capturePointerId = pointerId;\n }));\n // The `pointerup` listener registered by `GlobalEditorPointerMoveMonitor` does not get invoked 100% of the times.\n // I speculate that this is because the `pointerup` listener is only registered during the `mousedown` event, and perhaps\n // the `pointerup` event is already queued for dispatching, which makes it that the new listener doesn't get fired.\n // See https://github.com/microsoft/vscode/issues/146486 for repro steps.\n // To compensate for that, we simply register here a `pointerup` listener and just communicate it.\n this._register(dom.addDisposableListener(this.viewHelper.viewDomNode, dom.EventType.POINTER_UP, (e) => {\n this._mouseDownOperation.onPointerUp();\n }));\n this._register(mouseEvents.onMouseDown(this.viewHelper.viewDomNode, (e) => this._onMouseDown(e, capturePointerId)));\n this._setupMouseWheelZoomListener();\n this._context.addEventHandler(this);\n }\n _setupMouseWheelZoomListener() {\n const classifier = MouseWheelClassifier.INSTANCE;\n let prevMouseWheelTime = 0;\n let gestureStartZoomLevel = EditorZoom.getZoomLevel();\n let gestureHasZoomModifiers = false;\n let gestureAccumulatedDelta = 0;\n const onMouseWheel = (browserEvent) => {\n this.viewController.emitMouseWheel(browserEvent);\n if (!this._context.configuration.options.get(73 /* EditorOption.mouseWheelZoom */)) {\n return;\n }\n const e = new StandardWheelEvent(browserEvent);\n classifier.acceptStandardWheelEvent(e);\n if (classifier.isPhysicalMouseWheel()) {\n if (hasMouseWheelZoomModifiers(browserEvent)) {\n const zoomLevel = EditorZoom.getZoomLevel();\n const delta = e.deltaY > 0 ? 1 : -1;\n EditorZoom.setZoomLevel(zoomLevel + delta);\n e.preventDefault();\n e.stopPropagation();\n }\n }\n else {\n // we consider mousewheel events that occur within 50ms of each other to be part of the same gesture\n // we don't want to consider mouse wheel events where ctrl/cmd is pressed during the inertia phase\n // we also want to accumulate deltaY values from the same gesture and use that to set the zoom level\n if (Date.now() - prevMouseWheelTime > 50) {\n // reset if more than 50ms have passed\n gestureStartZoomLevel = EditorZoom.getZoomLevel();\n gestureHasZoomModifiers = hasMouseWheelZoomModifiers(browserEvent);\n gestureAccumulatedDelta = 0;\n }\n prevMouseWheelTime = Date.now();\n gestureAccumulatedDelta += e.deltaY;\n if (gestureHasZoomModifiers) {\n EditorZoom.setZoomLevel(gestureStartZoomLevel + gestureAccumulatedDelta / 5);\n e.preventDefault();\n e.stopPropagation();\n }\n }\n };\n this._register(dom.addDisposableListener(this.viewHelper.viewDomNode, dom.EventType.MOUSE_WHEEL, onMouseWheel, { capture: true, passive: false }));\n function hasMouseWheelZoomModifiers(browserEvent) {\n return (platform.isMacintosh\n // on macOS we support cmd + two fingers scroll (`metaKey` set)\n // and also the two fingers pinch gesture (`ctrKey` set)\n ? ((browserEvent.metaKey || browserEvent.ctrlKey) && !browserEvent.shiftKey && !browserEvent.altKey)\n : (browserEvent.ctrlKey && !browserEvent.metaKey && !browserEvent.shiftKey && !browserEvent.altKey));\n }\n }\n dispose() {\n this._context.removeEventHandler(this);\n if (this._mouseLeaveMonitor) {\n this._mouseLeaveMonitor.dispose();\n this._mouseLeaveMonitor = null;\n }\n super.dispose();\n }\n // --- begin event handlers\n onConfigurationChanged(e) {\n if (e.hasChanged(141 /* EditorOption.layoutInfo */)) {\n // layout change\n const height = this._context.configuration.options.get(141 /* EditorOption.layoutInfo */).height;\n if (this._height !== height) {\n this._height = height;\n this._mouseDownOperation.onHeightChanged();\n }\n }\n return false;\n }\n onCursorStateChanged(e) {\n this._mouseDownOperation.onCursorStateChanged(e);\n return false;\n }\n onFocusChanged(e) {\n return false;\n }\n // --- end event handlers\n getTargetAtClientPoint(clientX, clientY) {\n const clientPos = new ClientCoordinates(clientX, clientY);\n const pos = clientPos.toPageCoordinates();\n const editorPos = createEditorPagePosition(this.viewHelper.viewDomNode);\n if (pos.y < editorPos.y || pos.y > editorPos.y + editorPos.height || pos.x < editorPos.x || pos.x > editorPos.x + editorPos.width) {\n return null;\n }\n const relativePos = createCoordinatesRelativeToEditor(this.viewHelper.viewDomNode, editorPos, pos);\n return this.mouseTargetFactory.createMouseTarget(this.viewHelper.getLastRenderData(), editorPos, pos, relativePos, null);\n }\n _createMouseTarget(e, testEventTarget) {\n let target = e.target;\n if (!this.viewHelper.viewDomNode.contains(target)) {\n const shadowRoot = dom.getShadowRoot(this.viewHelper.viewDomNode);\n if (shadowRoot) {\n target = shadowRoot.elementsFromPoint(e.posx, e.posy).find((el) => this.viewHelper.viewDomNode.contains(el));\n }\n }\n return this.mouseTargetFactory.createMouseTarget(this.viewHelper.getLastRenderData(), e.editorPos, e.pos, e.relativePos, testEventTarget ? target : null);\n }\n _getMouseColumn(e) {\n return this.mouseTargetFactory.getMouseColumn(e.relativePos);\n }\n _onContextMenu(e, testEventTarget) {\n this.viewController.emitContextMenu({\n event: e,\n target: this._createMouseTarget(e, testEventTarget)\n });\n }\n _onMouseMove(e) {\n const targetIsWidget = this.mouseTargetFactory.mouseTargetIsWidget(e);\n if (!targetIsWidget) {\n e.preventDefault();\n }\n if (this._mouseDownOperation.isActive()) {\n // In selection/drag operation\n return;\n }\n const actualMouseMoveTime = e.timestamp;\n if (actualMouseMoveTime < this.lastMouseLeaveTime) {\n // Due to throttling, this event occurred before the mouse left the editor, therefore ignore it.\n return;\n }\n this.viewController.emitMouseMove({\n event: e,\n target: this._createMouseTarget(e, true)\n });\n }\n _onMouseLeave(e) {\n if (this._mouseLeaveMonitor) {\n this._mouseLeaveMonitor.dispose();\n this._mouseLeaveMonitor = null;\n }\n this.lastMouseLeaveTime = (new Date()).getTime();\n this.viewController.emitMouseLeave({\n event: e,\n target: null\n });\n }\n _onMouseUp(e) {\n this.viewController.emitMouseUp({\n event: e,\n target: this._createMouseTarget(e, true)\n });\n }\n _onMouseDown(e, pointerId) {\n const t = this._createMouseTarget(e, true);\n const targetIsContent = (t.type === 6 /* MouseTargetType.CONTENT_TEXT */ || t.type === 7 /* MouseTargetType.CONTENT_EMPTY */);\n const targetIsGutter = (t.type === 2 /* MouseTargetType.GUTTER_GLYPH_MARGIN */ || t.type === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */ || t.type === 4 /* MouseTargetType.GUTTER_LINE_DECORATIONS */);\n const targetIsLineNumbers = (t.type === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */);\n const selectOnLineNumbers = this._context.configuration.options.get(106 /* EditorOption.selectOnLineNumbers */);\n const targetIsViewZone = (t.type === 8 /* MouseTargetType.CONTENT_VIEW_ZONE */ || t.type === 5 /* MouseTargetType.GUTTER_VIEW_ZONE */);\n const targetIsWidget = (t.type === 9 /* MouseTargetType.CONTENT_WIDGET */);\n let shouldHandle = e.leftButton || e.middleButton;\n if (platform.isMacintosh && e.leftButton && e.ctrlKey) {\n shouldHandle = false;\n }\n const focus = () => {\n e.preventDefault();\n this.viewHelper.focusTextArea();\n };\n if (shouldHandle && (targetIsContent || (targetIsLineNumbers && selectOnLineNumbers))) {\n focus();\n this._mouseDownOperation.start(t.type, e, pointerId);\n }\n else if (targetIsGutter) {\n // Do not steal focus\n e.preventDefault();\n }\n else if (targetIsViewZone) {\n const viewZoneData = t.detail;\n if (shouldHandle && this.viewHelper.shouldSuppressMouseDownOnViewZone(viewZoneData.viewZoneId)) {\n focus();\n this._mouseDownOperation.start(t.type, e, pointerId);\n e.preventDefault();\n }\n }\n else if (targetIsWidget && this.viewHelper.shouldSuppressMouseDownOnWidget(t.detail)) {\n focus();\n e.preventDefault();\n }\n this.viewController.emitMouseDown({\n event: e,\n target: t\n });\n }\n}\nclass MouseDownOperation extends Disposable {\n constructor(_context, _viewController, _viewHelper, _mouseTargetFactory, createMouseTarget, getMouseColumn) {\n super();\n this._context = _context;\n this._viewController = _viewController;\n this._viewHelper = _viewHelper;\n this._mouseTargetFactory = _mouseTargetFactory;\n this._createMouseTarget = createMouseTarget;\n this._getMouseColumn = getMouseColumn;\n this._mouseMoveMonitor = this._register(new GlobalEditorPointerMoveMonitor(this._viewHelper.viewDomNode));\n this._topBottomDragScrolling = this._register(new TopBottomDragScrolling(this._context, this._viewHelper, this._mouseTargetFactory, (position, inSelectionMode, revealType) => this._dispatchMouse(position, inSelectionMode, revealType)));\n this._mouseState = new MouseDownState();\n this._currentSelection = new Selection(1, 1, 1, 1);\n this._isActive = false;\n this._lastMouseEvent = null;\n }\n dispose() {\n super.dispose();\n }\n isActive() {\n return this._isActive;\n }\n _onMouseDownThenMove(e) {\n this._lastMouseEvent = e;\n this._mouseState.setModifiers(e);\n const position = this._findMousePosition(e, false);\n if (!position) {\n // Ignoring because position is unknown\n return;\n }\n if (this._mouseState.isDragAndDrop) {\n this._viewController.emitMouseDrag({\n event: e,\n target: position\n });\n }\n else {\n if (position.type === 13 /* MouseTargetType.OUTSIDE_EDITOR */ && (position.outsidePosition === 'above' || position.outsidePosition === 'below')) {\n this._topBottomDragScrolling.start(position, e);\n }\n else {\n this._topBottomDragScrolling.stop();\n this._dispatchMouse(position, true, 1 /* NavigationCommandRevealType.Minimal */);\n }\n }\n }\n start(targetType, e, pointerId) {\n this._lastMouseEvent = e;\n this._mouseState.setStartedOnLineNumbers(targetType === 3 /* MouseTargetType.GUTTER_LINE_NUMBERS */);\n this._mouseState.setStartButtons(e);\n this._mouseState.setModifiers(e);\n const position = this._findMousePosition(e, true);\n if (!position || !position.position) {\n // Ignoring because position is unknown\n return;\n }\n this._mouseState.trySetCount(e.detail, position.position);\n // Overwrite the detail of the MouseEvent, as it will be sent out in an event and contributions might rely on it.\n e.detail = this._mouseState.count;\n const options = this._context.configuration.options;\n if (!options.get(88 /* EditorOption.readOnly */)\n && options.get(33 /* EditorOption.dragAndDrop */)\n && !options.get(20 /* EditorOption.columnSelection */)\n && !this._mouseState.altKey // we don't support multiple mouse\n && e.detail < 2 // only single click on a selection can work\n && !this._isActive // the mouse is not down yet\n && !this._currentSelection.isEmpty() // we don't drag single cursor\n && (position.type === 6 /* MouseTargetType.CONTENT_TEXT */) // single click on text\n && position.position && this._currentSelection.containsPosition(position.position) // single click on a selection\n ) {\n this._mouseState.isDragAndDrop = true;\n this._isActive = true;\n this._mouseMoveMonitor.startMonitoring(this._viewHelper.viewLinesDomNode, pointerId, e.buttons, (e) => this._onMouseDownThenMove(e), (browserEvent) => {\n const position = this._findMousePosition(this._lastMouseEvent, false);\n if (browserEvent && browserEvent instanceof KeyboardEvent) {\n // cancel\n this._viewController.emitMouseDropCanceled();\n }\n else {\n this._viewController.emitMouseDrop({\n event: this._lastMouseEvent,\n target: (position ? this._createMouseTarget(this._lastMouseEvent, true) : null) // Ignoring because position is unknown, e.g., Content View Zone\n });\n }\n this._stop();\n });\n return;\n }\n this._mouseState.isDragAndDrop = false;\n this._dispatchMouse(position, e.shiftKey, 1 /* NavigationCommandRevealType.Minimal */);\n if (!this._isActive) {\n this._isActive = true;\n this._mouseMoveMonitor.startMonitoring(this._viewHelper.viewLinesDomNode, pointerId, e.buttons, (e) => this._onMouseDownThenMove(e), () => this._stop());\n }\n }\n _stop() {\n this._isActive = false;\n this._topBottomDragScrolling.stop();\n }\n onHeightChanged() {\n this._mouseMoveMonitor.stopMonitoring();\n }\n onPointerUp() {\n this._mouseMoveMonitor.stopMonitoring();\n }\n onCursorStateChanged(e) {\n this._currentSelection = e.selections[0];\n }\n _getPositionOutsideEditor(e) {\n const editorContent = e.editorPos;\n const model = this._context.viewModel;\n const viewLayout = this._context.viewLayout;\n const mouseColumn = this._getMouseColumn(e);\n if (e.posy < editorContent.y) {\n const outsideDistance = editorContent.y - e.posy;\n const verticalOffset = Math.max(viewLayout.getCurrentScrollTop() - outsideDistance, 0);\n const viewZoneData = HitTestContext.getZoneAtCoord(this._context, verticalOffset);\n if (viewZoneData) {\n const newPosition = this._helpPositionJumpOverViewZone(viewZoneData);\n if (newPosition) {\n return MouseTarget.createOutsideEditor(mouseColumn, newPosition, 'above', outsideDistance);\n }\n }\n const aboveLineNumber = viewLayout.getLineNumberAtVerticalOffset(verticalOffset);\n return MouseTarget.createOutsideEditor(mouseColumn, new Position(aboveLineNumber, 1), 'above', outsideDistance);\n }\n if (e.posy > editorContent.y + editorContent.height) {\n const outsideDistance = e.posy - editorContent.y - editorContent.height;\n const verticalOffset = viewLayout.getCurrentScrollTop() + e.relativePos.y;\n const viewZoneData = HitTestContext.getZoneAtCoord(this._context, verticalOffset);\n if (viewZoneData) {\n const newPosition = this._helpPositionJumpOverViewZone(viewZoneData);\n if (newPosition) {\n return MouseTarget.createOutsideEditor(mouseColumn, newPosition, 'below', outsideDistance);\n }\n }\n const belowLineNumber = viewLayout.getLineNumberAtVerticalOffset(verticalOffset);\n return MouseTarget.createOutsideEditor(mouseColumn, new Position(belowLineNumber, model.getLineMaxColumn(belowLineNumber)), 'below', outsideDistance);\n }\n const possibleLineNumber = viewLayout.getLineNumberAtVerticalOffset(viewLayout.getCurrentScrollTop() + e.relativePos.y);\n if (e.posx < editorContent.x) {\n const outsideDistance = editorContent.x - e.posx;\n return MouseTarget.createOutsideEditor(mouseColumn, new Position(possibleLineNumber, 1), 'left', outsideDistance);\n }\n if (e.posx > editorContent.x + editorContent.width) {\n const outsideDistance = e.posx - editorContent.x - editorContent.width;\n return MouseTarget.createOutsideEditor(mouseColumn, new Position(possibleLineNumber, model.getLineMaxColumn(possibleLineNumber)), 'right', outsideDistance);\n }\n return null;\n }\n _findMousePosition(e, testEventTarget) {\n const positionOutsideEditor = this._getPositionOutsideEditor(e);\n if (positionOutsideEditor) {\n return positionOutsideEditor;\n }\n const t = this._createMouseTarget(e, testEventTarget);\n const hintedPosition = t.position;\n if (!hintedPosition) {\n return null;\n }\n if (t.type === 8 /* MouseTargetType.CONTENT_VIEW_ZONE */ || t.type === 5 /* MouseTargetType.GUTTER_VIEW_ZONE */) {\n const newPosition = this._helpPositionJumpOverViewZone(t.detail);\n if (newPosition) {\n return MouseTarget.createViewZone(t.type, t.element, t.mouseColumn, newPosition, t.detail);\n }\n }\n return t;\n }\n _helpPositionJumpOverViewZone(viewZoneData) {\n // Force position on view zones to go above or below depending on where selection started from\n const selectionStart = new Position(this._currentSelection.selectionStartLineNumber, this._currentSelection.selectionStartColumn);\n const positionBefore = viewZoneData.positionBefore;\n const positionAfter = viewZoneData.positionAfter;\n if (positionBefore && positionAfter) {\n if (positionBefore.isBefore(selectionStart)) {\n return positionBefore;\n }\n else {\n return positionAfter;\n }\n }\n return null;\n }\n _dispatchMouse(position, inSelectionMode, revealType) {\n if (!position.position) {\n return;\n }\n this._viewController.dispatchMouse({\n position: position.position,\n mouseColumn: position.mouseColumn,\n startedOnLineNumbers: this._mouseState.startedOnLineNumbers,\n revealType,\n inSelectionMode: inSelectionMode,\n mouseDownCount: this._mouseState.count,\n altKey: this._mouseState.altKey,\n ctrlKey: this._mouseState.ctrlKey,\n metaKey: this._mouseState.metaKey,\n shiftKey: this._mouseState.shiftKey,\n leftButton: this._mouseState.leftButton,\n middleButton: this._mouseState.middleButton,\n onInjectedText: position.type === 6 /* MouseTargetType.CONTENT_TEXT */ && position.detail.injectedText !== null\n });\n }\n}\nclass TopBottomDragScrolling extends Disposable {\n constructor(_context, _viewHelper, _mouseTargetFactory, _dispatchMouse) {\n super();\n this._context = _context;\n this._viewHelper = _viewHelper;\n this._mouseTargetFactory = _mouseTargetFactory;\n this._dispatchMouse = _dispatchMouse;\n this._operation = null;\n }\n dispose() {\n super.dispose();\n this.stop();\n }\n start(position, mouseEvent) {\n if (this._operation) {\n this._operation.setPosition(position, mouseEvent);\n }\n else {\n this._operation = new TopBottomDragScrollingOperation(this._context, this._viewHelper, this._mouseTargetFactory, this._dispatchMouse, position, mouseEvent);\n }\n }\n stop() {\n if (this._operation) {\n this._operation.dispose();\n this._operation = null;\n }\n }\n}\nclass TopBottomDragScrollingOperation extends Disposable {\n constructor(_context, _viewHelper, _mouseTargetFactory, _dispatchMouse, position, mouseEvent) {\n super();\n this._context = _context;\n this._viewHelper = _viewHelper;\n this._mouseTargetFactory = _mouseTargetFactory;\n this._dispatchMouse = _dispatchMouse;\n this._position = position;\n this._mouseEvent = mouseEvent;\n this._lastTime = Date.now();\n this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute());\n }\n dispose() {\n this._animationFrameDisposable.dispose();\n }\n setPosition(position, mouseEvent) {\n this._position = position;\n this._mouseEvent = mouseEvent;\n }\n /**\n * update internal state and return elapsed ms since last time\n */\n _tick() {\n const now = Date.now();\n const elapsed = now - this._lastTime;\n this._lastTime = now;\n return elapsed;\n }\n /**\n * get the number of lines per second to auto-scroll\n */\n _getScrollSpeed() {\n const lineHeight = this._context.configuration.options.get(64 /* EditorOption.lineHeight */);\n const viewportInLines = this._context.configuration.options.get(141 /* EditorOption.layoutInfo */).height / lineHeight;\n const outsideDistanceInLines = this._position.outsideDistance / lineHeight;\n if (outsideDistanceInLines <= 1.5) {\n return Math.max(30, viewportInLines * (1 + outsideDistanceInLines));\n }\n if (outsideDistanceInLines <= 3) {\n return Math.max(60, viewportInLines * (2 + outsideDistanceInLines));\n }\n return Math.max(200, viewportInLines * (7 + outsideDistanceInLines));\n }\n _execute() {\n const lineHeight = this._context.configuration.options.get(64 /* EditorOption.lineHeight */);\n const scrollSpeedInLines = this._getScrollSpeed();\n const elapsed = this._tick();\n const scrollInPixels = scrollSpeedInLines * (elapsed / 1000) * lineHeight;\n const scrollValue = (this._position.outsidePosition === 'above' ? -scrollInPixels : scrollInPixels);\n this._context.viewModel.viewLayout.deltaScrollNow(0, scrollValue);\n this._viewHelper.renderNow();\n const viewportData = this._context.viewLayout.getLinesViewportData();\n const edgeLineNumber = (this._position.outsidePosition === 'above' ? viewportData.startLineNumber : viewportData.endLineNumber);\n // First, try to find a position that matches the horizontal position of the mouse\n let mouseTarget;\n {\n const editorPos = createEditorPagePosition(this._viewHelper.viewDomNode);\n const horizontalScrollbarHeight = this._context.configuration.options.get(141 /* EditorOption.layoutInfo */).horizontalScrollbarHeight;\n const pos = new PageCoordinates(this._mouseEvent.pos.x, editorPos.y + editorPos.height - horizontalScrollbarHeight - 0.1);\n const relativePos = createCoordinatesRelativeToEditor(this._viewHelper.viewDomNode, editorPos, pos);\n mouseTarget = this._mouseTargetFactory.createMouseTarget(this._viewHelper.getLastRenderData(), editorPos, pos, relativePos, null);\n }\n if (!mouseTarget.position || mouseTarget.position.lineNumber !== edgeLineNumber) {\n if (this._position.outsidePosition === 'above') {\n mouseTarget = MouseTarget.createOutsideEditor(this._position.mouseColumn, new Position(edgeLineNumber, 1), 'above', this._position.outsideDistance);\n }\n else {\n mouseTarget = MouseTarget.createOutsideEditor(this._position.mouseColumn, new Position(edgeLineNumber, this._context.viewModel.getLineMaxColumn(edgeLineNumber)), 'below', this._position.outsideDistance);\n }\n }\n this._dispatchMouse(mouseTarget, true, 2 /* NavigationCommandRevealType.None */);\n this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute());\n }\n}\nclass MouseDownState {\n get altKey() { return this._altKey; }\n get ctrlKey() { return this._ctrlKey; }\n get metaKey() { return this._metaKey; }\n get shiftKey() { return this._shiftKey; }\n get leftButton() { return this._leftButton; }\n get middleButton() { return this._middleButton; }\n get startedOnLineNumbers() { return this._startedOnLineNumbers; }\n constructor() {\n this._altKey = false;\n this._ctrlKey = false;\n this._metaKey = false;\n this._shiftKey = false;\n this._leftButton = false;\n this._middleButton = false;\n this._startedOnLineNumbers = false;\n this._lastMouseDownPosition = null;\n this._lastMouseDownPositionEqualCount = 0;\n this._lastMouseDownCount = 0;\n this._lastSetMouseDownCountTime = 0;\n this.isDragAndDrop = false;\n }\n get count() {\n return this._lastMouseDownCount;\n }\n setModifiers(source) {\n this._altKey = source.altKey;\n this._ctrlKey = source.ctrlKey;\n this._metaKey = source.metaKey;\n this._shiftKey = source.shiftKey;\n }\n setStartButtons(source) {\n this._leftButton = source.leftButton;\n this._middleButton = source.middleButton;\n }\n setStartedOnLineNumbers(startedOnLineNumbers) {\n this._startedOnLineNumbers = startedOnLineNumbers;\n }\n trySetCount(setMouseDownCount, newMouseDownPosition) {\n // a. Invalidate multiple clicking if too much time has passed (will be hit by IE because the detail field of mouse events contains garbage in IE10)\n const currentTime = (new Date()).getTime();\n if (currentTime - this._lastSetMouseDownCountTime > MouseDownState.CLEAR_MOUSE_DOWN_COUNT_TIME) {\n setMouseDownCount = 1;\n }\n this._lastSetMouseDownCountTime = currentTime;\n // b. Ensure that we don't jump from single click to triple click in one go (will be hit by IE because the detail field of mouse events contains garbage in IE10)\n if (setMouseDownCount > this._lastMouseDownCount + 1) {\n setMouseDownCount = this._lastMouseDownCount + 1;\n }\n // c. Invalidate multiple clicking if the logical position is different\n if (this._lastMouseDownPosition && this._lastMouseDownPosition.equals(newMouseDownPosition)) {\n this._lastMouseDownPositionEqualCount++;\n }\n else {\n this._lastMouseDownPositionEqualCount = 1;\n }\n this._lastMouseDownPosition = newMouseDownPosition;\n // Finally set the lastMouseDownCount\n this._lastMouseDownCount = Math.min(setMouseDownCount, this._lastMouseDownPositionEqualCount);\n }\n}\nMouseDownState.CLEAR_MOUSE_DOWN_COUNT_TIME = 400; // ms\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { Emitter } from '../common/event.js';\nexport class DomEmitter {\n get event() {\n return this.emitter.event;\n }\n constructor(element, type, useCapture) {\n const fn = (e) => this.emitter.fire(e);\n this.emitter = new Emitter({\n onWillAddFirstListener: () => element.addEventListener(type, fn, useCapture),\n onDidRemoveLastListener: () => element.removeEventListener(type, fn, useCapture)\n });\n }\n dispose() {\n this.emitter.dispose();\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nexport var inputLatency;\n(function (inputLatency) {\n const totalKeydownTime = { total: 0, min: Number.MAX_VALUE, max: 0 };\n const totalInputTime = Object.assign({}, totalKeydownTime);\n const totalRenderTime = Object.assign({}, totalKeydownTime);\n const totalInputLatencyTime = Object.assign({}, totalKeydownTime);\n let measurementsCount = 0;\n const state = {\n keydown: 0 /* EventPhase.Before */,\n input: 0 /* EventPhase.Before */,\n render: 0 /* EventPhase.Before */,\n };\n /**\n * Record the start of the keydown event.\n */\n function onKeyDown() {\n /** Direct Check C. See explanation in {@link recordIfFinished} */\n recordIfFinished();\n performance.mark('inputlatency/start');\n performance.mark('keydown/start');\n state.keydown = 1 /* EventPhase.InProgress */;\n queueMicrotask(markKeyDownEnd);\n }\n inputLatency.onKeyDown = onKeyDown;\n /**\n * Mark the end of the keydown event.\n */\n function markKeyDownEnd() {\n if (state.keydown === 1 /* EventPhase.InProgress */) {\n performance.mark('keydown/end');\n state.keydown = 2 /* EventPhase.Finished */;\n }\n }\n /**\n * Record the start of the beforeinput event.\n */\n function onBeforeInput() {\n performance.mark('input/start');\n state.input = 1 /* EventPhase.InProgress */;\n /** Schedule Task A. See explanation in {@link recordIfFinished} */\n scheduleRecordIfFinishedTask();\n }\n inputLatency.onBeforeInput = onBeforeInput;\n /**\n * Record the start of the input event.\n */\n function onInput() {\n if (state.input === 0 /* EventPhase.Before */) {\n // it looks like we didn't receive a `beforeinput`\n onBeforeInput();\n }\n queueMicrotask(markInputEnd);\n }\n inputLatency.onInput = onInput;\n function markInputEnd() {\n if (state.input === 1 /* EventPhase.InProgress */) {\n performance.mark('input/end');\n state.input = 2 /* EventPhase.Finished */;\n }\n }\n /**\n * Record the start of the keyup event.\n */\n function onKeyUp() {\n /** Direct Check D. See explanation in {@link recordIfFinished} */\n recordIfFinished();\n }\n inputLatency.onKeyUp = onKeyUp;\n /**\n * Record the start of the selectionchange event.\n */\n function onSelectionChange() {\n /** Direct Check E. See explanation in {@link recordIfFinished} */\n recordIfFinished();\n }\n inputLatency.onSelectionChange = onSelectionChange;\n /**\n * Record the start of the animation frame performing the rendering.\n */\n function onRenderStart() {\n // Render may be triggered during input, but we only measure the following animation frame\n if (state.keydown === 2 /* EventPhase.Finished */ && state.input === 2 /* EventPhase.Finished */ && state.render === 0 /* EventPhase.Before */) {\n // Only measure the first render after keyboard input\n performance.mark('render/start');\n state.render = 1 /* EventPhase.InProgress */;\n queueMicrotask(markRenderEnd);\n /** Schedule Task B. See explanation in {@link recordIfFinished} */\n scheduleRecordIfFinishedTask();\n }\n }\n inputLatency.onRenderStart = onRenderStart;\n /**\n * Mark the end of the animation frame performing the rendering.\n */\n function markRenderEnd() {\n if (state.render === 1 /* EventPhase.InProgress */) {\n performance.mark('render/end');\n state.render = 2 /* EventPhase.Finished */;\n }\n }\n function scheduleRecordIfFinishedTask() {\n // Here we can safely assume that the `setTimeout` will not be\n // artificially delayed by 4ms because we schedule it from\n // event handlers\n setTimeout(recordIfFinished);\n }\n /**\n * Record the input latency sample if input handling and rendering are finished.\n *\n * The challenge here is that we want to record the latency in such a way that it includes\n * also the layout and painting work the browser does during the animation frame task.\n *\n * Simply scheduling a new task (via `setTimeout`) from the animation frame task would\n * schedule the new task at the end of the task queue (after other code that uses `setTimeout`),\n * so we need to use multiple strategies to make sure our task runs before others:\n *\n * We schedule tasks (A and B):\n * - we schedule a task A (via a `setTimeout` call) when the input starts in `markInputStart`.\n * If the animation frame task is scheduled quickly by the browser, then task A has a very good\n * chance of being the very first task after the animation frame and thus will record the input latency.\n * - however, if the animation frame task is scheduled a bit later, then task A might execute\n * before the animation frame task. We therefore schedule another task B from `markRenderStart`.\n *\n * We do direct checks in browser event handlers (C, D, E):\n * - if the browser has multiple keydown events queued up, they will be scheduled before the `setTimeout` tasks,\n * so we do a direct check in the keydown event handler (C).\n * - depending on timing, sometimes the animation frame is scheduled even before the `keyup` event, so we\n * do a direct check there too (E).\n * - the browser oftentimes emits a `selectionchange` event after an `input`, so we do a direct check there (D).\n */\n function recordIfFinished() {\n if (state.keydown === 2 /* EventPhase.Finished */ && state.input === 2 /* EventPhase.Finished */ && state.render === 2 /* EventPhase.Finished */) {\n performance.mark('inputlatency/end');\n performance.measure('keydown', 'keydown/start', 'keydown/end');\n performance.measure('input', 'input/start', 'input/end');\n performance.measure('render', 'render/start', 'render/end');\n performance.measure('inputlatency', 'inputlatency/start', 'inputlatency/end');\n addMeasure('keydown', totalKeydownTime);\n addMeasure('input', totalInputTime);\n addMeasure('render', totalRenderTime);\n addMeasure('inputlatency', totalInputLatencyTime);\n // console.info(\n // \t`input latency=${performance.getEntriesByName('inputlatency')[0].duration.toFixed(1)} [` +\n // \t`keydown=${performance.getEntriesByName('keydown')[0].duration.toFixed(1)}, ` +\n // \t`input=${performance.getEntriesByName('input')[0].duration.toFixed(1)}, ` +\n // \t`render=${performance.getEntriesByName('render')[0].duration.toFixed(1)}` +\n // \t`]`\n // );\n measurementsCount++;\n reset();\n }\n }\n function addMeasure(entryName, cumulativeMeasurement) {\n const duration = performance.getEntriesByName(entryName)[0].duration;\n cumulativeMeasurement.total += duration;\n cumulativeMeasurement.min = Math.min(cumulativeMeasurement.min, duration);\n cumulativeMeasurement.max = Math.max(cumulativeMeasurement.max, duration);\n }\n /**\n * Clear the current sample.\n */\n function reset() {\n performance.clearMarks('keydown/start');\n performance.clearMarks('keydown/end');\n performance.clearMarks('input/start');\n performance.clearMarks('input/end');\n performance.clearMarks('render/start');\n performance.clearMarks('render/end');\n performance.clearMarks('inputlatency/start');\n performance.clearMarks('inputlatency/end');\n performance.clearMeasures('keydown');\n performance.clearMeasures('input');\n performance.clearMeasures('render');\n performance.clearMeasures('inputlatency');\n state.keydown = 0 /* EventPhase.Before */;\n state.input = 0 /* EventPhase.Before */;\n state.render = 0 /* EventPhase.Before */;\n }\n /**\n * Gets all input latency samples and clears the internal buffers to start recording a new set\n * of samples.\n */\n function getAndClearMeasurements() {\n if (measurementsCount === 0) {\n return undefined;\n }\n // Assemble the result\n const result = {\n keydown: cumulativeToFinalMeasurement(totalKeydownTime),\n input: cumulativeToFinalMeasurement(totalInputTime),\n render: cumulativeToFinalMeasurement(totalRenderTime),\n total: cumulativeToFinalMeasurement(totalInputLatencyTime),\n sampleCount: measurementsCount\n };\n // Clear the cumulative measurements\n clearCumulativeMeasurement(totalKeydownTime);\n clearCumulativeMeasurement(totalInputTime);\n clearCumulativeMeasurement(totalRenderTime);\n clearCumulativeMeasurement(totalInputLatencyTime);\n measurementsCount = 0;\n return result;\n }\n inputLatency.getAndClearMeasurements = getAndClearMeasurements;\n function cumulativeToFinalMeasurement(cumulative) {\n return {\n average: cumulative.total / measurementsCount,\n max: cumulative.max,\n min: cumulative.min,\n };\n }\n function clearCumulativeMeasurement(cumulative) {\n cumulative.total = 0;\n cumulative.min = Number.MAX_VALUE;\n cumulative.max = 0;\n }\n})(inputLatency || (inputLatency = {}));\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as strings from '../../../base/common/strings.js';\nimport { Range } from '../../common/core/range.js';\nexport const _debugComposition = false;\nexport class TextAreaState {\n constructor(value, \n /** the offset where selection starts inside `value` */\n selectionStart, \n /** the offset where selection ends inside `value` */\n selectionEnd, \n /** the editor range in the view coordinate system that matches the selection inside `value` */\n selection, \n /** the visible line count (wrapped, not necessarily matching \\n characters) for the text in `value` before `selectionStart` */\n newlineCountBeforeSelection) {\n this.value = value;\n this.selectionStart = selectionStart;\n this.selectionEnd = selectionEnd;\n this.selection = selection;\n this.newlineCountBeforeSelection = newlineCountBeforeSelection;\n }\n toString() {\n return `[ <${this.value}>, selectionStart: ${this.selectionStart}, selectionEnd: ${this.selectionEnd}]`;\n }\n static readFromTextArea(textArea, previousState) {\n const value = textArea.getValue();\n const selectionStart = textArea.getSelectionStart();\n const selectionEnd = textArea.getSelectionEnd();\n let newlineCountBeforeSelection = undefined;\n if (previousState) {\n const valueBeforeSelectionStart = value.substring(0, selectionStart);\n const previousValueBeforeSelectionStart = previousState.value.substring(0, previousState.selectionStart);\n if (valueBeforeSelectionStart === previousValueBeforeSelectionStart) {\n newlineCountBeforeSelection = previousState.newlineCountBeforeSelection;\n }\n }\n return new TextAreaState(value, selectionStart, selectionEnd, null, newlineCountBeforeSelection);\n }\n collapseSelection() {\n if (this.selectionStart === this.value.length) {\n return this;\n }\n return new TextAreaState(this.value, this.value.length, this.value.length, null, undefined);\n }\n writeToTextArea(reason, textArea, select) {\n if (_debugComposition) {\n console.log(`writeToTextArea ${reason}: ${this.toString()}`);\n }\n textArea.setValue(reason, this.value);\n if (select) {\n textArea.setSelectionRange(reason, this.selectionStart, this.selectionEnd);\n }\n }\n deduceEditorPosition(offset) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n if (offset <= this.selectionStart) {\n const str = this.value.substring(offset, this.selectionStart);\n return this._finishDeduceEditorPosition((_b = (_a = this.selection) === null || _a === void 0 ? void 0 : _a.getStartPosition()) !== null && _b !== void 0 ? _b : null, str, -1);\n }\n if (offset >= this.selectionEnd) {\n const str = this.value.substring(this.selectionEnd, offset);\n return this._finishDeduceEditorPosition((_d = (_c = this.selection) === null || _c === void 0 ? void 0 : _c.getEndPosition()) !== null && _d !== void 0 ? _d : null, str, 1);\n }\n const str1 = this.value.substring(this.selectionStart, offset);\n if (str1.indexOf(String.fromCharCode(8230)) === -1) {\n return this._finishDeduceEditorPosition((_f = (_e = this.selection) === null || _e === void 0 ? void 0 : _e.getStartPosition()) !== null && _f !== void 0 ? _f : null, str1, 1);\n }\n const str2 = this.value.substring(offset, this.selectionEnd);\n return this._finishDeduceEditorPosition((_h = (_g = this.selection) === null || _g === void 0 ? void 0 : _g.getEndPosition()) !== null && _h !== void 0 ? _h : null, str2, -1);\n }\n _finishDeduceEditorPosition(anchor, deltaText, signum) {\n let lineFeedCnt = 0;\n let lastLineFeedIndex = -1;\n while ((lastLineFeedIndex = deltaText.indexOf('\\n', lastLineFeedIndex + 1)) !== -1) {\n lineFeedCnt++;\n }\n return [anchor, signum * deltaText.length, lineFeedCnt];\n }\n static deduceInput(previousState, currentState, couldBeEmojiInput) {\n if (!previousState) {\n // This is the EMPTY state\n return {\n text: '',\n replacePrevCharCnt: 0,\n replaceNextCharCnt: 0,\n positionDelta: 0\n };\n }\n if (_debugComposition) {\n console.log('------------------------deduceInput');\n console.log(`PREVIOUS STATE: ${previousState.toString()}`);\n console.log(`CURRENT STATE: ${currentState.toString()}`);\n }\n const prefixLength = Math.min(strings.commonPrefixLength(previousState.value, currentState.value), previousState.selectionStart, currentState.selectionStart);\n const suffixLength = Math.min(strings.commonSuffixLength(previousState.value, currentState.value), previousState.value.length - previousState.selectionEnd, currentState.value.length - currentState.selectionEnd);\n const previousValue = previousState.value.substring(prefixLength, previousState.value.length - suffixLength);\n const currentValue = currentState.value.substring(prefixLength, currentState.value.length - suffixLength);\n const previousSelectionStart = previousState.selectionStart - prefixLength;\n const previousSelectionEnd = previousState.selectionEnd - prefixLength;\n const currentSelectionStart = currentState.selectionStart - prefixLength;\n const currentSelectionEnd = currentState.selectionEnd - prefixLength;\n if (_debugComposition) {\n console.log(`AFTER DIFFING PREVIOUS STATE: <${previousValue}>, selectionStart: ${previousSelectionStart}, selectionEnd: ${previousSelectionEnd}`);\n console.log(`AFTER DIFFING CURRENT STATE: <${currentValue}>, selectionStart: ${currentSelectionStart}, selectionEnd: ${currentSelectionEnd}`);\n }\n if (currentSelectionStart === currentSelectionEnd) {\n // no current selection\n const replacePreviousCharacters = (previousState.selectionStart - prefixLength);\n if (_debugComposition) {\n console.log(`REMOVE PREVIOUS: ${replacePreviousCharacters} chars`);\n }\n return {\n text: currentValue,\n replacePrevCharCnt: replacePreviousCharacters,\n replaceNextCharCnt: 0,\n positionDelta: 0\n };\n }\n // there is a current selection => composition case\n const replacePreviousCharacters = previousSelectionEnd - previousSelectionStart;\n return {\n text: currentValue,\n replacePrevCharCnt: replacePreviousCharacters,\n replaceNextCharCnt: 0,\n positionDelta: 0\n };\n }\n static deduceAndroidCompositionInput(previousState, currentState) {\n if (!previousState) {\n // This is the EMPTY state\n return {\n text: '',\n replacePrevCharCnt: 0,\n replaceNextCharCnt: 0,\n positionDelta: 0\n };\n }\n if (_debugComposition) {\n console.log('------------------------deduceAndroidCompositionInput');\n console.log(`PREVIOUS STATE: ${previousState.toString()}`);\n console.log(`CURRENT STATE: ${currentState.toString()}`);\n }\n if (previousState.value === currentState.value) {\n return {\n text: '',\n replacePrevCharCnt: 0,\n replaceNextCharCnt: 0,\n positionDelta: currentState.selectionEnd - previousState.selectionEnd\n };\n }\n const prefixLength = Math.min(strings.commonPrefixLength(previousState.value, currentState.value), previousState.selectionEnd);\n const suffixLength = Math.min(strings.commonSuffixLength(previousState.value, currentState.value), previousState.value.length - previousState.selectionEnd);\n const previousValue = previousState.value.substring(prefixLength, previousState.value.length - suffixLength);\n const currentValue = currentState.value.substring(prefixLength, currentState.value.length - suffixLength);\n const previousSelectionStart = previousState.selectionStart - prefixLength;\n const previousSelectionEnd = previousState.selectionEnd - prefixLength;\n const currentSelectionStart = currentState.selectionStart - prefixLength;\n const currentSelectionEnd = currentState.selectionEnd - prefixLength;\n if (_debugComposition) {\n console.log(`AFTER DIFFING PREVIOUS STATE: <${previousValue}>, selectionStart: ${previousSelectionStart}, selectionEnd: ${previousSelectionEnd}`);\n console.log(`AFTER DIFFING CURRENT STATE: <${currentValue}>, selectionStart: ${currentSelectionStart}, selectionEnd: ${currentSelectionEnd}`);\n }\n return {\n text: currentValue,\n replacePrevCharCnt: previousSelectionEnd,\n replaceNextCharCnt: previousValue.length - previousSelectionEnd,\n positionDelta: currentSelectionEnd - currentValue.length\n };\n }\n}\nTextAreaState.EMPTY = new TextAreaState('', 0, 0, null, undefined);\nexport class PagedScreenReaderStrategy {\n static _getPageOfLine(lineNumber, linesPerPage) {\n return Math.floor((lineNumber - 1) / linesPerPage);\n }\n static _getRangeForPage(page, linesPerPage) {\n const offset = page * linesPerPage;\n const startLineNumber = offset + 1;\n const endLineNumber = offset + linesPerPage;\n return new Range(startLineNumber, 1, endLineNumber + 1, 1);\n }\n static fromEditorSelection(model, selection, linesPerPage, trimLongText) {\n // Chromium handles very poorly text even of a few thousand chars\n // Cut text to avoid stalling the entire UI\n const LIMIT_CHARS = 500;\n const selectionStartPage = PagedScreenReaderStrategy._getPageOfLine(selection.startLineNumber, linesPerPage);\n const selectionStartPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionStartPage, linesPerPage);\n const selectionEndPage = PagedScreenReaderStrategy._getPageOfLine(selection.endLineNumber, linesPerPage);\n const selectionEndPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionEndPage, linesPerPage);\n let pretextRange = selectionStartPageRange.intersectRanges(new Range(1, 1, selection.startLineNumber, selection.startColumn));\n if (trimLongText && model.getValueLengthInRange(pretextRange, 1 /* EndOfLinePreference.LF */) > LIMIT_CHARS) {\n const pretextStart = model.modifyPosition(pretextRange.getEndPosition(), -LIMIT_CHARS);\n pretextRange = Range.fromPositions(pretextStart, pretextRange.getEndPosition());\n }\n const pretext = model.getValueInRange(pretextRange, 1 /* EndOfLinePreference.LF */);\n const lastLine = model.getLineCount();\n const lastLineMaxColumn = model.getLineMaxColumn(lastLine);\n let posttextRange = selectionEndPageRange.intersectRanges(new Range(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn));\n if (trimLongText && model.getValueLengthInRange(posttextRange, 1 /* EndOfLinePreference.LF */) > LIMIT_CHARS) {\n const posttextEnd = model.modifyPosition(posttextRange.getStartPosition(), LIMIT_CHARS);\n posttextRange = Range.fromPositions(posttextRange.getStartPosition(), posttextEnd);\n }\n const posttext = model.getValueInRange(posttextRange, 1 /* EndOfLinePreference.LF */);\n let text;\n if (selectionStartPage === selectionEndPage || selectionStartPage + 1 === selectionEndPage) {\n // take full selection\n text = model.getValueInRange(selection, 1 /* EndOfLinePreference.LF */);\n }\n else {\n const selectionRange1 = selectionStartPageRange.intersectRanges(selection);\n const selectionRange2 = selectionEndPageRange.intersectRanges(selection);\n text = (model.getValueInRange(selectionRange1, 1 /* EndOfLinePreference.LF */)\n + String.fromCharCode(8230)\n + model.getValueInRange(selectionRange2, 1 /* EndOfLinePreference.LF */));\n }\n if (trimLongText && text.length > 2 * LIMIT_CHARS) {\n text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length);\n }\n return new TextAreaState(pretext + text + posttext, pretext.length, pretext.length + text.length, selection, pretextRange.endLineNumber - pretextRange.startLineNumber);\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as browser from '../../../base/browser/browser.js';\nimport * as dom from '../../../base/browser/dom.js';\nimport { DomEmitter } from '../../../base/browser/event.js';\nimport { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js';\nimport { inputLatency } from '../../../base/browser/performance.js';\nimport { RunOnceScheduler } from '../../../base/common/async.js';\nimport { Emitter } from '../../../base/common/event.js';\nimport { Disposable } from '../../../base/common/lifecycle.js';\nimport { Mimes } from '../../../base/common/mime.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { TextAreaState, _debugComposition } from './textAreaState.js';\nimport { Selection } from '../../common/core/selection.js';\nexport var TextAreaSyntethicEvents;\n(function (TextAreaSyntethicEvents) {\n TextAreaSyntethicEvents.Tap = '-monaco-textarea-synthetic-tap';\n})(TextAreaSyntethicEvents || (TextAreaSyntethicEvents = {}));\nexport const CopyOptions = {\n forceCopyWithSyntaxHighlighting: false\n};\n/**\n * Every time we write to the clipboard, we record a bit of extra metadata here.\n * Every time we read from the cipboard, if the text matches our last written text,\n * we can fetch the previous metadata.\n */\nexport class InMemoryClipboardMetadataManager {\n constructor() {\n this._lastState = null;\n }\n set(lastCopiedValue, data) {\n this._lastState = { lastCopiedValue, data };\n }\n get(pastedText) {\n if (this._lastState && this._lastState.lastCopiedValue === pastedText) {\n // match!\n return this._lastState.data;\n }\n this._lastState = null;\n return null;\n }\n}\nInMemoryClipboardMetadataManager.INSTANCE = new InMemoryClipboardMetadataManager();\nclass CompositionContext {\n constructor() {\n this._lastTypeTextLength = 0;\n }\n handleCompositionUpdate(text) {\n text = text || '';\n const typeInput = {\n text: text,\n replacePrevCharCnt: this._lastTypeTextLength,\n replaceNextCharCnt: 0,\n positionDelta: 0\n };\n this._lastTypeTextLength = text.length;\n return typeInput;\n }\n}\n/**\n * Writes screen reader content to the textarea and is able to analyze its input events to generate:\n * - onCut\n * - onPaste\n * - onType\n *\n * Composition events are generated for presentation purposes (composition input is reflected in onType).\n */\nexport class TextAreaInput extends Disposable {\n get textAreaState() {\n return this._textAreaState;\n }\n constructor(_host, _textArea, _OS, _browser) {\n super();\n this._host = _host;\n this._textArea = _textArea;\n this._OS = _OS;\n this._browser = _browser;\n this._onFocus = this._register(new Emitter());\n this.onFocus = this._onFocus.event;\n this._onBlur = this._register(new Emitter());\n this.onBlur = this._onBlur.event;\n this._onKeyDown = this._register(new Emitter());\n this.onKeyDown = this._onKeyDown.event;\n this._onKeyUp = this._register(new Emitter());\n this.onKeyUp = this._onKeyUp.event;\n this._onCut = this._register(new Emitter());\n this.onCut = this._onCut.event;\n this._onPaste = this._register(new Emitter());\n this.onPaste = this._onPaste.event;\n this._onType = this._register(new Emitter());\n this.onType = this._onType.event;\n this._onCompositionStart = this._register(new Emitter());\n this.onCompositionStart = this._onCompositionStart.event;\n this._onCompositionUpdate = this._register(new Emitter());\n this.onCompositionUpdate = this._onCompositionUpdate.event;\n this._onCompositionEnd = this._register(new Emitter());\n this.onCompositionEnd = this._onCompositionEnd.event;\n this._onSelectionChangeRequest = this._register(new Emitter());\n this.onSelectionChangeRequest = this._onSelectionChangeRequest.event;\n this._asyncTriggerCut = this._register(new RunOnceScheduler(() => this._onCut.fire(), 0));\n this._asyncFocusGainWriteScreenReaderContent = this._register(new RunOnceScheduler(() => this.writeScreenReaderContent('asyncFocusGain'), 0));\n this._textAreaState = TextAreaState.EMPTY;\n this._selectionChangeListener = null;\n this.writeScreenReaderContent('ctor');\n this._hasFocus = false;\n this._currentComposition = null;\n let lastKeyDown = null;\n this._register(this._textArea.onKeyDown((_e) => {\n const e = new StandardKeyboardEvent(_e);\n if (e.keyCode === 114 /* KeyCode.KEY_IN_COMPOSITION */\n || (this._currentComposition && e.keyCode === 1 /* KeyCode.Backspace */)) {\n // Stop propagation for keyDown events if the IME is processing key input\n e.stopPropagation();\n }\n if (e.equals(9 /* KeyCode.Escape */)) {\n // Prevent default always for `Esc`, otherwise it will generate a keypress\n // See https://msdn.microsoft.com/en-us/library/ie/ms536939(v=vs.85).aspx\n e.preventDefault();\n }\n lastKeyDown = e;\n this._onKeyDown.fire(e);\n }));\n this._register(this._textArea.onKeyUp((_e) => {\n const e = new StandardKeyboardEvent(_e);\n this._onKeyUp.fire(e);\n }));\n this._register(this._textArea.onCompositionStart((e) => {\n if (_debugComposition) {\n console.log(`[compositionstart]`, e);\n }\n const currentComposition = new CompositionContext();\n if (this._currentComposition) {\n // simply reset the composition context\n this._currentComposition = currentComposition;\n return;\n }\n this._currentComposition = currentComposition;\n if (this._OS === 2 /* OperatingSystem.Macintosh */\n && lastKeyDown\n && lastKeyDown.equals(114 /* KeyCode.KEY_IN_COMPOSITION */)\n && this._textAreaState.selectionStart === this._textAreaState.selectionEnd\n && this._textAreaState.selectionStart > 0\n && this._textAreaState.value.substr(this._textAreaState.selectionStart - 1, 1) === e.data\n && (lastKeyDown.code === 'ArrowRight' || lastKeyDown.code === 'ArrowLeft')) {\n // Handling long press case on Chromium/Safari macOS + arrow key => pretend the character was selected\n if (_debugComposition) {\n console.log(`[compositionstart] Handling long press case on macOS + arrow key`, e);\n }\n // Pretend the previous character was composed (in order to get it removed by subsequent compositionupdate events)\n currentComposition.handleCompositionUpdate('x');\n this._onCompositionStart.fire({ data: e.data });\n return;\n }\n if (this._browser.isAndroid) {\n // when tapping on the editor, Android enters composition mode to edit the current word\n // so we cannot clear the textarea on Android and we must pretend the current word was selected\n this._onCompositionStart.fire({ data: e.data });\n return;\n }\n this._onCompositionStart.fire({ data: e.data });\n }));\n this._register(this._textArea.onCompositionUpdate((e) => {\n if (_debugComposition) {\n console.log(`[compositionupdate]`, e);\n }\n const currentComposition = this._currentComposition;\n if (!currentComposition) {\n // should not be possible to receive a 'compositionupdate' without a 'compositionstart'\n return;\n }\n if (this._browser.isAndroid) {\n // On Android, the data sent with the composition update event is unusable.\n // For example, if the cursor is in the middle of a word like Mic|osoft\n // and Microsoft is chosen from the keyboard's suggestions, the e.data will contain \"Microsoft\".\n // This is not really usable because it doesn't tell us where the edit began and where it ended.\n const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);\n const typeInput = TextAreaState.deduceAndroidCompositionInput(this._textAreaState, newState);\n this._textAreaState = newState;\n this._onType.fire(typeInput);\n this._onCompositionUpdate.fire(e);\n return;\n }\n const typeInput = currentComposition.handleCompositionUpdate(e.data);\n this._textAreaState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);\n this._onType.fire(typeInput);\n this._onCompositionUpdate.fire(e);\n }));\n this._register(this._textArea.onCompositionEnd((e) => {\n if (_debugComposition) {\n console.log(`[compositionend]`, e);\n }\n const currentComposition = this._currentComposition;\n if (!currentComposition) {\n // https://github.com/microsoft/monaco-editor/issues/1663\n // On iOS 13.2, Chinese system IME randomly trigger an additional compositionend event with empty data\n return;\n }\n this._currentComposition = null;\n if (this._browser.isAndroid) {\n // On Android, the data sent with the composition update event is unusable.\n // For example, if the cursor is in the middle of a word like Mic|osoft\n // and Microsoft is chosen from the keyboard's suggestions, the e.data will contain \"Microsoft\".\n // This is not really usable because it doesn't tell us where the edit began and where it ended.\n const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);\n const typeInput = TextAreaState.deduceAndroidCompositionInput(this._textAreaState, newState);\n this._textAreaState = newState;\n this._onType.fire(typeInput);\n this._onCompositionEnd.fire();\n return;\n }\n const typeInput = currentComposition.handleCompositionUpdate(e.data);\n this._textAreaState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);\n this._onType.fire(typeInput);\n this._onCompositionEnd.fire();\n }));\n this._register(this._textArea.onInput((e) => {\n if (_debugComposition) {\n console.log(`[input]`, e);\n }\n // Pretend here we touched the text area, as the `input` event will most likely\n // result in a `selectionchange` event which we want to ignore\n this._textArea.setIgnoreSelectionChangeTime('received input event');\n if (this._currentComposition) {\n return;\n }\n const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);\n const typeInput = TextAreaState.deduceInput(this._textAreaState, newState, /*couldBeEmojiInput*/ this._OS === 2 /* OperatingSystem.Macintosh */);\n if (typeInput.replacePrevCharCnt === 0 && typeInput.text.length === 1) {\n // one character was typed\n if (strings.isHighSurrogate(typeInput.text.charCodeAt(0))\n || typeInput.text.charCodeAt(0) === 0x7f /* Delete */) {\n // Ignore invalid input but keep it around for next time\n return;\n }\n }\n this._textAreaState = newState;\n if (typeInput.text !== ''\n || typeInput.replacePrevCharCnt !== 0\n || typeInput.replaceNextCharCnt !== 0\n || typeInput.positionDelta !== 0) {\n this._onType.fire(typeInput);\n }\n }));\n // --- Clipboard operations\n this._register(this._textArea.onCut((e) => {\n // Pretend here we touched the text area, as the `cut` event will most likely\n // result in a `selectionchange` event which we want to ignore\n this._textArea.setIgnoreSelectionChangeTime('received cut event');\n this._ensureClipboardGetsEditorSelection(e);\n this._asyncTriggerCut.schedule();\n }));\n this._register(this._textArea.onCopy((e) => {\n this._ensureClipboardGetsEditorSelection(e);\n }));\n this._register(this._textArea.onPaste((e) => {\n // Pretend here we touched the text area, as the `paste` event will most likely\n // result in a `selectionchange` event which we want to ignore\n this._textArea.setIgnoreSelectionChangeTime('received paste event');\n e.preventDefault();\n if (!e.clipboardData) {\n return;\n }\n let [text, metadata] = ClipboardEventUtils.getTextData(e.clipboardData);\n if (!text) {\n return;\n }\n // try the in-memory store\n metadata = metadata || InMemoryClipboardMetadataManager.INSTANCE.get(text);\n this._onPaste.fire({\n text: text,\n metadata: metadata\n });\n }));\n this._register(this._textArea.onFocus(() => {\n const hadFocus = this._hasFocus;\n this._setHasFocus(true);\n if (this._browser.isSafari && !hadFocus && this._hasFocus) {\n // When \"tabbing into\" the textarea, immediately after dispatching the 'focus' event,\n // Safari will always move the selection at offset 0 in the textarea\n this._asyncFocusGainWriteScreenReaderContent.schedule();\n }\n }));\n this._register(this._textArea.onBlur(() => {\n if (this._currentComposition) {\n // See https://github.com/microsoft/vscode/issues/112621\n // where compositionend is not triggered when the editor\n // is taken off-dom during a composition\n // Clear the flag to be able to write to the textarea\n this._currentComposition = null;\n // Clear the textarea to avoid an unwanted cursor type\n this.writeScreenReaderContent('blurWithoutCompositionEnd');\n // Fire artificial composition end\n this._onCompositionEnd.fire();\n }\n this._setHasFocus(false);\n }));\n this._register(this._textArea.onSyntheticTap(() => {\n if (this._browser.isAndroid && this._currentComposition) {\n // on Android, tapping does not cancel the current composition, so the\n // textarea is stuck showing the old composition\n // Clear the flag to be able to write to the textarea\n this._currentComposition = null;\n // Clear the textarea to avoid an unwanted cursor type\n this.writeScreenReaderContent('tapWithoutCompositionEnd');\n // Fire artificial composition end\n this._onCompositionEnd.fire();\n }\n }));\n }\n _installSelectionChangeListener() {\n // See https://github.com/microsoft/vscode/issues/27216 and https://github.com/microsoft/vscode/issues/98256\n // When using a Braille display, it is possible for users to reposition the\n // system caret. This is reflected in Chrome as a `selectionchange` event.\n //\n // The `selectionchange` event appears to be emitted under numerous other circumstances,\n // so it is quite a challenge to distinguish a `selectionchange` coming in from a user\n // using a Braille display from all the other cases.\n //\n // The problems with the `selectionchange` event are:\n // * the event is emitted when the textarea is focused programmatically -- textarea.focus()\n // * the event is emitted when the selection is changed in the textarea programmatically -- textarea.setSelectionRange(...)\n // * the event is emitted when the value of the textarea is changed programmatically -- textarea.value = '...'\n // * the event is emitted when tabbing into the textarea\n // * the event is emitted asynchronously (sometimes with a delay as high as a few tens of ms)\n // * the event sometimes comes in bursts for a single logical textarea operation\n // `selectionchange` events often come multiple times for a single logical change\n // so throttle multiple `selectionchange` events that burst in a short period of time.\n let previousSelectionChangeEventTime = 0;\n return dom.addDisposableListener(document, 'selectionchange', (e) => {\n inputLatency.onSelectionChange();\n if (!this._hasFocus) {\n return;\n }\n if (this._currentComposition) {\n return;\n }\n if (!this._browser.isChrome) {\n // Support only for Chrome until testing happens on other browsers\n return;\n }\n const now = Date.now();\n const delta1 = now - previousSelectionChangeEventTime;\n previousSelectionChangeEventTime = now;\n if (delta1 < 5) {\n // received another `selectionchange` event within 5ms of the previous `selectionchange` event\n // => ignore it\n return;\n }\n const delta2 = now - this._textArea.getIgnoreSelectionChangeTime();\n this._textArea.resetSelectionChangeTime();\n if (delta2 < 100) {\n // received a `selectionchange` event within 100ms since we touched the textarea\n // => ignore it, since we caused it\n return;\n }\n if (!this._textAreaState.selection) {\n // Cannot correlate a position in the textarea with a position in the editor...\n return;\n }\n const newValue = this._textArea.getValue();\n if (this._textAreaState.value !== newValue) {\n // Cannot correlate a position in the textarea with a position in the editor...\n return;\n }\n const newSelectionStart = this._textArea.getSelectionStart();\n const newSelectionEnd = this._textArea.getSelectionEnd();\n if (this._textAreaState.selectionStart === newSelectionStart && this._textAreaState.selectionEnd === newSelectionEnd) {\n // Nothing to do...\n return;\n }\n const _newSelectionStartPosition = this._textAreaState.deduceEditorPosition(newSelectionStart);\n const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0], _newSelectionStartPosition[1], _newSelectionStartPosition[2]);\n const _newSelectionEndPosition = this._textAreaState.deduceEditorPosition(newSelectionEnd);\n const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0], _newSelectionEndPosition[1], _newSelectionEndPosition[2]);\n const newSelection = new Selection(newSelectionStartPosition.lineNumber, newSelectionStartPosition.column, newSelectionEndPosition.lineNumber, newSelectionEndPosition.column);\n this._onSelectionChangeRequest.fire(newSelection);\n });\n }\n dispose() {\n super.dispose();\n if (this._selectionChangeListener) {\n this._selectionChangeListener.dispose();\n this._selectionChangeListener = null;\n }\n }\n focusTextArea() {\n // Setting this._hasFocus and writing the screen reader content\n // will result in a focus() and setSelectionRange() in the textarea\n this._setHasFocus(true);\n // If the editor is off DOM, focus cannot be really set, so let's double check that we have managed to set the focus\n this.refreshFocusState();\n }\n isFocused() {\n return this._hasFocus;\n }\n refreshFocusState() {\n this._setHasFocus(this._textArea.hasFocus());\n }\n _setHasFocus(newHasFocus) {\n if (this._hasFocus === newHasFocus) {\n // no change\n return;\n }\n this._hasFocus = newHasFocus;\n if (this._selectionChangeListener) {\n this._selectionChangeListener.dispose();\n this._selectionChangeListener = null;\n }\n if (this._hasFocus) {\n this._selectionChangeListener = this._installSelectionChangeListener();\n }\n if (this._hasFocus) {\n this.writeScreenReaderContent('focusgain');\n }\n if (this._hasFocus) {\n this._onFocus.fire();\n }\n else {\n this._onBlur.fire();\n }\n }\n _setAndWriteTextAreaState(reason, textAreaState) {\n if (!this._hasFocus) {\n textAreaState = textAreaState.collapseSelection();\n }\n textAreaState.writeToTextArea(reason, this._textArea, this._hasFocus);\n this._textAreaState = textAreaState;\n }\n writeScreenReaderContent(reason) {\n if (this._currentComposition) {\n // Do not write to the text area when doing composition\n return;\n }\n this._setAndWriteTextAreaState(reason, this._host.getScreenReaderContent());\n }\n _ensureClipboardGetsEditorSelection(e) {\n const dataToCopy = this._host.getDataToCopy();\n const storedMetadata = {\n version: 1,\n isFromEmptySelection: dataToCopy.isFromEmptySelection,\n multicursorText: dataToCopy.multicursorText,\n mode: dataToCopy.mode\n };\n InMemoryClipboardMetadataManager.INSTANCE.set(\n // When writing \"LINE\\r\\n\" to the clipboard and then pasting,\n // Firefox pastes \"LINE\\n\", so let's work around this quirk\n (this._browser.isFirefox ? dataToCopy.text.replace(/\\r\\n/g, '\\n') : dataToCopy.text), storedMetadata);\n e.preventDefault();\n if (e.clipboardData) {\n ClipboardEventUtils.setTextData(e.clipboardData, dataToCopy.text, dataToCopy.html, storedMetadata);\n }\n }\n}\nclass ClipboardEventUtils {\n static getTextData(clipboardData) {\n const text = clipboardData.getData(Mimes.text);\n let metadata = null;\n const rawmetadata = clipboardData.getData('vscode-editor-data');\n if (typeof rawmetadata === 'string') {\n try {\n metadata = JSON.parse(rawmetadata);\n if (metadata.version !== 1) {\n metadata = null;\n }\n }\n catch (err) {\n // no problem!\n }\n }\n if (text.length === 0 && metadata === null && clipboardData.files.length > 0) {\n // no textual data pasted, generate text from file names\n const files = Array.prototype.slice.call(clipboardData.files, 0);\n return [files.map(file => file.name).join('\\n'), null];\n }\n return [text, metadata];\n }\n static setTextData(clipboardData, text, html, metadata) {\n clipboardData.setData(Mimes.text, text);\n if (typeof html === 'string') {\n clipboardData.setData('text/html', html);\n }\n clipboardData.setData('vscode-editor-data', JSON.stringify(metadata));\n }\n}\nexport class TextAreaWrapper extends Disposable {\n constructor(_actual) {\n super();\n this._actual = _actual;\n this.onKeyDown = this._register(new DomEmitter(this._actual, 'keydown')).event;\n this.onKeyUp = this._register(new DomEmitter(this._actual, 'keyup')).event;\n this.onCompositionStart = this._register(new DomEmitter(this._actual, 'compositionstart')).event;\n this.onCompositionUpdate = this._register(new DomEmitter(this._actual, 'compositionupdate')).event;\n this.onCompositionEnd = this._register(new DomEmitter(this._actual, 'compositionend')).event;\n this.onBeforeInput = this._register(new DomEmitter(this._actual, 'beforeinput')).event;\n this.onInput = this._register(new DomEmitter(this._actual, 'input')).event;\n this.onCut = this._register(new DomEmitter(this._actual, 'cut')).event;\n this.onCopy = this._register(new DomEmitter(this._actual, 'copy')).event;\n this.onPaste = this._register(new DomEmitter(this._actual, 'paste')).event;\n this.onFocus = this._register(new DomEmitter(this._actual, 'focus')).event;\n this.onBlur = this._register(new DomEmitter(this._actual, 'blur')).event;\n this._onSyntheticTap = this._register(new Emitter());\n this.onSyntheticTap = this._onSyntheticTap.event;\n this._ignoreSelectionChangeTime = 0;\n this._register(this.onKeyDown(() => inputLatency.onKeyDown()));\n this._register(this.onBeforeInput(() => inputLatency.onBeforeInput()));\n this._register(this.onInput(() => inputLatency.onInput()));\n this._register(this.onKeyUp(() => inputLatency.onKeyUp()));\n this._register(dom.addDisposableListener(this._actual, TextAreaSyntethicEvents.Tap, () => this._onSyntheticTap.fire()));\n }\n hasFocus() {\n const shadowRoot = dom.getShadowRoot(this._actual);\n if (shadowRoot) {\n return shadowRoot.activeElement === this._actual;\n }\n else if (dom.isInDOM(this._actual)) {\n return document.activeElement === this._actual;\n }\n else {\n return false;\n }\n }\n setIgnoreSelectionChangeTime(reason) {\n this._ignoreSelectionChangeTime = Date.now();\n }\n getIgnoreSelectionChangeTime() {\n return this._ignoreSelectionChangeTime;\n }\n resetSelectionChangeTime() {\n this._ignoreSelectionChangeTime = 0;\n }\n getValue() {\n // console.log('current value: ' + this._textArea.value);\n return this._actual.value;\n }\n setValue(reason, value) {\n const textArea = this._actual;\n if (textArea.value === value) {\n // No change\n return;\n }\n // console.log('reason: ' + reason + ', current value: ' + textArea.value + ' => new value: ' + value);\n this.setIgnoreSelectionChangeTime('setValue');\n textArea.value = value;\n }\n getSelectionStart() {\n return this._actual.selectionDirection === 'backward' ? this._actual.selectionEnd : this._actual.selectionStart;\n }\n getSelectionEnd() {\n return this._actual.selectionDirection === 'backward' ? this._actual.selectionStart : this._actual.selectionEnd;\n }\n setSelectionRange(reason, selectionStart, selectionEnd) {\n const textArea = this._actual;\n let activeElement = null;\n const shadowRoot = dom.getShadowRoot(textArea);\n if (shadowRoot) {\n activeElement = shadowRoot.activeElement;\n }\n else {\n activeElement = document.activeElement;\n }\n const currentIsFocused = (activeElement === textArea);\n const currentSelectionStart = textArea.selectionStart;\n const currentSelectionEnd = textArea.selectionEnd;\n if (currentIsFocused && currentSelectionStart === selectionStart && currentSelectionEnd === selectionEnd) {\n // No change\n // Firefox iframe bug https://github.com/microsoft/monaco-editor/issues/643#issuecomment-367871377\n if (browser.isFirefox && window.parent !== window) {\n textArea.focus();\n }\n return;\n }\n // console.log('reason: ' + reason + ', setSelectionRange: ' + selectionStart + ' -> ' + selectionEnd);\n if (currentIsFocused) {\n // No need to focus, only need to change the selection range\n this.setIgnoreSelectionChangeTime('setSelectionRange');\n textArea.setSelectionRange(selectionStart, selectionEnd);\n if (browser.isFirefox && window.parent !== window) {\n textArea.focus();\n }\n return;\n }\n // If the focus is outside the textarea, browsers will try really hard to reveal the textarea.\n // Here, we try to undo the browser's desperate reveal.\n try {\n const scrollState = dom.saveParentsScrollTop(textArea);\n this.setIgnoreSelectionChangeTime('setSelectionRange');\n textArea.focus();\n textArea.setSelectionRange(selectionStart, selectionEnd);\n dom.restoreParentsScrollTop(textArea, scrollState);\n }\n catch (e) {\n // Sometimes IE throws when setting selection (e.g. textarea is off-DOM)\n }\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as dom from '../../../base/browser/dom.js';\nimport * as platform from '../../../base/common/platform.js';\nimport { EventType, Gesture } from '../../../base/browser/touch.js';\nimport { Disposable } from '../../../base/common/lifecycle.js';\nimport { MouseHandler } from './mouseHandler.js';\nimport { EditorMouseEvent, EditorPointerEventFactory } from '../editorDom.js';\nimport { BrowserFeatures } from '../../../base/browser/canIUse.js';\nimport { TextAreaSyntethicEvents } from './textAreaInput.js';\n/**\n * Currently only tested on iOS 13/ iPadOS.\n */\nexport class PointerEventHandler extends MouseHandler {\n constructor(context, viewController, viewHelper) {\n super(context, viewController, viewHelper);\n this._register(Gesture.addTarget(this.viewHelper.linesContentDomNode));\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e)));\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e)));\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e) => this._onContextMenu(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode), false)));\n this._lastPointerType = 'mouse';\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, 'pointerdown', (e) => {\n const pointerType = e.pointerType;\n if (pointerType === 'mouse') {\n this._lastPointerType = 'mouse';\n return;\n }\n else if (pointerType === 'touch') {\n this._lastPointerType = 'touch';\n }\n else {\n this._lastPointerType = 'pen';\n }\n }));\n // PonterEvents\n const pointerEvents = new EditorPointerEventFactory(this.viewHelper.viewDomNode);\n this._register(pointerEvents.onPointerMove(this.viewHelper.viewDomNode, (e) => this._onMouseMove(e)));\n this._register(pointerEvents.onPointerUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e)));\n this._register(pointerEvents.onPointerLeave(this.viewHelper.viewDomNode, (e) => this._onMouseLeave(e)));\n this._register(pointerEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => this._onMouseDown(e, pointerId)));\n }\n onTap(event) {\n if (!event.initialTarget || !this.viewHelper.linesContentDomNode.contains(event.initialTarget)) {\n return;\n }\n event.preventDefault();\n this.viewHelper.focusTextArea();\n const target = this._createMouseTarget(new EditorMouseEvent(event, false, this.viewHelper.viewDomNode), false);\n if (target.position) {\n // this.viewController.moveTo(target.position);\n this.viewController.dispatchMouse({\n position: target.position,\n mouseColumn: target.position.column,\n startedOnLineNumbers: false,\n revealType: 1 /* NavigationCommandRevealType.Minimal */,\n mouseDownCount: event.tapCount,\n inSelectionMode: false,\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n leftButton: false,\n middleButton: false,\n onInjectedText: target.type === 6 /* MouseTargetType.CONTENT_TEXT */ && target.detail.injectedText !== null\n });\n }\n }\n onChange(e) {\n if (this._lastPointerType === 'touch') {\n this._context.viewModel.viewLayout.deltaScrollNow(-e.translationX, -e.translationY);\n }\n }\n _onMouseDown(e, pointerId) {\n if (e.browserEvent.pointerType === 'touch') {\n return;\n }\n super._onMouseDown(e, pointerId);\n }\n}\nclass TouchHandler extends MouseHandler {\n constructor(context, viewController, viewHelper) {\n super(context, viewController, viewHelper);\n this._register(Gesture.addTarget(this.viewHelper.linesContentDomNode));\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e)));\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e)));\n this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e) => this._onContextMenu(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode), false)));\n }\n onTap(event) {\n event.preventDefault();\n this.viewHelper.focusTextArea();\n const target = this._createMouseTarget(new EditorMouseEvent(event, false, this.viewHelper.viewDomNode), false);\n if (target.position) {\n // Send the tap event also to the