From 8ba70fba27891859902f4e30e4b57aa2ced10c30 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 01:21:59 -0800 Subject: [PATCH 01/16] First attempted import of `symbols-view` --- packages/symbols-view/README.md | 27 + .../keymaps/symbols-view-plus.cson | 20 + packages/symbols-view/lib/config.js | 39 + packages/symbols-view/lib/element-builder.js | 52 + packages/symbols-view/lib/file-view.js | 334 +++++ packages/symbols-view/lib/go-back-view.js | 29 + packages/symbols-view/lib/go-to-view.js | 114 ++ packages/symbols-view/lib/main.d.ts | 299 ++++ packages/symbols-view/lib/main.js | 229 +++ packages/symbols-view/lib/project-view.js | 198 +++ packages/symbols-view/lib/provider-broker.js | 241 ++++ packages/symbols-view/lib/symbols-view.js | 393 ++++++ packages/symbols-view/lib/util.js | 161 +++ packages/symbols-view/package-lock.json | 1233 +++++++++++++++++ packages/symbols-view/package.json | 78 ++ packages/symbols-view/spec/.eslintrc.js | 10 + .../symbols-view/spec/async-spec-helpers.js | 67 + .../spec/fixtures/js/other-file.js | 29 + .../symbols-view/spec/fixtures/js/sample.js | 13 + .../symbols-view/spec/fixtures/js/tagged.js | 11 + .../spec/fixtures/providers/async-provider.js | 60 + .../providers/cache-clearing-provider.js | 45 + .../providers/competing-exclusive-provider.js | 41 + .../spec/fixtures/providers/dummy-provider.js | 51 + .../spec/fixtures/providers/empty-provider.js | 13 + .../providers/progressive-project-provider.js | 57 + .../fixtures/providers/quicksort-provider.js | 44 + .../fixtures/providers/tagged-provider.js | 44 + .../fixtures/providers/useless-provider.js | 13 + .../fixtures/providers/very-slow-provider.js | 29 + .../symbols-view/spec/symbols-view-spec.js | 780 +++++++++++ .../symbols-view/styles/symbols-view.less | 90 ++ 32 files changed, 4844 insertions(+) create mode 100644 packages/symbols-view/README.md create mode 100644 packages/symbols-view/keymaps/symbols-view-plus.cson create mode 100644 packages/symbols-view/lib/config.js create mode 100644 packages/symbols-view/lib/element-builder.js create mode 100644 packages/symbols-view/lib/file-view.js create mode 100644 packages/symbols-view/lib/go-back-view.js create mode 100644 packages/symbols-view/lib/go-to-view.js create mode 100644 packages/symbols-view/lib/main.d.ts create mode 100644 packages/symbols-view/lib/main.js create mode 100644 packages/symbols-view/lib/project-view.js create mode 100644 packages/symbols-view/lib/provider-broker.js create mode 100644 packages/symbols-view/lib/symbols-view.js create mode 100644 packages/symbols-view/lib/util.js create mode 100644 packages/symbols-view/package-lock.json create mode 100644 packages/symbols-view/package.json create mode 100644 packages/symbols-view/spec/.eslintrc.js create mode 100644 packages/symbols-view/spec/async-spec-helpers.js create mode 100644 packages/symbols-view/spec/fixtures/js/other-file.js create mode 100644 packages/symbols-view/spec/fixtures/js/sample.js create mode 100644 packages/symbols-view/spec/fixtures/js/tagged.js create mode 100644 packages/symbols-view/spec/fixtures/providers/async-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/cache-clearing-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/competing-exclusive-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/dummy-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/empty-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/progressive-project-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/quicksort-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/tagged-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/useless-provider.js create mode 100644 packages/symbols-view/spec/fixtures/providers/very-slow-provider.js create mode 100644 packages/symbols-view/spec/symbols-view-spec.js create mode 100644 packages/symbols-view/styles/symbols-view.less diff --git a/packages/symbols-view/README.md b/packages/symbols-view/README.md new file mode 100644 index 000000000..1975dc318 --- /dev/null +++ b/packages/symbols-view/README.md @@ -0,0 +1,27 @@ +# symbols-view + +Display a list of symbols in the editor. Typically, a symbol will correspond to a meaningful part of a source code file (like a function definition) but can refer to other important parts of files depending on context. + +## Providers + +`symbols-view` uses a provider/subscriber model similar to that of `autocomplete-plus`. This package implements the UI, but it relies on other packages to suggest symbols. + +### Built-in providers + +The original symbol provider, `ctags`, now lives in its own provider package called `symbol-provider-ctags`. Another package, `symbol-provider-tree-sitter`, is the preferred provider (by default) in buffers that use a Tree-sitter grammar. + +### Community package providers + +Any package can act as a symbol provider. [These are the packages on the Pulsar Package Repository that provide the `symbol.provider` service.](https://web.pulsar-edit.dev/packages?service=symbol.provider&serviceType=provided) + +## Commands + +|Command|Description|Keybinding (Linux/Windows)|Keybinding (macOS)| +|-------|-----------|------------------|-----------------| +|`symbols-view:toggle-file-symbols`|Show all symbols in current file|ctrl-r|cmd-r| +|`symbols-view:toggle-project-symbols`|Show all symbols in the project|ctrl-shift-r|cmd-shift-r| +|`symbols-view:go-to-declaration`|Jump to the symbol under the cursor|ctrl-alt-down|cmd-alt-down| +|`symbols-view:return-from-declaration`|Return from the jump|ctrl-alt-up|cmd-alt-up| +|`symbols-view:show-active-providers`|Display a list of all known symbol providers||| + +Commands relating to project-wide symbols may fail if no provider can satisfy a request for project-wide symbols. See `symbol-provider-ctags` for more information. diff --git a/packages/symbols-view/keymaps/symbols-view-plus.cson b/packages/symbols-view/keymaps/symbols-view-plus.cson new file mode 100644 index 000000000..08535c3d5 --- /dev/null +++ b/packages/symbols-view/keymaps/symbols-view-plus.cson @@ -0,0 +1,20 @@ +'.platform-darwin atom-text-editor:not([mini])': + 'cmd-r': 'symbols-view:toggle-file-symbols' + 'cmd-alt-down': 'symbols-view:go-to-declaration' + 'cmd-alt-up': 'symbols-view:return-from-declaration' + +'.platform-win32 atom-text-editor:not([mini])': + 'ctrl-r': 'symbols-view:toggle-file-symbols' + 'ctrl-alt-down': 'symbols-view:go-to-declaration' + 'ctrl-alt-up': 'symbols-view:return-from-declaration' + +'.platform-linux atom-text-editor:not([mini])': + 'ctrl-r': 'symbols-view:toggle-file-symbols' + 'ctrl-alt-down': 'symbols-view:go-to-declaration' + 'ctrl-alt-up': 'symbols-view:return-from-declaration' + +'.platform-darwin': + 'cmd-shift-r': 'symbols-view:toggle-project-symbols' + +'.platform-win32, .platform-linux': + 'ctrl-shift-r': 'symbols-view:toggle-project-symbols' diff --git a/packages/symbols-view/lib/config.js b/packages/symbols-view/lib/config.js new file mode 100644 index 000000000..0a969b86f --- /dev/null +++ b/packages/symbols-view/lib/config.js @@ -0,0 +1,39 @@ +const { CompositeDisposable, Emitter } = require('atom'); + +const Config = { + activate() { + if (this.activated) return; + this.emitter ??= new Emitter(); + this.subscriptions = new CompositeDisposable(); + + this.subscriptions.add( + atom.config.onDidChange('symbols-view', config => { + this.emitter.emit('did-change-config', config); + }) + ); + this.activated = true; + }, + + deactivate() { + this.activated = false; + this.subscriptions?.dispose(); + }, + + get(key) { + return atom.config.get(`symbols-view.${key}`); + }, + + set(key, value) { + return atom.config.set(`symbols-view.${key}`, value); + }, + + observe(key, callback) { + return atom.config.observe(`symbols-view.${key}`, callback); + }, + + onDidChange(callback) { + return this.emitter.on('did-change-config', callback); + } +}; + +module.exports = Config; diff --git a/packages/symbols-view/lib/element-builder.js b/packages/symbols-view/lib/element-builder.js new file mode 100644 index 000000000..88abc5fae --- /dev/null +++ b/packages/symbols-view/lib/element-builder.js @@ -0,0 +1,52 @@ + +function parseTagName (selector) { + if (!selector.includes('.')) { + return [selector, null]; + } + let tagName = selector.substring(0, selector.indexOf('.')); + let classes = selector.substring(selector.indexOf('.') + 1); + let classList = classes.split('.'); + return [tagName ?? 'div', classList]; +} + +function el (selector, ...args) { + let attributes = null; + + if (typeof args[0] === 'object' && !args[0].nodeType) { + attributes = args.shift(); + } + + // Extract a tag name and any number of class names from the first argument. + let [tagName, classList] = parseTagName(selector); + + let element = document.createElement(tagName); + if (attributes) { + // If an object is given as a second argument, it's a list of + // attribute/value pairs. + for (let [attr, value] of Object.entries(attributes)) { + element.setAttribute(attr, value); + } + } + // Any further arguments are children of the element. + for (let item of args) { + if (!item) continue; + if (typeof item === 'string') { + item = document.createTextNode(item); + } else if (Array.isArray(item)) { + // This is an array; append its children, but do not append it. + for (let n of item) { + element.appendChild(n); + } + continue; + } + element.appendChild(item); + } + + if (classList) { + element.classList.add(...classList); + } + + return element; +} + +module.exports = el; diff --git a/packages/symbols-view/lib/file-view.js b/packages/symbols-view/lib/file-view.js new file mode 100644 index 000000000..30ce87833 --- /dev/null +++ b/packages/symbols-view/lib/file-view.js @@ -0,0 +1,334 @@ +const { CompositeDisposable, Point } = require('atom'); +const { match } = require('fuzzaldrin'); + +const Config = require('./config'); +const SymbolsView = require('./symbols-view'); +const el = require('./element-builder'); +const { badge, isIterable, timeout } = require('./util'); + +class FileView extends SymbolsView { + constructor (stack, broker) { + super(stack, broker); + this.cachedResults = new Map(); + // Cached results can be partially invalidated. If a provider wants to + // clear only its own cached results, keep track of it so that we know to + // ask it for new symbols in spite of the presence of other results in the + // cache. + this.providersWithInvalidatedCaches = new Map(); + this.watchedEditors = new WeakSet(); + + this.editorsSubscription = atom.workspace.observeTextEditors(editor => { + if (this.watchedEditors.has(editor)) return; + + const removeFromCache = (provider = null) => { + if (!provider) { + this.cachedResults.delete(editor); + this.providersWithInvalidatedCaches.delete(editor); + return; + } + let results = this.cachedResults.get(editor); + if (!results || results.length === 0) return; + results = results.filter(sym => { + return sym.providerId !== provider.packageName; + }); + if (results.length === 0) { + // No other providers had cached any symbols, so we can do the simple + // thing here. + this.cachedResults.delete(editor); + this.providersWithInvalidatedCaches.delete(editor); + return; + } + // There's at least one remaining cached symbol. When we fetch this + // cache result, we need a way of knowing whether this cache entry is + // comprehensive. So we'll add this provider to a list of providers + // that will need re-querying. + this.cachedResults.set(editor, results); + let providers = this.providersWithInvalidatedCaches.get(editor); + if (!providers) { + providers = new Set(); + this.providersWithInvalidatedCaches.set(editor, providers); + } + providers.add(provider); + }; + const removeAllFromCache = () => removeFromCache(null); + + const editorSubscriptions = new CompositeDisposable(); + let buffer = editor.getBuffer(); + + // All the core actions that can invalidate the symbol cache. + editorSubscriptions.add( + // Some of them invalidate the entire cache… + editor.onDidChangeGrammar(removeAllFromCache), + editor.onDidSave(removeAllFromCache), + editor.onDidChangePath(removeAllFromCache), + buffer.onDidReload(removeAllFromCache), + buffer.onDidDestroy(removeAllFromCache), + buffer.onDidStopChanging(removeAllFromCache), + Config.onDidChange(removeAllFromCache), + + // …and others invalidate only the cache for one specific provider. + this.broker.onDidAddProvider(removeFromCache), + this.broker.onDidRemoveProvider(removeFromCache), + this.broker.onShouldClearCache((bundle = {}) => { + let { provider = null, editor: someEditor = null } = bundle; + if (someEditor && editor.id !== someEditor.id) return; + removeFromCache(provider); + }) + ); + + editorSubscriptions.add( + editor.onDidDestroy(() => { + this.watchedEditors.delete(editor); + editorSubscriptions.dispose(); + }) + ); + + this.watchedEditors.add(editor); + }); + } + + destroy () { + this.editorsSubscription.dispose(); + return super.destroy(); + } + + elementForItem ({ position, name, tag, icon, context, providerName }) { + // Style matched characters in search results. + const matches = match(name, this.selectListView.getFilterQuery()); + + let badges = []; + if (providerName && this.shouldShowProviderName) { + badges.push(providerName); + } + if (tag) { + badges.push(tag); + } + + let primaryLineClasses = ['primary-line']; + if (this.showIconsInSymbolsView) { + if (icon) { + primaryLineClasses.push('icon', icon); + } else { + primaryLineClasses.push('no-icon'); + } + } + + // The “primary” results line shows the symbol's name and its tag, if any. + let primary = el(`div.${primaryLineClasses.join('.')}`, + el('div.name', + SymbolsView.highlightMatches(this, name, matches) + ), + badges && el('div.badge-container', + ...badges.map(b => badge(b, { variant: this.useBadgeColors })) + ) + ); + + // The “secondary” results line shows the symbol’s row number and its + // context, if any. + let secondaryLineClasses = ['secondary-line']; + if (this.showIconsInSymbolsView) { + secondaryLineClasses.push('no-icon'); + } + let secondary = el(`div.${secondaryLineClasses.join('.')}`, + el('span.location', `Line ${position.row + 1}`), + context && el('span.context', context) + ); + + return el('li.two-lines', primary, secondary); + } + + didChangeSelection (item) { + let quickJump = Config.get('quickJumpToFileSymbol'); + if (quickJump && item) this.openTag(item); + } + + async didCancelSelection () { + this.abortController?.abort(); + await this.cancel(); + let editor = this.getEditor(); + if (editor && this.initialState) { + this.deserializeEditorState(editor, this.initialState); + } + this.initialState = null; + } + + didConfirmEmptySelection () { + this.abortController?.abort(); + super.didConfirmEmptySelection(); + } + + async toggle () { + if (this.panel.isVisible()) await this.cancel(); + let editor = this.getEditor(); + // Remember exactly where the editor is so that we can restore that state + // if the user cancels. + let quickJump = Config.get('quickJumpToFileSymbol'); + if (quickJump && editor) { + this.initialState = this.serializeEditorState(editor); + } + + let populated = this.populate(editor); + if (!populated) return; + this.attach(); + } + + serializeEditorState (editor) { + let editorElement = atom.views.getView(editor); + let scrollTop = editorElement.getScrollTop(); + + return { + bufferRanges: editor.getSelectedBufferRanges(), + scrollTop + }; + } + + deserializeEditorState (editor, { bufferRanges, scrollTop }) { + let editorElement = atom.views.getView(editor); + + editor.setSelectedBufferRanges(bufferRanges); + editorElement.setScrollTop(scrollTop); + } + + getEditor () { + return atom.workspace.getActiveTextEditor(); + } + + getPath () { + return this.getEditor()?.getPath(); + } + + getScopeName () { + return this.getEditor()?.getGrammar()?.scopeName; + } + + isValidSymbol (symbol) { + if (!symbol.position || !(symbol.position instanceof Point)) return false; + if (typeof symbol.name !== 'string') return false; + return true; + } + + async populate (editor) { + let result = this.cachedResults.get(editor); + let providersToQuery = this.providersWithInvalidatedCaches.get(editor); + if (result && !providersToQuery?.size) { + let symbols = result; + await this.updateView({ + items: symbols + }); + return true; + } else { + await this.updateView({ + items: [], + loadingMessage: 'Generating symbols\u2026' + }); + result = this.generateSymbols(editor, result, providersToQuery); + if (result?.then) result = await result; + this.providersWithInvalidatedCaches.delete(editor); + + if (result == null) { + this.cancel(); + return false; + } + result.sort((a, b) => a.position.compare(b.position)); + await this.updateView({ + items: result, + loadingMessage: null + }); + return true; + } + } + + async generateSymbols (editor, existingSymbols = null, onlyProviders = null) { + this.abortController?.abort(); + this.abortController = new AbortController(); + + let meta = { type: 'file', editor, timeout: this.timeoutMs }; + + // The signal is how a provider can stop doing work if it's going async, + // since it'll be able to tell if we've cancelled this command and no + // longer need the symbols we asked for. + let signal = this.abortController.signal; + + let providers = await this.broker.select(meta); + // If our last cache result was only partially invalidated, `onlyProviders` + // will be a `Set` of providers that need re-querying — but only if the + // broker selected them again in the first place. + // + // When re-using a cache result that was preserved in its entirety, we + // don't give the broker a chance to assemble another list of providers. We + // should act similarly in the event of partial invalidation, and ignore + // any providers _except_ the ones whose caches were invalidated. + if (onlyProviders) { + providers = providers.filter(p => onlyProviders.has(p)); + } + + if (providers?.length === 0) { + // TODO: Either show the user a notification or just log a warning to the + // console, depending on the user's settings and whether we've notified + // about this already during this session. + return existingSymbols; + } + + let done = (symbols, provider) => { + if (signal.aborted) return; + // If these don't match up, our results are stale. + if (signal !== this.abortController.signal) return; + if (!isIterable(symbols)) { + error(`Provider did not return a list of symbols`, provider); + return; + } + this.addSymbols(allSymbols, symbols, provider); + }; + + let error = (err, provider) => { + if (signal.aborted) return; + let message = typeof err === 'string' ? err : err.message; + console.error(`Error in retrieving symbols from provider ${provider.name}: ${message}`); + }; + + let tasks = []; + let allSymbols = existingSymbols ? [...existingSymbols] : []; + for (let provider of providers) { + try { + // Each provider can return a list of symbols directly or a promise. + let symbols = this.getSymbolsFromProvider(provider, signal, meta); + if (symbols?.then) { + // This is a promise, so we'll add it to the list of tasks that we + // need to wait for. + let task = symbols + .then((result) => done(result, provider)) + .catch(err => error(err, provider)); + tasks.push(task); + } else if (isIterable(symbols)) { + // This is a valid list of symbols, so the provider acted + // synchronously. Add it to the results list. + done(symbols, provider); + } else { + error(`Provider did not return a list of symbols`, provider); + } + } catch (err) { + error(err, provider); + } + } + + if (tasks.length > 0) { + await Promise.race([Promise.allSettled(tasks), timeout(this.timeoutMs)]); + } + + this.updateView({ loadingMessage: null }); + + if (signal.aborted) { + // This means the user cancelled the task. No cleanup necessary; the + // `didCancelSelection` handler would've taken care of that. + return null; + } + + if (allSymbols.length > 0) { + // Only cache non-empty results. + this.cachedResults.set(editor, allSymbols); + } + return allSymbols; + } +} + +module.exports = FileView; diff --git a/packages/symbols-view/lib/go-back-view.js b/packages/symbols-view/lib/go-back-view.js new file mode 100644 index 000000000..2ac3a5200 --- /dev/null +++ b/packages/symbols-view/lib/go-back-view.js @@ -0,0 +1,29 @@ + +const SymbolsView = require('./symbols-view'); + +// TODO: Does this really need to extend SymbolsView? +module.exports = class GoBackView extends SymbolsView { + toggle () { + let previous = this.stack.pop(); + if (!previous) return; + + let restorePosition = () => { + if (!previous.position) return; + this.moveToPosition(previous.position, { beginningOfLine: false }); + }; + + let allEditors = atom.workspace.getTextEditors(); + let previousEditor = allEditors.find(e => e.id === previous.editorId); + + if (previousEditor) { + let pane = atom.workspace.paneForItem(previousEditor); + pane.setActiveItem(previousEditor); + restorePosition(); + } else if (previous.file) { + // The editor is not there anymore; e.g., a package like `zentabs` might + // have automatically closed it when a new editor view was opened. So we + // should restore it if we can. + atom.workspace.open(previous).then(restorePosition); + } + } +} diff --git a/packages/symbols-view/lib/go-to-view.js b/packages/symbols-view/lib/go-to-view.js new file mode 100644 index 000000000..02a3d2d2f --- /dev/null +++ b/packages/symbols-view/lib/go-to-view.js @@ -0,0 +1,114 @@ +const SymbolsView = require('./symbols-view'); +const { timeout } = require('./util'); + +module.exports = class GoToView extends SymbolsView { + constructor (stack, broker) { + super(stack, broker); + } + + toggle () { + if (this.panel.isVisible()) { + this.cancel(); + } else { + this.populate(); + } + } + + detached () { + // TODO + this.abortController?.abort(); + } + + async populate () { + let editor = atom.workspace.getActiveTextEditor(); + if (!editor) return; + + let symbols = await this.generateSymbols(editor); + + if (symbols?.length === 0) { + // TODO + console.warn('No symbols!'); + return; + } + + if (symbols.length === 1) { + if (this.openTag(symbols[0], { pending: true })) return; + } + + // There must be multiple tags. + await this.updateView({ items: symbols }); + this.attach(); + } + + shouldBePending () { + return true; + } + + async generateSymbols (editor, range = null) { + this.abortController?.abort(); + this.abortController = new AbortController(); + + let meta = { + type: 'project-find', + editor, + paths: atom.project.getPaths() + }; + + if (range) { + meta.range = range; + meta.query = editor.getTextInBufferRange(range); + } + + let signal = this.abortController.signal; + + let providers = await this.broker.select(meta); + if (providers?.length === 0) { + // TODO + return []; + } + + let allSymbols = []; + + let done = (symbols, provider) => { + if (signal.aborted) return; + if (!Array.isArray(symbols)) { + error(`Provider did not return a list of symbols`, provider); + return; + } + this.addSymbols(allSymbols, symbols, provider); + }; + + let error = (err, provider) => { + if (signal.aborted) return; + let message = typeof err === 'string' ? err : err.message; + console.error(`Error in retrieving symbols from provider ${provider.name}: ${message}`); + }; + + let tasks = []; + for (let provider of providers) { + try { + let symbols = this.getSymbolsFromProvider(provider, signal, meta); + if (symbols?.then) { + let task = symbols + .then(result => done(result, provider)) + .catch(err => error(err, provider)); + tasks.push(task); + } else { + done(symbols, provider); + } + } catch (err) { + error(err, provider); + } + } + + if (tasks.length > 0) { + await Promise.race([Promise.allSettled(tasks), timeout(this.timeoutMs)]); + } + + if (signal.aborted) { + return null; + } + + return allSymbols; + } +}; diff --git a/packages/symbols-view/lib/main.d.ts b/packages/symbols-view/lib/main.d.ts new file mode 100644 index 000000000..49226bf59 --- /dev/null +++ b/packages/symbols-view/lib/main.d.ts @@ -0,0 +1,299 @@ + +import type { TextEditor, Point, Range as AtomRange } from 'atom'; + +type MaybePromise = T | Promise; + +// The properties that a provider is allowed to modify on a `SelectList` +// instance during symbol retrieval. +// +// A provider that marks itself as `isExclusive: true` will be allowed to set +// certain UI messages on the `SelectList`. This allows the provider to offer +// UI guidance messages. +// +// For instance, if a project-wide symbol search is taking place, the provider +// could set an `emptyMessage` of “Query must be at least X characters long” to +// explain why no results are present at first. +type ListControllerParams = Partial<{ + errorMessage: string, + emptyMessage: string, + loadingMessage: string, + laodingBadge: string +}>; + +type ListControllerParamName = keyof ListControllerParams; + +// An object given to the exclusive provider during symbol retrieval. The +// provider can use this to control certain aspects of the symbol list's UI. +type ListController = { + // Set props on the `SelectList` instance. + set (params: ListControllerParams): void, + + // Clear any number of props on the `SelectList` instance. + clear(...propNames: ListControllerParamName[]): void +}; + +export type SymbolPosition = { + // An instance of `Point` describing the symbol's location. The `column` + // value of the point may be ignored, depending on the user's settings. At + // least one of `position` and `range` must exist. + position: Point; +}; + +export type SymbolRange = { + // An exact range describing the bounds of a given token. If present, might + // be used to highlight the token when selected by the user, though that + // depends on the user's settings. At least one of `position` and `range` + // must exist. + range: AtomRange +}; + +export type SymbolDirectoryAndFile = { + // The name of the file that contains the symbol. Will be shown in the UI. + file: string, + // The path of to the directory of the file that contains the symbol. Should + // not contain the file name. + directory: string +}; + +export type SymbolPath = { + // The full path to the file that contains the symbol. + path: string +}; + +// The only required fields in a file symbol are (a) the `name` of the symbol, +// and (b) a reference to its row in the buffer (via either `position` or +// `range`). Other fields are optional, but make for a richer UI presentation. +export type FileSymbol = (SymbolPosition | SymbolRange) & { + // The name of the symbol. This value will be shown in the UI and will be + // filtered against if the user types in the text box. Required. + name: string, + + // A word representing the symbol in some way. Typically this would describe + // the symbol — function, constant, et cetera — but can be used however the + // provider sees fit. If present, will be included in the symbol list as a + // badge. + tag?: string + + // A _short_ string of explanatory text. Optional. Can be used for text that + // is contexually significant to the symbol; for instance, a method or field + // might describe the class that owns it. Symbol consumers will expect this + // field to be short, and will not devote much space to it in the interface, + // so this field _should not_ contain unbounded text. + context?: string + + // POSSIBLE ENHANCEMENTS (UNIMPLEMENTED!): + // + // I don't necessarily find these useful myself, or at least not useful + // enough to warrant their inclusion in a space-constrained list of symbols, + // but some people might want these to be present. + + // A description of the symbol in code or pseudocode. For functions, this + // could be a function signature, along with parameter names and (if known) + // types. + // + // This field would receive its own line in a symbol list. + signature?: string + + // The literal line of code containing the symbol. A symbol consumer could + // try to retrieve this information itself, but some symbol providers would + // be able to supply it much more simply. + // + // This field would receive its own line in a symbol list. + source?: string +}; + +// A project symbol has the additional requirement of specifying the file in +// which each symbol is located, via either the `path` property or both +// `directory` and `file`. +export type ProjectSymbol = FileSymbol & (SymbolDirectoryAndFile | SymbolPath); + +// Metadata received by a symbol provider as part of a call to +// `canProvideSymbols` or `getSymbols`. +export type SymbolMeta = { + // The type of action being performed: + // + // * `file`: A symbol search within the current file. + // * `project`: A project-wide symbol search. + // * `project-find`: A project-wide attempt to resolve a reference based on + // (a) the position of the cursor, (b) the value of the editor's current + // text selection, or (c) whatever word was clicked on in the IDE. + type: 'file' | 'project' | 'project-find', + + // The current text editor. + editor: TextEditor, + + // The relevant search term, if any. + // + // When `type` is `project`, this will represent the text that the user has + // typed into a search field in order to filter the list of symbols. + // + // When `type` is `project-find`, this will represent the text that the IDE + // wants to resolve. + // + // When `type` is `file`, this field will be absent, because file symbols are + // queried only initially, before the user has typed anything; all winnowing + // is done on the frontend as the user types. + query?: string, + + // The relevant range in the buffer. + // + // This may be present when `type` is `project-find` and the consumer wants + // to resolve an arbitrary buffer range instead of the word under the cursor. + range?: Range, + + // An `AbortSignal` that represents whether the task has been cancelled. This + // will happen if the user cancels out of the symbol UI while waiting for + // symbols, or if they type a new character in the query field before the + // results have returned for the previous typed character. It will also + // happen if the provider exceeds the amount of time allotted to it (see + // `timeoutMs` below). + // + // If the provider goes async at any point, it should check the signal after + // resuming. If the signal has aborted, then there is no point in continuing. + // The provider should immediately return/resolve with `null` and avoid doing + // unnecessary further work. + signal: AbortSignal, + + // The amount of time, in milliseconds, the provider has before it must + // return results. This value is configurable by the user. If the provider + // doesn't return anything after this amount of time, it will be ignored. + // + // The provider is not in charge of ensuring that it returns results within + // this amount of time; `symbols-view` enforces that on its own. This value + // is given to providers so that they can act wisely when faced with a choice + // between “search for more symbols” and “return what we have.” + // + // The `timeoutMs` property is only present when the appropriate symbol list + // UI is not yet present. Its purpose is to show the UI within a reasonable + // amount of time. If the UI is already present — for instance, when + // winnowing results in a project-wide symbol search — `timeoutMs` will be + // omitted, and the provider can take as much time as it deems appropriate. + timeoutMs?: number +}; + +type FileSymbolMeta = SymbolMeta & { type: 'file' }; +type ProjectSymbolMeta = SymbolMeta & { type: 'project' | 'project-find' }; + +// Symbol metadata that will be passed to the `canProvideSymbols` method. +export type PreliminarySymbolMeta = Omit; + +export interface SymbolProvider { + // A human-readable name for your provider. This name may be displayed to the + // user, and it's how they can configure `symbols-view` to prefer + // certain providers over others. + name: string, + + // The name of your package. This is present so that the user can find out + // where a given provider comes from. In the settings for preferring certain + // providers over others, a package name can be specified instead of a + // specific provider name — either because that's the value the user + // remembers, or because the package contains several providers and the user + // wishes to express a preference for all those providers at once. + packageName: string, + + // If present, will be called on window teardown, or if `symbols-view` + // or the provider's own package is disabled. + destroy?(): void, + + // An optional method. If it exists, the main package will use it to register + // a callback so that it can clear the cache of this provider's symbols. + // + // The main package will automatically clear its cache for these reasons: + // + // * when the main package's config changes (entire cache); + // * when any provider is activated or deactivated (single provider's cache); + // * when the buffer is modified in any of several ways, including grammar + // change, save, or buffer change (entire cache). + // + // If your provider may have its cache invalidated for reasons not in this + // list, you should implement `onShouldClearCache` and invoke any callback + // that registers for it. The `EventEmitter` pattern found throughout Pulsar + // is probably how you want to pull this off. + onShouldClearCache?(callback: () => TextEditor): void, + + // Whether this provider aims to be the main symbol provider for a given + // file. The “exclusive” provider competes with the other workhorse providers + // of symbols like `ctags` and Tree-sitter to offer typical symbols like + // classes, method names, and the like. A maximum of one exclusive provider + // will be chosen for any task, depending on which one scores highest. + // + // “Supplemental” providers are those that contribute more specialized kinds + // of symbols. These providers generally do not compete with exclusive + // providers, or with each other, and can add symbols to any exclusive + // provider’s results. + isExclusive?: boolean, + + // Indicates whether the provider can provide symbols for a given task. Can + // return either a boolean or a number; boolean `true` is equivalent to a + // score of `1`, and boolean `false` is equivalent to a score of `0`. + // + // This method receives the same metadata bundle that will be present in the + // subsequent call to `getSymbols`. The provider can inspect this metadata + // and decide whether it can fulfill the given symbols request. + // + // Examples: + // + // * A provider that can analyze the current file, but not the entire + // project, should return `false` for any requests where `type` does not + // equal `file`. + // * A provider that works by analyzing code on disk, rather than looking at + // the current unsaved contents of buffers, could return a slightly lower + // score if asked to complete symbols for a file that has been modified. + // This would indicate that it’d be a slightly worse than usual candidate. + // + // Since language server providers will have to ask their servers about + // capabilities, this method can go async, though it’s strongly suggested to + // keep it synchronous if possible. + // + // To avoid a number war, any numeric value greater than `1` returned from + // `canProvideSymbols` will be clamped to `1`. The user can break ties by + // choosing their preferred providers in the package settings. + canProvideSymbols(meta: PreliminarySymbolMeta): MaybePromise, + + // Returns a list of symbols. + // + // If there are no results, you should return an empty array. If the request + // is invalid or cannot be completed — for instance, if the user cancels the + // task — you should return `null`. + // + // The second argument, `listController`, will be present _only_ for the + // provider marked with `isExclusive: true`. It allows the provider to set + // and clear UI messages if needed. Supplemental providers don't receive this + // argument. + // + // This method can go async if needed. Whenever it performs an async task, it + // should check `meta.signal` afterward to see if it should cancel. + getSymbols(meta: FileSymbolMeta, listController?: ListController): MaybePromise + getSymbols(meta: ProjectSymbolMeta, listController?: ListController): MaybePromise +} + +export type SymbolProviderMainModule = { + activate(): void, + deacivate(): void, + + // No business logic should go in here. If a package wants to provide symbols + // only under certain circumstances, it should decide those circumstances on + // demand, rather than return this provider only conditionally. + // + // A provider author may argue that they should be allowed to inspect the + // environment before deciding what (or if) to return — but anything they'd + // inspect is something that can change mid-session. Too complicated. All + // provider decisions can get decided at runtime. + // + // So, for instance, if a certain provider only works with PHP files, it + // should return its instance here no matter what, and that instance can + // respond to `canProvideSymbols` with `false` if the given editor isn't + // using a PHP grammar. It shouldn't try to get clever and bail out entirely + // if, say, the project doesn't have any PHP files on load — because, of + // course, it _could_ add a PHP file at any point, and we're not going to + // revisit the decision later. + // + // Likewise, if a provider depends upon a language server that may or may not + // be running, it should not try to be clever about what it returns from + // `provideSymbols`. Instead, it should return early from `canProvideSymbols` + // when the language server isn't running. + // + // A single package can supply multiple providers if need be. + // + provideSymbols(): SymbolProvider | [SymbolProvider...] +}; diff --git a/packages/symbols-view/lib/main.js b/packages/symbols-view/lib/main.js new file mode 100644 index 000000000..770f04afb --- /dev/null +++ b/packages/symbols-view/lib/main.js @@ -0,0 +1,229 @@ +const { Disposable } = require('atom'); +const Config = require('./config'); +const ProviderBroker = require('./provider-broker'); +const Path = require('path'); +const { shell } = require('electron'); +const { migrateOldConfigIfNeeded } = require('./util'); + +console.log('SYMBOLS VIEW !!!'); + +const NO_PROVIDERS_MESSAGE = `You don’t have any symbol providers installed.`; +const NO_PROVIDERS_DESCRIPTION = `The button below will show all packages that can provide symbols. + +At minimum, we recommend you install the following packages to get an experience similar to that of the built-in \`symbols-view\` package: + +* \`symbol-provider-tree-sitter\` +* \`symbol-provider-ctags\` +`; + +const NO_PROVIDERS_BUTTONS = [ + { + text: 'Find providers', + onDidClick: () => { + shell.openExternal(`https://web.pulsar-edit.dev/packages?service=symbol.provider&serviceType=provided`); + } + } +]; + +module.exports = { + activate() { + Config.activate(); + this.stack = []; + this.broker = new ProviderBroker(); + + this.workspaceSubscription = atom.commands.add( + 'atom-workspace', + { + 'symbols-view:toggle-project-symbols': () => { + if (!this.ensureProvidersExist()) return; + this.createProjectView().toggle(); + }, + 'symbols-view:show-active-providers': () => { + this.showActiveProviders(); + } + } + ); + + this.editorSubscription = atom.commands.add( + 'atom-text-editor:not([mini])', + { + 'symbols-view:toggle-file-symbols': (e) => { + if (!this.ensureProvidersExist()) { + e.abortKeyBinding(); + return; + } + this.createFileView().toggle(); + }, + 'symbols-view:go-to-declaration': () => { + if (!this.ensureProvidersExist()) return; + this.createGoToView().toggle(); + }, + 'symbols-view:return-from-declaration': () => { + if (!this.ensureProvidersExist()) return; + this.createGoBackView().toggle(); + } + } + ); + + migrateOldConfigIfNeeded(); + }, + + deactivate() { + this.fileView?.destroy(); + this.fileView = null; + + this.projectView?.destroy(); + this.projectView = null; + + this.goToView?.destroy(); + this.goToView = null; + + this.goBackView?.destroy(); + this.goBackView = null; + + this.workspaceSubscription?.dispose(); + this.workspaceSubscription = null; + + this.editorSubscription?.dispose(); + this.editorSubscription = null; + + this.broker?.destroy(); + this.broker = null; + + this.subscriptions?.dispose(); + this.subscriptions = null; + }, + + consumeSymbolProvider(provider) { + if (Array.isArray(provider)) { + this.broker.add(...provider); + } else { + this.broker.add(provider); + } + + return new Disposable(() => { + if (Array.isArray(provider)) { + this.broker.remove(...provider); + } else { + this.broker.remove(provider); + } + }); + }, + + createFileView() { + if (this.fileView) return this.fileView; + + const FileView = require('./file-view'); + this.fileView = new FileView(this.stack, this.broker); + return this.fileView; + }, + + createProjectView() { + if (this.projectView) return this.projectView; + + const ProjectView = require('./project-view'); + this.projectView = new ProjectView(this.stack, this.broker); + return this.projectView; + }, + + createGoToView() { + if (this.goToView) return this.goToView; + + const GoToView = require('./go-to-view'); + this.goToView = new GoToView(this.stack, this.broker); + return this.goToView; + }, + + createGoBackView() { + if (this.goBackView) return this.goBackView; + + const GoBackView = require('./go-back-view'); + this.goBackView = new GoBackView(this.stack, this.broker); + return this.goBackView; + }, + + showActiveProviders() { + let providerList = []; + for (let provider of this.broker.providers) { + providerList.push({ + name: provider.name, + packageName: provider.packageName + }); + } + + let message = providerList.map( + p => `* **${p.name}** provided by \`${p.packageName}\`` + ).join('\n'); + + atom.notifications.addInfo( + 'Symbols View Redux providers', + { + description: message, + dismissable: true, + buttons: [ + { + text: 'Copy', + onDidClick() { + atom.clipboard.write(message); + } + } + ] + } + ); + }, + + ensureProvidersExist() { + if (this.broker.providers.length > 0) return true; + + atom.notifications.addWarning( + NO_PROVIDERS_MESSAGE, + { + description: NO_PROVIDERS_DESCRIPTION, + buttons: NO_PROVIDERS_BUTTONS, + dismissable: true + } + ); + + return false; + }, + + ensureActiveTextEditorExists() { + let editor = atom.workspace.getActiveTextEditor(); + return !!editor; + }, + + // A `hyperclick` consumer that works similarly to the + // `symbols-view:go-to-definition` command. + provideHyperclick() { + return { + priority: 1, + getSuggestionForWord: async (editor, _text, range) => { + let goto = this.createGoToView(); + let symbols = await goto.generateSymbols(editor, range); + let editorPath = editor.getPath(); + if (!symbols || symbols.length === 0) return; + + // If we're at the definition site, the only result will be a symbol + // whose position is identical to the position we asked about. Filter + // it out. In that situation, we don't want a hyperclick affordance at + // all. + symbols = symbols.filter(sym => { + let { path, directory, file } = sym; + if (!path) { + path = Path.join(directory, file); + } + return path !== editorPath || sym.position.compare(range.start) !== 0; + }); + if (symbols.length === 0) return; + + return { + range, + callback: () => { + editor.setSelectedBufferRange(range); + goto.toggle(); + } + }; + } + }; + } +}; diff --git a/packages/symbols-view/lib/project-view.js b/packages/symbols-view/lib/project-view.js new file mode 100644 index 000000000..4dfe0d11f --- /dev/null +++ b/packages/symbols-view/lib/project-view.js @@ -0,0 +1,198 @@ +// const { Point } = require('atom'); + +const SymbolsView = require('./symbols-view'); +const { isIterable, timeout } = require('./util'); + +module.exports = class ProjectView extends SymbolsView { + constructor (stack, broker) { + // TODO: Do these defaults make sense? Should we allow a provider to + // override them? + super(stack, broker, { + emptyMessage: 'Project has no symbols or is empty', + maxResults: 20, + isDynamic: true + }); + + this.shouldReload = true; + } + + destroy () { + return super.destroy(); + } + + toggle () { + if (this.panel.isVisible()) { + this.cancel(); + } else { + this.populate(); + this.attach(); + } + } + + didCancelSelection () { + this.abortController?.abort(); + super.didCancelSelection(); + } + + didConfirmEmptySelection () { + this.abortController?.abort(); + super.didConfirmEmptySelection(); + } + + isValidSymbol (symbol) { + if (!super.isValidSymbol(symbol)) return false; + if ( + !(typeof symbol.file === 'string' && typeof symbol.directory === 'string') && + !(typeof symbol.path === 'string') + ) { + return false; + } + return true; + } + + shouldUseCache () { + let query = this.selectListView?.getQuery(); + if (query && query.length > 0) return false; + if (this.shouldReload) return false; + return !!this.cachedSymbols; + } + + didChangeQuery () { + this.populate({ retain: true }); + } + + clear () { + + } + + async populate ({ retain = false } = {}) { + if (this.shouldUseCache()) { + await this.updateView({ items: this.cachedSymbols }); + return true; + } + + let query = this.selectListView?.getQuery(); + + let listViewOptions = { + loadingMessage: this.cachedSymbols ? + `Reloading project symbols\u2026` : + `Loading project symbols\u2026` + }; + + if (!this.cachedSymbols) { + listViewOptions.loadingBadge = 0; + } + + // await this.updateView(listViewOptions); + let editor = atom.workspace.getActiveTextEditor(); + + let start = performance.now(); + this._lastTimestamp = start; + let anySymbolsLoaded = false; + let result = this.generateSymbols(editor, query, (symbols) => { + anySymbolsLoaded = symbols.length > 0; + + // TODO: Should we sort by buffer position? Should we leave it up to the + // provider? Should we make it configurable? + let options = { + ...listViewOptions, + items: symbols, + loadingMessage: null + }; + this.updateView(options); + }); + + let loadingTimeout; + if (retain) { + loadingTimeout = setTimeout((timestamp) => { + if (timestamp !== this._lastTimestamp) return; + if (anySymbolsLoaded) return; + this.updateView({ loadingMessage: `Reloading project symbols\u2026` }); + }, 500, start); + } + + if (result?.then) result = await result; + clearTimeout(loadingTimeout); + if (result == null) { + result = []; + } + + this.cachedSymbols = result; + + // TODO: We assume that project-wide symbol search will involve re-querying + // the language server whenever the user types another character. This + // distinguishes it from searching within one buffer — where typing in the + // query field just filters a static list. + // + // This is a safe assumption to make, but we could at least make it + // possible for a provider to return a static list and somehow indicate + // that it’s static so that we don’t have to keep re-querying. + this.shouldReload = true; + return true; + } + + async generateSymbols (editor, query = '', callback) { + this.abortController?.abort(); + this.abortController = new AbortController(); + + let meta = { type: 'project', editor, query }; + + // The signal is how a provider can stop doing work if it's going async, + // since it'll be able to tell if we've cancelled this command and no + // longer need the symbols we asked for. + let signal = this.abortController.signal; + + let providers = await this.broker.select(meta); + if (providers?.length === 0) { + console.warn('No providers found!'); + return null; + } + + let allSymbols = []; + let done = (symbols, provider) => { + if (signal.aborted) return; + if (!isIterable(symbols)) { + error(`Provider did not return a list of symbols`, provider); + return; + } + this.addSymbols(allSymbols, symbols, provider); + callback(allSymbols); + }; + + let error = (err, provider) => { + if (signal.aborted) return; + let message = typeof err === 'string' ? err : err.message; + console.error(`Error in retrieving symbols from provider ${provider.name}: ${message}`); + }; + + let tasks = []; + for (let provider of providers) { + try { + let symbols = this.getSymbolsFromProvider(provider, signal, meta); + if (symbols?.then) { + let task = symbols + .then((result) => done(result, provider)) + .catch(err => error(err, provider)); + tasks.push(task); + } else if (isIterable(symbols)) { + done(symbols, provider); + } else { + error(`Provider did not return a list of symbols`, provider); + } + } catch (err) { + error(err, provider); + } + } + + if (tasks.length > 0) { + await Promise.race([Promise.allSettled(tasks), timeout(this.timeoutMs)]); + } + + // Since we might've gone async here, we should check our own signal. If + // it's aborted, that means the user has cancelled. + if (signal.aborted) return null; + + this.cachedSymbols = allSymbols; + return allSymbols; + } +}; diff --git a/packages/symbols-view/lib/provider-broker.js b/packages/symbols-view/lib/provider-broker.js new file mode 100644 index 000000000..fb60bb071 --- /dev/null +++ b/packages/symbols-view/lib/provider-broker.js @@ -0,0 +1,241 @@ +const { CompositeDisposable, Emitter } = require('atom'); +const Config = require('./config'); + +/** + * An error thrown when a newly added symbol provider does not conform to its + * contract. + * + * @extends Error + */ +class InvalidProviderError extends Error { + constructor (faults, provider) { + let packageName = provider.packageName ? + `the ${provider.packageName} provider` + : 'a symbol provider'; + let message = `symbols-view failed to consume ${packageName} because certain properties are invalid: ${faults.join(', ')}. Please fix these faults or contact the package author.`; + super(message); + this.name = 'InvalidProviderError'; + } +} + +/** + * A class that keeps track of various symbol providers and selects which ones + * should respond for a given request. + * + * @type {ProviderBroker} + * @class + */ +module.exports = class ProviderBroker { + constructor () { + this.providers = []; + this.providerSubscriptions = new Map(); + this.subscriptions = new CompositeDisposable(); + this.emitter = new Emitter(); + } + + /** + * Add one or more symbol providers. + * + * @param {SymbolProvider[]} providers Any number of symbol providers. + */ + add (...providers) { + for (let provider of providers) { + try { + this.validateSymbolProvider(provider); + } catch (err) { + console.warn(err.message); + continue; + } + this.providers.push(provider); + this.emitter.emit('did-add-provider', provider); + this.observeProvider(provider); + } + } + + /** + * Remove one or more symbol providers. + * + * @param {SymbolProvider[]} providers Any number of symbol providers. + */ + remove (...providers) { + for (let provider of providers) { + let index = this.providers.indexOf(provider); + // Providers that were invalid may not have been added. Not a problem. + if (index === -1) continue; + + this.providers.splice(index, 1); + this.emitter.emit('did-remove-provider', provider); + this.stopObservingProvider(provider); + } + } + + /** + * Ensure a symbol provider abides by the contract. + * + * @param {SymbolProvider} provider A symbol provider to validate. + */ + validateSymbolProvider (provider) { + let faults = []; + if (typeof provider.name !== 'string') faults.push('name'); + if (typeof provider.packageName !== 'string') faults.push('packageName'); + if (typeof provider.canProvideSymbols !== 'function') + faults.push('canProvideSymbols'); + if (typeof provider.getSymbols !== 'function') + faults.push('getSymbols'); + + if (faults.length > 0) { + throw new InvalidProviderError(faults, provider); + } + } + + /** + * Observe a symbol provider so that we can clear our symbol cache if needed. + * + * @param {SymbolProvider} provider A symbol provider. + */ + observeProvider (provider) { + let disposable = new CompositeDisposable(); + this.providerSubscriptions.set(provider, disposable); + + // Providers can implement `onShouldClearCache` when they want to control + // when symbols they provide are no longer valid. + if (!provider.onShouldClearCache) return; + + disposable.add( + provider.onShouldClearCache((bundle) => { + this.emitter.emit('should-clear-cache', { ...bundle, provider }); + }) + ); + } + + /** + * Stop observing a symbol provider. + * + * @param {SymbolProvider} provider A symbol provider. + */ + stopObservingProvider (provider) { + let disposable = this.providerSubscriptions.get(provider); + this.providerSubscriptions.delete(provider); + disposable?.dispose; + } + + destroy () { + for (let provider of this.providers) { + provider?.destroy?.(); + this.emitter.emit('did-remove-provider', provider); + } + } + + onDidAddProvider (callback) { + return this.emitter.on('did-add-provider', callback); + } + + onDidRemoveProvider (callback) { + return this.emitter.on('did-remove-provider', callback); + } + + onShouldClearCache (callback) { + return this.emitter.on('should-clear-cache', callback); + } + + /** + * Boost the relevance score of certain providers based on their position in + * the settings value. If there are 5 providers listed, the first one gets a + * five-point boost; the second a four-point boost; and so on. + * + * @param {String} name The provider's name. + * @param {String} packageName The provider's package name. + * @param {Array} preferredProviders A list of preferred providers from + * configuration; each entry can refer to a provider's name or its package + * name. + * + * @returns {Number} The amount by which to boost the provider's relevance + * score. + */ + getScoreBoost (name, packageName, preferredProviders = []) { + if (packageName === 'unknown') return 0; + let index = preferredProviders.indexOf(packageName); + if (index === -1) { + index = preferredProviders.indexOf(name); + } + if (index === -1) return 0; + let scoreBoost = preferredProviders.length - index; + return scoreBoost; + } + + /** + * Given metadata about a symbol request, choose the best provider(s) for the + * job. + * + * @param {SymbolMeta} meta Metadata about the symbol request. + * + * @returns {Promise} A promise that resolves with a list + * of symbol providers. + */ + async select (meta) { + let shouldLog = Config.get('enableDebugLogging'); + let exclusivesByScore = []; + let results = []; + + let preferredProviders = atom.config.get('symbols-view-redux.preferCertainProviders'); + + if (shouldLog) { + console.debug(`Provider broker choosing among ${this.providers.length} candidates:`, this.providers); + console.debug('Metadata is:', meta); + } + + let answers = this.providers.map(provider => { + // TODO: This method can reluctantly go async because language clients + // might have to ask their servers about capabilities. We must introduce + // a timeout value here so that we don't wait indefinitely for providers + // to respond. + if (shouldLog) + console.debug(`Asking provider:`, provider.name, provider); + return provider.canProvideSymbols(meta); + // return timeout(provider.canProvideSymbols(meta), 500); + }); + + let outcomes = await Promise.allSettled(answers); + + for (let [index, provider] of this.providers.entries()) { + let outcome = outcomes[index]; + + if (shouldLog) + console.debug(`Outcome for provider`, provider.name, 'is', outcome); + + if (outcome.status === 'rejected') continue; + let { value: score } = outcome; + let name = provider.name ?? 'unknown'; + let packageName = provider?.packageName ?? 'unknown'; + let isExclusive = provider?.isExclusive ?? false; + + if (shouldLog) + console.debug('Score for', provider.name, 'is:', score); + + if (!score) continue; + if (score === true) score = 1; + score += this.getScoreBoost(name, packageName, preferredProviders); + + if (isExclusive) { + // “Exclusive” providers get put aside until the end. We'll pick the + // _one_ that has the highest score. + exclusivesByScore.push({ provider, score }); + } else { + // Non-exclusive providers go into the pile because we know we'll be + // using them all. + results.push(provider); + } + } + + if (exclusivesByScore.length > 0) { + exclusivesByScore.sort((a, b) => b.score - a.score); + let exclusive = exclusivesByScore[0].provider; + results.unshift(exclusive); + } + + if (shouldLog) + console.debug('Returned providers:', results); + + return results; + } +}; diff --git a/packages/symbols-view/lib/symbols-view.js b/packages/symbols-view/lib/symbols-view.js new file mode 100644 index 000000000..7ed478941 --- /dev/null +++ b/packages/symbols-view/lib/symbols-view.js @@ -0,0 +1,393 @@ +const Path = require('path'); +const fs = require('fs-plus'); +const Config = require('./config'); +const { CompositeDisposable, Point } = require('atom'); +const SelectListView = require('atom-select-list'); +const { match } = require('fuzzaldrin'); + +const el = require('./element-builder'); +const { badge } = require('./util'); + +// Properties that we allow a provider to set on a `SelectListView` via a +// `ListController` instance. +const ALLOWED_PROPS_IN_LIST_CONTROLLER = new Set([ + 'errorMessage', + 'emptyMessage', + 'loadingMessage', + 'loadingBadge' +]); + +function validateListControllerProps(props) { + return Object.keys(props).every(k => ( + ALLOWED_PROPS_IN_LIST_CONTROLLER.has(k) + )); +} + +/** + * A class for setting various UI properties on a symbol list palette. This is a + * privilege given to the “main” (or _exclusive_) provider for a given task. + * + * This is how we allow a provider to communicate its state to the UI without + * giving it full control over the `SelectListView` used to show results. + */ +class ListController { + constructor(view) { + this.view = view; + } + + set(props) { + if (!validateListControllerProps(props)) { + console.warn('Provider gave invalid properties to symbol list UI:', props); + } + return this.view.update(props); + } + + clear(...propNames) { + let props = {}; + for (let propName of propNames) { + if (!ALLOWED_PROPS_IN_LIST_CONTROLLER.has(propName)) continue; + props[propName] = null; + } + return this.view.update(props); + } +} + + +class SymbolsView { + static highlightMatches(_context, name, matches, offsetIndex = 0) { + let lastIndex = 0; + let matchedChars = []; + + const fragment = document.createDocumentFragment(); + + for (let matchIndex of [...matches]) { + matchIndex -= offsetIndex; + if (matchIndex < 0) continue; + + let unmatched = name.substring(lastIndex, matchIndex); + if (unmatched) { + if (matchedChars.length) { + let span = document.createElement('span'); + span.classList.add('character-match'); + span.textContent = matchedChars.join(''); + fragment.appendChild(span); + } + matchedChars = []; + fragment.appendChild(document.createTextNode(unmatched)); + } + matchedChars.push(name[matchIndex]); + lastIndex = matchIndex + 1; + } + + if (matchedChars.length) { + const span = document.createElement('span'); + span.classList.add('character-match'); + span.textContent = matchedChars.join(''); + fragment.appendChild(span); + } + + // Remaining characters are plain text. + fragment.appendChild( + document.createTextNode(name.substring(lastIndex)) + ); + + return fragment; + } + + constructor(stack, broker, options = {}) { + this.stack = stack; + this.broker = broker; + + options = { + emptyMessage: 'No symbols found', + maxResults: null, + ...options + }; + + this.selectListView = new SelectListView({ + ...options, + items: [], + filterKeyForItem: (item) => item.name, + elementForItem: this.elementForItem.bind(this), + didChangeQuery: this.didChangeQuery.bind(this), + didChangeSelection: this.didChangeSelection.bind(this), + didConfirmSelection: this.didConfirmSelection.bind(this), + didConfirmEmptySelection: this.didConfirmEmptySelection.bind(this), + didCancelSelection: this.didCancelSelection.bind(this) + }); + + this.selectListViewOptions = options; + + this.listController = new ListController(this.selectListView); + + this.element = this.selectListView.element; + this.element.classList.add('symbols-view'); + + this.panel = atom.workspace.addModalPanel({ item: this, visible: false }); + + this.configDisposable = new CompositeDisposable(); + + this.configDisposable.add( + atom.config.observe( + `symbols-view`, + (value) => { + this.shouldShowProviderName = value.showProviderNamesInSymbolsView; + this.useBadgeColors = value.useBadgeColors; + } + ), + Config.observe('providerTimeout', (ms) => this.timeoutMs = ms), + Config.observe('showIconsInSymbolsView', (show) => this.showIconsInSymbolsView = show) + ); + + } + + async destroy() { + await this.cancel(); + this.configDisposable.dispose(); + this.panel.destroy(); + return this.selectListView.destroy(); + } + + getFilterKey() { + return 'name'; + } + + elementForItem({ position, name, file, icon, tag, context, directory, providerName }) { + name = name.replace(/\n/g, ' '); + + if (atom.project.getPaths().length > 1) { + // More than one project root — we need to disambiguate the file paths. + file = Path.join(Path.basename(directory), file); + } + + let badges = []; + + if (providerName && this.shouldShowProviderName) { + badges.push(providerName); + } + if (tag) badges.push(tag); + + let primaryLineClasses = ['primary-line']; + if (this.showIconsInSymbolsView) { + if (icon) { + primaryLineClasses.push('icon', icon); + } else { + primaryLineClasses.push('no-icon'); + } + } + + let matches = match(name, this.selectListView.getFilterQuery()); + let primary = el(`div.${primaryLineClasses.join('.')}`, + el('div.name', + SymbolsView.highlightMatches(this, name, matches) + ), + badges && el('div.badge-container', + ...badges.map( + b => badge(b, { variant: this.useBadgeColors }) + ) + ) + ); + + let secondaryLineClasses = ['secondary-line']; + if (this.showIconsInSymbolsView) { + secondaryLineClasses.push('no-icon'); + } + let secondary = el(`div.${secondaryLineClasses.join('.')}`, + el('span.location', + position ? `${file}:${position.row + 1}` : file + ), + context ? el('span.context', context) : null + ); + + return el('li.two-lines', primary, secondary); + } + + async cancel() { + if (!this.isCanceling) { + this.isCanceling = true; + await this.updateView({ items: [] }); + this.panel.hide(); + if (this.previouslyFocusedElement) { + this.previouslyFocusedElement.focus(); + this.previouslyFocusedElement = null; + } + this.isCanceling = false; + } + } + + async updateView(options) { + this.selectListView.update(options); + } + + didChangeQuery() { + // no-op + } + + didCancelSelection() { + this.cancel(); + } + + didConfirmEmptySelection() { + this.cancel(); + } + + async didConfirmSelection(tag) { + if (tag.file && !fs.isFileSync(Path.join(tag.directory, tag.file))) { + await this.updateView({ + errorMessage: `Selected file does not exist` + }); + setTimeout(() => { + this.updateView({ errorMessage: null }); + }, 2000); + } else { + await this.cancel(); + this.openTag(tag, { pending: this.shouldBePending() }); + } + } + + // Whether a pane opened by a view should be treated as a pending pane. + shouldBePending() { + return false; + } + + didChangeSelection() { + // no-op + } + + openTag(tag, { pending } = {}) { + pending ??= this.shouldBePending(); + let editor = atom.workspace.getActiveTextEditor(); + let previous; + if (editor) { + previous = { + editorId: editor.id, + position: editor.getCursorBufferPosition(), + file: editor.getURI() + }; + } + + let { position, range } = tag; + if (!position) position = this.getTagLine(tag); + + let result = false; + if (tag.file) { + // Open a different file, then jump to a position. + atom.workspace.open( + Path.join(tag.directory, tag.file), + { pending } + ).then(() => { + if (position) { + return this.moveToPosition(position, { range }); + } + return undefined; + }); + result = true; + } else if (position && previous && !previous.position.isEqual(position)) { + // Jump to a position in the same file. + this.moveToPosition(position, { range }); + result = true; + } + if (result) this.stack.push(previous); + return result; + } + + moveToPosition(position, { beginningOfLine = true } = {}) { + let editor = atom.workspace.getActiveTextEditor(); + if (editor) { + editor.setCursorBufferPosition(position, { autoscroll: false }); + if (beginningOfLine) { + editor.moveToFirstCharacterOfLine(); + } + editor.scrollToCursorPosition({ center: true }); + } + } + + attach() { + this.previouslyFocusedElement = document.activeElement; + this.panel.show(); + this.selectListView.reset(); + this.selectListView.focus(); + } + + isValidSymbol(symbol) { + if (typeof symbol.name !== 'string') return false; + if (!symbol.position && !symbol.range) return false; + if (symbol.position && !(symbol.position instanceof Point)) { + return false; + } + return true; + } + + addSymbols(allSymbols, newSymbols, provider) { + for (let symbol of newSymbols) { + if (!this.isValidSymbol(symbol)) { + console.warn('Invalid symbol:', symbol); + continue; + } + // We enforce these so that (a) we can show a human-readable name of the + // provider for each symbol (if the user opts into it), and (b) we can + // selectively clear cached results for certain providers without + // affecting others. + symbol.providerName ??= provider.name; + symbol.providerId ??= provider.packageName; + if (symbol.path) { + let parts = Path.parse(symbol.path); + symbol.directory = `${parts.dir}${Path.sep}`; + symbol.file = parts.base; + } + allSymbols.push(symbol); + } + } + + // TODO: What on earth is this? Can we possibly still need it? + getTagLine(tag) { + if (!tag) return undefined; + + if (tag.lineNumber) { + return new Point(tag.lineNumber - 1, 0); + } + + if (!tag.pattern) return undefined; + let pattern = tag.pattern.replace(/(^\/\^)|(\$\/$)/g, '').trim(); + if (!pattern) return undefined; + + const file = Path.join(tag.directory, tag.file); + if (!fs.isFileSync(file)) return undefined; + + let iterable = fs.readFileSync(file, 'utf8').split('\n'); + for (let index = 0; index < iterable.length; index++) { + let line = iterable[index]; + if (pattern === line.trim()) { + return new Point(index, 0); + } + } + + return undefined; + } + + getSymbolsFromProvider(provider, signal, meta) { + let controller = new AbortController(); + + // If the user cancels the task, propagate that cancellation to this + // provider's AbortController. + signal.addEventListener('abort', () => controller.abort()); + + // Cancel this job automatically if it times out. + setTimeout(() => controller.abort(), this.timeoutMs); + + if (provider.isExclusive) { + // The exclusive provider is the only one that gets an instance of + // `ListController` so that it can set UI messages. + return provider.getSymbols( + { signal: controller.signal, ...meta }, + this.listController + ); + } else { + return provider.getSymbols( + { signal: controller.signal, ...meta } + ); + } + } +} + +module.exports = SymbolsView; diff --git a/packages/symbols-view/lib/util.js b/packages/symbols-view/lib/util.js new file mode 100644 index 000000000..bc9808e37 --- /dev/null +++ b/packages/symbols-view/lib/util.js @@ -0,0 +1,161 @@ +const el = require('./element-builder'); + +const murmur = require('murmurhash-js'); +const BADGE_TEXT_HASH_MAP = new Map(); + +/** + * Ensures an object can be iterated over. + * + * The contract with the symbol providers is that they return an object that + * gives us symbol objects when we iterate over it. It'll probably be an array, + * but we're cool with anything iterable. + * + * @param {?} obj Anything. + * @returns {Boolean} Whether the item will respond correctly to a `for..of` + * loop. + */ +function isIterable(obj) { + if (obj === null || obj === undefined) return false; + return typeof obj[Symbol.iterator] === 'function'; +} + +/** + * Returns a promise that resolves after a given number of milliseconds. + * @param {Number} ms Number of milliseconds after which to resolve. + * @returns {Promise} A promise that resolves with `true` as its argument. + */ +function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms, true)); +} + +/** + * Given a string of text, returns a hexadecimal character from `0` to `f` to + * represent a classification “bucket.” This is used when assigning colors to + * various symbol badges. + * + * @param {String} text The text of the badge. + * @returns {String} A single character that represents a hexadecimal digit. + */ +function getBadgeTextVariant(text) { + // The goal here is to give each tag a color such that (a) two things with the + // same tag will have badges of identical colors, and (b) two things with + // different tags are very likely to have badges of different colors. We use a + // fast (non-cryptographic) hashing algorithm, convert its return integer to + // hex, then take the final character; this, in effect, gives a piece of text + // an equal chance of being sorted into any of sixteen random buckets. + // + // In the CSS, we generate sixteen badge colors based on the user's UI theme; + // they are identical in saturation and brightness and vary only in hue. + if (BADGE_TEXT_HASH_MAP.has(text)) { + return BADGE_TEXT_HASH_MAP.get(text); + } + let hash = murmur.murmur3(text, 'symbols-view').toString(16); + let variantType = hash.charAt(hash.length - 1); + BADGE_TEXT_HASH_MAP.set(text, variantType); + return variantType; +} + +/** + * Return a DOM element for a badge for a given symbol tag name. + * + * @param {String} text The text of the tag. + * @param {Object} options Options. Defaults to an empty object. + * @param {Boolean} options.variant Whether to add a class name for the badge's + * “variant.” If enabled, this will attempt to assign a different badge color + * for each kind of tag. Optional; defaults to `false`. + * @returns {Element} An element for adding to an `atom-select-view` entry. + */ +function badge(text, options = {}) { + let { variant = false } = options; + let classNames = `.badge.badge-info.badge-flexible.badge-symbol-tag`; + if (variant) { + let variantType = getBadgeTextVariant(text); + classNames += `.symbols-view-badge-variant-${variantType}`; + } + return el(`span${classNames}`, text); +} + +const MIGRATED_SETTINGS_MESSAGE = `The \`symbols-view\` package has migrated the setting \`symbols-view.useEditorGrammarAsCtagsLanguage\` to its new location inside the core package \`symbol-provider-ctags\`. If you have defined any scope-specific overrides for this setting, you’ll need to change those overrides manually.`; + +// TODO: This function performs a one-time config migration. We can remove this +// chore in the future when we feel like it's served its purpose. +function migrateOldConfigIfNeeded({ force = false } = {}) { + if (!force) { + // Look up the schema for `symbols-view` and make sure that the deprecated + // setting isn't present. + let schema = atom.config.getSchema('symbols-view'); + if (schema?.type === 'any') { + // We might be in a testing environment. + return; + } + + if (!schema.properties || ('useEditorGrammarAsCtagsLanguage' in schema.properties)) { + // This means the setting is still expected as part of `symbols-view` and + // should not be migrated. + return; + } + } + + // If we get this far, we know that any + // `symbols-view.useEditorGrammarAsCtagsLanguage` setting we find should be + // migrated to `symbol-provider-ctags.useEditorGrammarAsCtagsLanguage`. + + // We're only interested in the value we get directly from the config file. + let settings = atom.config.get( + 'symbols-view', + { sources: [atom.config.getUserConfigPath()] } + ) || {}; + + if ('useEditorGrammarAsCtagsLanguage' in settings) { + atom.config.set( + 'symbol-provider-ctags.useEditorGrammarAsCtagsLanguage', + settings.useEditorGrammarAsCtagsLanguage + ); + atom.config.unset('symbols-view.useEditorGrammarAsCtagsLanguage'); + } + + // 99% of users won't care that we've migrated this setting, but the other 1% + // would appreciate a heads-up. So let's try to detect any scope-specific + // overrides that have touched this setting. We won't attempt to migrate + // those automatically, but we'll at least let the user know that they might + // have to be changed. + // + // This reaches into the private implementation of `atom.config`, so let's + // exit gracefully if this fails. + let propertySets = atom.config?.scopedSettingsStore.propertySets; + if (!propertySets) return; + + let sources = []; + for (let { properties, source } of propertySets) { + if ( + properties['symbols-view'] && + ('useEditorGrammarAsCtagsLanguage' in properties['symbols-view']) + ) { + sources.push(source); + } + } + + if (sources.length > 0) { + sources = Array.from(new Set(sources)); + let overrideSources = sources.map(s => `* \`${s}\``).join('\n'); + + atom.notifications.addInfo( + `Setting migrated`, + { + description: `${MIGRATED_SETTINGS_MESSAGE} + +Detected overrides in the following locations: + +${overrideSources}`, + dismissable: true + } + ); + } +} + +module.exports = { + badge, + isIterable, + migrateOldConfigIfNeeded, + timeout +}; diff --git a/packages/symbols-view/package-lock.json b/packages/symbols-view/package-lock.json new file mode 100644 index 000000000..e036bbec1 --- /dev/null +++ b/packages/symbols-view/package-lock.json @@ -0,0 +1,1233 @@ +{ + "name": "symbols-view-redux", + "version": "0.0.6", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "symbols-view-redux", + "version": "0.0.6", + "license": "MIT", + "dependencies": { + "atom-select-list": "^0.8.1", + "fs-plus": "^3.1.1", + "fuzzaldrin": "^2.1.0", + "murmurhash-js": "^1.0.0" + }, + "devDependencies": { + "eslint": "^8.39.0", + "temp": "^0.9.4" + }, + "engines": { + "atom": "*", + "node": ">=14" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", + "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", + "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.1", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", + "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==" + }, + "node_modules/atom-select-list": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.8.1.tgz", + "integrity": "sha512-MpwlZmmI81odx7rY+HpJrRmDW9aXlkFDFDNt70JxrPibxEh8h9HCZZj22woa4CKFKVXC8sEiLMcNtuDeE10jog==", + "dependencies": { + "etch": "^0.14.0", + "fuzzaldrin": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", + "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.39.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", + "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etch": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/etch/-/etch-0.14.1.tgz", + "integrity": "sha512-+IwqSDBhaQFMUHJu4L/ir0dhDoW5IIihg4Z9lzsIxxne8V0PlSg0gnk2STaKWjGJQnDR4cxpA+a/dORX9kycTA==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "dependencies": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + } + }, + "node_modules/fs-plus/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fuzzaldrin": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", + "integrity": "sha512-zgllBYwfHR5P3CncJiGbGVPpa3iFYW1yuPaIv8DiTVRrcg5/6uETNL5zvIoKflG1aifXVUZTlIroDehw4WygGA==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "node_modules/underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "dependencies": { + "underscore": "^1.9.1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/packages/symbols-view/package.json b/packages/symbols-view/package.json new file mode 100644 index 000000000..fb1ec705a --- /dev/null +++ b/packages/symbols-view/package.json @@ -0,0 +1,78 @@ +{ + "name": "symbols-view", + "version": "1.0.0", + "main": "./lib/main", + "types": "./lib/main.d.ts", + "description": "Jump to a function/method in the current editor or in the project.", + "repository": "https://github.com/pulsar-edit/pulsar", + "engines": { + "atom": "*", + "node": ">=14" + }, + "configSchema": { + "quickJumpToFileSymbol": { + "default": true, + "type": "boolean", + "description": "Automatically visit selected file-symbols as you navigate the symbols list." + }, + "showProviderNamesInSymbolsView": { + "default": false, + "type": "boolean", + "description": "When enabled, the name of the provider will be shown alongside each result." + }, + "showIconsInSymbolsView": { + "default": true, + "type": "boolean", + "description": "When enabled, an icon will be shown alongside a symbol if the symbol provider specifies one." + }, + "preferCertainProviders": { + "default": [], + "type": "array", + "items": { + "type": "string" + }, + "description": "A comma-separated list of preferred providers. Used to help break ties when more than one provider can contribute symbols. Anything on this list will be preferred over anything not on this list, and earlier items will be preferred over later items. (A provider can be identified by its official name or its package name; run the **Symbols View: Show Active Providers** command to see both values.)" + }, + "useBadgeColors": { + "default": false, + "type": "boolean", + "description": "Whether to use an assortment of colors for symbol badges. If enabled, each badge will be one of sixteen colors based on its text. Badge colors are generated automatically as hue variants of your theme’s ordinary badge color." + }, + "providerTimeout": { + "default": 2000, + "type": "number", + "description": "How long providers have to respond to symbol requests before this package gives up and shows the list. If a certain provider is particularly slow, you may have to increase this value. (Does not apply to project-wide symbol search **if** the list is already visible.)" + }, + "enableDebugLogging": { + "default": false, + "type": "boolean", + "description": "Whether to log certain diagnostic information to the console. (For example: which provider is chosen for a given task.)" + } + }, + "consumedServices": { + "symbol.provider": { + "description": "Allows external sources to suggest symbols for a given file or project.", + "versions": { + "1.0.0": "consumeSymbolProvider" + } + } + }, + "providedServices": { + "hyperclick": { + "versions": { + "0.1.0": "provideHyperclick" + } + } + }, + "license": "MIT", + "dependencies": { + "atom-select-list": "^0.8.1", + "fs-plus": "^3.1.1", + "fuzzaldrin": "^2.1.0", + "murmurhash-js": "^1.0.0" + }, + "devDependencies": { + "eslint": "^8.39.0", + "temp": "^0.9.4" + } +} diff --git a/packages/symbols-view/spec/.eslintrc.js b/packages/symbols-view/spec/.eslintrc.js new file mode 100644 index 000000000..81e4f8437 --- /dev/null +++ b/packages/symbols-view/spec/.eslintrc.js @@ -0,0 +1,10 @@ +module.exports = { + env: { jasmine: true }, + rules: { + "node/no-unpublished-require": "off", + "node/no-extraneous-require": "off", + "no-unused-vars": "off", + "no-empty": "off", + "no-constant-condition": "off" + } +}; diff --git a/packages/symbols-view/spec/async-spec-helpers.js b/packages/symbols-view/spec/async-spec-helpers.js new file mode 100644 index 000000000..7a2257747 --- /dev/null +++ b/packages/symbols-view/spec/async-spec-helpers.js @@ -0,0 +1,67 @@ +/** @babel */ + +export function beforeEach (fn) { + global.beforeEach(function () { + const result = fn(); + if (result instanceof Promise) { + waitsForPromise(() => result); + } + }); +} + +export function afterEach (fn) { + global.afterEach(function () { + const result = fn(); + if (result instanceof Promise) { + waitsForPromise(() => result); + } + }); +} + +['it', 'fit', 'ffit', 'fffit'].forEach(function (name) { + module.exports[name] = function (description, fn) { + global[name](description, function () { + const result = fn(); + if (result instanceof Promise) { + waitsForPromise(() => result); + } + }); + }; +}); + +export async function conditionPromise (condition) { + const startTime = Date.now(); + + while (true) { + await timeoutPromise(100); + + let conditionResult = condition(); + if (conditionResult instanceof Promise) { + conditionResult = await conditionResult; + } + + if (conditionResult) { + return; + } + + if (Date.now() - startTime > 5000) { + throw new Error('Timed out waiting on condition'); + } + } +} + +export function timeoutPromise (timeout) { + return new Promise(function (resolve) { + global.setTimeout(resolve, timeout); + }); +} + +function waitsForPromise (fn) { + const promise = fn(); + global.waitsFor('spec promise to resolve', function (done) { + promise.then(done, function (error) { + jasmine.getEnv().currentSpec.fail(error); + done(); + }); + }); +} diff --git a/packages/symbols-view/spec/fixtures/js/other-file.js b/packages/symbols-view/spec/fixtures/js/other-file.js new file mode 100644 index 000000000..4e79b3a98 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/js/other-file.js @@ -0,0 +1,29 @@ +// Another file for symbols to exist in. Used for project search. + +var quicksort = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; + +var quicksort2 = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; diff --git a/packages/symbols-view/spec/fixtures/js/sample.js b/packages/symbols-view/spec/fixtures/js/sample.js new file mode 100644 index 000000000..15ab7c831 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/js/sample.js @@ -0,0 +1,13 @@ +var quicksort = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; diff --git a/packages/symbols-view/spec/fixtures/js/tagged.js b/packages/symbols-view/spec/fixtures/js/tagged.js new file mode 100644 index 000000000..932d7750c --- /dev/null +++ b/packages/symbols-view/spec/fixtures/js/tagged.js @@ -0,0 +1,11 @@ +var thisIsCrazy = true; + +function callMeMaybe () { + return "here's my number"; +} + +var iJustMetYou = callMeMaybe(); + +function duplicate () { + return true; +} diff --git a/packages/symbols-view/spec/fixtures/providers/async-provider.js b/packages/symbols-view/spec/fixtures/providers/async-provider.js new file mode 100644 index 000000000..643cc5dfe --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/async-provider.js @@ -0,0 +1,60 @@ +const { Point } = require('atom'); +// const path = require('path'); + +function last (arr) { + return arr[arr.length - 1]; +} + +async function wait (ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +const ICONS = [ + 'icon-package', + 'icon-key', + 'icon-gear', + 'icon-tag', + null +]; + +module.exports = { + packageName: 'symbol-provider-dummy-async', + name: 'Dummy (Async)', + isExclusive: true, + canProvideSymbols (_meta) { + return true; + }, + async getSymbols (meta, listController) { + let { editor, type } = meta; + let results = []; + if (type === 'file') { + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + icon: ICONS[(i / 3) % (ICONS.length + 1)] + }); + } + } else if (type === 'project') { + let root = last(atom.project.getPaths()); + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + directory: root, + file: 'other-file.js', + icon: ICONS[i % (ICONS.length + 1)] + }); + } + } + await wait(100); + listController.set({ loadingMessage: 'Loading…' }); + await wait(250); + listController.clear('loadingMessage'); + return results; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/cache-clearing-provider.js b/packages/symbols-view/spec/fixtures/providers/cache-clearing-provider.js new file mode 100644 index 000000000..f73fd04c5 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/cache-clearing-provider.js @@ -0,0 +1,45 @@ +const { Emitter, Point } = require('atom'); +// const path = require('path'); + +function last (arr) { + return arr[arr.length - 1]; +} + +module.exports = { + packageName: 'symbol-provider-cache-clearing', + name: 'Cache-clearing', + isExclusive: false, + canProvideSymbols (_meta) { + return true; + }, + onShouldClearCache (callback) { + this.emitter ??= new Emitter; + return this.emitter.on('should-clear-cache', callback); + }, + getSymbols (meta) { + let { editor, type } = meta; + let results = []; + setTimeout(() => { + this.emitter.emit('should-clear-cache', { editor }); + }, 0); + if (type === 'file') { + results = [{ + position: new Point(1, 0), + name: 'Transient symbol on row 2' + }]; + } else if (type === 'project') { + let root = last(atom.project.getPaths()); + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + directory: root, + file: 'other-file.js' + }); + } + } + return results; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/competing-exclusive-provider.js b/packages/symbols-view/spec/fixtures/providers/competing-exclusive-provider.js new file mode 100644 index 000000000..d54e49293 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/competing-exclusive-provider.js @@ -0,0 +1,41 @@ +const { Point } = require('atom'); + +function last (arr) { + return arr[arr.length - 1]; +} + +module.exports = { + packageName: 'symbol-provider-competing-exclusive', + name: 'Competing Exclusive', + isExclusive: true, + canProvideSymbols () { + return 0.9; + }, + getSymbols (meta) { + let { editor, type } = meta; + let results = []; + if (type === 'file') { + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}` + }); + } + } else if (type === 'project') { + let root = last(atom.project.getPaths()); + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + directory: root, + file: 'other-file.js' + }); + } + } + return results; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/dummy-provider.js b/packages/symbols-view/spec/fixtures/providers/dummy-provider.js new file mode 100644 index 000000000..844fcb10a --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/dummy-provider.js @@ -0,0 +1,51 @@ +const { Point } = require('atom'); + +function last (arr) { + return arr[arr.length - 1]; +} + +const ICONS = [ + 'icon-package', + 'icon-key', + 'icon-gear', + 'icon-tag', + null +]; + +module.exports = { + packageName: 'symbol-provider-dummy', + name: 'Dummy', + isExclusive: true, + canProvideSymbols () { + return true; + }, + getSymbols (meta) { + let { editor, type } = meta; + let results = []; + if (type === 'file') { + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + icon: ICONS[(i / 3) % (ICONS.length + 1)] + }); + } + } else if (type === 'project') { + let root = last(atom.project.getPaths()); + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + directory: root, + file: 'other-file.js', + icon: ICONS[i % (ICONS.length + 1)] + }); + } + } + return results; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/empty-provider.js b/packages/symbols-view/spec/fixtures/providers/empty-provider.js new file mode 100644 index 000000000..042ab3507 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/empty-provider.js @@ -0,0 +1,13 @@ +const { Point } = require('atom'); + +module.exports = { + packageName: 'symbol-provider-empty', + name: 'Empty', + isExclusive: false, + canProvideSymbols (meta) { + return true; + }, + getSymbols (meta) { + return []; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/progressive-project-provider.js b/packages/symbols-view/spec/fixtures/providers/progressive-project-provider.js new file mode 100644 index 000000000..4e4ed3cb3 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/progressive-project-provider.js @@ -0,0 +1,57 @@ +const { Point } = require('atom'); + +function last (arr) { + return arr[arr.length - 1]; +} + +const SYMBOLS = [ + { + name: 'Lorem ipsum', + position: new Point(0, 0), + file: 'other-file.js', + }, + { + name: 'Loyalty', + position: new Point(1, 0), + file: 'other-file.js', + }, + { + name: 'Lox', + position: new Point(2, 0), + file: 'other-file.js', + }, + { + name: 'Lo mein', + position: new Point(3, 0), + file: 'other-file.js', + } +]; + +module.exports = { + packageName: 'symbol-provider-progressive', + name: 'Progressive Project Provider', + isExclusive: true, + canProvideSymbols (meta) { + return meta.type === 'project'; + }, + getSymbols (meta, controller) { + let root = last(atom.project.getPaths()); + let { type, query = '' } = meta; + if (type !== 'project') return []; + + // Simulate a provider that requires a minimum character count. + if (query.length < 3) { + controller.set({ emptyMessage: 'Query must be at least 3 characters long.' }); + return []; + } else { + controller.clear('emptyMessage'); + } + + let results = SYMBOLS.filter(s => { + let term = s.name.toLowerCase(); + return term.startsWith(query); + }); + + return results.map(r => ({ ...r, directory: root })); + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/quicksort-provider.js b/packages/symbols-view/spec/fixtures/providers/quicksort-provider.js new file mode 100644 index 000000000..4dc2aad24 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/quicksort-provider.js @@ -0,0 +1,44 @@ +const { Point } = require('atom'); +const path = require('path'); + +function last (arr) { + return arr[arr.length - 1]; +} + +module.exports = { + packageName: 'symbol-provider-quicksort', + name: 'Quicksort', + isExclusive: true, + canProvideSymbols (meta) { + return true; + }, + getSymbols (meta) { + let { editor, type } = meta; + let results = []; + if (type === 'file') { + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + let name = `Symbol on Row ${i + 1}`; + if (i === 0) name = 'quicksort'; + results.push({ + position: new Point(i, 0), + name + }); + } + } else if (type === 'project') { + let root = last(atom.project.getPaths()); + let count = editor.getLineCount(); + // Put a symbol on every third line. + for (let i = 0; i < count; i += 3) { + results.push({ + position: new Point(i, 0), + name: `Symbol on Row ${i + 1}`, + directory: root, + file: 'other-file.js' + }); + } + } + return results; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/tagged-provider.js b/packages/symbols-view/spec/fixtures/providers/tagged-provider.js new file mode 100644 index 000000000..74c2daa27 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/tagged-provider.js @@ -0,0 +1,44 @@ +const { Point } = require('atom'); +const path = require('path'); + +function last (arr) { + return arr[arr.length - 1]; +} + +const MOCK_FILE_NAME = 'tagged.js'; +const MOCK_RESULT_COUNT = 1; + +module.exports = { + // If you change these values, you MUST remember to call `reset` in an + // `afterEach` block! + mockResultCount: MOCK_RESULT_COUNT, + mockFileName: MOCK_FILE_NAME, + + reset () { + this.mockFileName = MOCK_FILE_NAME; + this.mockResultCount = MOCK_RESULT_COUNT; + }, + + packageName: 'symbol-provider-tagged', + name: 'Tagged', + isExclusive: true, + canProvideSymbols (meta) { + if (!meta.type === 'project') return false; + return true; + }, + getSymbols (meta) { + let root = last(atom.project.getPaths()); + let { editor, type } = meta; + let results = []; + if (!type.includes('project')) return []; + for (let i = 0; i < this.mockResultCount; i++) { + results.push({ + directory: root, + file: this.mockFileName, + position: new Point(2 + i, 10), + name: 'callMeMaybe' + }); + } + return results; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/useless-provider.js b/packages/symbols-view/spec/fixtures/providers/useless-provider.js new file mode 100644 index 000000000..4701c7a51 --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/useless-provider.js @@ -0,0 +1,13 @@ +const { Point } = require('atom'); + +module.exports = { + packageName: 'symbol-provider-useless', + name: 'Useless', + isExclusive: false, + canProvideSymbols (meta) { + return false; + }, + getSymbols (meta) { + return null; + } +}; diff --git a/packages/symbols-view/spec/fixtures/providers/very-slow-provider.js b/packages/symbols-view/spec/fixtures/providers/very-slow-provider.js new file mode 100644 index 000000000..076f076fd --- /dev/null +++ b/packages/symbols-view/spec/fixtures/providers/very-slow-provider.js @@ -0,0 +1,29 @@ +const { Point } = require('atom'); + +function wait (ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); +} + +module.exports = { + packageName: 'symbol-provider-very-slow', + name: 'Very Slow', + isExclusive: false, + canProvideSymbols () { + return true; + }, + async getSymbols (meta) { + let { signal } = meta; + await wait(3000); + if (signal.aborted) { + return null; + } + return [ + { + position: new Point(0, 0), + name: `Slow Symbol on Row 1` + } + ]; + } +}; diff --git a/packages/symbols-view/spec/symbols-view-spec.js b/packages/symbols-view/spec/symbols-view-spec.js new file mode 100644 index 000000000..df0ab1a48 --- /dev/null +++ b/packages/symbols-view/spec/symbols-view-spec.js @@ -0,0 +1,780 @@ +const path = require('path'); +const etch = require('etch'); +const fs = require('fs-plus'); +const temp = require('temp'); +const SymbolsView = require('../lib/symbols-view'); + +const { migrateOldConfigIfNeeded } = require('../lib/util'); + +const DummyProvider = require('./fixtures/providers/dummy-provider'); +const AsyncDummyProvider = require('./fixtures/providers/async-provider'); +const ProgressiveProjectProvider = require('./fixtures/providers/progressive-project-provider.js'); +const QuicksortProvider = require('./fixtures/providers/quicksort-provider.js'); +const VerySlowProvider = require('./fixtures/providers/very-slow-provider'); +const UselessProvider = require('./fixtures/providers/useless-provider.js'); +const EmptyProvider = require('./fixtures/providers/empty-provider.js'); +const TaggedProvider = require('./fixtures/providers/tagged-provider.js'); +const CacheClearingProvider = require('./fixtures/providers/cache-clearing-provider.js'); +const CompetingExclusiveProvider = require('./fixtures/providers/competing-exclusive-provider.js'); + +const { it, fit, ffit, fffit, beforeEach, afterEach, conditionPromise } = require('./async-spec-helpers'); + +async function wait(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +function getOrScheduleUpdatePromise() { + return new Promise((resolve) => etch.getScheduler().updateDocument(resolve)); +} + +function choiceCount(symbolsView) { + return symbolsView.element.querySelectorAll('li').length; +} + +function getWorkspaceView() { + return atom.views.getView(atom.workspace); +} + +function getEditorView() { + return atom.views.getView(atom.workspace.getActiveTextEditor()); +} + +function getSymbolsView() { + return atom.workspace.getModalPanels()[0]?.item; +} + +async function dispatchAndWaitForChoices(commandName) { + atom.commands.dispatch(getEditorView(), commandName); + let symbolsView = atom.workspace.getModalPanels()[0].item; + await conditionPromise(() => { + let count = symbolsView.element.querySelectorAll('li').length; + return count > 0; + }); +} + +function registerProvider(...args) { + let pkg = atom.packages.getActivePackage('symbols-view'); + let main = pkg?.mainModule; + if (!main) { + let disposable = atom.packages.onDidActivatePackage(pack => { + if (pack.name !== 'symbols-view') return; + for (let provider of args) { + pack.mainModule.consumeSymbolProvider(provider); + } + disposable.dispose(); + }); + // If we let the package lazy-activate the first time a command is invoked, + // we lose an opportunity to add mock providers. So we should activate it + // manually. + atom.packages.getLoadedPackage('symbols-view').activateNow(); + } else { + for (let provider of args) { + main.consumeSymbolProvider(provider); + } + } +} + +describe('SymbolsView', () => { + let symbolsView, activationPromise, editor, directory, mainModule; + + beforeEach(async () => { + jasmine.unspy(Date, 'now'); + jasmine.unspy(global, 'setTimeout'); + + atom.project.setPaths([ + temp.mkdirSync('other-dir-'), + temp.mkdirSync('atom-symbols-view-') + ]); + + directory = atom.project.getDirectories()[1]; + + fs.copySync( + path.join(__dirname, 'fixtures', 'js'), + atom.project.getPaths()[1] + ); + + atom.config.set('symbols-view.showProviderNamesInSymbolsView', false); + atom.config.set('symbols-view.showIconsInSymbolsView', false); + + activationPromise = atom.packages.activatePackage('symbols-view'); + activationPromise.then(() => { + mainModule = atom.packages.getActivePackage('symbols-view').mainModule; + }); + jasmine.attachToDOM(getWorkspaceView()); + }); + + afterEach(async () => { + await atom.packages.deactivatePackage('symbols-view'); + }); + + describe('when toggling file symbols', () => { + beforeEach(async () => { + atom.config.set('symbols-view.providerTimeout', 500); + await atom.workspace.open(directory.resolve('sample.js')); + }); + + it('displays all symbols with line numbers', async () => { + registerProvider(DummyProvider); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + expect(symbolsView.selectListView.refs.loadingMessage).toBeUndefined(); + expect(document.body.contains(symbolsView.element)).toBe(true); + expect(symbolsView.element.querySelectorAll('li').length).toBe(5); + + expect(symbolsView.element.querySelector('li:first-child .primary-line')).toHaveText('Symbol on Row 1'); + expect(symbolsView.element.querySelector('li:first-child .secondary-line')).toHaveText('Line 1'); + expect(symbolsView.element.querySelector('li:last-child .primary-line')).toHaveText('Symbol on Row 13'); + expect(symbolsView.element.querySelector('li:last-child .secondary-line')).toHaveText('Line 13'); + + // No icon-related classes should be added when `showIconsInSymbolsView` + // is false. + expect(symbolsView.element.querySelector('li:first-child .primary-line').classList.contains('icon')).toBe(false); + expect(symbolsView.element.querySelector('li:first-child .primary-line').classList.contains('no-icon')).toBe(false); + + }); + + it('does not wait for providers that take too long', async () => { + registerProvider(DummyProvider, VerySlowProvider); + await activationPromise; + expect(mainModule.broker.providers.length).toBe(2); + atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-file-symbols'); + + symbolsView = atom.workspace.getModalPanels()[0].item; + await conditionPromise(async () => { + await getOrScheduleUpdatePromise(); + let count = symbolsView.element.querySelectorAll('li').length; + return count > 0; + }); + + expect(symbolsView.selectListView.refs.loadingMessage).toBeUndefined(); + expect(document.body.contains(symbolsView.element)).toBe(true); + expect(symbolsView.element.querySelectorAll('li').length).toBe(5); + + expect(symbolsView.element.querySelector('li:first-child .primary-line')).toHaveText('Symbol on Row 1'); + expect(symbolsView.element.querySelector('li:first-child .secondary-line')).toHaveText('Line 1'); + expect(symbolsView.element.querySelector('li:last-child .primary-line')).toHaveText('Symbol on Row 13'); + expect(symbolsView.element.querySelector('li:last-child .secondary-line')).toHaveText('Line 13'); + }); + + it('allows the exclusive provider to control certain UI aspects', async () => { + registerProvider(AsyncDummyProvider); + await activationPromise; + expect(mainModule.broker.providers.length).toBe(1); + atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + spyOn(symbolsView.selectListView, 'update').andCallThrough(); + await conditionPromise(async () => { + await getOrScheduleUpdatePromise(); + let count = symbolsView.element.querySelectorAll('li').length; + return count > 0; + }); + + expect(symbolsView.selectListView.update).toHaveBeenCalledWith( + { loadingMessage: 'Loading…' } + ); + }); + + it('caches tags until the editor changes', async () => { + registerProvider(DummyProvider); + await activationPromise; + editor = atom.workspace.getActiveTextEditor(); + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = atom.workspace.getModalPanels()[0].item; + await symbolsView.cancel(); + + spyOn(DummyProvider, 'getSymbols').andCallThrough(); + + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + expect(choiceCount(symbolsView)).toBe(5); + expect(DummyProvider.getSymbols).not.toHaveBeenCalled(); + await symbolsView.cancel(); + + await editor.save(); + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + + expect(symbolsView.selectListView.refs.loadingMessage).toBeUndefined(); + expect(choiceCount(symbolsView)).toBe(5); + expect(DummyProvider.getSymbols).toHaveBeenCalled(); + editor.destroy(); + expect(symbolsView.cachedResults.get(editor)).toBeUndefined(); + }); + + it("invalidates a single provider's tags if the provider asks it to", async () => { + registerProvider(DummyProvider, CacheClearingProvider); + await activationPromise; + editor = atom.workspace.getActiveTextEditor(); + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = atom.workspace.getModalPanels()[0].item; + expect(choiceCount(symbolsView)).toBe(6); + await symbolsView.cancel(); + await wait(100); + + spyOn(DummyProvider, 'getSymbols').andCallThrough(); + spyOn(CacheClearingProvider, 'getSymbols').andCallThrough(); + + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + expect(choiceCount(symbolsView)).toBe(6); + expect(DummyProvider.getSymbols).not.toHaveBeenCalled(); + expect(CacheClearingProvider.getSymbols).toHaveBeenCalled(); + await symbolsView.cancel(); + await editor.save(); + + expect(symbolsView.cachedResults.get(editor)).toBeUndefined(); + + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + + expect(symbolsView.selectListView.refs.loadingMessage).toBeUndefined(); + expect(choiceCount(symbolsView)).toBe(6); + expect(DummyProvider.getSymbols).toHaveBeenCalled(); + expect(CacheClearingProvider.getSymbols).toHaveBeenCalled(); + editor.destroy(); + expect(symbolsView.cachedResults.get(editor)).toBeUndefined(); + }); + + it('displays a message when no tags match text in mini-editor', async () => { + registerProvider(DummyProvider); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + + symbolsView = getSymbolsView(); + symbolsView.selectListView.refs.queryEditor.setText('nothing will match this'); + + await conditionPromise(() => symbolsView.selectListView.refs.emptyMessage); + expect(document.body.contains(symbolsView.element)).toBe(true); + expect(choiceCount(symbolsView)).toBe(0); + + expect(symbolsView.selectListView.refs.emptyMessage.textContent.length).toBeGreaterThan(0); + + symbolsView.selectListView.refs.queryEditor.setText(''); + await conditionPromise(() => choiceCount(symbolsView) > 0); + expect( choiceCount(symbolsView) ).toBe(5); + expect(symbolsView.selectListView.refs.emptyMessage).toBeUndefined(); + }); + + it('moves the cursor to the selected function', async () => { + registerProvider(DummyProvider); + await activationPromise; + editor = atom.workspace.getActiveTextEditor(); + expect(editor.getCursorBufferPosition()).toEqual([0, 0]); + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + symbolsView.element.querySelectorAll('li')[1].click(); + // It'll move to the first non-whitespace character on the line. + expect(editor.getCursorBufferPosition()).toEqual([3, 4]); + }); + + describe('when there are multiple exclusive providers', () => { + describe("and none have priority in the user's settings", () => { + it('prefers the one with the highest score', async () => { + registerProvider(DummyProvider, CompetingExclusiveProvider); + spyOn(CompetingExclusiveProvider, 'getSymbols').andCallThrough(); + spyOn(DummyProvider, 'getSymbols').andCallThrough(); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + expect(choiceCount(symbolsView)).toBe(5); + expect(DummyProvider.getSymbols).toHaveBeenCalled(); + expect(CompetingExclusiveProvider.getSymbols).not.toHaveBeenCalled(); + }); + }); + + describe('and one is listed in `preferCertainProviders`', () => { + beforeEach(() => { + atom.config.set('symbols-view.preferCertainProviders', ['symbol-provider-competing-exclusive']); + }); + + it('prefers the one with the highest score (providers listed beating those not listed)', async () => { + registerProvider(DummyProvider, CompetingExclusiveProvider); + spyOn(CompetingExclusiveProvider, 'getSymbols').andCallThrough(); + spyOn(DummyProvider, 'getSymbols').andCallThrough(); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + expect(choiceCount(symbolsView)).toBe(5); + expect(DummyProvider.getSymbols).not.toHaveBeenCalled(); + expect(CompetingExclusiveProvider.getSymbols).toHaveBeenCalled(); + }); + }); + + describe('and more than one is listed in `preferCertainProviders`', () => { + beforeEach(() => { + // Last time we referred to this one by its package name; now we use + // its human-friendly name. They should be interchangeable. + atom.config.set('symbols-view.preferCertainProviders', ['Competing Exclusive', 'symbol-provider-dummy']); + }); + + it('prefers the one with the highest score (providers listed earlier beating those listed later)', async () => { + registerProvider(DummyProvider, CompetingExclusiveProvider); + spyOn(CompetingExclusiveProvider, 'getSymbols').andCallThrough(); + spyOn(DummyProvider, 'getSymbols').andCallThrough(); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + expect(choiceCount(symbolsView)).toBe(5); + expect(DummyProvider.getSymbols).not.toHaveBeenCalled(); + expect(CompetingExclusiveProvider.getSymbols).toHaveBeenCalled(); + }); + }); + }); + + describe('when no symbols are found', () => { + it('shows the list view with an error message', async () => { + registerProvider(EmptyProvider); + await activationPromise; + atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-file-symbols'); + await conditionPromise(() => getSymbolsView()?.selectListView.refs.emptyMessage); + symbolsView = getSymbolsView(); + + expect(document.body.contains(symbolsView.element)); + expect(choiceCount(symbolsView)).toBe(0); + let refs = symbolsView.selectListView.refs; + expect(refs.emptyMessage).toBeVisible(); + expect(refs.emptyMessage.textContent.length).toBeGreaterThan(0); + expect(refs.loadingMessage).not.toBeVisible(); + }); + }); + + describe("when symbols can't be generated for a file", () => { + it('does not show the list view', async () => { + registerProvider(UselessProvider); + await activationPromise; + expect(mainModule.broker.providers.length).toBe(1); + atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-file-symbols'); + + await wait(1000); + symbolsView = atom.workspace.getModalPanels()[0].item; + + // List view should not be visible, nor should it have any options. + expect( + symbolsView.element.querySelectorAll('li').length + ).toBe(0); + expect(symbolsView.element).not.toBeVisible(); + }); + }); + + describe("when the user has enabled icons in the symbols list", () => { + beforeEach(() => { + atom.config.set('symbols-view.showIconsInSymbolsView', true); + }); + + it('shows icons in the symbols list', async () => { + registerProvider(DummyProvider); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + expect(symbolsView.selectListView.refs.loadingMessage).toBeUndefined(); + expect(document.body.contains(symbolsView.element)).toBe(true); + expect(symbolsView.element.querySelectorAll('li').length).toBe(5); + + expect(symbolsView.element.querySelector('li:first-child .primary-line').classList.contains('icon-package')).toBe(true); + expect(symbolsView.element.querySelector('li:first-child .secondary-line').classList.contains('no-icon')).toBe(true); + + expect(symbolsView.element.querySelector('li:nth-child(2) .primary-line').classList.contains('icon-key')).toBe(true); + expect(symbolsView.element.querySelector('li:nth-child(3) .primary-line').classList.contains('icon-gear')).toBe(true); + expect(symbolsView.element.querySelector('li:nth-child(4) .primary-line').classList.contains('icon-tag')).toBe(true); + + // Simulate lack of icon on a random element. + expect(symbolsView.element.querySelector('li:nth-child(5) .primary-line').classList.contains('no-icon')).toBe(true); + }); + }); + }); + + describe('when going to declaration', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + }); + + describe('when no declaration is found', () => { + beforeEach(async () => { + registerProvider(EmptyProvider); + editor = atom.workspace.getActiveTextEditor(); + }); + + it("doesn't move the cursor", async () => { + await activationPromise; + editor.setCursorBufferPosition([0, 2]); + atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-project-symbols'); + await wait(100); + + expect(editor.getCursorBufferPosition()).toEqual([0, 2]); + }); + }); + + describe('when there is a single matching declaration', () => { + beforeEach(async () => { + registerProvider(TaggedProvider); + await atom.workspace.open(directory.resolve('tagged.js')); + editor = atom.workspace.getActiveTextEditor(); + }); + + it('moves the cursor to the declaration', async () => { + editor.setCursorBufferPosition([6, 24]); + spyOn(SymbolsView.prototype, 'moveToPosition').andCallThrough(); + + atom.commands.dispatch(getEditorView(), 'symbols-view:go-to-declaration'); + + await conditionPromise(() => { + return SymbolsView.prototype.moveToPosition.callCount === 1; + }); + expect(editor.getCursorBufferPosition()).toEqual([2, 0]); + }); + }); + + describe('when there is more than one matching declaration', () => { + beforeEach(async () => { + registerProvider(TaggedProvider); + TaggedProvider.mockResultCount = 2; + TaggedProvider.mockFileName = 'other-file.js'; + await atom.workspace.open(directory.resolve('tagged.js')); + editor = atom.workspace.getActiveTextEditor(); + await activationPromise; + }); + + afterEach(() => { + TaggedProvider.reset(); + }); + + it('displays matches and opens the selected match', async () => { + editor.setCursorBufferPosition([8, 14]); + atom.commands.dispatch(getEditorView(), 'symbols-view:go-to-declaration'); + symbolsView = getSymbolsView(); + + await conditionPromise(() => { + return symbolsView.element.querySelectorAll('li').length > 0; + }); + + expect(choiceCount(symbolsView)).toBe(2); + expect(symbolsView.element).toBeVisible(); + spyOn(SymbolsView.prototype, 'moveToPosition').andCallThrough(); + symbolsView.selectListView.confirmSelection(); + + await conditionPromise(() => { + return SymbolsView.prototype.moveToPosition.callCount === 1; + }); + + editor = atom.workspace.getActiveTextEditor(); + + expect( + atom.workspace.getActiveTextEditor().getPath() + ).toBe(directory.resolve('other-file.js')); + + expect( + atom.workspace.getActiveTextEditor().getCursorBufferPosition() + ).toEqual([2, 0]); + }); + }); + }); + + describe('return from declaration', () => { + beforeEach(async () => { + registerProvider(TaggedProvider); + await atom.workspace.open(directory.resolve('tagged.js')); + await activationPromise; + editor = atom.workspace.getActiveTextEditor(); + }); + + it("doesn't do anything when no go-tos have been triggered", async () => { + editor.setCursorBufferPosition([6, 0]); + atom.commands.dispatch(getEditorView(), 'symbols-view:return-from-declaration'); + + expect(editor.getCursorBufferPosition()).toEqual([6, 0]); + }); + + it('returns to the previous row and column', async () => { + editor.setCursorBufferPosition([6, 24]); + editor = atom.workspace.getActiveTextEditor(); + spyOn(SymbolsView.prototype, 'moveToPosition').andCallThrough(); + atom.commands.dispatch(getEditorView(), 'symbols-view:go-to-declaration'); + + await conditionPromise(() => { + return SymbolsView.prototype.moveToPosition.callCount === 1; + }); + expect(editor.getCursorBufferPosition()).toEqual([2, 0]); + atom.commands.dispatch(getEditorView(), 'symbols-view:return-from-declaration'); + + await conditionPromise(() => SymbolsView.prototype.moveToPosition.callCount === 2); + expect(editor.getCursorBufferPosition()).toEqual([6, 24]); + }); + }); + + describe('when toggling project symbols', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + }); + + it('displays all symbols', async () => { + registerProvider(DummyProvider); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-project-symbols'); + symbolsView = atom.workspace.getModalPanels()[0].item; + + expect(symbolsView.selectListView.refs.loadingMessage).toBeUndefined(); + expect(document.body.contains(symbolsView.element)).toBe(true); + expect(symbolsView.element.querySelectorAll('li').length).toBe(5); + + let root = atom.project.getPaths()[1]; + let resolved = directory.resolve('other-file.js'); + let relative = `${path.basename(root)}${resolved.replace(root, '')}`; + + expect(symbolsView.element.querySelector('li:first-child .primary-line')).toHaveText('Symbol on Row 1'); + expect(symbolsView.element.querySelector('li:first-child .secondary-line')).toHaveText(`${relative}:1`); + expect(symbolsView.element.querySelector('li:last-child .primary-line')).toHaveText('Symbol on Row 13'); + expect(symbolsView.element.querySelector('li:last-child .secondary-line')).toHaveText(`${relative}:13`); + }); + + it('asks for new symbols when the user starts typing', async () => { + registerProvider(ProgressiveProjectProvider); + spyOn(ProgressiveProjectProvider, 'getSymbols').andCallThrough(); + await activationPromise; + atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-project-symbols'); + symbolsView = atom.workspace.getModalPanels()[0].item; + await wait(200); + + expect(symbolsView.element.querySelectorAll('li .primary-line').length).toBe(0); + expect(ProgressiveProjectProvider.getSymbols.callCount).toBe(1); + + expect(symbolsView.selectListView.props.emptyMessage).toBe('Query must be at least 3 characters long.'); + + await symbolsView.updateView({ query: 'lor' }); + await wait(200); + + expect(symbolsView.selectListView.props.emptyMessage).toBeNull(); + + expect(symbolsView.element.querySelectorAll('li .primary-line').length).toBe(1); + expect(symbolsView.element.querySelector('li:first-child .primary-line')).toHaveText('Lorem ipsum'); + expect(ProgressiveProjectProvider.getSymbols.callCount).toBe(2); + }); + + describe('when there is only one project', () => { + beforeEach(() => { + atom.project.setPaths([directory.getPath()]); + }); + + it("does not include the root directory's name when displaying the symbol's filename", async () => { + registerProvider(TaggedProvider); + await atom.workspace.open(directory.resolve('tagged.js')); + await activationPromise; + expect(getWorkspaceView().querySelector('.symbols-view')).toBeNull(); + await dispatchAndWaitForChoices('symbols-view:toggle-project-symbols'); + symbolsView = getSymbolsView(); + + expect(choiceCount(symbolsView)).toBe(1); + + expect(symbolsView.element.querySelector('li:first-child .primary-line')).toHaveText('callMeMaybe'); + expect(symbolsView.element.querySelector('li:first-child .secondary-line')).toHaveText('tagged.js:3'); + }); + }); + + describe('when selecting a tag', () => { + describe("when the file doesn't exist", () => { + beforeEach(async () => fs.removeSync(directory.resolve('tagged.js'))); + + it("doesn't open the editor", async () => { + registerProvider(TaggedProvider); + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-project-symbols'); + symbolsView = getSymbolsView(); + + spyOn(atom.workspace, 'open').andCallThrough(); + + symbolsView.element.querySelector('li:first-child').click(); + + await conditionPromise(() => symbolsView.selectListView.refs.errorMessage); + + expect(atom.workspace.open).not.toHaveBeenCalled(); + expect( + symbolsView.selectListView.refs.errorMessage.textContent.length + ).toBeGreaterThan(0); + }); + }); + }); + + describe('match highlighting', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = atom.workspace.getActiveTextEditor(); + registerProvider(QuicksortProvider); + }); + + it('highlights an exact match', async () => { + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + + symbolsView = getSymbolsView(); + symbolsView.selectListView.refs.queryEditor.setText('quicksort'); + await getOrScheduleUpdatePromise(); + let resultView = symbolsView.element.querySelector('.selected'); + let matches = resultView.querySelectorAll('.character-match'); + expect(matches.length).toBe(1); + expect(matches[0].textContent).toBe('quicksort'); + }); + + it('highlights a partial match', async () => { + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + symbolsView.selectListView.refs.queryEditor.setText('quick'); + await getOrScheduleUpdatePromise(); + + let resultView = symbolsView.element.querySelector('.selected'); + let matches = resultView.querySelectorAll('.character-match'); + expect(matches.length).toBe(1); + expect(matches[0].textContent).toBe('quick'); + }); + + it('highlights multiple matches in the symbol name', async () => { + await activationPromise; + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + symbolsView.selectListView.refs.queryEditor.setText('quicort'); + await getOrScheduleUpdatePromise(); + + let resultView = symbolsView.element.querySelector('.selected'); + let matches = resultView.querySelectorAll('.character-match'); + expect(matches.length).toBe(2); + expect(matches[0].textContent).toBe('quic'); + expect(matches[1].textContent).toBe('ort'); + }); + }); + + describe('when quickJumpToSymbol is true', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + }); + + it('jumps to the selected function', async () => { + registerProvider(DummyProvider); + await activationPromise; + editor = atom.workspace.getActiveTextEditor(); + expect(editor.getCursorBufferPosition()).toEqual([0, 0]); + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + symbolsView.selectListView.selectNext(); + + expect(editor.getCursorBufferPosition()).toEqual([3, 4]); + }); + + // NOTE: If this test fails, could it have been because you opened the + // dev tools console? That seems to break it on a reliable basis. Not + // sure why yet. + it('restores previous editor state on cancel', async () => { + registerProvider(DummyProvider); + await activationPromise; + const bufferRanges = [{start: {row: 0, column: 0}, end: {row: 0, column: 3}}]; + editor = atom.workspace.getActiveTextEditor(); + editor.setSelectedBufferRanges(bufferRanges); + + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + + symbolsView.selectListView.selectNext(); + expect(editor.getCursorBufferPosition()).toEqual([3, 4]); + + await symbolsView.cancel(); + expect(editor.getSelectedBufferRanges()).toEqual(bufferRanges); + }); + }); + + describe('when quickJumpToSymbol is false', () => { + beforeEach(async () => { + atom.config.set('symbols-view.quickJumpToFileSymbol', false); + await atom.workspace.open(directory.resolve('sample.js')); + }); + + it("won't jump to the selected function", async () => { + registerProvider(DummyProvider); + await activationPromise; + editor = atom.workspace.getActiveTextEditor(); + expect(editor.getCursorBufferPosition()).toEqual([0, 0]); + + await dispatchAndWaitForChoices('symbols-view:toggle-file-symbols'); + symbolsView = getSymbolsView(); + symbolsView.selectListView.selectNext(); + expect(editor.getCursorBufferPosition()).toEqual([0, 0]); + }); + }); + }); + + describe('when migrating legacy setting', () => { + beforeEach(async () => { + atom.config.set( + 'symbols-view.useEditorGrammarAsCtagsLanguage', + false, + { source: atom.config.getUserConfigPath() } + ); + spyOn(atom.notifications, 'addInfo'); + }); + + afterEach(async () => { + atom.config.unset( + 'symbols-view.useEditorGrammarAsCtagsLanguage', + { source: atom.config.getUserConfigPath() } + ); + }); + + it('migrates the setting as expected', () => { + expect( + atom.config.get('symbols-view.useEditorGrammarAsCtagsLanguage') + ).toBe(false); + + migrateOldConfigIfNeeded({ force: true }); + + expect( + atom.config.get( + 'symbols-view.useEditorGrammarAsCtagsLanguage', + { source: atom.config.getUserConfigPath() } + ) + ).toBeUndefined(); + + expect( + atom.config.get( + 'symbol-provider-ctags.useEditorGrammarAsCtagsLanguage', + { source: atom.config.getUserConfigPath() } + ) + ).toBe(false); + + expect(atom.notifications.addInfo).not.toHaveBeenCalled(); + }); + + describe('and a scope-specific override has been made for that setting', () => { + beforeEach(() => { + atom.config.set( + 'symbols-view.useEditorGrammarAsCtagsLanguage', + true, + { + source: 'baz', + scopeSelector: ['.source.ts'] + } + ); + }); + + afterEach(() => { + atom.config.unset( + 'symbols-view.useEditorGrammarAsCtagsLanguage', + { + source: 'baz', + scopeSelector: ['.source.ts'] + } + ); + }); + + fit('alerts the user', () => { + migrateOldConfigIfNeeded({ force: true }); + + expect(atom.notifications.addInfo).toHaveBeenCalled(); + + expect( + atom.notifications.addInfo.mostRecentCall?.args[1].description + ).toBe("The `symbols-view` package has migrated the setting `symbols-view.useEditorGrammarAsCtagsLanguage` to its new location inside the core package `symbol-provider-ctags`. If you have defined any scope-specific overrides for this setting, you’ll need to change those overrides manually.\n\nDetected overrides in the following locations:\n\n* `baz`"); + }); + }); + + }); +}); diff --git a/packages/symbols-view/styles/symbols-view.less b/packages/symbols-view/styles/symbols-view.less new file mode 100644 index 000000000..7e1a7151c --- /dev/null +++ b/packages/symbols-view/styles/symbols-view.less @@ -0,0 +1,90 @@ +@import "ui-variables"; + +@wedge: (360 / 16); + +.badge-variant(@char, @num) { + .symbols-view-badge-variant-@{char} { + background-color: spin(@background-color-info, @wedge * @num) !important; + } +} + +// Generate 16 different badge colors. +// +// We need colors that vary from one another, but they need to harmonize with +// the user's chosen UI theme. So we'll just use `spin` to move around the +// color wheel, starting with their UI theme's own badge background color, and +// varying the hue while keeping the saturation and brightness constant. +.badge-variant(e('0'), 0); +.badge-variant(e('1'), 1); +.badge-variant(e('2'), 2); +.badge-variant(e('3'), 3); +.badge-variant(e('4'), 4); +.badge-variant(e('5'), 5); +.badge-variant(e('6'), 6); +.badge-variant(e('7'), 7); +.badge-variant(e('8'), 8); +.badge-variant(e('9'), 9); +.badge-variant(e('a'), 10); +.badge-variant(e('b'), 11); +.badge-variant(e('c'), 12); +.badge-variant(e('d'), 13); +.badge-variant(e('e'), 14); +.badge-variant(e('f'), 15); + + +// Highlight matched text +.symbols-view .list-group .character-match { + color: @text-color-highlight; + font-weight: bold; +} + + +atom-panel.modal .symbols-view { + .primary-line { + display: flex !important; + flex-direction: row; + align-items: baseline; + + .name { + text-overflow: ellipsis; + overflow: hidden; + white-space: pre; + margin-right: auto; + } + + .badge-container { + display: block; + flex-grow: 0; + display: flex; + flex-direction: row; + + .badge:not(:last-child) { + margin-right: 5px; + } + } + + .badge-symbol-tag { + text-transform: capitalize; + } + } + + .secondary-line { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: baseline; + max-width: 100%; + + .location { + display: block; + } + + .context { + display: block; + text-overflow: ellipsis; + overflow: hidden; + flex-grow: 0; + } + } + +} From 5514c982bdec1cc648f402df49532fb39eb6ae72 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 10:30:17 -0800 Subject: [PATCH 02/16] Add symbol provider packages --- packages/symbol-provider-ctags/.eslintrc.js | 42 + packages/symbol-provider-ctags/LICENSE.md | 21 + packages/symbol-provider-ctags/README.md | 24 + .../symbol-provider-ctags/lib/ctags-config | 222 ++ .../lib/ctags-provider.js | 284 +++ .../lib/get-tags-file.js | 22 + .../lib/load-tags-handler.js | 26 + packages/symbol-provider-ctags/lib/main.js | 16 + .../symbol-provider-ctags/lib/tag-reader.js | 131 + .../symbol-provider-ctags/package-lock.json | 2248 +++++++++++++++++ packages/symbol-provider-ctags/package.json | 36 + .../symbol-provider-ctags/spec/.eslintrc.js | 13 + .../spec/fixtures/c/sample.c | 6 + .../spec/fixtures/c/tags | 8 + .../spec/fixtures/js/.eslintignore | 3 + .../spec/fixtures/js/no-symbols.js | 6 + .../spec/fixtures/js/other-file.js | 29 + .../spec/fixtures/js/sample.js | 13 + .../spec/fixtures/js/tagged.js | 11 + .../spec/fixtures/js/tags | 10 + .../spec/fixtures/ruby/file1.rb | 33 + .../spec/fixtures/ruby/tags | 15 + .../spec/symbol-provider-ctags-spec.js | 297 +++ .../symbol-provider-ctags/vendor/ctags-darwin | Bin 0 -> 212624 bytes .../symbol-provider-ctags/vendor/ctags-linux | Bin 0 -> 250080 bytes .../vendor/ctags-win32.exe | Bin 0 -> 315392 bytes .../symbol-provider-tree-sitter/.eslintrc.js | 42 + .../symbol-provider-tree-sitter/LICENSE.md | 20 + .../symbol-provider-tree-sitter/README.md | 181 ++ .../lib/capture-organizer.js | 391 +++ .../symbol-provider-tree-sitter/lib/main.js | 16 + .../lib/tree-sitter-provider.js | 86 + .../package-lock.json | 2122 ++++++++++++++++ .../symbol-provider-tree-sitter/package.json | 32 + .../spec/.eslintrc.js | 13 + .../spec/fixtures/c/sample.c | 6 + .../spec/fixtures/js/.eslintignore | 3 + .../spec/fixtures/js/no-symbols.js | 6 + .../spec/fixtures/js/other-file.js | 29 + .../spec/fixtures/js/sample.js | 13 + .../spec/fixtures/js/tagged.js | 11 + .../spec/fixtures/ruby/embed.rb | 10 + .../spec/fixtures/ruby/file1.rb | 33 + .../spec/symbol-provider-tree-sitter-spec.js | 391 +++ packages/symbols-view/.eslintrc.js | 42 + 45 files changed, 6963 insertions(+) create mode 100644 packages/symbol-provider-ctags/.eslintrc.js create mode 100644 packages/symbol-provider-ctags/LICENSE.md create mode 100644 packages/symbol-provider-ctags/README.md create mode 100644 packages/symbol-provider-ctags/lib/ctags-config create mode 100644 packages/symbol-provider-ctags/lib/ctags-provider.js create mode 100644 packages/symbol-provider-ctags/lib/get-tags-file.js create mode 100644 packages/symbol-provider-ctags/lib/load-tags-handler.js create mode 100644 packages/symbol-provider-ctags/lib/main.js create mode 100644 packages/symbol-provider-ctags/lib/tag-reader.js create mode 100644 packages/symbol-provider-ctags/package-lock.json create mode 100644 packages/symbol-provider-ctags/package.json create mode 100644 packages/symbol-provider-ctags/spec/.eslintrc.js create mode 100644 packages/symbol-provider-ctags/spec/fixtures/c/sample.c create mode 100644 packages/symbol-provider-ctags/spec/fixtures/c/tags create mode 100644 packages/symbol-provider-ctags/spec/fixtures/js/.eslintignore create mode 100644 packages/symbol-provider-ctags/spec/fixtures/js/no-symbols.js create mode 100644 packages/symbol-provider-ctags/spec/fixtures/js/other-file.js create mode 100644 packages/symbol-provider-ctags/spec/fixtures/js/sample.js create mode 100644 packages/symbol-provider-ctags/spec/fixtures/js/tagged.js create mode 100644 packages/symbol-provider-ctags/spec/fixtures/js/tags create mode 100644 packages/symbol-provider-ctags/spec/fixtures/ruby/file1.rb create mode 100644 packages/symbol-provider-ctags/spec/fixtures/ruby/tags create mode 100644 packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js create mode 100755 packages/symbol-provider-ctags/vendor/ctags-darwin create mode 100755 packages/symbol-provider-ctags/vendor/ctags-linux create mode 100644 packages/symbol-provider-ctags/vendor/ctags-win32.exe create mode 100644 packages/symbol-provider-tree-sitter/.eslintrc.js create mode 100644 packages/symbol-provider-tree-sitter/LICENSE.md create mode 100644 packages/symbol-provider-tree-sitter/README.md create mode 100644 packages/symbol-provider-tree-sitter/lib/capture-organizer.js create mode 100644 packages/symbol-provider-tree-sitter/lib/main.js create mode 100644 packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js create mode 100644 packages/symbol-provider-tree-sitter/package-lock.json create mode 100644 packages/symbol-provider-tree-sitter/package.json create mode 100644 packages/symbol-provider-tree-sitter/spec/.eslintrc.js create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/c/sample.c create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/js/.eslintignore create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/js/no-symbols.js create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/js/other-file.js create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/js/sample.js create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/js/tagged.js create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/ruby/embed.rb create mode 100644 packages/symbol-provider-tree-sitter/spec/fixtures/ruby/file1.rb create mode 100644 packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js create mode 100644 packages/symbols-view/.eslintrc.js diff --git a/packages/symbol-provider-ctags/.eslintrc.js b/packages/symbol-provider-ctags/.eslintrc.js new file mode 100644 index 000000000..00404ea92 --- /dev/null +++ b/packages/symbol-provider-ctags/.eslintrc.js @@ -0,0 +1,42 @@ +module.exports = { + env: { + browser: true, + commonjs: true, + es2021: true, + }, + extends: [ + "eslint:recommended", + "plugin:node/recommended", + ], + overrides: [], + parserOptions: { + ecmaVersion: "latest" + }, + rules: { + "no-fallthrough": "off", + "no-case-declarations": "off", + "space-before-function-paren": ["error", { + anonymous: "always", + asyncArrow: "always", + named: "never" + }], + "node/no-unpublished-require": [ + "error", + { + allowModules: ["electron"] + } + ], + "node/no-missing-require": [ + "error", + { + allowModules: ["atom"] + } + ] + }, + plugins: [ + "jsdoc" + ], + globals: { + atom: "writeable" + } +}; diff --git a/packages/symbol-provider-ctags/LICENSE.md b/packages/symbol-provider-ctags/LICENSE.md new file mode 100644 index 000000000..fd1a7ace7 --- /dev/null +++ b/packages/symbol-provider-ctags/LICENSE.md @@ -0,0 +1,21 @@ +Copyright (c) 2023 Pulsar-Edit +Original work copyright (c) 2011-2022 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/symbol-provider-ctags/README.md b/packages/symbol-provider-ctags/README.md new file mode 100644 index 000000000..478db1c10 --- /dev/null +++ b/packages/symbol-provider-ctags/README.md @@ -0,0 +1,24 @@ +# symbol-provider-ctags package + +Provides symbols to `symbols-view` via `ctags`. + +This is the approach historically used by `symbols-view` — now spun out into its own “provider” package among several. + +This symbol provider will typically be used on non-Tree-sitter grammars, and possibly when performing a project-wide search. Symbol-based navigation on files with Tree-sitter grammars will typically be provided by `symbol-provider-tree-sitter`. + +## Language support + +This provider supports any language that is present in its config file, and detects any symbols that match the specified patterns. If your language isn’t supported and you can help add support, we’ll happily accept a pull request. + +## Toggle file symbols + +For the **Symbols View: Toggle File Symbols** command, `ctags` will scan the file on disk and emit its tag information to stdout, where it is read by this package. You don’t need a `TAGS` file to do a symbol search within a single file. + +## Toggle Project Symbols, Go To Declaration + +These commands require a tags file, typically defined at `.tags`/`tags`/`.TAGS`/`TAGS` in the root of your project. This package cannot generate (or regenerate) your tags file, since it doesn’t know which files to include. You can run `ctags` regularly on your own to generate this file. Consult [the documentation for Exuberant Ctags](https://ctags.sourceforge.net/ctags.html) for more information. + +Once your tags file is present, these commands can be fulfilled by `symbol-provider-ctags`… + +* The **Symbols View: Toggle Project Symbols** command works like **Symbols View: Toggle File Symbols** described above, except it’ll show you symbols from the entire project. +* The **Symbols View: Go To Declaration** command works like **Symbols View: Toggle Project Symbols**, except the word under the cursor will be pre-filled in the search box, and a result will automatically be opened if it is the only result. diff --git a/packages/symbol-provider-ctags/lib/ctags-config b/packages/symbol-provider-ctags/lib/ctags-config new file mode 100644 index 000000000..a9a9d8d8f --- /dev/null +++ b/packages/symbol-provider-ctags/lib/ctags-config @@ -0,0 +1,222 @@ +--langdef=CoffeeScript +--langmap=CoffeeScript:.coffee +--regex-CoffeeScript=/^[ \t]*(@?[a-zA-Z$_\.0-9]+)[ \t]*(=|\:)[ \t]*(\(.*\))?[ \t]*(-|=)>/\1/f,function/ +--regex-CoffeeScript=/^[ \t]*([a-zA-Z$_0-9]+\:\:[a-zA-Z$_\.0-9]+)[ \t]*(=|\:)[ \t]*(\(.*\))?[ \t]*(-|=)>/\1/f,function/ +--regex-CoffeeScript=/^[ \t]*describe[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-CoffeeScript=/^[ \t]*describe[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-CoffeeScript=/^[ \t]*it[ \t]"([^"]+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-CoffeeScript=/^[ \t]*it[ \t]'([^']+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-CoffeeScript=/^[ \t]*f+describe[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/focused\: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*f+describe[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/focused: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*f+it[ \t]"([^"]+)"[ \t]*,[ \t]+[-=]>/focused: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*f+it[ \t]'([^']+)'[ \t]*,[ \t]+[-=]>/focused: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*xdescribe[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/disabled\: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*xdescribe[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/disabled: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*xit[ \t]"([^"]+)"[ \t]*,[ \t]+[-=]>/disabled: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*xit[ \t]'([^']+)'[ \t]*,[ \t]+[-=]>/disabled: \1/f,function/ +--regex-CoffeeScript=/^[ \t]*class[ \t]*([a-zA-Z$_\.0-9]+)[ \t]*/\1/f,function/ + +--langdef=ColdFusion +--langmap=ColdFusion:.cfc +--langmap=ColdFusion:+.cfm +--langmap=ColdFusion:+.cfml +--regex-ColdFusion=/(,|(;|^)[ \t]*(var|([A-Za-z_$][A-Za-z0-9_$.]*\.)*))[ \t]*([A-Za-z0-9_$]+)[ \t]*=[ \t]*function[ \t]*\(/\5/,function/ +--regex-ColdFusion=/function[ \t]+([A-Za-z0-9_$]+)[ \t]*\([^)]*\)/\1/,function/ +--regex-ColdFusion=/cffunction[ \t]+([A-Za-z0-9_$]+)[ \t]*\([^)]*\)/\1/,cffunction/ +--regex-ColdFusion=/(,|^|\*\/)[ \t]*([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*:[ \t]*function[ \t]*\(/\2/,function/ +--regex-ColdFusion=/(,|^|\*\/)[ \t]*(static[ \t]+)?(while|if|for|function|switch|with|([A-Za-z_$][A-Za-z0-9_$]+))[ \t]*\(.*\)[ \t]*\{/\2\4/,function/ +--regex-ColdFusion=/(,|^|\*\/)[ \t]*get[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*\)[ \t]*\{/get \2/,function/ +--regex-ColdFusion=/(,|^|\*\/)[ \t]*set[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*([A-Za-z_$][A-Za-z0-9_$]+)?[ \t]*\)[ \t]*\{/set \2/,function/ +--regex-ColdFusion=/(,|^|\*\/)[ \t]*async[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*([A-Za-z_$].+)?[ \t]*\)[ \t]*\{/\2/,function/ +--regex-ColdFusion=/component[ \t]+([A-Za-z0-9._$]+)[ \t]*/\1/c,component/ +--regex-ColdFusion=/^[ \t]*given[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*given[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*story[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*story[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*feature[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*feature[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*when[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*when[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*then[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*then[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*describe[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*describe[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*it[ \t]"([^"]+)"[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*it[ \t]'([^']+)'[ \t]*,[ \t]+[-=]>/\1/f,function/ +--regex-ColdFusion=/^[ \t]*xdescribe[ \t]"(.+)"[ \t]*,[ \t]+[-=]>/disabled\: \1/f,function/ +--regex-ColdFusion=/^[ \t]*xdescribe[ \t]'(.+)'[ \t]*,[ \t]+[-=]>/disabled: \1/f,function/ +--regex-ColdFusion=/^[ \t]*xit[ \t]"([^"]+)"[ \t]*,[ \t]+[-=]>/disabled: \1/f,function/ +--regex-ColdFusion=/^[ \t]*xit[ \t]'([^']+)'[ \t]*,[ \t]+[-=]>/disabled: \1/f,function/ + +--langdef=Css +--langmap=Css:.css +--langmap=Css:+.less +--langmap=Css:+.scss +--regex-Css=/^[ \t]*(.+)[ \t]*\{/\1/f,function/ +--regex-Css=/^[ \t]*(.+)[ \t]*,[ \t]*$/\1/f,function/ +--regex-Css=/^[ \t]*[@$]([a-zA-Z$_][-a-zA-Z$_0-9]*)[ \t]*:/\1/f,function/ + +--langdef=Sass +--langmap=Sass:.sass +--regex-Sass=/^[ \t]*([#.]*[a-zA-Z_0-9]+)[ \t]*$/\1/f,function/ + +--langdef=Yaml +--langmap=Yaml:.yaml +--langmap=Yaml:+.yml +--regex-Yaml=/^[ \t]*([a-zA-Z_0-9 ]+)[ \t]*\:[ \t]*/\1/f,function/ + +--regex-Html=/^[ \t]*<([a-zA-Z]+)[ \t]*.*>/\1/f,function/ + +--langdef=Markdown +--langmap=Markdown:.md +--langmap=Markdown:+.markdown +--langmap=Markdown:+.mdown +--langmap=Markdown:+.mkd +--langmap=Markdown:+.mkdown +--langmap=Markdown:+.ron +--regex-Markdown=/^#+[ \t]*([^#]+)/\1/f,function/ + +--langdef=Json +--langmap=Json:.json +--regex-Json=/^[ \t]*"([^"]+)"[ \t]*\:/\1/f,function/ + +--langdef=Cson +--langmap=Cson:.cson +--langmap=Cson:+.gyp +--regex-Cson=/^[ \t]*'([^']+)'[ \t]*\:/\1/f,function/ +--regex-Cson=/^[ \t]*"([^"]+)"[ \t]*\:/\1/f,function/ +--regex-Cson=/^[ \t]*([^'"]+)[ \t]*\:/\1/f,function/ + +--langmap=C++:+.mm + +--langmap=Ruby:+(Rakefile) + +--langmap=Php:+.module + +--langdef=Go +--langmap=Go:.go +--regex-Go=/func([ \t]+\([^)]+\))?[ \t]+([a-zA-Z0-9_]+)/\2/f,func/ +--regex-Go=/var[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)/\1/v,var/ +--regex-Go=/type[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)/\1/t,type/ + +--langdef=Capnp +--langmap=Capnp:.capnp +--regex-Capnp=/struct[ \t]+([A-Za-z]+)/\1/s,struct/ +--regex-Capnp=/enum[ \t]+([A-Za-z]+)/\1/e,enum/ +--regex-Capnp=/using[ \t]+([A-Za-z]+)[ \t]+=[ \t]+import/\1/u,using/ +--regex-Capnp=/const[ \t]+([A-Za-z]+)/\1/c,const/ + +--langmap=perl:+.pod +--regex-perl=/with[ \t]+([^;]+)[ \t]*?;/\1/w,role,roles/ +--regex-perl=/extends[ \t]+['"]([^'"]+)['"][ \t]*?;/\1/e,extends/ +--regex-perl=/use[ \t]+base[ \t]+['"]([^'"]+)['"][ \t]*?;/\1/e,extends/ +--regex-perl=/use[ \t]+parent[ \t]+['"]([^'"]+)['"][ \t]*?;/\1/e,extends/ +--regex-perl=/Mojo::Base[ \t]+['"]([^'"]+)['"][ \t]*?;/\1/e,extends/ +--regex-perl=/^[ \t]*?use[ \t]+([^;]+)[ \t]*?;/\1/u,use,uses/ +--regex-perl=/^[ \t]*?require[ \t]+((\w|\:)+)/\1/r,require,requires/ +--regex-perl=/^[ \t]*?has[ \t]+['"]?(\w+)['"]?/\1/a,attribute,attributes/ +--regex-perl=/^[ \t]*?\*(\w+)[ \t]*?=/\1/a,alias,aliases/ +--regex-perl=/->helper\([ \t]?['"]?(\w+)['"]?/\1/h,helper,helpers/ +--regex-perl=/^[ \t]*?our[ \t]*?[\$@%](\w+)/\1/o,our,ours/ +--regex-perl=/^\=head1[ \t]+(.+)/\1/p,pod,Plain Old Documentation/ +--regex-perl=/^\=head2[ \t]+(.+)/-- \1/p,pod,Plain Old Documentation/ +--regex-perl=/^\=head[3-5][ \t]+(.+)/---- \1/p,pod,Plain Old Documentation/ + +--regex-JavaScript=/(,|(;|^)[ \t]*(var|let|([A-Za-z_$][A-Za-z0-9_$.]*\.)*))[ \t]*([A-Za-z0-9_$]+)[ \t]*=[ \t]*function[ \t]*\(/\5/,function/ +--regex-JavaScript=/function[ \t]+([A-Za-z0-9_$]+)[ \t]*\([^)]*\)/\1/,function/ +--regex-JavaScript=/(,|^|\*\/)[ \t]*([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*:[ \t]*function[ \t]*\(/\2/,function/ +--regex-JavaScript=/(,|^|\*\/)[ \t]*(static[ \t]+)?(while|if|for|function|switch|with|([A-Za-z_$][A-Za-z0-9_$]+))[ \t]*\(.*\)[ \t]*\{/\2\4/,function/ +--regex-JavaScript=/(,|^|\*\/)[ \t]*get[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*\)[ \t]*\{/get \2/,function/ +--regex-JavaScript=/(,|^|\*\/)[ \t]*set[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*([A-Za-z_$][A-Za-z0-9_$]+)?[ \t]*\)[ \t]*\{/set \2/,function/ +--regex-JavaScript=/(,|^|\*\/)[ \t]*async[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*([A-Za-z_$].+)?[ \t]*\)[ \t]*\{/\2/,function/ +--regex-JavaScript=/class[ \t]+([A-Za-z0-9._$]+)[ \t]*/\1/c,class/ +--regex-JavaScript=/^[ \t]*describe\("([^"]+)"[ \t]*,/\1/f,function/ +--regex-JavaScript=/^[ \t]*describe\('([^']+)'[ \t]*,/\1/f,function/ +--regex-JavaScript=/^[ \t]*it\("([^"]+)"[ \t]*,/\1/f,function/ +--regex-JavaScript=/^[ \t]*it\('([^']+)'[ \t]*,/\1/f,function/ +--regex-JavaScript=/^[ \t]*f+describe\('([^']+)'[ \t]*,/focused: \1/f,function/ +--regex-JavaScript=/^[ \t]*f+describe\("([^"]+)"[ \t]*,/focused: \1/f,function/ +--regex-JavaScript=/^[ \t]*f+it\('([^']+)'[ \t]*,/focused: \1/f,function/ +--regex-JavaScript=/^[ \t]*f+it\("([^"]+)"[ \t]*,/focused: \1/f,function/ +--regex-JavaScript=/^[ \t]*xdescribe\('([^']+)'[ \t]*,/disabled: \1/f,function/ +--regex-JavaScript=/^[ \t]*xdescribe\("([^"]+)"[ \t]*,/disabled: \1/f,function/ +--regex-JavaScript=/^[ \t]*xit\('([^']+)'[ \t]*,/disabled: \1/f,function/ +--regex-JavaScript=/^[ \t]*xit\("([^"]+)"[ \t]*,/disabled: \1/f,function/ + +--langdef=TypeScript +--langmap=TypeScript:.ts +--langmap=TypeScript:+.tsx +--regex-TypeScript=/(,|(;|^)[ \t]*(var|let|([A-Za-z_$][A-Za-z0-9_$.]*\.)*))[ \t]*([A-Za-z0-9_$]+)[ \t]*=[ \t]*function[ \t]*\(/\5/,function/ +--regex-TypeScript=/function[ \t]+([A-Za-z0-9_$]+)[ \t]*\([^)]*\)/\1/,function/ +--regex-TypeScript=/(,|^|\*\/)[ \t]*([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*:[ \t]*function[ \t]*\(/\2/,function/ +--regex-TypeScript=/(,|^|\*\/)[ \t]*(static[ \t]+)?(while|if|for|function|switch|with|([A-Za-z_$][A-Za-z0-9_$]+))[ \t]*\(.*\)[ \t]*\{/\2\4/,function/ +--regex-TypeScript=/(,|^|\*\/)[ \t]*get[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*\)[ \t]*\{/get \2/,function/ +--regex-TypeScript=/(,|^|\*\/)[ \t]*set[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*([A-Za-z_$][A-Za-z0-9_$]+)?[ \t]*\)[ \t]*\{/set \2/,function/ +--regex-TypeScript=/(,|^|\*\/)[ \t]*async[ \t]+([A-Za-z_$][A-Za-z0-9_$]+)[ \t]*\([ \t]*([A-Za-z_$].+)?[ \t]*\)[ \t]*\{/\2/,function/ +--regex-TypeScript=/class[ \t]+([A-Za-z0-9._$]+)[ \t]*/\1/c,class/ +--regex-TypeScript=/^[ \t]*describe\("([^"]+)"[ \t]*,/\1/f,function/ +--regex-TypeScript=/^[ \t]*describe\('([^']+)'[ \t]*,/\1/f,function/ +--regex-TypeScript=/^[ \t]*it\("([^"]+)"[ \t]*,/\1/f,function/ +--regex-TypeScript=/^[ \t]*it\('([^']+)'[ \t]*,/\1/f,function/ +--regex-TypeScript=/^[ \t]*f+describe\('([^']+)'[ \t]*,/focused: \1/f,function/ +--regex-TypeScript=/^[ \t]*f+describe\("([^"]+)"[ \t]*,/focused: \1/f,function/ +--regex-TypeScript=/^[ \t]*f+it\('([^']+)'[ \t]*,/focused: \1/f,function/ +--regex-TypeScript=/^[ \t]*f+it\("([^"]+)"[ \t]*,/focused: \1/f,function/ +--regex-TypeScript=/^[ \t]*xdescribe\('([^']+)'[ \t]*,/disabled: \1/f,function/ +--regex-TypeScript=/^[ \t]*xdescribe\("([^"]+)"[ \t]*,/disabled: \1/f,function/ +--regex-TypeScript=/^[ \t]*xit\('([^']+)'[ \t]*,/disabled: \1/f,function/ +--regex-TypeScript=/^[ \t]*xit\("([^"]+)"[ \t]*,/disabled: \1/f,function/ + +--langdef=haxe +--langmap=haxe:.hx +--regex-haxe=/^package[ \t]+([A-Za-z0-9_.]+)/\1/p,package/ +--regex-haxe=/^[ \t]*[(@:macro|private|public|static|override|inline|dynamic)( \t)]*function[ \t]+([A-Za-z0-9_]+)/\1/f,function/ +--regex-haxe=/^[ \t]*([private|public|static|protected|inline][ \t]*)+var[ \t]+([A-Za-z0-9_]+)/\2/v,variable/ +--regex-haxe=/^[ \t]*package[ \t]*([A-Za-z0-9_]+)/\1/p,package/ +--regex-haxe=/^[ \t]*(extern[ \t]*|@:native\([^)]*\)[ \t]*)*class[ \t]+([A-Za-z0-9_]+)[ \t]*[^\{]*/\2/c,class/ +--regex-haxe=/^[ \t]*(extern[ \t]+)?interface[ \t]+([A-Za-z0-9_]+)/\2/i,interface/ +--regex-haxe=/^[ \t]*typedef[ \t]+([A-Za-z0-9_]+)/\1/t,typedef/ +--regex-haxe=/^[ \t]*enum[ \t]+([A-Za-z0-9_]+)/\1/t,typedef/ +--regex-haxe=/^[ \t]*+([A-Za-z0-9_]+)(;|\([^)]*:[^)]*\))/\1/t,enum_field/ + +--langdef=Elixir +--langmap=Elixir:.ex.exs +--regex-Elixir=/^[ \t]*def(p?)[ \t]+([a-z_][a-zA-Z0-9_?!]*)/\2/f,functions,functions (def ...)/ +--regex-Elixir=/^[ \t]*defcallback[ \t]+([a-z_][a-zA-Z0-9_?!]*)/\1/c,callbacks,callbacks (defcallback ...)/ +--regex-Elixir=/^[ \t]*defdelegate[ \t]+([a-z_][a-zA-Z0-9_?!]*)/\1/d,delegates,delegates (defdelegate ...)/ +--regex-Elixir=/^[ \t]*defexception[ \t]+([A-Z][a-zA-Z0-9_]*\.)*([A-Z][a-zA-Z0-9_?!]*)/\2/e,exceptions,exceptions (defexception ...)/ +--regex-Elixir=/^[ \t]*defimpl[ \t]+([A-Z][a-zA-Z0-9_]*\.)*([A-Z][a-zA-Z0-9_?!]*)/\2/i,implementations,implementations (defimpl ...)/ +--regex-Elixir=/^[ \t]*defmacro(p?)[ \t]+([a-z_][a-zA-Z0-9_?!]*)\(/\2/a,macros,macros (defmacro ...)/ +--regex-Elixir=/^[ \t]*defmacro(p?)[ \t]+([a-zA-Z0-9_?!]+)?[ \t]+([^ \tA-Za-z0-9_]+)[ \t]*[a-zA-Z0-9_!?!]/\3/o,operators,operators (e.g. "defmacro a <<< b")/ +--regex-Elixir=/^[ \t]*defmodule[ \t]+([A-Z][a-zA-Z0-9_]*\.)*([A-Z][a-zA-Z0-9_?!]*)/\2/m,modules,modules (defmodule ...)/ +--regex-Elixir=/^[ \t]*defprotocol[ \t]+([A-Z][a-zA-Z0-9_]*\.)*([A-Z][a-zA-Z0-9_?!]*)/\2/p,protocols,protocols (defprotocol...)/ +--regex-Elixir=/^[ \t]*Record\.defrecord[ \t]+:([a-zA-Z0-9_]+)/\1/r,records,records (defrecord...)/ + +--langdef=Nim +--langmap=Nim:.nim +--regex-Nim=/^[\t\s]*proc\s+([_A-Za-z0-9]+)\**(\[\w+(\:\s+\w+)?\])?\s*\(/\1/f,function/ +--regex-Nim=/^[\t\s]*iterator\s+([_A-Za-z0-9]+)\**(\[\w+(\:\s+\w+)?\])?\s*\(/\1/i,iterator/ +--regex-Nim=/^[\t\s]*macro\s+([_A-Za-z0-9]+)\**(\[\w+(\:\s+\w+)?\])?\s*\(/\1/m,macro/ +--regex-Nim=/^[\t\s]*method\s+([_A-Za-z0-9]+)\**(\[\w+(\:\s+\w+)?\])?\s*\(/\1/h,method/ +--regex-Nim=/^[\t\s]*template\s+([_A-Za-z0-9]+)\**(\[\w+(\:\s+\w+)?\])?\s*\(/\1/t,generics/ +--regex-Nim=/^[\t\s]*converter\s+([_A-Za-z0-9]+)\**(\[\w+(\:\s+\w+)?\])?\s*\(/\1/c,converter/ + +--langdef=Fountain +--langmap=Fountain:.fountain +--langmap=Fountain:+.ftn +--regex-Fountain=/^(([iI][nN][tT]|[eE][xX][tT]|[^\w][eE][sS][tT]|\.|[iI]\.?\/[eE]\.?)([^\n]+))/\1/f,function/ + +--langdef=Julia +--langmap=Julia:.jl +--regex-Julia=/^[ \t]*(function|macro|abstract|type|typealias|immutable)[ \t]+([^ \t({[]+).*$/\2/f,function/ +--regex-Julia=/^[ \t]*(([^@#$ \t({[]+)|\(([^@#$ \t({[]+)\)|\((\$)\))[ \t]*(\{.*\})?[ \t]*\([^#]*\)[ \t]*=([^=].*$|$)/\2\3\4/f,function/ + +--langdef=Latex +--langmap=latex:.tex +--regex-latex=/\\label\{([^}]*)\}/\1/l,label/ +--regex-latex=/\\section\{([^}]*)\}/\1/s,section/ +--regex-latex=/\\subsection\{([^}]*)\}/\1/t,subsection/ +--regex-latex=/\\subsubsection\{([^}]*)\}/\1/u,subsubsection/ +--regex-latex=/\\section\*\{([^}]*)\}/\1/s,section/ +--regex-latex=/\\subsection\*\{([^}]*)\}/\1/t,subsection/ +--regex-latex=/\\subsubsection\*\{([^}]*)\}/\1/u,subsubsection/ diff --git a/packages/symbol-provider-ctags/lib/ctags-provider.js b/packages/symbol-provider-ctags/lib/ctags-provider.js new file mode 100644 index 000000000..ea8ad638f --- /dev/null +++ b/packages/symbol-provider-ctags/lib/ctags-provider.js @@ -0,0 +1,284 @@ +const { + BufferedProcess, + CompositeDisposable, + File, + Point +} = require('atom'); + +const TagReader = require('./tag-reader'); +const getTagsFile = require('./get-tags-file'); +const fs = require('fs-plus'); +const path = require('path'); + +class CtagsProvider { + constructor() { + this.watchTagsFiles(); + this.loadSymbols(); + this.packageName = 'symbol-provider-ctags'; + this.name = 'ctags'; + this.isExclusive = true; + } + + destroy() { + this.loadTask?.terminate?.(); + this.unwatchTagsFiles(); + } + + canProvideSymbols(meta) { + let { editor } = meta; + // Can't provide symbols unless a file is saved. + if (editor.getPath() === undefined) return 0; + + // We start off with a score less than 1 because `ctags` should always lose + // out when it's competing against the Tree-sitter provider. + let score = 0.99; + + // If the file isn't saved on disk, this provider's results may be + // inaccurate, so it's a less attractive candidate. + if (editor.isModified()) score -= 0.1; + + return score; + } + + getEditor() { + return atom.workspace.getActiveTextEditor(); + } + + getPath() { + if (this.getEditor()) { + return this.getEditor().getPath(); + } + return undefined; + } + + getScopeName() { + if (this.getEditor() && this.getEditor().getGrammar()) { + return this.getEditor().getGrammar().scopeName; + } + return undefined; + } + + getPackageRoot() { + const {resourcePath} = atom.getLoadSettings(); + const currentFileWasRequiredFromSnapshot = !fs.isAbsolute(__dirname); + const packageRoot = currentFileWasRequiredFromSnapshot + ? path.join(resourcePath, 'node_modules', 'symbols-view') + : path.resolve(__dirname, '..'); + + if (path.extname(resourcePath) === '.asar' && packageRoot.indexOf(resourcePath) === 0) { + return path.join(`${resourcePath}.unpacked`, 'node_modules', 'symbols-view'); + } else { + return packageRoot; + } + } + + parseTagLine(line) { + let sections = line.split('\t'); + if (sections.length > 3) { + return { + position: new Point(parseInt(sections[2], 10) - 1), + name: sections[0], + }; + } + return null; + } + + validateTags(tags) { + let symbols = []; + for (let tag of tags) { + let tagFilePath = path.join(tag.directory, tag.file); + if (!fs.existsSync(tagFilePath)) { + continue; + } + symbols.push(this.interpretTag(tag)); + } + return symbols; + } + + interpretTag(tag) { + return { + directory: tag.directory, + file: tag.file, + name: tag.name, + position: this.getTagPosition(tag) + }; + } + + getTagPosition(tag) { + if (!tag) { + return undefined; + } + + if (tag.lineNumber) { + return new Point(tag.lineNumber - 1, 0); + } + + // Remove leading /^ and trailing $/ + if (!tag.pattern) { + return undefined; + } + const pattern = tag.pattern.replace(/(^\/\^)|(\$\/$)/g, '').trim(); + + if (!pattern) { + return undefined; + } + const file = path.join(tag.directory, tag.file); + if (!fs.isFileSync(file)) { + return undefined; + } + const iterable = fs.readFileSync(file, 'utf8').split('\n'); + for (let index = 0; index < iterable.length; index++) { + let line = iterable[index]; + if (pattern === line.trim()) { + return new Point(index, 0); + } + } + + return undefined; + } + + watchTagsFiles() { + this.unwatchTagsFiles(); + this.tagsFileSubscriptions = new CompositeDisposable(); + let reloadTags = () => { + this.reloadTags = true; + this.watchTagsFiles(); + }; + + for (let projectPath of atom.project.getPaths()) { + let tagsFilePath = getTagsFile(projectPath); + if (!tagsFilePath) continue; + let tagsFile = new File(tagsFilePath); + + this.tagsFileSubscriptions.add( + tagsFile.onDidChange(reloadTags), + tagsFile.onDidDelete(reloadTags), + tagsFile.onDidRename(reloadTags) + ); + } + } + + unwatchTagsFiles() { + this.tagsFileSubscriptions?.dispose(); + } + + getLanguage(editor) { + if (['.cson', '.gyp'].includes(path.extname(this.path))) { + return 'Cson'; + } + + let scopeName = this.getScopeName(editor); + + switch (scopeName) { + case 'source.c': return 'C'; + case 'source.cpp': return 'C++'; + case 'source.clojure': return 'Lisp'; + case 'source.capnp': return 'Capnp'; + case 'source.cfscript': return 'ColdFusion'; + case 'source.cfscript.embedded': return 'ColdFusion'; + case 'source.coffee': return 'CoffeeScript'; + case 'source.css': return 'Css'; + case 'source.css.less': return 'Css'; + case 'source.css.scss': return 'Css'; + case 'source.elixir': return 'Elixir'; + case 'source.fountain': return 'Fountain'; + case 'source.gfm': return 'Markdown'; + case 'source.go': return 'Go'; + case 'source.java': return 'Java'; + case 'source.js': return 'JavaScript'; + case 'source.js.jsx': return 'JavaScript'; + case 'source.jsx': return 'JavaScript'; + case 'source.json': return 'Json'; + case 'source.julia': return 'Julia'; + case 'source.makefile': return 'Make'; + case 'source.objc': return 'C'; + case 'source.objcpp': return 'C++'; + case 'source.python': return 'Python'; + case 'source.ruby': return 'Ruby'; + case 'source.sass': return 'Sass'; + case 'source.ts': return 'TypeScript'; + case 'source.ts.tsx': return 'TypeScript'; + case 'source.yaml': return 'Yaml'; + case 'text.html': return 'Html'; + case 'text.html.php': return 'Php'; + case 'text.tex.latex': return 'Latex'; + case 'text.html.cfml': return 'ColdFusion'; + } + + // TODO: Fall back to a grammar registry lookup? + return undefined; + } + + + loadSymbols() { + return new Promise(resolve => { + this.loadTask = TagReader.getAllTags(resolve); + }); + } + + getSymbols(meta) { + if (meta.type === 'project') { + return this.getSymbolsInProject(meta); + } else if (meta.type === 'project-find') { + return this.findDefinitionsInProject(meta); + } + let { editor } = meta; + + let tags = {}; + let packageRoot = this.getPackageRoot(); + + let command = path.join(packageRoot, 'vendor', `ctags-${process.platform}`); + let defaultCtagsFile = path.join(packageRoot, 'lib', 'ctags-config'); + + const args = [ + `--options=${defaultCtagsFile}`, + `--fields=+KS` + ]; + + if (atom.config.get('symbol-provider-ctags.useEditorGrammarAsCtagsLanguage')) { + let language = this.getLanguage(editor); + if (language) { + args.push(`--language-force=${language}`); + } + } + + args.push('-nf', '-', editor.getPath()); + + return new Promise(resolve => { + let result, tag; + return new BufferedProcess({ + command, + args, + stdout: lines => { + result = []; + for (let line of lines.split('\n')) { + let item; + tag = this.parseTagLine(line); + if (tag) { + item = tags[tag.position.row] ? + tags[tag.position.row] : + (tags[tag.position.row] = tag); + } + result.push(item); + } + return result; + }, + stderr: () => {}, + exit: () => { + return resolve(Object.values(tags)); + } + }) + }); + } + + async getSymbolsInProject() { + return TagReader.getAllTags(); + } + + async findDefinitionsInProject(meta) { + let tags = await TagReader.find(meta.editor); + return this.validateTags(tags); + } +} + +module.exports = CtagsProvider; diff --git a/packages/symbol-provider-ctags/lib/get-tags-file.js b/packages/symbol-provider-ctags/lib/get-tags-file.js new file mode 100644 index 000000000..9a09e5c62 --- /dev/null +++ b/packages/symbol-provider-ctags/lib/get-tags-file.js @@ -0,0 +1,22 @@ +const fs = require('fs-plus'); +const path = require('path'); + +const FILES = [ + 'TAGS', + 'tags', + '.TAGS', + '.tags', + path.join('.git', 'tags'), + path.join('.git', 'TAGS') +]; + +function getTagsFile(directoryPath) { + if (!directoryPath) return; + + for (let file of FILES) { + let tagsFile = path.join(directoryPath, file); + if (fs.isFileSync(tagsFile)) return tagsFile; + } +} + +module.exports = getTagsFile; diff --git a/packages/symbol-provider-ctags/lib/load-tags-handler.js b/packages/symbol-provider-ctags/lib/load-tags-handler.js new file mode 100644 index 000000000..d7068cda0 --- /dev/null +++ b/packages/symbol-provider-ctags/lib/load-tags-handler.js @@ -0,0 +1,26 @@ +/* global emit */ + +const async = require('async'); +const ctags = require('ctags'); +const getTagsFile = require('./get-tags-file'); + +module.exports = function loadTags(directoryPaths) { + // TODO: I tried to remove the dependency on the `async` package but failed + // spectacularly. I should try again at some point. + return async.each( + directoryPaths, + (directoryPath, done) => { + let tagsFilePath = getTagsFile(directoryPath); + if (!tagsFilePath) { return done(); } + + let stream = ctags.createReadStream(tagsFilePath); + stream.on('data', function(tags) { + for (const tag of Array.from(tags)) { tag.directory = directoryPath; } + return emit('tags', tags); + }); + stream.on('end', done); + return stream.on('error', done); + } + , this.async() + ); +}; diff --git a/packages/symbol-provider-ctags/lib/main.js b/packages/symbol-provider-ctags/lib/main.js new file mode 100644 index 000000000..69c7a9745 --- /dev/null +++ b/packages/symbol-provider-ctags/lib/main.js @@ -0,0 +1,16 @@ + +const CtagsProvider = require('./ctags-provider'); + +module.exports = { + activate() { + this.provider = new CtagsProvider(); + }, + + deactivate() { + this.provider?.destroy?.(); + }, + + provideSymbols() { + return this.provider; + } +}; diff --git a/packages/symbol-provider-ctags/lib/tag-reader.js b/packages/symbol-provider-ctags/lib/tag-reader.js new file mode 100644 index 000000000..51d199572 --- /dev/null +++ b/packages/symbol-provider-ctags/lib/tag-reader.js @@ -0,0 +1,131 @@ +const { Point, Task } = require('atom'); +const util = require('util'); +const ctags = require('ctags'); +const getTagsFile = require('./get-tags-file'); +const _ = require('underscore-plus'); + +let handlerPath = require.resolve('./load-tags-handler'); + +let findTagsWithPromise = util.promisify(ctags.findTags).bind(ctags); + +function wordAtCursor(text, cursorIndex, wordSeparator, noStripBefore) { + const beforeCursor = text.slice(0, cursorIndex); + const afterCursor = text.slice(cursorIndex); + + const beforeCursorWordBegins = noStripBefore ? 0 : + beforeCursor.lastIndexOf(wordSeparator) + 1; + let afterCursorWordEnds = afterCursor.indexOf(wordSeparator); + if (afterCursorWordEnds === -1) { + afterCursorWordEnds = afterCursor.length; + } + + return beforeCursor.slice(beforeCursorWordBegins) + + afterCursor.slice(0, afterCursorWordEnds); +} + +module.exports = { + async find(editor) { + let symbol = editor.getSelectedText(); + let symbols = []; + + if (symbol) symbols.push(symbol); + + if (!symbols.length) { + let nonWordCharacters; + let cursor = editor.getLastCursor(); + let cursorPosition = cursor.getBufferPosition(); + let scope = cursor.getScopeDescriptor(); + const rubyScopes = scope.getScopesArray().filter(s => /^source\.ruby($|\.)/.test(s)); + + let hasRubyScope = rubyScopes.length > 0; + + let wordRegExp = cursor.wordRegExp(); + if (hasRubyScope) { + nonWordCharacters = atom.config.get('editor.nonWordCharacters', { scope }); + nonWordCharacters = nonWordCharacters.replace(/:/g, ''); + wordRegExp = new RegExp( + `[^\\s${_.escapeRegExp(nonWordCharacters)}]+([!?]|\\s*=>?)?|[<=>]+`, + 'g' + ); + } + + let addSymbol = (symbol) => { + if (hasRubyScope) { + // Normalize assignment syntax + if (/\s+=?$/.test(symbol)) { + symbols.push(symbol.replace(/\s+=$/, '=')); + } + // Strip away assignment & hashrocket syntax + symbols.push(symbol.replace(/\s+=>?$/, '')); + } else { + symbols.push(symbol); + } + }; + + // Can't use `getCurrentWordBufferRange` here because we want to select + // the last match of the potential 2 matches under cursor. + editor.scanInBufferRange(wordRegExp, cursor.getCurrentLineBufferRange(), ({range, match}) => { + if (range.containsPoint(cursorPosition)) { + symbol = match[0]; + if (rubyScopes.length && symbol.indexOf(':') > -1) { + const cursorWithinSymbol = cursorPosition.column - range.start.column; + // Add fully-qualified ruby constant up until the cursor position + addSymbol(wordAtCursor(symbol, cursorWithinSymbol, ':', true)); + // Additionally, also look up the bare word under cursor + addSymbol(wordAtCursor(symbol, cursorWithinSymbol, ':')); + } else { + addSymbol(symbol); + } + } + }); + } + + if (symbols.length === 0) return []; + + let results = []; + for (let projectPath of atom.project.getPaths()) { + let tagsFile = getTagsFile(projectPath); + if (!tagsFile) continue; + + for (let symbol of symbols) { + let tags; + try { + tags = await findTagsWithPromise(tagsFile, symbol); + if (!tags) tags = []; + } catch (err) { + continue; + } + if (tags.length === 0) continue; + + for (let tag of [...tags]) { + tag.directory = projectPath; + } + + results.push(...tags); + } + } + return results; + }, + + getAllTags() { + let projectTags = []; + return new Promise(resolve => { + let task = Task.once( + handlerPath, + atom.project.getPaths(), + () => { + resolve(projectTags); + } + ); + + task.on('tags', tags => { + for (let tag of tags) { + if (tag.lineNumber) { + tag.position = new Point(tag.lineNumber - 1, 0); + } + } + projectTags.push(...tags); + }); + }); + }, +}; diff --git a/packages/symbol-provider-ctags/package-lock.json b/packages/symbol-provider-ctags/package-lock.json new file mode 100644 index 000000000..9833a905c --- /dev/null +++ b/packages/symbol-provider-ctags/package-lock.json @@ -0,0 +1,2248 @@ +{ + "name": "symbol-provider-ctags", + "version": "0.0.5", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "symbol-provider-ctags", + "version": "0.0.5", + "license": "MIT", + "dependencies": { + "async": "^0.2.6", + "ctags": "^3.1.0", + "fs-plus": "^3.1.1" + }, + "devDependencies": { + "eslint": "^8.39.0", + "temp": "^0.9.4" + }, + "engines": { + "atom": ">=1.0.0 <2.0.0", + "node": ">=14" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ctags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ctags/-/ctags-3.1.0.tgz", + "integrity": "sha512-7/aiGLj8Ih7Ko3bAAg8bQUwHjOGXKQ7XC+bv+vLh84BtkVodPEOpOnr65FnWjX2oFWoKSaDuxe7jFHudD2Q0uw==", + "hasInstallScript": true, + "dependencies": { + "event-stream": "~3.1.0", + "nan": "^2.14.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.1.7.tgz", + "integrity": "sha512-ddACn1VEffD+nvbofs8gs/0qJZC9gtEGLG+WykE//rinSpYLSaTsnN96eVQV+gHdUhV/nVtxUNKC3OjrApuEMw==", + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.2", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, + "node_modules/fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "dependencies": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + } + }, + "node_modules/fs-plus/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==" + }, + "node_modules/fs-plus/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/split": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/split/-/split-0.2.10.tgz", + "integrity": "sha512-e0pKq+UUH2Xq/sXbYpZBZc3BawsfDZ7dgv+JtRTUPNcvF5CMR4Y9cvJqkMY0MoxWzTHvZuz1beg6pNEKlszPiQ==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "node_modules/underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "dependencies": { + "underscore": "^1.9.1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "ctags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ctags/-/ctags-3.1.0.tgz", + "integrity": "sha512-7/aiGLj8Ih7Ko3bAAg8bQUwHjOGXKQ7XC+bv+vLh84BtkVodPEOpOnr65FnWjX2oFWoKSaDuxe7jFHudD2Q0uw==", + "requires": { + "event-stream": "~3.1.0", + "nan": "^2.14.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + } + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "event-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.1.7.tgz", + "integrity": "sha512-ddACn1VEffD+nvbofs8gs/0qJZC9gtEGLG+WykE//rinSpYLSaTsnN96eVQV+gHdUhV/nVtxUNKC3OjrApuEMw==", + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.2", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, + "fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "requires": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "requires": { + "through": "~2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "split": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/split/-/split-0.2.10.tgz", + "integrity": "sha512-e0pKq+UUH2Xq/sXbYpZBZc3BawsfDZ7dgv+JtRTUPNcvF5CMR4Y9cvJqkMY0MoxWzTHvZuz1beg6pNEKlszPiQ==", + "requires": { + "through": "2" + } + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "requires": { + "duplexer": "~0.1.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "requires": { + "underscore": "^1.9.1" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/packages/symbol-provider-ctags/package.json b/packages/symbol-provider-ctags/package.json new file mode 100644 index 000000000..16ab16de3 --- /dev/null +++ b/packages/symbol-provider-ctags/package.json @@ -0,0 +1,36 @@ +{ + "name": "symbol-provider-ctags", + "main": "./lib/main", + "version": "1.0.0", + "description": "Provides symbols to symbols-view via ctags", + "repository": "https://github.com/pulsar-edit/pulsar", + "license": "MIT", + "engines": { + "atom": ">=1.0.0 <2.0.0", + "node": ">=14" + }, + "providedServices": { + "symbol.provider": { + "description": "Allows external sources to suggest symbols for a given file or project.", + "versions": { + "1.0.0": "provideSymbols" + } + } + }, + "configSchema": { + "useEditorGrammarAsCtagsLanguage": { + "default": true, + "type": "boolean", + "description": "Force `ctags` to use the name of the current file's language in Pulsar when generating tags. By default, `ctags` automatically selects the language of a source file, ignoring those files whose language cannot be determined. This option forces the specified language to be used instead of automatically selecting the language based upon its extension." + } + }, + "dependencies": { + "async": "^0.2.6", + "fs-plus": "^3.1.1", + "ctags": "^3.1.0" + }, + "devDependencies": { + "eslint": "^8.39.0", + "temp": "^0.9.4" + } +} diff --git a/packages/symbol-provider-ctags/spec/.eslintrc.js b/packages/symbol-provider-ctags/spec/.eslintrc.js new file mode 100644 index 000000000..8ee8742b4 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/.eslintrc.js @@ -0,0 +1,13 @@ +module.exports = { + env: { jasmine: true }, + globals: { + waitsForPromise: true + }, + rules: { + "node/no-unpublished-require": "off", + "node/no-extraneous-require": "off", + "no-unused-vars": "off", + "no-empty": "off", + "no-constant-condition": "off" + } +}; diff --git a/packages/symbol-provider-ctags/spec/fixtures/c/sample.c b/packages/symbol-provider-ctags/spec/fixtures/c/sample.c new file mode 100644 index 000000000..5a98bf4c1 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/c/sample.c @@ -0,0 +1,6 @@ +#define UNUSED(x) (void)(x) + +static void f(int x) +{ + UNUSED(x); +} diff --git a/packages/symbol-provider-ctags/spec/fixtures/c/tags b/packages/symbol-provider-ctags/spec/fixtures/c/tags new file mode 100644 index 000000000..25d845e75 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/c/tags @@ -0,0 +1,8 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.9~svn20110310 // +UNUSED sample.c 1;" d file: +f sample.c /^static void f(int x)$/;" f file: diff --git a/packages/symbol-provider-ctags/spec/fixtures/js/.eslintignore b/packages/symbol-provider-ctags/spec/fixtures/js/.eslintignore new file mode 100644 index 000000000..c8078be87 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/js/.eslintignore @@ -0,0 +1,3 @@ +tagged.js +sample.js +other-file.js diff --git a/packages/symbol-provider-ctags/spec/fixtures/js/no-symbols.js b/packages/symbol-provider-ctags/spec/fixtures/js/no-symbols.js new file mode 100644 index 000000000..9a1aba6f7 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/js/no-symbols.js @@ -0,0 +1,6 @@ +// Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +// quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +// consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +// cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat +// non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/packages/symbol-provider-ctags/spec/fixtures/js/other-file.js b/packages/symbol-provider-ctags/spec/fixtures/js/other-file.js new file mode 100644 index 000000000..4e79b3a98 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/js/other-file.js @@ -0,0 +1,29 @@ +// Another file for symbols to exist in. Used for project search. + +var quicksort = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; + +var quicksort2 = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; diff --git a/packages/symbol-provider-ctags/spec/fixtures/js/sample.js b/packages/symbol-provider-ctags/spec/fixtures/js/sample.js new file mode 100644 index 000000000..15ab7c831 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/js/sample.js @@ -0,0 +1,13 @@ +var quicksort = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; diff --git a/packages/symbol-provider-ctags/spec/fixtures/js/tagged.js b/packages/symbol-provider-ctags/spec/fixtures/js/tagged.js new file mode 100644 index 000000000..4adaac609 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/js/tagged.js @@ -0,0 +1,11 @@ +var thisIsCrazy = true; + +function callMeMaybe() { + return "here's my number"; +} + +var iJustMetYou = callMeMaybe(); + +function duplicate() { + return true; +} diff --git a/packages/symbol-provider-ctags/spec/fixtures/js/tags b/packages/symbol-provider-ctags/spec/fixtures/js/tags new file mode 100644 index 000000000..eed641589 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/js/tags @@ -0,0 +1,10 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.8 // +callMeMaybe tagged.js /^function callMeMaybe() {$/;" f +duplicate tagged-duplicate.js /^function duplicate() {$/;" f +duplicate tagged.js /^function duplicate() {$/;" f +thisIsCrazy tagged.js /^var thisIsCrazy = true;$/;" v diff --git a/packages/symbol-provider-ctags/spec/fixtures/ruby/file1.rb b/packages/symbol-provider-ctags/spec/fixtures/ruby/file1.rb new file mode 100644 index 000000000..62697a7b3 --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/ruby/file1.rb @@ -0,0 +1,33 @@ +module A::Foo + B = 'b' + + def bar! + + end + + def bar? + + end + + def baz + end + + def baz=(*) + end +end + +if bar? + baz + bar! +elsif !bar! + baz= 1 + baz = 2 + Foo = 3 + { :baz => 4 } + A::Foo::B + C::Foo::B + D::Foo::E +end + +module D::Foo +end diff --git a/packages/symbol-provider-ctags/spec/fixtures/ruby/tags b/packages/symbol-provider-ctags/spec/fixtures/ruby/tags new file mode 100644 index 000000000..26cb7967a --- /dev/null +++ b/packages/symbol-provider-ctags/spec/fixtures/ruby/tags @@ -0,0 +1,15 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.8 // +A::Foo file1.rb /^module A::Foo$/;" m +A::Foo::B file1.rb /^ B = 'b'$/;" C +B file1.rb /^ B = 'b'$/;" C +D::Foo file1.rb /^module D::Foo$/;" m +Foo file1.rb /^module A::Foo$/;" m +bar! file1.rb /^ def bar!$/;" f class:Foo +bar? file1.rb /^ def bar?$/;" f class:Foo +baz file1.rb /^ def baz$/;" f class:Foo +baz= file1.rb /^ def baz=(*)$/;" f class:Foo diff --git a/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js b/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js new file mode 100644 index 000000000..4738a7ced --- /dev/null +++ b/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js @@ -0,0 +1,297 @@ + +const path = require('path'); +const fs = require('fs-plus'); +const temp = require('temp'); +const CTagsProvider = require('../lib/ctags-provider'); + +function getEditor() { + return atom.workspace.getActiveTextEditor(); +} + +async function wait(ms) { + return new Promise(r => setTimeout(r, ms)); +} + +async function getProjectSymbols(provider, editor) { + let symbols = await provider.getSymbols({ + type: 'project', + editor, + paths: atom.project.getPaths() + }); + return symbols; +} + +async function findDeclarationInProject(provider, editor) { + let symbols = await provider.getSymbols({ + type: 'project-find', + editor, + paths: atom.project.getPaths(), + word: editor.getWordUnderCursor() + }); + return symbols; +} + +describe('CTagsProvider', () => { + let provider, directory, editor; + + beforeEach(() => { + jasmine.unspy(global, 'setTimeout'); + jasmine.unspy(Date, 'now'); + + provider = new CTagsProvider(); + + atom.project.setPaths([ + temp.mkdirSync('other-dir-'), + temp.mkdirSync('atom-symbols-view-') + ]); + + directory = atom.project.getDirectories()[1]; + fs.copySync( + path.join(__dirname, 'fixtures', 'js'), + atom.project.getPaths()[1] + ); + }); + + describe('when tags can be generated for a file', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + }); + + it('provides all JavaScript functions', async () => { + let symbols = await provider.getSymbols({ + type: 'file', + editor + }); + + expect(symbols[0].name).toBe('quicksort'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('quicksort.sort'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + describe('when the buffer is new and unsaved', () => { + beforeEach(async () => { + await atom.workspace.open(); + editor = getEditor(); + }); + + it('does not try to provide symbols', () => { + let meta = { type: 'file', editor }; + expect(provider.canProvideSymbols(meta)).toBe(0); + }); + }); + + describe('when the buffer is modified', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + }); + + it('returns a lower match score', () => { + editor.insertText("\n"); + let meta = { type: 'file', editor }; + expect(provider.canProvideSymbols(meta)).toBe(0.9); + }); + }); + + describe('when no tags can be generated for a file', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('no-symbols.js')); + editor = getEditor(); + }); + + it('returns an empty array', async () => { + let symbols = await provider.getSymbols({ type: 'file', editor }); + expect(Array.isArray(symbols)).toBe(true); + expect(symbols.length).toBe(0); + }); + }); + + describe('go to declaration', () => { + it("returns nothing when no declaration is found", async () => { + await atom.workspace.open(directory.resolve('tagged.js')); + editor = getEditor(); + editor.setCursorBufferPosition([0, 2]); + + let symbols = await provider.getSymbols({ + type: 'project-find', + editor, + paths: atom.project.getPaths(), + word: editor.getWordUnderCursor() + }); + + expect(symbols.length).toBe(0); + }); + + it("returns one result when there is a single matching declaration", async () => { + await atom.workspace.open(directory.resolve('tagged.js')); + editor = getEditor(); + + editor.setCursorBufferPosition([6, 24]); + let symbols = await provider.getSymbols({ + type: 'project-find', + editor, + paths: atom.project.getPaths(), + word: editor.getWordUnderCursor() + }); + + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([2, 0]); + }); + + it("correctly identifies the tag for a C preprocessor macro", async () => { + atom.project.setPaths([temp.mkdirSync('atom-symbols-view-c-')]); + fs.copySync( + path.join(__dirname, 'fixtures', 'c'), + atom.project.getPaths()[0] + ); + + await atom.packages.activatePackage('language-c'); + await atom.workspace.open('sample.c'); + + editor = getEditor(); + editor.setCursorBufferPosition([4, 4]); + + let symbols = await findDeclarationInProject(provider, editor); + + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([0, 0]); + }); + + it('ignores results that reference nonexistent files', async () => { + await atom.workspace.open(directory.resolve('tagged.js')); + editor = getEditor(); + editor.setCursorBufferPosition([8, 14]); + + let symbols = await findDeclarationInProject(provider, editor); + + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([8, 0]); + }); + + it('includes ? and ! characters in ruby symbols', async () => { + atom.project.setPaths([temp.mkdirSync('atom-symbols-view-ruby-')]); + fs.copySync( + path.join(__dirname, 'fixtures', 'ruby'), + atom.project.getPaths()[0] + ); + + await atom.packages.activatePackage('language-ruby'); + await atom.workspace.open('file1.rb'); + let symbols; + + editor = getEditor(); + + editor.setCursorBufferPosition([18, 4]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([7, 0]); + + editor.setCursorBufferPosition([19, 2]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([11, 0]); + + editor.setCursorBufferPosition([20, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([3, 0]); + + editor.setCursorBufferPosition([21, 7]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([3, 0]); + }); + + it('understands assignment ruby method definitions', async () => { + atom.project.setPaths([temp.mkdirSync('atom-symbols-view-ruby-')]); + fs.copySync( + path.join(__dirname, 'fixtures', 'ruby'), + atom.project.getPaths()[0] + ); + + await atom.packages.activatePackage('language-ruby'); + await atom.workspace.open('file1.rb'); + let symbols; + + editor = getEditor(); + + editor.setCursorBufferPosition([22, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([14, 0]); + + editor.setCursorBufferPosition([23, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(2); + expect(symbols[0].position).toEqual([14, 0]); + + editor.setCursorBufferPosition([24, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([0, 0]); + + editor.setCursorBufferPosition([25, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([11, 0]); + }); + + it('understands fully qualified ruby constant definitions', async () => { + atom.project.setPaths([temp.mkdirSync('atom-symbols-view-ruby-')]); + fs.copySync( + path.join(__dirname, 'fixtures', 'ruby'), + atom.project.getPaths()[0] + ); + + await atom.packages.activatePackage('language-ruby'); + await atom.workspace.open('file1.rb'); + let symbols; + + editor = getEditor(); + + editor.setCursorBufferPosition([26, 10]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(2); + expect(symbols[0].position).toEqual([1, 0]); + + editor.setCursorBufferPosition([27, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(1); + expect(symbols[0].position).toEqual([0, 0]); + + editor.setCursorBufferPosition([28, 5]); + symbols = await findDeclarationInProject(provider, editor); + expect(symbols.length).toBe(2); + expect(symbols[0].position).toEqual([31, 0]); + }); + }); + + describe('project symbols', () => { + it('displays all tags', async () => { + await atom.workspace.open(directory.resolve('tagged.js')); + editor = getEditor(); + + let symbols = await getProjectSymbols(provider, editor); + + expect(symbols.length).toBe(4); + + expect(symbols[0].name).toBe('callMeMaybe'); + expect(symbols[0].directory).toBe(directory.getPath()); + expect(symbols[0].file).toBe('tagged.js'); + + expect(symbols[3].name).toBe('thisIsCrazy'); + expect(symbols[3].directory).toBe(directory.getPath()); + expect(symbols[3].file).toBe('tagged.js'); + + fs.removeSync(directory.resolve('tags')); + await wait(50); + + symbols = await getProjectSymbols(provider, editor); + expect(symbols.length).toBe(0); + }); + }); +}); diff --git a/packages/symbol-provider-ctags/vendor/ctags-darwin b/packages/symbol-provider-ctags/vendor/ctags-darwin new file mode 100755 index 0000000000000000000000000000000000000000..86576c957aa7f403f294aa2fec54e24fdb2ee277 GIT binary patch literal 212624 zcmeFad3;nw*7)6>q#-QfhE2c)g9Zf!Bx;n91k=)iZb=jcS3n#=M`u(Jx&>v6cDHc3 zwBk1E%sAsZ<2a5wt^pN-0TNspToDyqscXC727xI3eox)oNhhGr@A*7`y`Kl|+`6@# zI(6#QsZ*y;)qQQxmwP*UJl<@NrzXqe@#OQnql3p2_Y@HFc>3`R@|!w!ynk%vd6j3J zCb4b*dE373_f6moqJpVYCsv*_v27Mz{sO5z~*k`_coAoJT%7Hn;o8Y=@q|qvhM@$>240Z;8-Vvyl4Jv`zH8In{mbL zRsy!i&vTXo?-Cb3dC$oN*e*PEYUGMJmtHY_>ZMm)JcG3M@Gd#mfp@D*AbD?(Qzl5^ z6Q$t<{1g3CN1t};1czJT2i*k~Zf@T7KlfeGm7l~44^N%?+ZnB`l=uC^8%|#R4|wS& z%e$bP$?E&ktu4IaE`9|gG&GOA{}SD#ol9ttgO^iA|Gm3iJ9*dt3Y8qG`OyMU}0ypZLRe1 zM&1<-d#oYL)3=Air+taP4nEkzxuN2yvx6X_z4~(*DC*0fwGPd4Y=y| zGv7aU!m-2^@S}Q<$LOqo64tzvCd`OoxEoG?CQ?u;%Pmu(|#!^P? zMqn(>4w>)A>cS`bS4%eiGPhgMSXJk@0xS*#*sWa{1*4 ztu8?`SfGKp{gBbEODLV$tp(Dx4SJ@PF4ffD`K!IT%bGeUXzo%aKSGo(Ml1$3<8?;7 zhNt>wr}W+WDyTk?bhAEWb%-{14xbcl&I^x>HmAbVgNdLwRC;P|q)Qc0LQ=r$5VB6q zUvjWFz9qcYeG4YWdqd^{>jPe|C;4bFUKf4{7?EKD`o(6iC)(6GJV5wkuR4V8N%khk zD9C6Zk6u7_BUV5FU~TK${6kB9>vOywL7{rL*JHme*dOO&Zw);4^fYrxedkf1Ss!g$ zG$$`Ot=?r2mF%jy!`!O2?a}=42JJIq{{WK1m-|#cxwUequ|4jUKYZV&jUj7PFx8-zvI@|{>MA{GZ>3F|?}P*fi0z;GGQ~m=2tUI=4Hbh# z9m`;&bw8z2?S(?n8e8D7Wl>!)x~RZo+*;?nH;hHE^LScb1eo)px!>v-ZORT0i#BD2 zE2B-`$i$#EuOJvtg?(yw9HbJnVg1pxYjocr{V}gOl}Zk2&GV+@v1Y^JTh&nTN;{gqP$Wb>3HGly(>1uNuD)Lzf2*|Hb&GK9vG_F`f_z5?>;bP;m#_x

vu5GAn1d^x9 z8rqd=l0Aaff{irb#^qU_qD^)&nf%7n2N%Y+%!k`X0IE1f2kFObH6psJg6g?{6du3#N5-=}nq@ZzI zoj-RSO)9C*@)+?iS(z-&E<4q(gma6luZ4^h3MNiRNKP!wHEw-@ndhO{CI{$& zF3^w_D9m4|tk$Kei4x_lrx@cpS`I)+r;t04tIj zGk83&@o?$>H;RBIc)TZafA-g2cq@5gu;eY79#iTlB0`oSJal%Ng_txthOE?sKlzQSTU2Vu3tC@_k5VR^c z2BRZ9k*Z&B)PF=uIE@k!X-(OPUZjqNApYlMPzIx=9wYXEFsYdeCL%AZ^C5h6!ONcT zAh#gfR#%0rLxZRYMS>S%sLptLgu0H(qD_Iw!NF*AR`?YD z`obgmn-l2_&UH0&vxbF_uZ-;sk8mJT8=RtRiwtxt*p6mR820 z)uZG^tDW0BVD1iDy>AOuH&qSz2zL2srXPV(TndYWD{aLGR~Ol^R43h@4|le z%?I$RsPkLZ_euJ$&L2&sWF9a(g!4nw8ki=Bl#3u;laut-ruf&cLEtnToRr58T;^Z1 zWk#k65|f~xT-879$c+1sxHh{%*Zth8XnDy#UBF=_qOeks@Ebf+U7 z50YwMgF?uZxgu({;6cgpT|*fW{eb~H(qjKek+53mzR7~d(OQ8%o}Bipf>v4%-TS%l zgW+E)lb4o6{u&XI`;$eX)LQD*ll(yd%NA6vz+VuUw0%IMQ%ka6x;O8G^er{NRhcFA zq-9i1^Hd`?2lC3$o59moz-Ym$>;DX^Zkgza7VogtfsU-rs5^WcM7+sfBvVy%Z3p`T zjMy}7eqlDk+*l%m2vDn_sIs5o#hFVtAv~qGUS;U{byO%3DC`D=PF3cI(tqa1A@dat zXt&G?(mC%3_UW9Zz^O`1^M(@DGAVBWK+{S(+tqnQ%U7R)v(#0B0M%pKVS)pg+tiCX ztsN6Y_O0hI5%&8s!8mfZWrDlZ|CkB(j{apP_zNPfg$e#c=3iujkD+x76LkEaVf8ai z&>KYB*6lLEHBguy=x9%ZTQZp7A>vz@;P1RROz;ZgMLOn6m_Ul@5-mD_W|{OLyjP@S zYAs#-ZgNCRvxaZ~9})X!nl(yG;LLI5HtPZSsfF<8oQ#5-p{le&vl(gR&g$4~GBCaV zv;R#@Zxx}}MglmPwh*R|Q(am&(JDmo4KZeLi0`psW+8a4{e+B88LU1%SdoaW{Un*3 zei}%1(oY+lVp+e?PkTh#?9)$6KKAExuMlBHQKk|M&I(u|7N4_v45q@3!UoPHu_K3(P$*IM;%|HRWVge zHd{1I+LUcS(b8N$@TIwTIY~Lc(8mV|D*N>D{U85tHurHyVEud_7dzFpZSKR@x;m=e zm3h!%-b;Wa4O{E<<1aO=Tq@nCVK063zuB!7?hD~;=Yum8bYqV|PguSU0{pRy8 zJ-9I0-M@5lA*R-~u`OX=P4i)qudxv1+2@I@ZAp=ZofzY;m-$x~cFhh|&HxRB>06Ww zKU33uq!Bxeav8JZ*~obHuuHq|pq*wTXXe}{Y0KR-Sx2uF^~_1zAZg*uG}+X4(w>yG zbKJC}V6=>xdYq({xoJ;Hnv7Ma++~th;HKTZE0xMfyF}7*+%$7HX-qwCIU9klly0dJ z>&>DhBkg!8_p+Pz6=|Y>c(uY-WmImn?}XHP42T*t_vG~Kl{{HT=4f#lrKWU(T_Z0d zN;~MZZZx4KtqU&>-QPtt2{$hMQTOC8NtH)Min-i4QA6&iAwRnl%+eZFEiVq_8Vxxd zmT|3f?|&jaw-ssz^9x(=4RxN5MbjEB#H96FZ}jrtlP6;qulwNtNfcBXPY)@qjD4w%A&;bW zds%S8qXF}4^>SK>Io1Y$%}-OqH#016Xqn1Rb!u!Y4c5(fCvtWEagJ1QEsLPYb)=9mem#=C^09M{`zX`1VP7Ks|H{0uC{(hVOEG$iJ?oG z6{@WA60~fmUp0G);mG_-UF!6D{3x>12f`uR&a)b^)Uwc8h2#^~@CnRleaCcXi9x7M z#@oo~YFWt=A(gfz9{#>`&VOl3q&U`rqtl)9=zcoq7%hmqvX;ZdD8?Y&J&EA)N4Y}RkT`VP@1PXmQ8<;GY#k#Fm&WXGtCq~TdKeLt=<8?6M zyZZ@>TKqpZU!8fCbT=#c;zEF922k^LAB6{sHI*pXO z7`tg#2pCMn8s=Z&UKWd0W@KZ{2v4}IvS{aMW7Yg(kGh^>L96s+V^!A^OBy2vwp;ZE zeGn>HKkL2Z0eUk;Y)SFDDl4)vvL<;pWz~c&y3NsfT|ILPs=Z(NpF@>^^1Eagt(VgP ze`;-@bXwQ>wlx8%g?X+x>l)g*@fe39pT5h}qKz2V1+dzH@GGN!L-J)@3L=<`Cqo5-SNCFy|`P4RB^`h z7TIXKc{8TFr7||d3!I{Qn8GUSD7lzXwJq7rZ>;*snNb!~+F$cZ4yH8>ap{pdBs?23 z&2RGXJQ< zhS9i0-j(?Lxg%2aabj*f@z>-nBXUIOIdXf11=R|v-CS?^E(exb`K0ALUI!klHg|=h z4f$B}*mm+i?+wa`SkP$8y4s≀UJ;giW^5+>EWc)@~LpF}f}*`BBlPWC#D?*8=9A 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≀Sdelry8DNM6ZCVfeUxSm&9){Tl1+QzX_} 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 EKbghndjJ3c literal 0 HcmV?d00001 diff --git a/packages/symbol-provider-ctags/vendor/ctags-win32.exe b/packages/symbol-provider-ctags/vendor/ctags-win32.exe new file mode 100644 index 0000000000000000000000000000000000000000..b688c2936ea384957525223de1fa9a64828ef410 GIT binary patch literal 315392 zcmeGFdwf*I`3H`l&2ExSvdLK>K$M^XSB(-N7_@{0h!PTz+a^nPu|R_LwnkLca{%QQ zJXvLPOiNp}wrUIFt@ZM;Rw>>f7|cRNyjD@HQj0oqQSk;rlziXMGv{nJKrjA&-#@;8 zn7n4soVh&n%rnnCGxN+dbEf}vjp9@k#Rb>httcDuq`wOO{m(xF(K#nSoufRF@zRiu zj%hCqnH9eLx`Kt*UVYiM7hYL#(S=uCb+uOTvr7uD)vqeJ{HlV=nSp{UufF(_5!u<9 zJ`42j^52dA!@RFAv)$a)JbMfuhVGaqYzyY8NWXqqkEWYPr^W(!=_z06|8`WXf!$Rn{V1vGugl(4#_8 z+UWV?-;Wgdkpe$b;71DlNP!lrXQs74l{C|f6ou4jGQFiqF1N1YR#&7=J0b3Doua6lW;%?RqekqsBlLYu6BOMYEo(44>gTkZ z@2i{o)r$X1M5i0=jxkQX)BI}K!PY8AonLfa?@)rK2-S%ZD^e75n$Kr!^>(;MDCP_E z8tS7b%xUkzr_Nm9bDPtV{)?8hP)T=rrk2y(re(HNIgAcRd8YnlzXGQn({+fOoiCZT>lunQ2CwqpZrM zX9UImy$+`3ZgYm)9I!gSkLEGb9A+9`J6vw1PIws*$c^k;c0e>TKqCG|bAa)@qb$g9 z9+Ys*Dz}+K89A<2tXl$f0J#eQ%(q(a^%0k~I98_^TO7#T+@^mS6wk`M^>aXod7yJ$ zsN_?T)>E|)Wz}9lvXHr7tT3o*7Djbwf8%hbc9wBCTN|ESvjNA{tZ#D7;;zyWi~EK| zaS}BB$#^QNsUvDp7y$LWknkd&%IeD0GDCjxETaWd^;G?le=!NU>OrczSo#raO(|-{ z+QpIp0*zq)z4gxH)?WfZ{a>K!?+7;Li7@4x=JS~QOWLAU?r4=aT9r$9tjJYbtK6|P z(yv5kxS}&WQMX@H#bw`jcOwaZ2K!U%L??TrlXFp$JElO( zq(mpXqLbZb2H+q{GJPJw z#(0PBO+buFh-jO%XqAf_i0BbSBZ(_zoLzggC*^Nc!bK^SO1O}I6#N8*?+Zmi@IHqf zycNEn$VRZSwXi3DxB|(=M-^O&ScT_VB#Tw#zLHykM*-2@BD95eu;hSw(==zLVrCb- zh~L{M!|$)D73=>6$Q^EDt7p}bCS<#I7Z(yBf#L~<#6|x^8}C}9ZqSv;0c}=LTnkwU z!a;iU4Td!ru&97IV0ogQZ8}MeOhoq&h(GR;ePF8F?AJ0$S?%i6v|LdjOPmhVX-;KX zV!Ysp-)r`xjuYTanw4py+stB_ah<#5waw)~_NjDW_tpL8^WYG(D+0OIh5&WLbfrdg zF0*jb23hh%-B9NM@LI9cj?(u9M3sb2<3pl8_pta)uFpd5-jI*I>+|;e|3B2{UMmyT z2kok?tyBUm4_+Kk&^!V0nw28fP(QC{L5)SK-+z`+wivp8}fWG-

o;+I%ap42T6w z68stnFC>0lV~>BDj>M7OT5UkwwKORebG01Qhzm-RhmhC*A-RBt#+Gzq>IuZtN#i4? z9q|W}2ZOa%mc%$1Yv|P$L_bFV0hy2>R&lHJxxvQj95V;QW7!NISZ7)Q2SBd1sH;6G zNjL=2ue=IypxMsT$(Wyzgt-~(aP?6ddSryL&l9KHC?Gy@!FCn1aigi);+Xop!C4-Dm&u5XRe0y}BX9l*G|1%o2UYY8GC?tx%G)o#y27DE+SKNAG8H8h zcU$6kP16{~>{6TiB2>=LN$8xl*kW(0xHVrt$qv)^wWOC1)lY4yripy{P_=nShN3hB z^h{sO0rPeSo<+nYiX+ncu zk}UWh*d=8p3BHzrt8?8+a!RfxNLKb*GiXU!AOI@BhI0OV=TER06A_N~c5cCBAVIMU zp0HX*jXWsPm+k$!X0um+%wH`0H`##}{_7Lt3~=GTIkposeAJW zx5&_>EWJ2t%GuN+B^>STyc+xD364rX27Spi1Ht*RB7S&1FF;~xk||*W=siD zbf{IOdaPj+3~}K95>?ugEMgWeOjKzE(sLh~YlqP!$dbB~?J#|xT<>$mPESu*vQN?4cwDr{=T%})HS-47$q%O6wn5uLSM|(Tp zLvx@?9&V;Zk0h$JNj8(L(*7$GReF@e(M<2!VM+YA%?|6ue-9)odThnwul(SOZM3p* z#gwFqy+4vFwwI)i>SUV$+2@X^gyymxiF&ECD62FvFuk2XO#^u(-qg zlmrpxrx4nBcoam&D)QF$%t)cR_#>cTLi#hnmimHhViJ4$wVDTBOc2$`M@+eDn)5(4 zyC6Z)og9uiPKzC;)O}uEZQ2~0k3Vx~`rtb@i z_MHx;B^`|j?Rc%a2@A5KMD%%>@fT|4H5MS!SKv`94%xCEbzN%>63{V6FEds7ytGw;ZGy>st1SIo(wg zUdzoBE24h!>Pu8TFVsK0z?*Xcv^Dce+VJF-kUwU7??QvET3)xhDa|iFy}XAZHqGcZ zKEtNR+jbZjV*FVBjF7ksg$(-&I+8$0yaHS?6CxZ!Vj^$|iRp|(eh(kitW(~HnsBna zE*Pp2pIyW)u=!%NySe`<((abL_SOBQBhb^IQ`S`~@qBat=J|-0k!@ey|J-B*YpKsY zhKKmaJh>`dhnxZKFPq#o<}OieBTDRIEq(LtFd$#1XczHX`5SFO5cHfxYiCwIrW+le z(lq@OEULYXSE69OsHtp(UL^jwgZe-ATSNmE&sK$lqIMV&eJ&zF^mwYc2Oz~biC^Rr zD5d6r{Jm(;{lS}tYAixt6p#Ku#6y3;yqNmKU8p1E&%!ej{lVBb8(TqJK5`kG{P$Es z?OEh+o#u1bh>|eW3b)TjSj$bb@QYASO>~xT%<4*CxrkgwdR|Yxv2}KG>+jfM>4$PAtDlgNyWW8HcHOFkbbO| zPQ`x{KMBDnG6J(kb=Qi!F71WhM`cHrpSlL+LJEwj5i9IiJp&bLDjzspw-9}|wW_wK#={A@b-rtuyczDWgk3II7{{_qnN97qIvIJjiH*a}u%=SA1^i#%H{ zs?8(7qXF^Yb|xR$Ra{J5)k#RuO7+q@cW^Ha~Iujj9#(m)O)p4|SA%v+Tpx6|S=HR}MlA8(q$h z@Ph#67x&$3O=$EK^B~|@3;+Owj{#8jjd?_Ey$P)d7%i^!^6}c>^0C?p>ZWZFO&43` z=^4Z?-!I!8Zz%hI`5chH!!?j{I6M5Z751*RTVWii

  • !Tj8Zd@M+X$Z`Lx3VnZTW zWgt(1T#E2P-`2XA>XidcAt;YZb~clgr-GWsjMYB@*X1dCUp(>^?cJ6N2XJ+jm+P-a z4w#>5r%C>k>~;p&ZMaT0P4* zTbzhk(vV>zWi+x&gi4A3FS1*(4@%KLvTON!uqLHWqtxhz%f@sUsgW+K`{$k02m@+w ziyze1bC8@kajx!Zt?MrPa`_&_$9I>XuD`_z)z)037~>kHMk?WnZ=q->xXRWAmwltQ zegSf$tQJo(hG#y&5rN-Z|vY~~P&I8D^Biu$EtOM*TUQL}#@dHi0}?>4jZ;jhI`srdW_ zhjP@2VNNbG4y9b15vwR7K=Cwa@1v885NuYiF76GzKSTF>%xs1}*=zPE&{2P`S%Dep zFOP+e{nE)r*g^y(8iBCYD)E$%f}V8*$PCgJv5n@8TrnAdAlW^jNHp!J86V(9w(Ep0 zu{ojJEz$kKrF^he(wq@Xlwwx6jJB_hu9=IWIa$4LRE5&*Yu$?n&w1KQ+S<+TxAFQu zoZ?9QC3%kxJ6?Ww+OWMk^E6`Zjv_pS3_PCmu-pWXhXSym^1@Hn�= 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�nQXq$3WTRPgj^86X`5tRN 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

    =kBW>nD^VB+_tjDy`tnXHpP^Mev=-#1j> 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 dUphdz64*Z30I^dTh1^p2CC4T@R69o5?;={^9 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

    3A^IGA;;|ViWB?} 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 literal 0 HcmV?d00001 diff --git a/packages/symbol-provider-tree-sitter/.eslintrc.js b/packages/symbol-provider-tree-sitter/.eslintrc.js new file mode 100644 index 000000000..00404ea92 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/.eslintrc.js @@ -0,0 +1,42 @@ +module.exports = { + env: { + browser: true, + commonjs: true, + es2021: true, + }, + extends: [ + "eslint:recommended", + "plugin:node/recommended", + ], + overrides: [], + parserOptions: { + ecmaVersion: "latest" + }, + rules: { + "no-fallthrough": "off", + "no-case-declarations": "off", + "space-before-function-paren": ["error", { + anonymous: "always", + asyncArrow: "always", + named: "never" + }], + "node/no-unpublished-require": [ + "error", + { + allowModules: ["electron"] + } + ], + "node/no-missing-require": [ + "error", + { + allowModules: ["atom"] + } + ] + }, + plugins: [ + "jsdoc" + ], + globals: { + atom: "writeable" + } +}; diff --git a/packages/symbol-provider-tree-sitter/LICENSE.md b/packages/symbol-provider-tree-sitter/LICENSE.md new file mode 100644 index 000000000..ed5b10bc1 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2023 Andrew Dupont + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/symbol-provider-tree-sitter/README.md b/packages/symbol-provider-tree-sitter/README.md new file mode 100644 index 000000000..0d2d00567 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/README.md @@ -0,0 +1,181 @@ +# symbol-provider-tree-sitter package + +Provides symbols to `symbols-view` via Tree-sitter queries. + +Tree-sitter grammars [with tags queries](https://tree-sitter.github.io/tree-sitter/code-navigation-systems) can very easily give us a list of all the symbols in a file without the drawbacks of a `ctags`-based approach. For instance, they operate on the contents of the buffer, not the contents of the file on disk, so they work just fine in brand-new files and in files that have been modified since the last save. + +This provider does not currently support project-wide symbol search, but possibly could do so in the future. + +## Tags queries + +This provider expects for a grammar to have specified a tags query in its grammar definition file. All the built-in Tree-sitter grammars will have such a file. If you’re using a third-party Tree-sitter grammar that hasn’t defined one, file an issue on Pulsar and we’ll see what we can do. + +If you’re writing your own grammar, or contributing a `tags.scm` to a grammar without one, keep reading. + +### Query syntax + +The query syntax starts as a subset of what is described [on this page](https://tree-sitter.github.io/tree-sitter/code-navigation-systems). Here’s what this package can understand: + +* A query that consists of a `@definition.THING` capture with a `@name` capture inside will properly be understood as a symbol with a tag corresponding to `THING` and a name corresponding to the `@name` capture’s text. +* A query that consists of a `@reference.THING` capture with a `@name` capture inside will be ignored by default. If the proper setting is enabled, each of these references will become a symbol with a tag corresponding to `THING` and a name corresponding to the `@name` capture’s text. +* All other `@name` captures that are not within either a `@definition` or a `@reference` will be considered as a symbol in isolation. (These symbols can still specify a tag via a `#set!` predicate.) + +To match the current behavior of the `symbols-view` package, you can usually take a `queries/tags.scm` file from a Tree-sitter repository — many parsers define them — and paste it straight into your grammar’s `tags.scm` file. + +#### Advanced features + +The text of the captured node is what will be displayed as the symbol’s name, but a few predicates are available to alter that field and others. Symbol predicates use `#set!` and the `symbol` namespace. + +##### Node position descriptors + +Several predicates take a **node position descriptor** as an argument. It’s a string that resembles an object lookup chain in JavaScript: + +```scm +(#set! symbol.prependTextForNode parent.parent.firstNamedChild) +``` + +Starting at the captured node, it describes a path to take within the tree in order to get to another meaningful node. + +In all these examples, if the descriptor is invalid and does not return a node, the predicate will be ignored. + +##### Changing the symbol’s name + +There are several ways to add text to the beginning or end of the symbol’s name: + +###### symbol.prepend + +```scm +(class_declaration + name: (identifier) @name + (#set! symbol.prepend "Class: ")) +``` + +The `symbol.prepend` predicate adds a constant string to the beginning of a symbol name. For a class `Foo` in JavaScript, this predicate would result in a symbol called `Class: Foo`. + +###### symbol.append + +```scm +(class_declaration + name: (identifier) @name + (#set! symbol.append " (class)")) +``` + +The `symbol.append` predicate adds a constant string to the end of a symbol name. For a class `Foo`, this predicate would result in a symbol called `Foo (class)`. + + +###### symbol.strip + +```scm +(class_declaration + name: (identifier) @name + (#set! symbol.strip "^\\s+|\\s+$")) +``` + +The `symbol.strip` predicate will replace everything matched by the regular expression with an empty string. The pattern given is compiled into a JavaScript `RegExp` with an implied `g` (global) flag. + +In this example, _if_ the `identifier` node included whitespace on either side of the symbol, the symbol’s name would be stripped of that whitespace before being shown in the UI. + +###### symbol.prependTextForNode + +```scm +(class_body (method_definition + name: (property_identifier) @name + (#set! symbol.prependTextForNode "parent.parent.previousNamedSibling") + (#set! symbol.joiner "#") +)) +``` + +The `symbol.prependTextForNode` predicate will look up the text of the node referred to by the provided _node position descriptor_, then prepend that text to the symbol name. If `symbol.joiner` is provided, it will be inserted in between the two. + +In this example, a `bar` method on a class named `Foo` would have a symbol name of `Foo#bar`. + +###### symbol.prependSymbolForNode + +```scm +(class_body (method_definition + name: (property_identifier) @name + (#set! symbol.prependSymbolForNode "parent.parent.previousNamedSibling") + (#set! symbol.joiner "#") +)) +``` + +The `symbol.prependSymbolForNode` predicate will look up the symbol name of the node referred to by the provided _node position descriptor_, then prepend that name to the symbol name. If `symbol.joiner` is provided, it will be inserted in between the two. + +Unlike `symbol.prependTextForNode`, the node referred to with the descriptor must have its own symbol name, and it must have been processed already — that is, it must be a symbol whose name was determined earlier than that of the current node. + +This allows us to incorporate any transformations that were applied to the other node’s symbol name. We can use this to build “recursive” symbol names — for instance, JSON keys whose symbols consist of their entire key path from the root. + +##### Adding the `context` field + +The `context` field of a symbol is a short piece of text meant to give context. For instance, a symbol that represents a class method could have a `context` field that contains the name of the owning class. The `context` field is not filtered on. + +###### symbol.contextNode + +```scm +(class_body (method_definition + name: (property_identifier) @name + (#set! symbol.contextNode "parent.parent.previousNamedSibling") +)) +``` + +The `symbol.contextNode` predicate will set the value of a symbol’s `context` property to the text of a node based on the provided _node position descriptor_. + +###### symbol.context + +```scm +(class_body (method_definition + name: (property_identifier) @name + (#set! symbol.context "class") +)) +``` + +The `symbol.context` predicate will set the value of a symbol’s `context` property to a fixed string. + +The point of `context` is to provide information to help you tell symbols apart, so you probably don’t want to set it to a fixed value. But this predicate is available just in case. + +##### Adding a tag + +The `tag` field is a string (ideally a short string) that indicates a symbol’s kind or type. A `tag` for a class method’s symbol might say `method`, whereas the symbol for the class itself might have a `tag` of `class`. These tags will be indicated in the UI with a badge or an icon. + +The preferred method of adding a tag is to leverage the `@definition.` captures that are typically present in a tags file. For instance, in this excerpt from the JavaScript grammar’s `tags.scm` file… + +```scm +(assignment_expression + left: [ + (identifier) @name + (member_expression + property: (property_identifier) @name) + ] + right: [(arrow_function) (function)] +) @definition.function +``` + +…the resulting symbol will infer a `tag` value of `function`. + +In cases where this is impractical, you can provide the tag explicitly with a predicate. + +###### symbol.icon + +```scm +(class_body (method_definition + name: (property_identifier) @name + (#set! symbol.icon "package") +)) +``` + +The icon to be shown alongside the symbol in a list. Will only be shown if the user has enabled the “Show Icons in Symbols View” option in the `symbols-view` settings. You can see the full list of available icons by invoking the **Styleguide: Show** command and browsing the “Icons” section. The value can include the preceding `icon-` or can omit it; e.g., `icon-package` and `package` are both valid values. + +If this value is omitted, this provider will still attempt to match certain common tag values to icons. If `tag` is not present on the symbol, or is an uncommon value, there will be a blank space instead of an icon. + +###### symbol.tag + +```scm +(class_body (method_definition + name: (property_identifier) @name + (#set! symbol.tag "class") +)) +``` + +The `symbol.tag` predicate will set the value of a symbol’s `tag` property to a fixed string. + +The `tag` property is used to supply a word that represents the symbol in some way. For conventional symbols, this will often be something like `class` or `function`. diff --git a/packages/symbol-provider-tree-sitter/lib/capture-organizer.js b/packages/symbol-provider-tree-sitter/lib/capture-organizer.js new file mode 100644 index 000000000..ef7a926f7 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/lib/capture-organizer.js @@ -0,0 +1,391 @@ +const { Point } = require('atom'); + +function resolveNodeDescriptor(node, descriptor) { + let parts = descriptor.split('.'); + let result = node; + while (result !== null && parts.length > 0) { + let part = parts.shift(); + if (!result[part]) { return null; } + result = result[part]; + } + return result; +} + +const PatternCache = { + getOrCompile(pattern) { + this.patternCache ??= new Map(); + let regex = this.patternCache.get(pattern); + if (!regex) { + regex = new RegExp(pattern, 'g'); + this.patternCache.set(pattern, regex); + } + return regex; + }, + + clear() { + this.patternCache?.clear(); + }, +}; + +function iconForTag(tag) { + switch (tag) { + case 'function': + return 'icon-gear'; + case 'method': + return 'icon-gear'; + case 'namespace': + return 'icon-tag'; + case 'variable': + return 'icon-code'; + case 'class': + return 'icon-package'; + case 'constant': + return 'icon-primitive-square'; + case 'property': + return 'icon-primitive-dot'; + case 'interface': + return 'icon-key'; + case 'constructor': + return 'icon-tools'; + case 'module': + return 'icon-database'; + default: + return null; + } +} + + +/** + * A container capture. When another capture's node is contained by the + * definition capture's node, it gets added to this instance. + */ +class Container { + constructor(capture, organizer) { + this.captureFields = new Map(); + this.captureFields.set(capture.name, capture); + this.capture = capture; + this.node = capture.node; + this.organizer = organizer; + + this.tag = capture.name.substring(capture.name.indexOf('.') + 1); + this.icon = iconForTag(this.tag); + this.position = capture.node.range.start; + } + + getCapture(name) { + return this.captureFields.get(name); + } + + hasCapture(capture) { + return this.captureFields.has(capture.name); + } + + endsBefore(range) { + let containerRange = this.node.range; + return containerRange.end.compare(range.start) === -1; + } + + add(capture) { + if (this.captureFields.has(capture.name)) { + console.warn(`Name already exists:`, capture.name); + } + // Any captures added to this definition need to be checked to make sure + // their nodes are actually descendants of this definition's node. + if (!this.node.range.containsRange(capture.node.range)) { + return false; + } + this.captureFields.set(capture.name, capture); + if (capture.name === 'name') { + this.nameCapture = new Name(capture, this.organizer); + } + return true; + } + + isValid() { + return ( + this.nameCapture && + this.position instanceof Point + ); + } + + toSymbol() { + if (!this.nameCapture) return null; + let nameSymbol = this.nameCapture.toSymbol(); + let symbol = { + name: nameSymbol.name, + shortName: nameSymbol.shortName, + tag: nameSymbol.tag ?? this.tag, + icon: nameSymbol.icon ?? iconForTag(nameSymbol.tag) ?? iconForTag(this.tag), + position: this.position + }; + + if (nameSymbol.context) { + symbol.context = nameSymbol.context; + } + + return symbol; + } +} + +class Definition extends Container { + constructor(...args) { + super(...args); + this.type = 'definition'; + } +} + +class Reference extends Container { + constructor(...args) { + super(...args); + this.type = 'reference'; + } +} + +class Name { + constructor(capture, organizer) { + this.type = 'name'; + this.organizer = organizer; + this.props = capture.setProperties ?? {}; + this.capture = capture; + this.node = capture.node; + this.position = capture.node.range.start; + this.name = this.resolveName(capture); + this.shortName = this.resolveName(capture, { short: true }); + this.context = this.resolveContext(capture); + this.tag = this.resolveTag(capture); + this.icon = this.resolveIcon(capture); + } + + getSymbolNameForNode(node) { + return this.organizer.nameCache.get(node.id); + } + + resolveName(capture, { short = false } = {}) { + let { node, props } = this; + let base = node.text; + if (props['symbol.strip']) { + let pattern = PatternCache.getOrCompile(props['symbol.strip']); + base = base.replace(pattern, ''); + } + + // The “short name” is the symbol's base name before we prepend or append + // any text. + if (short) return base; + + // TODO: Regex-based replacement? + if (props['symbol.prepend']) { + base = `${props['symbol.prepend']}${base}`; + } + if (props['symbol.append']) { + base = `${base}${props['symbol.append']}`; + } + + let prefix = this.resolvePrefix(capture); + if (prefix) { + let joiner = props['symbol.joiner'] ?? ''; + base = `${prefix}${joiner}${base}`; + } + this.organizer.nameCache.set(node.id, base); + return base; + } + + resolveContext() { + let { node, props } = this; + let result = null; + if (props['symbol.contextNode']) { + let contextNode = resolveNodeDescriptor(node, props['symbol.contextNode']); + if (contextNode) { + result = contextNode.text; + } + } + + if (props['symbol.context']) { + result = props['symbol.context']; + } + + return result; + } + + resolvePrefix() { + let { node, props } = this; + let symbolDescriptor = props['symbol.prependSymbolForNode']; + let textDescriptor = props['symbol.prependTextForNode']; + + // Prepending with a symbol name requires that we already have determined + // the name for another node, which means the other node must have a + // corresponding symbol. But it allows for recursion. + if (symbolDescriptor) { + let other = resolveNodeDescriptor(node, symbolDescriptor); + if (other) { + let symbolName = this.getSymbolNameForNode(other); + if (symbolName) return symbolName; + } + } + + // A simpler option is to prepend with a node's text. This works on any + // arbitrary node, even nodes that don't have their own symbol names. + if (textDescriptor) { + let other = resolveNodeDescriptor(node, textDescriptor); + if (other) { + return other.text; + } + } + + return null; + } + + resolveTag() { + return this.props['symbol.tag'] ?? null; + } + + resolveIcon() { + let icon = this.props['symbol.icon'] ?? null; + if (icon && !icon.startsWith('icon-')) + icon = `icon-${icon}`; + return icon; + } + + toSymbol() { + let { name, shortName, position, context, tag } = this; + let symbol = { name, shortName, position }; + if (tag) { + symbol.tag = tag; + symbol.icon = iconForTag(tag); + } + if (context) symbol.context = context; + + return symbol; + } + +} + +/** + * Keeps track of @definition.* captures and the captures they may contain. + */ +class CaptureOrganizer { + clear() { + this.nameCache ??= new Map(); + this.nameCache.clear(); + this.activeContainers = []; + + this.definitions = []; + this.references = []; + this.names = []; + this.extraCaptures = []; + } + + destroy() { + PatternCache.clear(); + this.clear(); + } + + isDefinition(capture) { + return capture.name.startsWith('definition.'); + } + + isReference(capture) { + return capture.name.startsWith('reference.'); + } + + isName(capture) { + return capture.name === 'name'; + } + + finish(container) { + if (!container) return; + if (container instanceof Definition) { + this.definitions.push(container); + } else if (container instanceof Reference) { + this.references.push(container); + } + let index = this.activeContainers.indexOf(container); + if (index === -1) return; + this.activeContainers.splice(index, 1); + } + + addToContainer(capture) { + let index = this.activeContainers.length - 1; + let added = false; + while (index >= 0) { + let container = this.activeContainers[index]; + if (!container.hasCapture(capture)) { + if (container.add(capture)) { + added = true; + break; + } + } + index--; + } + return added; + } + + pruneActiveContainers(capture) { + let { range } = capture.node; + let indices = []; + for (let [index, container] of this.activeContainers.entries()) { + if (container.endsBefore(range)) { + indices.unshift(index); + } + } + + for (let index of indices) { + this.finish(this.activeContainers[index]); + } + } + + process(captures, scopeResolver) { + scopeResolver.reset(); + + this.clear(); + + for (let capture of captures) { + if (!scopeResolver.store(capture)) continue; + this.pruneActiveContainers(capture); + + if (this.isDefinition(capture)) { + this.activeContainers.push(new Definition(capture, this)); + } else if (this.isReference(capture)) { + this.activeContainers.push(new Reference(capture, this)); + } else if (this.isName(capture)) { + // See if this @name capture belongs with the most recent @definition + // capture. + if (this.addToContainer(capture)) { + continue; + } + this.names.push(new Name(capture, this)); + } else { + if (!this.addToContainer(capture)) { + continue; + } else { + this.extraCaptures.push(capture); + } + } + } + while (this.activeContainers.length) { + this.finish(this.activeContainers[0]); + } + + let symbols = []; + for (let definition of this.definitions) { + if (!definition.isValid()) continue; + symbols.push(definition.toSymbol()); + } + + if (atom.config.get('symbol-provider-tree-sitter.includeReferences')) { + for (let reference of this.references) { + if (!reference.isValid()) continue; + symbols.push(reference.toSymbol()); + } + } + + for (let name of this.names) { + symbols.push(name.toSymbol()); + } + + scopeResolver.reset(); + + return symbols; + } +} + +module.exports = CaptureOrganizer; diff --git a/packages/symbol-provider-tree-sitter/lib/main.js b/packages/symbol-provider-tree-sitter/lib/main.js new file mode 100644 index 000000000..ec7a35d60 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/lib/main.js @@ -0,0 +1,16 @@ + +const TreeSitterProvider = require('./tree-sitter-provider'); + +module.exports = { + activate () { + this.provider = new TreeSitterProvider(); + }, + + deactivate () { + this.provider?.destroy?.(); + }, + + provideSymbols () { + return this.provider; + } +}; diff --git a/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js b/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js new file mode 100644 index 000000000..e7c5624d4 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js @@ -0,0 +1,86 @@ +const CaptureOrganizer = require('./capture-organizer'); +const { Emitter } = require('atom'); + +class TreeSitterProvider { + constructor () { + this.packageName = 'symbol-provider-tree-sitter'; + this.name = 'Tree-sitter'; + this.isExclusive = true; + this.captureOrganizer = new CaptureOrganizer(); + this.emitter = new Emitter(); + this.disposable = atom.config.onDidChange('symbol-provider-tree-sitter', () => { + // Signal the consumer to clear its cache whenever we change the package + // config. + this.emitter.emit('should-clear-cache', { provider: this }); + }); + } + + destroy () { + this.captureOrganizer.destroy(); + this.disposable.dispose(); + } + + onShouldClearCache (callback) { + return this.emitter.on('should-clear-cache', callback); + } + + canProvideSymbols (meta) { + let { editor, type } = meta; + + // This provider can't crawl the whole project. + if (type === 'project' || type === 'project-find') return false; + + // This provider works only for editors with Tree-sitter grammars. + let languageMode = editor?.getBuffer()?.getLanguageMode(); + if (!languageMode?.atTransactionEnd) { + return false; + } + + // This provider needs at least one layer to have a tags query. + let layers = languageMode.getAllLanguageLayers(l => !!l.tagsQuery); + if (layers.length === 0) { + return false; + } + + return true; + } + + async getSymbols (meta) { + let { editor, signal } = meta; + let languageMode = editor?.getBuffer()?.getLanguageMode(); + if (!languageMode) return null; + + let scopeResolver = languageMode?.rootLanguageLayer?.scopeResolver; + if (!scopeResolver) return null; + + let results = []; + + // Wait for the buffer to be at rest so we know we're capturing against + // clean trees. + await languageMode.atTransactionEnd(); + + // The symbols-view package might've cancelled us in the interim. + if (signal.aborted) return null; + + let layers = languageMode.getAllLanguageLayers(l => !!l.tagsQuery); + if (layers.length === 0) return null; + + for (let layer of layers) { + let extent = layer.getExtent(); + + let captures = layer.tagsQuery.captures( + layer.tree.rootNode, + extent.start, + extent.end + ); + + results.push( + ...this.captureOrganizer.process(captures, scopeResolver) + ); + } + results.sort((a, b) => a.position.compare(b.position)); + return results; + } +} + +module.exports = TreeSitterProvider; diff --git a/packages/symbol-provider-tree-sitter/package-lock.json b/packages/symbol-provider-tree-sitter/package-lock.json new file mode 100644 index 000000000..a2fa93a56 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/package-lock.json @@ -0,0 +1,2122 @@ +{ + "name": "symbol-provider-tree-sitter", + "version": "0.0.4", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "symbol-provider-tree-sitter", + "version": "0.0.4", + "license": "MIT", + "devDependencies": { + "eslint": "^8.44.0", + "fs-plus": "^3.1.1", + "temp": "^0.9.4" + }, + "engines": { + "atom": ">=1.0.0 <2.0.0", + "node": ">=14" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "dev": true, + "dependencies": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + } + }, + "node_modules/fs-plus/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "node_modules/underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "dev": true, + "dependencies": { + "underscore": "^1.9.1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + } + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "fs-plus": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", + "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", + "dev": true, + "requires": { + "async": "^1.5.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2", + "underscore-plus": "1.x" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "underscore-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", + "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", + "dev": true, + "requires": { + "underscore": "^1.9.1" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/packages/symbol-provider-tree-sitter/package.json b/packages/symbol-provider-tree-sitter/package.json new file mode 100644 index 000000000..41cfe1614 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/package.json @@ -0,0 +1,32 @@ +{ + "name": "symbol-provider-tree-sitter", + "main": "./lib/main", + "version": "1.0.0", + "description": "Provides symbols to symbols-view based on tree-sitter queries", + "repository": "https://github.com/pulsar-edit/pulsar", + "license": "MIT", + "engines": { + "atom": ">=1.0.0 <2.0.0", + "node": ">=14" + }, + "providedServices": { + "symbol.provider": { + "description": "Allows external sources to suggest symbols for a given file or project.", + "versions": { + "1.0.0": "provideSymbols" + } + } + }, + "configSchema": { + "includeReferences": { + "default": false, + "type": "boolean", + "description": "Whether to make symbols out of references (for example, function calls) in addition to definitions." + } + }, + "devDependencies": { + "eslint": "^8.44.0", + "fs-plus": "^3.1.1", + "temp": "^0.9.4" + } +} diff --git a/packages/symbol-provider-tree-sitter/spec/.eslintrc.js b/packages/symbol-provider-tree-sitter/spec/.eslintrc.js new file mode 100644 index 000000000..8ee8742b4 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/.eslintrc.js @@ -0,0 +1,13 @@ +module.exports = { + env: { jasmine: true }, + globals: { + waitsForPromise: true + }, + rules: { + "node/no-unpublished-require": "off", + "node/no-extraneous-require": "off", + "no-unused-vars": "off", + "no-empty": "off", + "no-constant-condition": "off" + } +}; diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/c/sample.c b/packages/symbol-provider-tree-sitter/spec/fixtures/c/sample.c new file mode 100644 index 000000000..5a98bf4c1 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/c/sample.c @@ -0,0 +1,6 @@ +#define UNUSED(x) (void)(x) + +static void f(int x) +{ + UNUSED(x); +} diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/js/.eslintignore b/packages/symbol-provider-tree-sitter/spec/fixtures/js/.eslintignore new file mode 100644 index 000000000..c8078be87 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/js/.eslintignore @@ -0,0 +1,3 @@ +tagged.js +sample.js +other-file.js diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/js/no-symbols.js b/packages/symbol-provider-tree-sitter/spec/fixtures/js/no-symbols.js new file mode 100644 index 000000000..9a1aba6f7 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/js/no-symbols.js @@ -0,0 +1,6 @@ +// Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +// quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +// consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +// cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat +// non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/js/other-file.js b/packages/symbol-provider-tree-sitter/spec/fixtures/js/other-file.js new file mode 100644 index 000000000..4e79b3a98 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/js/other-file.js @@ -0,0 +1,29 @@ +// Another file for symbols to exist in. Used for project search. + +var quicksort = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; + +var quicksort2 = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/js/sample.js b/packages/symbol-provider-tree-sitter/spec/fixtures/js/sample.js new file mode 100644 index 000000000..15ab7c831 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/js/sample.js @@ -0,0 +1,13 @@ +var quicksort = function () { + var sort = function (items) { + if (items.length <= 1) return items; + var pivot = items.shift(), current, left = [], right = []; + while(items.length > 0) { + current = items.shift(); + current < pivot ? left.push(current) : right.push(current); + } + return sort(left).concat(pivot).concat(sort(right)); + }; + + return sort(Array.apply(this, arguments)); +}; diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/js/tagged.js b/packages/symbol-provider-tree-sitter/spec/fixtures/js/tagged.js new file mode 100644 index 000000000..4adaac609 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/js/tagged.js @@ -0,0 +1,11 @@ +var thisIsCrazy = true; + +function callMeMaybe() { + return "here's my number"; +} + +var iJustMetYou = callMeMaybe(); + +function duplicate() { + return true; +} diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/ruby/embed.rb b/packages/symbol-provider-tree-sitter/spec/fixtures/ruby/embed.rb new file mode 100644 index 000000000..e5a6e1cb2 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/ruby/embed.rb @@ -0,0 +1,10 @@ + +def foo + + return <<-js + function bar () { + return 'aha!'; + } + js + +end diff --git a/packages/symbol-provider-tree-sitter/spec/fixtures/ruby/file1.rb b/packages/symbol-provider-tree-sitter/spec/fixtures/ruby/file1.rb new file mode 100644 index 000000000..62697a7b3 --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/fixtures/ruby/file1.rb @@ -0,0 +1,33 @@ +module A::Foo + B = 'b' + + def bar! + + end + + def bar? + + end + + def baz + end + + def baz=(*) + end +end + +if bar? + baz + bar! +elsif !bar! + baz= 1 + baz = 2 + Foo = 3 + { :baz => 4 } + A::Foo::B + C::Foo::B + D::Foo::E +end + +module D::Foo +end diff --git a/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js b/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js new file mode 100644 index 000000000..62d95fc9c --- /dev/null +++ b/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js @@ -0,0 +1,391 @@ + +const path = require('path'); +const fs = require('fs-plus'); +const temp = require('temp'); +const TreeSitterProvider = require('../lib/tree-sitter-provider'); + +// Just for syntax highlighting. +function scm (strings) { + return strings.join(''); +} + +function getEditor () { + return atom.workspace.getActiveTextEditor(); +} + +async function wait (ms) { + return new Promise(r => setTimeout(r, ms)); +} + +let provider; + +async function getSymbols (editor, type = 'file') { + let controller = new AbortController(); + let symbols = await provider.getSymbols({ + type, + editor, + signal: controller.signal + }); + + return symbols; +} + +describe('TreeSitterProvider', () => { + let directory, editor; + + beforeEach(async () => { + jasmine.unspy(global, 'setTimeout'); + jasmine.unspy(Date, 'now'); + + atom.config.set('core.useTreeSitterParsers', true); + atom.config.set('core.useExperimentalModernTreeSitter', true); + await atom.packages.activatePackage('language-javascript'); + + atom.config.set('symbol-provider-tree-sitter.includeReferences', false); + + provider = new TreeSitterProvider(); + + atom.project.setPaths([ + temp.mkdirSync('other-dir-'), + temp.mkdirSync('atom-symbols-view-') + ]); + + directory = atom.project.getDirectories()[1]; + fs.copySync( + path.join(__dirname, 'fixtures', 'js'), + atom.project.getPaths()[1] + ); + + fs.copySync( + path.join(__dirname, 'fixtures', 'ruby'), + atom.project.getPaths()[1] + ); + }); + + describe('when a tree-sitter grammar is used for a file', () => { + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + let languageMode = editor.getBuffer().getLanguageMode(); + await languageMode.ready; + }); + + it('is willing to provide symbols for the current file', () => { + let meta = { type: 'file', editor }; + expect(provider.canProvideSymbols(meta)).toBe(true); + }); + + it('is not willing to provide symbols for an entire project', () => { + let meta = { type: 'project', editor }; + expect(provider.canProvideSymbols(meta)).toBe(false); + }); + + it('provides all JavaScript functions', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('quicksort'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('sort'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + describe('when a non-tree-sitter grammar is used for a file', () => { + beforeEach(async () => { + atom.config.set('core.useTreeSitterParsers', false); + atom.config.set('core.useExperimentalModernTreeSitter', false); + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + }); + + it('is not willing to provide symbols for the current file', () => { + expect(editor.getGrammar().rootLanguageLayer).toBe(undefined); + let meta = { type: 'file', editor }; + expect(provider.canProvideSymbols(meta)).toBe(false); + }); + }); + + // TODO: Test that `canProvideSymbols` returns `false` when no layer has a + // tags query. + + describe('when the buffer is new and unsaved', () => { + let grammar; + beforeEach(async () => { + await atom.workspace.open(); + editor = getEditor(); + grammar = atom.grammars.grammarForId('source.js'); + editor.setGrammar(grammar); + await editor.getBuffer().getLanguageMode().ready; + }); + + it('is willing to provide symbols', () => { + let meta = { type: 'file', editor }; + expect(provider.canProvideSymbols(meta)).toBe(true); + }); + + describe('and has content', () => { + beforeEach(async () => { + let text = fs.readFileSync( + path.join(__dirname, 'fixtures', 'js', 'sample.js') + ); + editor.setText(text); + await editor.getBuffer().getLanguageMode().atTransactionEnd(); + }); + + it('provides symbols just as if the file were saved on disk', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('quicksort'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('sort'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + }); + + describe('when the file has multiple language layers', () => { + beforeEach(async () => { + await atom.packages.activatePackage('language-ruby'); + await atom.workspace.open(directory.resolve('embed.rb')); + editor = getEditor(); + await editor.getBuffer().getLanguageMode().ready; + }); + + it('detects symbols across several layers', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('foo'); + expect(symbols[0].position.row).toEqual(1); + + expect(symbols[1].name).toBe('bar'); + expect(symbols[1].position.row).toEqual(4); + }); + }); + + describe('when the tags query contains @definition captures', () => { + let grammar; + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + let languageMode = editor.getBuffer().getLanguageMode(); + await languageMode.ready; + grammar = editor.getGrammar(); + await grammar.setQueryForTest( + 'tagsQuery', + scm` + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + ) @definition.function + ` + ); + }); + + it('can infer tag names from those captures', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('quicksort'); + expect(symbols[0].tag).toBe('function'); + + expect(symbols[1].name).toBe('sort'); + expect(symbols[1].tag).toBe('function'); + }); + }); + + describe('when the tags query contains @reference captures', () => { + let grammar; + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + let languageMode = editor.getBuffer().getLanguageMode(); + await languageMode.ready; + grammar = editor.getGrammar(); + await grammar.setQueryForTest( + 'tagsQuery', + scm` + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + ) @definition.function + + ( + (call_expression + function: (identifier) @name) @reference.call + (#not-match? @name "^(require)$")) + ` + ); + }); + + it('skips references when they are disabled in settings', async () => { + let symbols = await getSymbols(editor, 'file'); + expect(symbols.length).toBe(2); + }); + + it('includes references when they are enabled in settings', async () => { + atom.config.set('symbol-provider-tree-sitter.includeReferences', true); + let symbols = await getSymbols(editor, 'file'); + expect(symbols.length).toBe(5); + expect(symbols.map(s => s.tag)).toEqual( + ['function', 'function', 'call', 'call', 'call'] + ); + }); + + }); + + describe('when the tags query uses the predicate', () => { + let grammar; + beforeEach(async () => { + await atom.workspace.open(directory.resolve('sample.js')); + editor = getEditor(); + let languageMode = editor.getBuffer().getLanguageMode(); + await languageMode.ready; + grammar = editor.getGrammar(); + }); + + describe('symbol.strip', () => { + beforeEach(async () => { + await grammar.setQueryForTest('tagsQuery', scm` + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + (#set! symbol.strip "ort$") + ) + `); + }); + it('strips the given text from each symbol', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('quicks'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('s'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + describe('symbol.prepend', () => { + beforeEach(async () => { + await grammar.setQueryForTest('tagsQuery', scm` + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + (#set! symbol.prepend "Foo: ") + ) + `); + }); + it('prepends the given text to each symbol', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('Foo: quicksort'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('Foo: sort'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + describe('symbol.append', () => { + beforeEach(async () => { + await grammar.setQueryForTest('tagsQuery', scm` + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + (#set! symbol.append " (foo)") + ) + + `); + }); + it('appends the given text to each symbol', async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('quicksort (foo)'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('sort (foo)'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + describe('symbol.prependTextForNode', () => { + beforeEach(async () => { + await grammar.setQueryForTest('tagsQuery', scm` + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + (#set! test.onlyIfDescendantOfType function) + (#set! symbol.prependTextForNode "parent.parent.parent.parent.parent.firstNamedChild") + (#set! symbol.joiner ".") + (#set! test.final true) + ) + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + ) + `); + }); + it(`prepends the associated node's text to each symbol`, async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('quicksort'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('quicksort.sort'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + describe('symbol.prependSymbolForNode', () => { + beforeEach(async () => { + await grammar.setQueryForTest('tagsQuery', scm` + ; Outer function has prepended text... + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + (#set! test.onlyIfNotDescendantOfType function) + (#set! symbol.prepend "ROOT: ") + (#set! test.final true) + ) + ; …which the inner function picks up on. + ( + (variable_declaration + (variable_declarator + name: (identifier) @name + value: [(arrow_function) (function)])) + (#set! test.onlyIfDescendantOfType function) + (#set! symbol.prependSymbolForNode "parent.parent.parent.parent.parent.firstNamedChild") + (#set! symbol.joiner ".") + (#set! test.final true) + ) + `); + }); + it(`prepends the associated node's symbol name to each symbol`, async () => { + let symbols = await getSymbols(editor, 'file'); + + expect(symbols[0].name).toBe('ROOT: quicksort'); + expect(symbols[0].position.row).toEqual(0); + + expect(symbols[1].name).toBe('ROOT: quicksort.sort'); + expect(symbols[1].position.row).toEqual(1); + }); + }); + + }); +}); diff --git a/packages/symbols-view/.eslintrc.js b/packages/symbols-view/.eslintrc.js new file mode 100644 index 000000000..00404ea92 --- /dev/null +++ b/packages/symbols-view/.eslintrc.js @@ -0,0 +1,42 @@ +module.exports = { + env: { + browser: true, + commonjs: true, + es2021: true, + }, + extends: [ + "eslint:recommended", + "plugin:node/recommended", + ], + overrides: [], + parserOptions: { + ecmaVersion: "latest" + }, + rules: { + "no-fallthrough": "off", + "no-case-declarations": "off", + "space-before-function-paren": ["error", { + anonymous: "always", + asyncArrow: "always", + named: "never" + }], + "node/no-unpublished-require": [ + "error", + { + allowModules: ["electron"] + } + ], + "node/no-missing-require": [ + "error", + { + allowModules: ["atom"] + } + ] + }, + plugins: [ + "jsdoc" + ], + globals: { + atom: "writeable" + } +}; From d48e191024f105868568247302aad8dc649d7801 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 10:31:04 -0800 Subject: [PATCH 03/16] Fix setting name --- packages/symbols-view/lib/provider-broker.js | 31 +- packages/symbols-view/package-lock.json | 1233 ------------------ 2 files changed, 17 insertions(+), 1247 deletions(-) delete mode 100644 packages/symbols-view/package-lock.json diff --git a/packages/symbols-view/lib/provider-broker.js b/packages/symbols-view/lib/provider-broker.js index fb60bb071..c6b9efc67 100644 --- a/packages/symbols-view/lib/provider-broker.js +++ b/packages/symbols-view/lib/provider-broker.js @@ -8,7 +8,7 @@ const Config = require('./config'); * @extends Error */ class InvalidProviderError extends Error { - constructor (faults, provider) { + constructor(faults, provider) { let packageName = provider.packageName ? `the ${provider.packageName} provider` : 'a symbol provider'; @@ -26,7 +26,7 @@ class InvalidProviderError extends Error { * @class */ module.exports = class ProviderBroker { - constructor () { + constructor() { this.providers = []; this.providerSubscriptions = new Map(); this.subscriptions = new CompositeDisposable(); @@ -38,7 +38,7 @@ module.exports = class ProviderBroker { * * @param {SymbolProvider[]} providers Any number of symbol providers. */ - add (...providers) { + add(...providers) { for (let provider of providers) { try { this.validateSymbolProvider(provider); @@ -57,7 +57,7 @@ module.exports = class ProviderBroker { * * @param {SymbolProvider[]} providers Any number of symbol providers. */ - remove (...providers) { + remove(...providers) { for (let provider of providers) { let index = this.providers.indexOf(provider); // Providers that were invalid may not have been added. Not a problem. @@ -74,7 +74,7 @@ module.exports = class ProviderBroker { * * @param {SymbolProvider} provider A symbol provider to validate. */ - validateSymbolProvider (provider) { + validateSymbolProvider(provider) { let faults = []; if (typeof provider.name !== 'string') faults.push('name'); if (typeof provider.packageName !== 'string') faults.push('packageName'); @@ -93,7 +93,7 @@ module.exports = class ProviderBroker { * * @param {SymbolProvider} provider A symbol provider. */ - observeProvider (provider) { + observeProvider(provider) { let disposable = new CompositeDisposable(); this.providerSubscriptions.set(provider, disposable); @@ -113,28 +113,28 @@ module.exports = class ProviderBroker { * * @param {SymbolProvider} provider A symbol provider. */ - stopObservingProvider (provider) { + stopObservingProvider(provider) { let disposable = this.providerSubscriptions.get(provider); this.providerSubscriptions.delete(provider); disposable?.dispose; } - destroy () { + destroy() { for (let provider of this.providers) { provider?.destroy?.(); this.emitter.emit('did-remove-provider', provider); } } - onDidAddProvider (callback) { + onDidAddProvider(callback) { return this.emitter.on('did-add-provider', callback); } - onDidRemoveProvider (callback) { + onDidRemoveProvider(callback) { return this.emitter.on('did-remove-provider', callback); } - onShouldClearCache (callback) { + onShouldClearCache(callback) { return this.emitter.on('should-clear-cache', callback); } @@ -152,7 +152,8 @@ module.exports = class ProviderBroker { * @returns {Number} The amount by which to boost the provider's relevance * score. */ - getScoreBoost (name, packageName, preferredProviders = []) { + getScoreBoost(name, packageName, preferredProviders = []) { + let shouldLog = Config.get('enableDebugLogging'); if (packageName === 'unknown') return 0; let index = preferredProviders.indexOf(packageName); if (index === -1) { @@ -160,6 +161,8 @@ module.exports = class ProviderBroker { } if (index === -1) return 0; let scoreBoost = preferredProviders.length - index; + if (shouldLog) + console.log('Score boost for provider', name, packageName, 'is', scoreBoost); return scoreBoost; } @@ -172,12 +175,12 @@ module.exports = class ProviderBroker { * @returns {Promise} A promise that resolves with a list * of symbol providers. */ - async select (meta) { + async select(meta) { let shouldLog = Config.get('enableDebugLogging'); let exclusivesByScore = []; let results = []; - let preferredProviders = atom.config.get('symbols-view-redux.preferCertainProviders'); + let preferredProviders = atom.config.get('symbols-view.preferCertainProviders'); if (shouldLog) { console.debug(`Provider broker choosing among ${this.providers.length} candidates:`, this.providers); diff --git a/packages/symbols-view/package-lock.json b/packages/symbols-view/package-lock.json deleted file mode 100644 index e036bbec1..000000000 --- a/packages/symbols-view/package-lock.json +++ /dev/null @@ -1,1233 +0,0 @@ -{ - "name": "symbols-view-redux", - "version": "0.0.6", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "symbols-view-redux", - "version": "0.0.6", - "license": "MIT", - "dependencies": { - "atom-select-list": "^0.8.1", - "fs-plus": "^3.1.1", - "fuzzaldrin": "^2.1.0", - "murmurhash-js": "^1.0.0" - }, - "devDependencies": { - "eslint": "^8.39.0", - "temp": "^0.9.4" - }, - "engines": { - "atom": "*", - "node": ">=14" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.1", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==" - }, - "node_modules/atom-select-list": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.8.1.tgz", - "integrity": "sha512-MpwlZmmI81odx7rY+HpJrRmDW9aXlkFDFDNt70JxrPibxEh8h9HCZZj22woa4CKFKVXC8sEiLMcNtuDeE10jog==", - "dependencies": { - "etch": "^0.14.0", - "fuzzaldrin": "^2.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etch": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/etch/-/etch-0.14.1.tgz", - "integrity": "sha512-+IwqSDBhaQFMUHJu4L/ir0dhDoW5IIihg4Z9lzsIxxne8V0PlSg0gnk2STaKWjGJQnDR4cxpA+a/dORX9kycTA==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/fs-plus": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", - "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", - "dependencies": { - "async": "^1.5.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2", - "underscore-plus": "1.x" - } - }, - "node_modules/fs-plus/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fuzzaldrin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", - "integrity": "sha512-zgllBYwfHR5P3CncJiGbGVPpa3iFYW1yuPaIv8DiTVRrcg5/6uETNL5zvIoKflG1aifXVUZTlIroDehw4WygGA==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/murmurhash-js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", - "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" - }, - "node_modules/underscore-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", - "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", - "dependencies": { - "underscore": "^1.9.1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} From f7a58013d9bc5469b40ed1ded6e6e5fa22a1b067 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 10:57:58 -0800 Subject: [PATCH 04/16] Resolve `symbols-view` as a built-in package --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d7b34fd92..e98eaa4fd 100644 --- a/package.json +++ b/package.json @@ -166,7 +166,9 @@ "status-bar": "file:packages/status-bar", "styleguide": "file:./packages/styleguide", "superstring": "^2.4.4", - "symbols-view": "https://codeload.github.com/atom/symbols-view/legacy.tar.gz/refs/tags/v0.118.4", + "symbol-provider-ctags": "file:./packages/symbol-provider-ctags", + "symbol-provider-tree-sitter": "file:./packages/symbol-provider-tree-sitter", + "symbols-view": "file:./packages/symbols-view", "tabs": "file:packages/tabs", "temp": "0.9.4", "text-buffer": "^13.18.6", From 66f03932fe4228662f0f4b355ff763631ed6e994 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 10:58:51 -0800 Subject: [PATCH 05/16] Prefer an IDE package provider (if one is installed) over Tree-sitter --- .../lib/tree-sitter-provider.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js b/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js index e7c5624d4..215a7b49a 100644 --- a/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js +++ b/packages/symbol-provider-tree-sitter/lib/tree-sitter-provider.js @@ -2,7 +2,7 @@ const CaptureOrganizer = require('./capture-organizer'); const { Emitter } = require('atom'); class TreeSitterProvider { - constructor () { + constructor() { this.packageName = 'symbol-provider-tree-sitter'; this.name = 'Tree-sitter'; this.isExclusive = true; @@ -15,16 +15,16 @@ class TreeSitterProvider { }); } - destroy () { + destroy() { this.captureOrganizer.destroy(); this.disposable.dispose(); } - onShouldClearCache (callback) { + onShouldClearCache(callback) { return this.emitter.on('should-clear-cache', callback); } - canProvideSymbols (meta) { + canProvideSymbols(meta) { let { editor, type } = meta; // This provider can't crawl the whole project. @@ -42,10 +42,12 @@ class TreeSitterProvider { return false; } - return true; + // Return a value that will beat the built-in `ctags` provider, but which + // will (by default) lose to any provider from a community package. + return 0.999; } - async getSymbols (meta) { + async getSymbols(meta) { let { editor, signal } = meta; let languageMode = editor?.getBuffer()?.getLanguageMode(); if (!languageMode) return null; From 5e644e4c8d3b85b0fd4f6d101eb68358c70f85a8 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 11:24:39 -0800 Subject: [PATCH 06/16] Add package tests to CI --- .github/workflows/package-tests-linux.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/package-tests-linux.yml b/.github/workflows/package-tests-linux.yml index ab7659fb7..844e948a6 100644 --- a/.github/workflows/package-tests-linux.yml +++ b/.github/workflows/package-tests-linux.yml @@ -116,7 +116,9 @@ jobs: - package: "spell-check" - package: "status-bar" - package: "styleguide" - # - package: "symbols-view" + - package: "symbol-provider-ctags" + - package: "symbol-provider-tree-sitter" + - package: "symbols-view" - package: "tabs" - package: "timecop" - package: "tree-view" From 21095ee94f7f3fc0a6f7174e81c8a005e1bd0d6c Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 11:40:01 -0800 Subject: [PATCH 07/16] Wrongly focused test --- packages/symbols-view/lib/main.js | 2 -- packages/symbols-view/spec/symbols-view-spec.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/symbols-view/lib/main.js b/packages/symbols-view/lib/main.js index 770f04afb..43ae43648 100644 --- a/packages/symbols-view/lib/main.js +++ b/packages/symbols-view/lib/main.js @@ -5,8 +5,6 @@ const Path = require('path'); const { shell } = require('electron'); const { migrateOldConfigIfNeeded } = require('./util'); -console.log('SYMBOLS VIEW !!!'); - const NO_PROVIDERS_MESSAGE = `You don’t have any symbol providers installed.`; const NO_PROVIDERS_DESCRIPTION = `The button below will show all packages that can provide symbols. diff --git a/packages/symbols-view/spec/symbols-view-spec.js b/packages/symbols-view/spec/symbols-view-spec.js index df0ab1a48..7f79e6eec 100644 --- a/packages/symbols-view/spec/symbols-view-spec.js +++ b/packages/symbols-view/spec/symbols-view-spec.js @@ -765,7 +765,7 @@ describe('SymbolsView', () => { ); }); - fit('alerts the user', () => { + it('alerts the user', () => { migrateOldConfigIfNeeded({ force: true }); expect(atom.notifications.addInfo).toHaveBeenCalled(); From 66b5022fb0ebd54f0a23f88e74f7bccd3d0f0cfd Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 11:41:12 -0800 Subject: [PATCH 08/16] Update specs --- .../spec/symbol-provider-tree-sitter-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js b/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js index 62d95fc9c..acc0228f7 100644 --- a/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js +++ b/packages/symbol-provider-tree-sitter/spec/symbol-provider-tree-sitter-spec.js @@ -5,21 +5,21 @@ const temp = require('temp'); const TreeSitterProvider = require('../lib/tree-sitter-provider'); // Just for syntax highlighting. -function scm (strings) { +function scm(strings) { return strings.join(''); } -function getEditor () { +function getEditor() { return atom.workspace.getActiveTextEditor(); } -async function wait (ms) { +async function wait(ms) { return new Promise(r => setTimeout(r, ms)); } let provider; -async function getSymbols (editor, type = 'file') { +async function getSymbols(editor, type = 'file') { let controller = new AbortController(); let symbols = await provider.getSymbols({ type, @@ -72,7 +72,7 @@ describe('TreeSitterProvider', () => { it('is willing to provide symbols for the current file', () => { let meta = { type: 'file', editor }; - expect(provider.canProvideSymbols(meta)).toBe(true); + expect(provider.canProvideSymbols(meta)).toBe(0.999); }); it('is not willing to provide symbols for an entire project', () => { @@ -121,7 +121,7 @@ describe('TreeSitterProvider', () => { it('is willing to provide symbols', () => { let meta = { type: 'file', editor }; - expect(provider.canProvideSymbols(meta)).toBe(true); + expect(provider.canProvideSymbols(meta)).toBe(0.999); }); describe('and has content', () => { From 812ab75acffc1bc4396918bf9c0a1f69808c08a5 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Fri, 8 Dec 2023 11:41:49 -0800 Subject: [PATCH 09/16] Update specs --- .../symbol-provider-ctags/spec/symbol-provider-ctags-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js b/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js index 4738a7ced..ec4fea27a 100644 --- a/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js +++ b/packages/symbol-provider-ctags/spec/symbol-provider-ctags-spec.js @@ -93,7 +93,7 @@ describe('CTagsProvider', () => { it('returns a lower match score', () => { editor.insertText("\n"); let meta = { type: 'file', editor }; - expect(provider.canProvideSymbols(meta)).toBe(0.9); + expect(provider.canProvideSymbols(meta)).toBe(0.89); }); }); From 6a5a840b575fed7b75cd463ddee33a9839702394 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Tue, 12 Dec 2023 17:53:12 -0800 Subject: [PATCH 10/16] Add an `await` where appropriate --- packages/symbols-view/lib/file-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/symbols-view/lib/file-view.js b/packages/symbols-view/lib/file-view.js index 30ce87833..94b362e6c 100644 --- a/packages/symbols-view/lib/file-view.js +++ b/packages/symbols-view/lib/file-view.js @@ -315,7 +315,7 @@ class FileView extends SymbolsView { await Promise.race([Promise.allSettled(tasks), timeout(this.timeoutMs)]); } - this.updateView({ loadingMessage: null }); + await this.updateView({ loadingMessage: null }); if (signal.aborted) { // This means the user cancelled the task. No cleanup necessary; the From 83972a9ef9d24ec666fa9edbf87cb31d739088a9 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Tue, 12 Dec 2023 17:53:38 -0800 Subject: [PATCH 11/16] Don't activate a new pane when it's created (steals focus) --- packages/symbols-view/lib/symbols-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/symbols-view/lib/symbols-view.js b/packages/symbols-view/lib/symbols-view.js index 7ed478941..2d69a9b32 100644 --- a/packages/symbols-view/lib/symbols-view.js +++ b/packages/symbols-view/lib/symbols-view.js @@ -274,7 +274,7 @@ class SymbolsView { // Open a different file, then jump to a position. atom.workspace.open( Path.join(tag.directory, tag.file), - { pending } + { pending, activatePane: false } ).then(() => { if (position) { return this.moveToPosition(position, { range }); From ee86a18b12702ad2a102603f4b4fac2a80b8a142 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Tue, 12 Dec 2023 17:54:01 -0800 Subject: [PATCH 12/16] Strip line breaks and other spaces from symbol names --- packages/symbols-view/lib/symbols-view.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/symbols-view/lib/symbols-view.js b/packages/symbols-view/lib/symbols-view.js index 2d69a9b32..3c716b20d 100644 --- a/packages/symbols-view/lib/symbols-view.js +++ b/packages/symbols-view/lib/symbols-view.js @@ -335,6 +335,7 @@ class SymbolsView { symbol.directory = `${parts.dir}${Path.sep}`; symbol.file = parts.base; } + symbol.name = symbol.name.replace(/[\n\r\t]/, ' '); allSymbols.push(symbol); } } From eb56712358779630d31cc7eabed8aae5bd26aab1 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Wed, 3 Jan 2024 11:07:35 -0800 Subject: [PATCH 13/16] Fix type definition --- packages/symbols-view/lib/main.d.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/symbols-view/lib/main.d.ts b/packages/symbols-view/lib/main.d.ts index 49226bf59..580fd8e6f 100644 --- a/packages/symbols-view/lib/main.d.ts +++ b/packages/symbols-view/lib/main.d.ts @@ -1,4 +1,3 @@ - import type { TextEditor, Point, Range as AtomRange } from 'atom'; type MaybePromise = T | Promise; @@ -295,5 +294,5 @@ export type SymbolProviderMainModule = { // // A single package can supply multiple providers if need be. // - provideSymbols(): SymbolProvider | [SymbolProvider...] + provideSymbols(): SymbolProvider | SymbolProvider[], }; From ecc9180caf234f2b491ff3bd3dac45c7c1c991d5 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Wed, 3 Jan 2024 11:13:43 -0800 Subject: [PATCH 14/16] Wait longer when running `symbols-view` spec --- packages/symbols-view/spec/symbols-view-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/symbols-view/spec/symbols-view-spec.js b/packages/symbols-view/spec/symbols-view-spec.js index 7f79e6eec..8f9719167 100644 --- a/packages/symbols-view/spec/symbols-view-spec.js +++ b/packages/symbols-view/spec/symbols-view-spec.js @@ -532,7 +532,7 @@ describe('SymbolsView', () => { await activationPromise; atom.commands.dispatch(getEditorView(), 'symbols-view:toggle-project-symbols'); symbolsView = atom.workspace.getModalPanels()[0].item; - await wait(200); + await wait(2000); expect(symbolsView.element.querySelectorAll('li .primary-line').length).toBe(0); expect(ProgressiveProjectProvider.getSymbols.callCount).toBe(1); @@ -540,7 +540,7 @@ describe('SymbolsView', () => { expect(symbolsView.selectListView.props.emptyMessage).toBe('Query must be at least 3 characters long.'); await symbolsView.updateView({ query: 'lor' }); - await wait(200); + await wait(2000); expect(symbolsView.selectListView.props.emptyMessage).toBeNull(); From 227ac4a1478231e534ba9ec1b03c4e0c7ffaca0f Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Wed, 3 Jan 2024 11:27:29 -0800 Subject: [PATCH 15/16] Rename `symbols-view` keymap file --- .../keymaps/{symbols-view-plus.cson => symbols-view.cson} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/symbols-view/keymaps/{symbols-view-plus.cson => symbols-view.cson} (100%) diff --git a/packages/symbols-view/keymaps/symbols-view-plus.cson b/packages/symbols-view/keymaps/symbols-view.cson similarity index 100% rename from packages/symbols-view/keymaps/symbols-view-plus.cson rename to packages/symbols-view/keymaps/symbols-view.cson From 21441e0b09c427c69942c7dfa834de8608d0a815 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sun, 7 Jan 2024 15:26:28 -0800 Subject: [PATCH 16/16] Add new bundled packages to `packageDependencies` --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e98eaa4fd..dbe724068 100644 --- a/package.json +++ b/package.json @@ -239,7 +239,9 @@ "spell-check": "file:./packages/spell-check", "status-bar": "file:./packages/status-bar", "styleguide": "file:./packages/styleguide", - "symbols-view": "0.118.4", + "symbol-provider-ctags": "file:./packages/symbol-provider-ctags", + "symbol-provider-tree-sitter": "file:./packages/symbol-provider-tree-sitter", + "symbols-view": "file:./packages/symbols-view", "tabs": "file:./packages/tabs", "timecop": "file:./packages/timecop", "tree-view": "file:./packages/tree-view",