diff --git a/package.json b/package.json
index 666000ae34..70398b3916 100644
--- a/package.json
+++ b/package.json
@@ -66,7 +66,7 @@
"fs-admin": "0.19.0",
"fs-plus": "^3.1.1",
"fstream": "1.0.12",
- "fuzzy-finder": "https://codeload.github.com/atom/fuzzy-finder/legacy.tar.gz/refs/tags/v1.14.3",
+ "fuzzy-finder": "file:packages/fuzzy-finder",
"git-diff": "file:packages/git-diff",
"git-utils": "5.7.1",
"github": "https://codeload.github.com/pulsar-edit/github/tar.gz/refs/tags/v0.36.15-pretranspiled",
@@ -204,7 +204,7 @@
"encoding-selector": "file:./packages/encoding-selector",
"exception-reporting": "file:./packages/exception-reporting",
"find-and-replace": "file:./packages/find-and-replace",
- "fuzzy-finder": "1.14.3",
+ "fuzzy-finder": "file:packages/fuzzy-finder",
"github": "0.36.14",
"git-diff": "file:./packages/git-diff",
"go-to-line": "file:./packages/go-to-line",
diff --git a/packages/README.md b/packages/README.md
index df27d4052c..9677d61cae 100644
--- a/packages/README.md
+++ b/packages/README.md
@@ -32,7 +32,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
| **encoding-selector** | [`./encoding-selector`](./encoding-selector) | |
| **exception-reporting** | [`./exception-reporting`](./exception-reporting) | |
| **find-and-replace** | [`./find-and-replace`][find-and-replace] | |
-| **fuzzy-finder** | [`pulsar-edit/fuzzy-finder`][fuzzy-finder] | |
+| **fuzzy-finder** | [`./fuzzy-finder`][fuzzy-finder] | |
| **github** | [`pulsar-edit/github`][github] | |
| **git-diff** | [`./git-diff`](./git-diff) | |
| **go-to-line** | [`./go-to-line`](./go-to-line) | |
diff --git a/packages/fuzzy-finder/.gitignore b/packages/fuzzy-finder/.gitignore
new file mode 100644
index 0000000000..3c3629e647
--- /dev/null
+++ b/packages/fuzzy-finder/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/packages/fuzzy-finder/CONTRIBUTING.md b/packages/fuzzy-finder/CONTRIBUTING.md
new file mode 100644
index 0000000000..9c8ac3e5b5
--- /dev/null
+++ b/packages/fuzzy-finder/CONTRIBUTING.md
@@ -0,0 +1 @@
+[See how you can contribute](https://github.com/pulsar-edit/.github/blob/main/CONTRIBUTING.md)
diff --git a/packages/fuzzy-finder/LICENSE.md b/packages/fuzzy-finder/LICENSE.md
new file mode 100644
index 0000000000..4d231b4563
--- /dev/null
+++ b/packages/fuzzy-finder/LICENSE.md
@@ -0,0 +1,20 @@
+Copyright (c) 2014 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/fuzzy-finder/README.md b/packages/fuzzy-finder/README.md
new file mode 100644
index 0000000000..85191752e1
--- /dev/null
+++ b/packages/fuzzy-finder/README.md
@@ -0,0 +1,22 @@
+# Fuzzy Finder package
+
+Quickly find and open files using cmd-t.
+
+ * cmd-t or cmd-p to open the file finder
+ * cmd-b to open the list of open buffers
+ * cmd-shift-b to open the list of Git modified and untracked files
+
+When opening a file, you can control the behavior.
+
+ * enter defaults to opening the selected file without leaving the current pane
+ * shift-enter defaults to switching to another pane if the file is already open there
+ * cmd-k right (or any other directional arrow) will open the highlighted file in a new pane on the side indicated by the arrow
+ * Adding `:` to the end of your search will go directly to the line number you specify, or the last line if the number is larger
+
+Turning on the "Search All Panes" setting reverses the behavior of enter and shift-enter so enter opens the file in any pane and shift-enter creates a new tab in the current pane.
+
+This package uses both the `core.ignoredNames` and `fuzzy-finder.ignoredNames` config settings to filter out files and folders that will not be shown. Both of those config settings are interpreted as arrays of [minimatch](https://github.com/isaacs/minimatch) glob patterns.
+
+This package also will also not show Git ignored files when the `core.excludeVcsIgnoredPaths` is enabled.
+
+![](https://f.cloud.github.com/assets/671378/2241456/100db6b8-9cd3-11e3-9b3a-569c6b50cc60.png)
diff --git a/packages/fuzzy-finder/docs/events.md b/packages/fuzzy-finder/docs/events.md
new file mode 100644
index 0000000000..cbd75be3cf
--- /dev/null
+++ b/packages/fuzzy-finder/docs/events.md
@@ -0,0 +1,44 @@
+# Events specification
+
+This document specifies all the data (along with the format) which gets sent from the Fuzzy Finder package to the GitHub analytics pipeline. This document follows the same format and nomenclature as the [Atom Core Events spec](https://github.com/atom/metrics/blob/master/docs/events.md).
+
+## Counters
+
+| counter name | description |
+|-------|-------|
+| `show-enable-prompt` | Number of times the prompt to enable fast mode is shown |
+| `click-enable-prompt` | Number of clicks on the "enable fast mode" prompt |
+| `confirm-enable-prompt` | Number of confirmations on the "enable fast mode" notification |
+| `cancel-enable-prompt` | Number of cancels on the "enable fast mode" notification |
+| `show-disable-prompt` | Number of times the prompt to disable fast mode is shown |
+| `click-disable-prompt` | Number of clicks on the "disable fast mode" prompt |
+| `confirm-disable-prompt` | Number of confirmations on the "disable fast mode" notification |
+| `cancel-disable-prompt` | Number of cancels on the "disable fast mode" notification |
+
+## Timing events
+
+#### Time to crawl the project
+
+* **eventType**: `fuzzy-finder-v1`
+* **metadata**
+
+ | field | value |
+ |-------|-------|
+ | `ec` | `time-to-crawl`
+ | `el` | Crawler type (`ripgrep` or `fs`)
+ | `ev` | Number of crawled files
+
+#### Time to filter results
+
+* **eventType**: `fuzzy-finder-v1`
+* **metadata**
+
+ | field | value |
+ |-------|-------|
+ | `ec` | `time-to-filter`
+ | `el` | Scoring system (`alternate` or `fast`)
+ | `ev` | Number of items in the list
+
+## Standard events
+
+Currently the Fuzzy Finder does not log any standard events.
diff --git a/packages/fuzzy-finder/keymaps/fuzzy-finder.cson b/packages/fuzzy-finder/keymaps/fuzzy-finder.cson
new file mode 100644
index 0000000000..e0f627b093
--- /dev/null
+++ b/packages/fuzzy-finder/keymaps/fuzzy-finder.cson
@@ -0,0 +1,20 @@
+'.platform-darwin':
+ 'cmd-t': 'fuzzy-finder:toggle-file-finder'
+ 'cmd-p': 'fuzzy-finder:toggle-file-finder'
+ 'cmd-b': 'fuzzy-finder:toggle-buffer-finder'
+ 'cmd-B': 'fuzzy-finder:toggle-git-status-finder'
+
+'.platform-win32':
+ 'ctrl-t': 'fuzzy-finder:toggle-file-finder'
+ 'ctrl-p': 'fuzzy-finder:toggle-file-finder'
+ 'ctrl-b': 'fuzzy-finder:toggle-buffer-finder'
+ 'ctrl-B': 'fuzzy-finder:toggle-git-status-finder'
+
+'.platform-linux':
+ 'ctrl-t': 'fuzzy-finder:toggle-file-finder'
+ 'ctrl-p': 'fuzzy-finder:toggle-file-finder'
+ 'ctrl-b': 'fuzzy-finder:toggle-buffer-finder'
+ 'ctrl-B': 'fuzzy-finder:toggle-git-status-finder'
+
+'.fuzzy-finder atom-text-editor[mini]':
+ 'shift-enter': 'fuzzy-finder:invert-confirm'
diff --git a/packages/fuzzy-finder/lib/buffer-view.js b/packages/fuzzy-finder/lib/buffer-view.js
new file mode 100644
index 0000000000..85f8c0f556
--- /dev/null
+++ b/packages/fuzzy-finder/lib/buffer-view.js
@@ -0,0 +1,89 @@
+const FuzzyFinderView = require('./fuzzy-finder-view')
+const path = require('path')
+
+module.exports =
+class BufferView extends FuzzyFinderView {
+ setTeletypeService (teletypeService) {
+ this.teletypeService = teletypeService
+ }
+
+ getEmptyMessage () {
+ return 'No open editors'
+ }
+
+ async toggle () {
+ if (this.panel && this.panel.isVisible()) {
+ this.cancel()
+ } else {
+ const items = this.sortItems(await this.buildItems())
+ if (items.length > 0) {
+ this.show()
+ await this.setItems(items)
+ }
+ }
+ }
+
+ async buildItems () {
+ const itemsByURI = new Map()
+
+ const remoteEditorsByURI = await this.getRemoteEditorsByURI()
+ const projectHasMultipleDirectories = atom.project.getDirectories().length > 1
+ const localEditors = atom.workspace.getTextEditors()
+ for (let i = 0; i < localEditors.length; i++) {
+ const localEditor = localEditors[i]
+ const localEditorURI = localEditor.getURI()
+ const localEditorPath = localEditor.getPath()
+ if (!localEditorURI) continue
+ if (itemsByURI.has(localEditorURI)) continue
+
+ const item = {uri: localEditorURI}
+
+ const remoteEditor = remoteEditorsByURI.get(localEditorURI)
+ if (remoteEditor) {
+ item.filePath = remoteEditor.path
+ item.label = `@${remoteEditor.hostGitHubUsername}: ${remoteEditor.path}`
+ item.ownerGitHubUsername = remoteEditor.hostGitHubUsername
+ } else {
+ const [projectRootPath, projectRelativePath] = atom.project.relativizePath(localEditorPath)
+ item.filePath = localEditorPath
+ item.label =
+ projectRootPath && projectHasMultipleDirectories
+ ? path.join(path.basename(projectRootPath), projectRelativePath)
+ : projectRelativePath
+ }
+
+ if (localEditor.lastOpened != null) {
+ item.lastOpened = localEditor.lastOpened
+ }
+
+ itemsByURI.set(localEditorURI, item)
+ }
+
+ return Array.from(itemsByURI.values())
+ }
+
+ sortItems (items) {
+ const activeEditor = atom.workspace.getActiveTextEditor()
+ const activeEditorURI = activeEditor ? activeEditor.getURI() : null
+ items.sort((a, b) => {
+ if (a.uri === activeEditorURI) {
+ return 1
+ } else if (b.uri === activeEditorURI) {
+ return -1
+ } else {
+ return (b.lastOpened || 1) - (a.lastOpened || 1)
+ }
+ })
+ return items
+ }
+
+ async getRemoteEditorsByURI () {
+ const remoteEditorsByURI = new Map()
+ const remoteEditors = this.teletypeService ? await this.teletypeService.getRemoteEditors() : []
+ for (var i = 0; i < remoteEditors.length; i++) {
+ const remoteEditor = remoteEditors[i]
+ remoteEditorsByURI.set(remoteEditor.uri, remoteEditor)
+ }
+ return remoteEditorsByURI
+ }
+}
diff --git a/packages/fuzzy-finder/lib/default-file-icons.js b/packages/fuzzy-finder/lib/default-file-icons.js
new file mode 100644
index 0000000000..96c7a8d34a
--- /dev/null
+++ b/packages/fuzzy-finder/lib/default-file-icons.js
@@ -0,0 +1,26 @@
+const fs = require('fs-plus')
+const path = require('path')
+
+class DefaultFileIcons {
+ iconClassForPath (filePath) {
+ const extension = path.extname(filePath)
+
+ if (fs.isSymbolicLinkSync(filePath)) {
+ return 'icon-file-symlink-file'
+ } else if (fs.isReadmePath(filePath)) {
+ return 'icon-book'
+ } else if (fs.isCompressedExtension(extension)) {
+ return 'icon-file-zip'
+ } else if (fs.isImageExtension(extension)) {
+ return 'icon-file-media'
+ } else if (fs.isPdfExtension(extension)) {
+ return 'icon-file-pdf'
+ } else if (fs.isBinaryExtension(extension)) {
+ return 'icon-file-binary'
+ } else {
+ return 'icon-file-text'
+ }
+ }
+}
+
+module.exports = new DefaultFileIcons()
diff --git a/packages/fuzzy-finder/lib/fuzzy-finder-view.js b/packages/fuzzy-finder/lib/fuzzy-finder-view.js
new file mode 100644
index 0000000000..d34d80ac68
--- /dev/null
+++ b/packages/fuzzy-finder/lib/fuzzy-finder-view.js
@@ -0,0 +1,437 @@
+const {Point, CompositeDisposable} = require('atom')
+const fs = require('fs')
+const NativeFuzzy = require('@pulsar-edit/fuzzy-native')
+
+const path = require('path')
+const SelectListView = require('atom-select-list')
+
+const {repositoryForPath} = require('./helpers')
+const getIconServices = require('./get-icon-services')
+
+const MAX_RESULTS = 10
+
+module.exports = class FuzzyFinderView {
+ constructor (metricsReporter) {
+ this.previousQueryWasLineJump = false
+ this.items = []
+ this.metricsReporter = metricsReporter
+ this.filterFn = this.filterFn.bind(this)
+
+ this.selectListView = new SelectListView({
+ items: this.items,
+ maxResults: MAX_RESULTS,
+ emptyMessage: this.getEmptyMessage(),
+ filterKeyForItem: (item) => item.label,
+ filterQuery: (query) => {
+ const colon = query.indexOf(':')
+ if (colon !== -1) {
+ query = query.slice(0, colon)
+ }
+ // Normalize to backslashes on Windows
+ if (process.platform === 'win32') {
+ query = query.replace(/\//g, '\\')
+ }
+
+ return query
+ },
+ didCancelSelection: () => { this.cancel() },
+ didConfirmSelection: (item) => {
+ this.confirm(item, {searchAllPanes: atom.config.get('fuzzy-finder.searchAllPanes')})
+ },
+ didConfirmEmptySelection: () => {
+ this.confirm()
+ },
+ didChangeQuery: () => {
+ if (this.iconDisposables) {
+ this.iconDisposables.dispose()
+ this.iconDisposables = null
+ }
+ const isLineJump = this.isQueryALineJump()
+ if (isLineJump) {
+ this.previousQueryWasLineJump = true
+ const query = this.selectListView.getQuery()
+ let emptyMessage = null
+ let errorMessage = null
+ if (/^:\d+:\d*\D/.test(query)) {
+ errorMessage = 'Invalid column number'
+ } else if (/^:\d+:/.test(query)) {
+ emptyMessage = 'Jump to line and column in active editor'
+ } else if (/^:\d*\D/.test(query)) {
+ errorMessage = 'Invalid line number'
+ } else {
+ emptyMessage = 'Jump to line in active editor'
+ }
+
+ this.selectListView.update({
+ items: [],
+ emptyMessage: emptyMessage,
+ errorMessage: errorMessage
+ })
+ } else if (this.previousQueryWasLineJump) {
+ this.previousQueryWasLineJump = false
+ this.selectListView.update({
+ items: this.items,
+ emptyMessage: this.getEmptyMessage(),
+ errorMessage: null
+ })
+ }
+ },
+ elementForItem: ({filePath, label, ownerGitHubUsername}) => {
+ const filterQuery = this.selectListView.getFilterQuery()
+
+ this.nativeFuzzyForResults.setCandidates([0], [label])
+ const items = this.nativeFuzzyForResults.match(
+ filterQuery,
+ {maxResults: 1, recordMatchIndexes: true}
+ )
+ const matches = items.length ? items[0].matchIndexes : []
+ const repository = repositoryForPath(filePath)
+
+ return new FuzzyFinderItem({
+ filePath,
+ label,
+ ownerGitHubUsername,
+ filterQuery,
+ matches,
+ repository
+ }).element
+ }
+ })
+ this.selectListView.element.classList.add('fuzzy-finder')
+
+ const splitLeft = () => { this.splitOpenPath((pane) => pane.splitLeft.bind(pane)) }
+ const splitRight = () => { this.splitOpenPath((pane) => pane.splitRight.bind(pane)) }
+ const splitUp = () => { this.splitOpenPath((pane) => pane.splitUp.bind(pane)) }
+ const splitDown = () => { this.splitOpenPath((pane) => pane.splitDown.bind(pane)) }
+ atom.commands.add(this.selectListView.element, {
+ 'pane:split-left': splitLeft,
+ 'pane:split-left-and-copy-active-item': splitLeft,
+ 'pane:split-left-and-move-active-item': splitLeft,
+ 'pane:split-right': splitRight,
+ 'pane:split-right-and-copy-active-item': splitRight,
+ 'pane:split-right-and-move-active-item': splitRight,
+ 'pane:split-up': splitUp,
+ 'pane:split-up-and-copy-active-item': splitUp,
+ 'pane:split-up-and-move-active-item': splitUp,
+ 'pane:split-down': splitDown,
+ 'pane:split-down-and-copy-active-item': splitDown,
+ 'pane:split-down-and-move-active-item': splitDown,
+ 'fuzzy-finder:invert-confirm': () => {
+ this.confirm(
+ this.selectListView.getSelectedItem(),
+ {searchAllPanes: !atom.config.get('fuzzy-finder.searchAllPanes')}
+ )
+ }
+ })
+
+ if (!this.nativeFuzzy) {
+ this.nativeFuzzy = new NativeFuzzy.Matcher(
+ indexArray(this.items.length),
+ this.items.map(el => el.label)
+ )
+ // We need a separate instance of the fuzzy finder to calculate the
+ // matched paths only for the returned results. This speeds up considerably
+ // the filtering of items.
+ this.nativeFuzzyForResults = new NativeFuzzy.Matcher([], [])
+ }
+ this.selectListView.update({ filter: this.filterFn })
+ }
+
+ get element () {
+ return this.selectListView.element
+ }
+
+ destroy () {
+ if (this.panel) {
+ this.panel.destroy()
+ }
+
+ return this.selectListView.destroy()
+ }
+
+ cancel () {
+ if (atom.config.get('fuzzy-finder.preserveLastSearch')) {
+ this.selectListView.refs.queryEditor.selectAll()
+ } else {
+ this.selectListView.reset()
+ }
+
+ this.hide()
+ }
+
+ confirm ({uri} = {}, openOptions) {
+ if (atom.workspace.getActiveTextEditor() && this.isQueryALineJump()) {
+ const caretPosition = this.getCaretPosition()
+ this.cancel()
+ this.moveToCaretPosition(caretPosition)
+ } else if (!uri) {
+ this.cancel()
+ } else if (fs.lstatSync(uri).isDirectory()) {
+ this.selectListView.update({errorMessage: 'Selected path is a directory'})
+ setTimeout(() => { this.selectListView.update({errorMessage: null}) }, 2000)
+ } else {
+ const caretPosition = this.getCaretPosition()
+ this.cancel()
+ this.openURI(uri, caretPosition, openOptions)
+ }
+ }
+
+ getEditorSelection () {
+ const editor = atom.workspace.getActiveTextEditor()
+ if (!editor) {
+ return
+ }
+ const selectedText = editor.getSelectedText()
+ if (/\n/m.test(selectedText)) {
+ return
+ }
+ return selectedText
+ }
+
+ prefillQueryFromSelection () {
+ const selectedText = this.getEditorSelection()
+ if (selectedText) {
+ this.selectListView.refs.queryEditor.setText(selectedText)
+ const textLength = selectedText.length
+ this.selectListView.refs.queryEditor.setSelectedBufferRange([[0, 0], [0, textLength]])
+ }
+ }
+
+ show () {
+ this.previouslyFocusedElement = document.activeElement
+ if (!this.panel) {
+ this.panel = atom.workspace.addModalPanel({item: this})
+ }
+ this.panel.show()
+ if (atom.config.get('fuzzy-finder.prefillFromSelection') === true) {
+ this.prefillQueryFromSelection()
+ }
+ this.selectListView.focus()
+ }
+
+ hide () {
+ if (this.panel) {
+ this.panel.hide()
+ }
+
+ if (this.previouslyFocusedElement) {
+ this.previouslyFocusedElement.focus()
+ this.previouslyFocusedElement = null
+ }
+ }
+
+ async openURI (uri, caretPosition, openOptions) {
+ if (uri) {
+ await atom.workspace.open(uri, openOptions)
+ this.moveToCaretPosition(caretPosition)
+ }
+ }
+
+ moveToCaretPosition (caretPosition) {
+ const editor = atom.workspace.getActiveTextEditor()
+ if (editor && caretPosition.row >= 0) {
+ editor.unfoldBufferRow(caretPosition.row)
+ editor.setCursorBufferPosition(caretPosition)
+ if (caretPosition.column === -1) {
+ editor.moveToFirstCharacterOfLine()
+ }
+
+ editor.scrollToBufferPosition(caretPosition, {center: true})
+ }
+ }
+
+ splitOpenPath (splitFn) {
+ const {uri} = this.selectListView.getSelectedItem() || {}
+ const caretPosition = this.getCaretPosition()
+ const editor = atom.workspace.getActiveTextEditor()
+ const activePane = atom.workspace.getActivePane()
+
+ if (this.isQueryALineJump() && editor) {
+ this.previouslyFocusedElement = null
+ splitFn(activePane)({copyActiveItem: true})
+ this.moveToCaretPosition(caretPosition)
+ } else if (!uri) {
+ return // eslint-disable-line no-useless-return
+ } else if (activePane) {
+ this.previouslyFocusedElement = null
+ splitFn(activePane)()
+ this.openURI(uri, caretPosition)
+ } else {
+ this.previouslyFocusedElement = null
+ this.openURI(uri, caretPosition)
+ }
+ }
+
+ isQueryALineJump () {
+ return (
+ this.selectListView.getFilterQuery().trim() === '' &&
+ this.selectListView.getQuery().includes(':')
+ )
+ }
+
+ getCaretPosition () {
+ const query = this.selectListView.getQuery()
+ const firstColon = query.indexOf(':')
+ const secondColon = query.indexOf(':', firstColon + 1)
+ let position = new Point(-1, -1)
+
+ if (firstColon !== -1) {
+ if (secondColon !== -1) {
+ position.row = parseInt(query.slice(firstColon + 1, secondColon)) - 1
+ const column = parseInt(query.slice(secondColon + 1))
+ position.column = isNaN(column) ? -1 : column
+ } else {
+ position.row = parseInt(query.slice(firstColon + 1)) - 1
+ }
+ }
+
+ return position
+ }
+
+ setItems (items) {
+ this.items = items
+ this.nativeFuzzy.setCandidates(
+ indexArray(this.items.length),
+ this.items.map(item => item.label)
+ )
+
+ if (this.isQueryALineJump()) {
+ this.selectListView.update({
+ items: [],
+ infoMessage: null,
+ loadingMessage: null,
+ loadingBadge: null
+ })
+ } else {
+ this.selectListView.update({
+ items: this.items,
+ infoMessage: null,
+ loadingMessage: null,
+ loadingBadge: null
+ })
+ }
+ }
+
+ projectRelativePathsForFilePaths (filePaths) {
+ // Don't regenerate project relative paths unless the file paths have changed
+ if (filePaths !== this.filePaths) {
+ this.filePaths = filePaths
+ this.projectRelativePaths = this.filePaths.map(
+ (filePath) => this.convertPathToSelectViewObject(filePath)
+ )
+ }
+
+ return this.projectRelativePaths
+ }
+
+ convertPathToSelectViewObject (filePath) {
+ const projectHasMultipleDirectories = atom.project.getDirectories().length > 1
+
+ const [rootPath, projectRelativePath] = atom.project.relativizePath(filePath)
+ const label =
+ rootPath && projectHasMultipleDirectories
+ ? path.join(path.basename(rootPath), projectRelativePath)
+ : projectRelativePath
+
+ return {uri: filePath, filePath, label}
+ }
+
+ filterFn(items, query) {
+ if (!query) return items
+ return this.nativeFuzzy.match(query, {maxResults: MAX_RESULTS})
+ .map(({id}) => this.items[id])
+ }
+}
+
+function highlight (path, matches, offsetIndex) {
+ let lastIndex = 0
+ let matchedChars = []
+ const fragment = document.createDocumentFragment()
+ for (let matchIndex of matches) {
+ matchIndex -= offsetIndex
+ // If marking up the basename, omit path matches
+ if (matchIndex < 0) {
+ continue
+ }
+ const unmatched = path.substring(lastIndex, matchIndex)
+ if (unmatched) {
+ if (matchedChars.length > 0) {
+ const span = document.createElement('span')
+ span.classList.add('character-match')
+ span.textContent = matchedChars.join('')
+ fragment.appendChild(span)
+ matchedChars = []
+ }
+
+ fragment.appendChild(document.createTextNode(unmatched))
+ }
+
+ matchedChars.push(path[matchIndex])
+ lastIndex = matchIndex + 1
+ }
+
+ if (matchedChars.length > 0) {
+ 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(path.substring(lastIndex)))
+ return fragment
+}
+
+function indexArray (length) {
+ const array = []
+ for (let i = 0; i < length; i++) {
+ array[i] = i
+ }
+ return array
+}
+
+class FuzzyFinderItem {
+ constructor ({filePath, label, ownerGitHubUsername, filterQuery, matches, repository}) {
+ this.filePath = filePath
+ this.label = label
+ this.element = document.createElement('li')
+ this.element.className = 'FuzzyFinderResult'
+
+ if (repository) {
+ const status = repository.getCachedPathStatus(filePath)
+ if (repository.isStatusNew(status)) {
+ const div = document.createElement('div')
+ div.classList.add('status', 'status-added', 'icon', 'icon-diff-added')
+ this.element.appendChild(div)
+ } else if (repository.isStatusModified(status)) {
+ const div = document.createElement('div')
+ div.classList.add('status', 'status-modified', 'icon', 'icon-diff-modified')
+ this.element.appendChild(div)
+ }
+ }
+
+ const fileBasename = path.basename(filePath)
+ const baseOffset = label.length - fileBasename.length
+ this.primaryLine = document.createElement('div')
+ this.primaryLine.dataset.name = fileBasename
+ this.primaryLine.dataset.path = label
+ this.primaryLine.classList.add('primary-line', 'file', 'icon')
+ this.primaryLine.appendChild(highlight(fileBasename, matches, baseOffset))
+ this.element.appendChild(this.primaryLine)
+
+ this.secondaryLine = document.createElement('div')
+ this.secondaryLine.classList.add('secondary-line', 'path', 'no-icon')
+ this.secondaryLine.appendChild(highlight(label, matches, 0))
+ this.element.appendChild(this.secondaryLine)
+
+ if (ownerGitHubUsername) {
+ this.element.classList.add('has-avatar')
+ const avatarElement = document.createElement('img')
+ avatarElement.className = 'FuzzyFinderResult-avatar'
+ avatarElement.src = `https://avatars.githubusercontent.com/${ownerGitHubUsername}?size=56`
+ this.element.appendChild(avatarElement)
+ }
+
+ getIconServices().updateIcon(this)
+ }
+}
diff --git a/packages/fuzzy-finder/lib/get-icon-services.js b/packages/fuzzy-finder/lib/get-icon-services.js
new file mode 100644
index 0000000000..d978189b85
--- /dev/null
+++ b/packages/fuzzy-finder/lib/get-icon-services.js
@@ -0,0 +1,63 @@
+const DefaultFileIcons = require('./default-file-icons')
+const {Emitter, CompositeDisposable} = require('atom')
+
+let iconServices
+module.exports = function () {
+ if (!iconServices) iconServices = new IconServices()
+ return iconServices
+}
+
+class IconServices {
+ constructor () {
+ this.emitter = new Emitter()
+ this.elementIcons = null
+ this.elementIconDisposables = new CompositeDisposable()
+ this.fileIcons = DefaultFileIcons
+ }
+
+ onDidChange (callback) {
+ return this.emitter.on('did-change', callback)
+ }
+
+ resetElementIcons () {
+ this.setElementIcons(null)
+ }
+
+ resetFileIcons () {
+ this.setFileIcons(DefaultFileIcons)
+ }
+
+ setElementIcons (service) {
+ if (service !== this.elementIcons) {
+ if (this.elementIconDisposables != null) {
+ this.elementIconDisposables.dispose()
+ }
+ if (service) { this.elementIconDisposables = new CompositeDisposable() }
+ this.elementIcons = service
+ return this.emitter.emit('did-change')
+ }
+ }
+
+ setFileIcons (service) {
+ if (service !== this.fileIcons) {
+ this.fileIcons = service
+ return this.emitter.emit('did-change')
+ }
+ }
+
+ updateIcon (view) {
+ if (this.elementIcons) {
+ const disposable = this.elementIcons(view.primaryLine, view.filePath)
+ this.elementIconDisposables.add(disposable)
+ } else {
+ let classList = []
+ const iconClasses = this.fileIcons.iconClassForPath(view.filePath, 'fuzzy-finder')
+ if (Array.isArray(iconClasses)) {
+ classList = iconClasses
+ } else if (iconClasses) {
+ classList = iconClasses.toString().split(/\s+/g)
+ }
+ view.primaryLine.classList.add(...classList)
+ }
+ }
+}
diff --git a/packages/fuzzy-finder/lib/git-status-view.js b/packages/fuzzy-finder/lib/git-status-view.js
new file mode 100644
index 0000000000..8876d17710
--- /dev/null
+++ b/packages/fuzzy-finder/lib/git-status-view.js
@@ -0,0 +1,32 @@
+const fs = require('fs')
+const path = require('path')
+
+const FuzzyFinderView = require('./fuzzy-finder-view')
+
+module.exports =
+class GitStatusView extends FuzzyFinderView {
+ async toggle () {
+ if (this.panel && this.panel.isVisible()) {
+ this.cancel()
+ } else if (atom.project.getRepositories().some((repo) => repo)) {
+ const paths = []
+ for (const repo of atom.project.getRepositories()) {
+ if (repo) {
+ const workingDirectory = repo.getWorkingDirectory()
+ for (let filePath in repo.statuses) {
+ filePath = path.join(workingDirectory, filePath)
+ if (fs.lstatSync(filePath).isFile()) {
+ paths.push(filePath)
+ }
+ }
+ }
+ }
+ this.show()
+ await this.setItems(this.projectRelativePathsForFilePaths(paths))
+ }
+ }
+
+ getEmptyMessage () {
+ return 'Nothing to commit, working directory clean'
+ }
+}
diff --git a/packages/fuzzy-finder/lib/helpers.js b/packages/fuzzy-finder/lib/helpers.js
new file mode 100644
index 0000000000..3a1c8744c3
--- /dev/null
+++ b/packages/fuzzy-finder/lib/helpers.js
@@ -0,0 +1,14 @@
+const path = require('path')
+
+module.exports = {
+ repositoryForPath (filePath) {
+ const paths = atom.project.getPaths()
+ for (let i = 0; i < paths.length; i++) {
+ const projectPath = paths[i]
+ if ((filePath === projectPath) || filePath.startsWith(projectPath + path.sep)) {
+ return atom.project.getRepositories()[i]
+ }
+ }
+ return null
+ }
+}
diff --git a/packages/fuzzy-finder/lib/load-paths-handler.js b/packages/fuzzy-finder/lib/load-paths-handler.js
new file mode 100644
index 0000000000..95e72cc76d
--- /dev/null
+++ b/packages/fuzzy-finder/lib/load-paths-handler.js
@@ -0,0 +1,203 @@
+/* global emit */
+
+const async = require('async')
+const fs = require('fs')
+const os = require('os')
+const path = require('path')
+const {GitRepository} = require('atom')
+const {Minimatch} = require('minimatch')
+const childProcess = require('child_process')
+const { rgPath } = require('vscode-ripgrep')
+
+const PathsChunkSize = 100
+
+// Use the unpacked path if the ripgrep binary is in asar archive.
+const realRgPath = rgPath.replace(/\bapp\.asar\b/, 'app.asar.unpacked')
+
+// Define the maximum number of concurrent crawling processes based on the number of CPUs
+// with a maximum value of 8 and minimum of 1.
+const MaxConcurrentCrawls = Math.min(Math.max(os.cpus().length - 1, 8), 1)
+
+const emittedPaths = new Set()
+
+class PathLoader {
+ constructor (rootPath, ignoreVcsIgnores, traverseSymlinkDirectories, ignoredNames, useRipGrep) {
+ this.rootPath = rootPath
+ this.ignoreVcsIgnores = ignoreVcsIgnores
+ this.traverseSymlinkDirectories = traverseSymlinkDirectories
+ this.ignoredNames = ignoredNames
+ this.useRipGrep = useRipGrep
+ this.paths = []
+ this.inodes = new Set()
+ this.repo = null
+ if (ignoreVcsIgnores && !this.useRipGrep) {
+ const repo = GitRepository.open(this.rootPath, {refreshOnWindowFocus: false})
+ if ((repo && repo.relativize(path.join(this.rootPath, 'test'))) === 'test') {
+ this.repo = repo
+ }
+ }
+ }
+
+ load (done) {
+ if (this.useRipGrep) {
+ this.loadFromRipGrep().then(done)
+
+ return
+ }
+
+ this.loadPath(this.rootPath, true, () => {
+ this.flushPaths()
+ if (this.repo != null) this.repo.destroy()
+ done()
+ })
+ }
+
+ async loadFromRipGrep () {
+ return new Promise((resolve) => {
+ const args = ['--files', '--hidden', '--sort', 'path']
+
+ if (!this.ignoreVcsIgnores) {
+ args.push('--no-ignore')
+ }
+
+ if (this.traverseSymlinkDirectories) {
+ args.push('--follow')
+ }
+
+ for (let ignoredName of this.ignoredNames) {
+ args.push('-g', '!' + ignoredName.pattern)
+ }
+
+ if (this.ignoreVcsIgnores) {
+ if (!args.includes('!.git')) args.push('-g', '!.git')
+ if (!args.includes('!.hg')) args.push('-g', '!.hg')
+ }
+
+ let output = ''
+ const result = childProcess.spawn(realRgPath, args, {cwd: this.rootPath})
+
+ result.stdout.on('data', chunk => {
+ const files = (output + chunk).split('\n')
+ output = files.pop()
+
+ for (const file of files) {
+ this.pathLoaded(path.join(this.rootPath, file))
+ }
+ })
+ result.stderr.on('data', () => {
+ // intentionally ignoring errors for now
+ })
+ result.on('close', () => {
+ this.flushPaths()
+ resolve()
+ })
+ })
+ }
+
+ isIgnored (loadedPath) {
+ const relativePath = path.relative(this.rootPath, loadedPath)
+ if (this.repo && this.repo.isPathIgnored(relativePath)) {
+ return true
+ } else {
+ for (let ignoredName of this.ignoredNames) {
+ if (ignoredName.match(relativePath)) return true
+ }
+ }
+ }
+
+ pathLoaded (loadedPath, done) {
+ if (!emittedPaths.has(loadedPath)) {
+ this.paths.push(loadedPath)
+ emittedPaths.add(loadedPath)
+ }
+
+ if (this.paths.length === PathsChunkSize) {
+ this.flushPaths()
+ }
+ done && done()
+ }
+
+ flushPaths () {
+ emit('load-paths:paths-found', this.paths)
+ this.paths = []
+ }
+
+ loadPath (pathToLoad, root, done) {
+ if (this.isIgnored(pathToLoad) && !root) return done()
+
+ fs.lstat(pathToLoad, (error, stats) => {
+ if (error != null) { return done() }
+ if (stats.isSymbolicLink()) {
+ fs.stat(pathToLoad, (error, stats) => {
+ if (error != null) return done()
+ if (this.inodes.has(stats.ino)) {
+ return done()
+ } else {
+ this.inodes.add(stats.ino)
+ }
+
+ if (stats.isFile()) {
+ this.pathLoaded(pathToLoad, done)
+ } else if (stats.isDirectory()) {
+ if (this.traverseSymlinkDirectories) {
+ this.loadFolder(pathToLoad, done)
+ } else {
+ done()
+ }
+ } else {
+ done()
+ }
+ })
+ } else {
+ this.inodes.add(stats.ino)
+ if (stats.isDirectory()) {
+ this.loadFolder(pathToLoad, done)
+ } else if (stats.isFile()) {
+ this.pathLoaded(pathToLoad, done)
+ } else {
+ done()
+ }
+ }
+ })
+ }
+
+ loadFolder (folderPath, done) {
+ fs.readdir(folderPath, (_, children = []) => {
+ async.each(
+ children,
+ (childName, next) => {
+ this.loadPath(path.join(folderPath, childName), false, next)
+ },
+ done
+ )
+ })
+ }
+}
+
+module.exports = function (rootPaths, followSymlinks, ignoreVcsIgnores, ignores, useRipGrep) {
+ const ignoredNames = []
+ for (let ignore of ignores) {
+ if (ignore) {
+ try {
+ ignoredNames.push(new Minimatch(ignore, {matchBase: true, dot: true}))
+ } catch (error) {
+ console.warn(`Error parsing ignore pattern (${ignore}): ${error.message}`)
+ }
+ }
+ }
+
+ async.eachLimit(
+ rootPaths,
+ MaxConcurrentCrawls,
+ (rootPath, next) =>
+ new PathLoader(
+ rootPath,
+ ignoreVcsIgnores,
+ followSymlinks,
+ ignoredNames,
+ useRipGrep
+ ).load(next)
+ ,
+ this.async()
+ )
+}
diff --git a/packages/fuzzy-finder/lib/main.js b/packages/fuzzy-finder/lib/main.js
new file mode 100644
index 0000000000..1a5aa055d1
--- /dev/null
+++ b/packages/fuzzy-finder/lib/main.js
@@ -0,0 +1,149 @@
+const {CompositeDisposable, Disposable} = require('atom')
+const getIconServices = require('./get-icon-services')
+const ReporterProxy = require('./reporter-proxy')
+
+const metricsReporter = new ReporterProxy()
+
+module.exports = {
+ activate (state) {
+ this.active = true
+
+ this.disposables = new CompositeDisposable()
+
+ this.disposables.add(atom.commands.add('atom-workspace', {
+ 'fuzzy-finder:toggle-file-finder': () => {
+ this.createProjectView().toggle()
+ },
+ 'fuzzy-finder:toggle-buffer-finder': () => {
+ this.createBufferView().toggle()
+ },
+ 'fuzzy-finder:toggle-git-status-finder': () => {
+ this.createGitStatusView().toggle()
+ }
+ }))
+
+ process.nextTick(() => this.startLoadPathsTask())
+
+ for (let editor of atom.workspace.getTextEditors()) {
+ editor.lastOpened = state[editor.getPath()]
+ }
+
+ this.disposables.add(atom.workspace.observePanes(pane => {
+ this.disposables.add(pane.observeActiveItem(item => {
+ if (item != null) item.lastOpened = Date.now()
+ }))
+ }))
+ },
+
+ deactivate () {
+ this.disposables.dispose()
+
+ if (this.projectView != null) {
+ this.projectView.destroy()
+ this.projectView = null
+ }
+ if (this.bufferView != null) {
+ this.bufferView.destroy()
+ this.bufferView = null
+ }
+ if (this.gitStatusView != null) {
+ this.gitStatusView.destroy()
+ this.gitStatusView = null
+ }
+ this.projectPaths = null
+ this.stopLoadPathsTask()
+ this.active = false
+ },
+
+ consumeElementIcons (service) {
+ getIconServices().setElementIcons(service)
+ return new Disposable(() => getIconServices().resetElementIcons())
+ },
+
+ consumeFileIcons (service) {
+ getIconServices().setFileIcons(service)
+ return new Disposable(() => getIconServices().resetFileIcons())
+ },
+
+ consumeTeletype (teletypeService) {
+ this.teletypeService = teletypeService
+ if (this.bufferView) this.bufferView.setTeletypeService(teletypeService)
+ if (this.projectView) this.projectView.setTeletypeService(teletypeService)
+ },
+
+ consumeMetricsReporter (metricsReporterService) {
+ metricsReporter.setReporter(metricsReporterService)
+
+ return new Disposable(() => metricsReporter.unsetReporter())
+ },
+
+ serialize () {
+ const paths = {}
+ for (let editor of atom.workspace.getTextEditors()) {
+ const path = editor.getPath()
+ if (path != null) { paths[path] = editor.lastOpened }
+ }
+ return paths
+ },
+
+ createProjectView () {
+ this.stopLoadPathsTask()
+
+ if (this.projectView == null) {
+ const ProjectView = require('./project-view')
+ this.projectView = new ProjectView(this.projectPaths, metricsReporter)
+ this.projectPaths = null
+ if (this.teletypeService) {
+ this.projectView.setTeletypeService(this.teletypeService)
+ }
+ }
+ return this.projectView
+ },
+
+ createGitStatusView () {
+ if (this.gitStatusView == null) {
+ const GitStatusView = require('./git-status-view')
+ this.gitStatusView = new GitStatusView(metricsReporter)
+ }
+ return this.gitStatusView
+ },
+
+ createBufferView () {
+ if (this.bufferView == null) {
+ const BufferView = require('./buffer-view')
+ this.bufferView = new BufferView(metricsReporter)
+ if (this.teletypeService) {
+ this.bufferView.setTeletypeService(this.teletypeService)
+ }
+ }
+ return this.bufferView
+ },
+
+ startLoadPathsTask () {
+ this.stopLoadPathsTask()
+
+ if (!this.active) return
+ if (atom.project.getPaths().length === 0) return
+
+ const PathLoader = require('./path-loader')
+ this.loadPathsTask = PathLoader.startTask((projectPaths) => {
+ this.projectPaths = projectPaths
+ }, metricsReporter)
+ this.projectPathsSubscription = atom.project.onDidChangePaths(() => {
+ this.projectPaths = null
+ this.stopLoadPathsTask()
+ })
+ },
+
+ stopLoadPathsTask () {
+ if (this.projectPathsSubscription != null) {
+ this.projectPathsSubscription.dispose()
+ }
+ this.projectPathsSubscription = null
+
+ if (this.loadPathsTask != null) {
+ this.loadPathsTask.terminate()
+ }
+ this.loadPathsTask = null
+ }
+}
diff --git a/packages/fuzzy-finder/lib/path-loader.js b/packages/fuzzy-finder/lib/path-loader.js
new file mode 100644
index 0000000000..7a2e4bf84b
--- /dev/null
+++ b/packages/fuzzy-finder/lib/path-loader.js
@@ -0,0 +1,44 @@
+const fs = require('fs')
+const {Task} = require('atom')
+
+module.exports = {
+ startTask (callback, metricsReporter) {
+ const results = []
+ const taskPath = require.resolve('./load-paths-handler')
+ const followSymlinks = atom.config.get('core.followSymlinks')
+ let ignoredNames = atom.config.get('fuzzy-finder.ignoredNames') || []
+ ignoredNames = ignoredNames.concat(atom.config.get('core.ignoredNames') || [])
+ const ignoreVcsIgnores = atom.config.get('core.excludeVcsIgnoredPaths')
+ const projectPaths = atom.project.getPaths().map((path) => fs.realpathSync(path))
+ const useRipGrep = atom.config.get('fuzzy-finder.useRipGrep')
+
+ const startTime = performance.now()
+
+ const task = Task.once(
+ taskPath,
+ projectPaths,
+ followSymlinks,
+ ignoreVcsIgnores,
+ ignoredNames,
+ useRipGrep,
+ () => {
+ callback(results)
+
+ const duration = Math.round(performance.now() - startTime)
+ const numFiles = results.length
+ const crawlerType = useRipGrep ? 'ripgrep' : 'fs'
+
+ metricsReporter.sendCrawlEvent(duration, numFiles, crawlerType)
+ }
+ )
+
+ task.on('load-paths:paths-found',
+ (paths) => {
+ paths = paths || []
+ results.push(...paths)
+ }
+ )
+
+ return task
+ }
+}
diff --git a/packages/fuzzy-finder/lib/project-view.js b/packages/fuzzy-finder/lib/project-view.js
new file mode 100644
index 0000000000..3d3d082817
--- /dev/null
+++ b/packages/fuzzy-finder/lib/project-view.js
@@ -0,0 +1,191 @@
+const {Disposable, CompositeDisposable} = require('atom')
+const humanize = require('humanize-plus')
+
+const FuzzyFinderView = require('./fuzzy-finder-view')
+const PathLoader = require('./path-loader')
+
+module.exports =
+class ProjectView extends FuzzyFinderView {
+ constructor (paths, metricsReporter) {
+ super(metricsReporter)
+ this.disposables = new CompositeDisposable()
+ this.paths = paths
+ this.reloadPaths = !this.paths || this.paths.length === 0
+ this.reloadAfterFirstLoad = false
+
+ const windowFocused = () => {
+ if (this.paths) {
+ this.reloadPaths = true
+ } else {
+ // The window gained focused while the first task was still running
+ // so let it complete but reload the paths on the next populate call.
+ this.reloadAfterFirstLoad = true
+ }
+ }
+ window.addEventListener('focus', windowFocused)
+ this.disposables.add(new Disposable(() => { window.removeEventListener('focus', windowFocused) }))
+
+ this.disposables.add(atom.config.onDidChange('fuzzy-finder.ignoredNames', () => { this.reloadPaths = true }))
+ this.disposables.add(atom.config.onDidChange('core.followSymlinks', () => { this.reloadPaths = true }))
+ this.disposables.add(atom.config.onDidChange('core.ignoredNames', () => { this.reloadPaths = true }))
+ this.disposables.add(atom.config.onDidChange('core.excludeVcsIgnoredPaths', () => { this.reloadPaths = true }))
+ this.disposables.add(atom.project.onDidChangePaths(() => {
+ this.reloadPaths = true
+ this.paths = null
+ }))
+
+ if (!this.reloadPaths) {
+ this.populate()
+ }
+ }
+
+ destroy () {
+ if (this.loadPathsTask) {
+ this.loadPathsTask.terminate()
+ }
+
+ this.disposables.dispose()
+ return super.destroy()
+ }
+
+ setTeletypeService (teletypeService) {
+ this.teletypeService = teletypeService
+ }
+
+ async toggle () {
+ if (this.panel && this.panel.isVisible()) {
+ this.cancel()
+ } else {
+ this.show()
+ await this.reloadPathsIfNeeded()
+ }
+ }
+
+ async populate () {
+ const remoteEditors = (this.teletypeService && await this.teletypeService.getRemoteEditors()) || []
+
+ const remoteItems = remoteEditors.map((remoteEditor) => {
+ return {
+ uri: remoteEditor.uri,
+ filePath: remoteEditor.path,
+ label: `@${remoteEditor.hostGitHubUsername}: ${remoteEditor.path}`,
+ ownerGitHubUsername: remoteEditor.hostGitHubUsername
+ }
+ })
+
+ const localItems = this.projectRelativePathsForFilePaths(this.paths || [])
+ await this.setItems(remoteItems.concat(localItems))
+ }
+
+ async reloadPathsIfNeeded () {
+ if (this.reloadPaths) {
+ this.reloadPaths = false
+ let task = null
+
+ if (atom.project.getPaths().length === 0) {
+ return this.populate()
+ }
+
+ try {
+ task = this.runLoadPathsTask(() => {
+ if (this.reloadAfterFirstLoad) {
+ this.reloadPaths = true
+ this.reloadAfterFirstLoad = false
+ }
+
+ this.populate()
+ })
+ } catch (error) {
+ // If, for example, a network drive is unmounted, @runLoadPathsTask will
+ // throw ENOENT when it tries to get the realpath of all the project paths.
+ // This catch block allows the file finder to still operate on the last
+ // set of paths and still let the user know that something is wrong.
+ if (error.code === 'ENOENT' || error.code === 'EPERM') {
+ atom.notifications.addError('Project path not found!', {detail: error.message})
+ } else {
+ throw error
+ }
+ }
+
+ if (this.paths) {
+ await this.selectListView.update({loadingMessage: 'Reindexing project\u2026', infoMessage: null})
+ } else {
+ await this.selectListView.update({loadingMessage: 'Indexing project\u2026', infoMessage: null, loadingBadge: '0'})
+ if (task) {
+ let pathsFound = 0
+ task.on('load-paths:paths-found', (paths) => {
+ pathsFound += paths.length
+ this.selectListView.update({loadingMessage: 'Indexing project\u2026', infoMessage: null, loadingBadge: humanize.intComma(pathsFound)})
+ })
+ }
+ }
+ }
+ }
+
+ getEmptyMessage () {
+ return 'Project is empty'
+ }
+
+ projectRelativePathsForFilePaths (filePaths) {
+ const projectRelativePaths = super.projectRelativePathsForFilePaths(filePaths)
+ const lastOpenedPath = this.getLastOpenedPath()
+ if (lastOpenedPath) {
+ for (let i = 0; i < projectRelativePaths.length; i++) {
+ const {filePath} = projectRelativePaths[i]
+ if (filePath === lastOpenedPath) {
+ const [entry] = projectRelativePaths.splice(i, 1)
+ projectRelativePaths.unshift(entry)
+ break
+ }
+ }
+ }
+
+ return projectRelativePaths
+ }
+
+ getLastOpenedPath () {
+ let activePath = null
+ const activePaneItem = atom.workspace.getActivePaneItem()
+ if (activePaneItem && activePaneItem.getPath) {
+ activePath = activePaneItem.getPath()
+ }
+
+ let lastOpenedEditor = null
+ for (const editor of atom.workspace.getTextEditors()) {
+ const filePath = editor.getPath()
+ if (!filePath) {
+ continue
+ }
+
+ if (activePath === filePath) {
+ continue
+ }
+
+ if (!lastOpenedEditor) {
+ lastOpenedEditor = editor
+ }
+
+ if (editor.lastOpened > lastOpenedEditor.lastOpened) {
+ lastOpenedEditor = editor
+ }
+ }
+
+ return lastOpenedEditor ? lastOpenedEditor.getPath() : null
+ }
+
+ runLoadPathsTask (fn) {
+ if (this.loadPathsTask) {
+ this.loadPathsTask.terminate()
+ }
+
+ this.loadPathsTask = PathLoader.startTask((paths) => {
+ this.paths = paths
+ this.reloadPaths = false
+ if (fn) {
+ fn()
+ }
+ }, this.metricsReporter)
+
+ return this.loadPathsTask
+ }
+}
diff --git a/packages/fuzzy-finder/lib/reporter-proxy.js b/packages/fuzzy-finder/lib/reporter-proxy.js
new file mode 100644
index 0000000000..d21e996de7
--- /dev/null
+++ b/packages/fuzzy-finder/lib/reporter-proxy.js
@@ -0,0 +1,69 @@
+const _ = require('underscore-plus')
+
+module.exports = class ReporterProxy {
+ constructor () {
+ this.reporter = null
+ this.timingsQueue = []
+ this.countersQueue = []
+
+ this.eventType = 'fuzzy-finder-v1'
+
+ this._addTimingThrottled = _.throttle(this._addTiming.bind(this), 60 * 1000)
+ }
+
+ setReporter (reporter) {
+ this.reporter = reporter
+ let timingsEvent
+ let counterName
+
+ while ((timingsEvent = this.timingsQueue.shift())) {
+ this.reporter.addTiming(this.eventType, timingsEvent[0], timingsEvent[1])
+ }
+
+ while ((counterName = this.countersQueue.shift())) {
+ this.reporter.incrementCounter(counterName)
+ }
+ }
+
+ unsetReporter () {
+ this._addTimingThrottled.cancel()
+
+ delete this.reporter
+ }
+
+ sendCrawlEvent (duration, numFiles, crawlerType) {
+ const metadata = {
+ ec: 'time-to-crawl',
+ el: crawlerType,
+ ev: numFiles
+ }
+
+ this._addTiming(duration, metadata)
+ }
+
+ sendFilterEvent (duration, numFiles, scoringSystem) {
+ const metadata = {
+ ec: 'time-to-filter',
+ el: scoringSystem,
+ ev: numFiles
+ }
+
+ this._addTimingThrottled(duration, metadata)
+ }
+
+ incrementCounter (counterName) {
+ if (this.reporter) {
+ this.reporter.incrementCounter(counterName)
+ } else {
+ this.countersQueue.push(counterName)
+ }
+ }
+
+ _addTiming (duration, metadata) {
+ if (this.reporter) {
+ this.reporter.addTiming(this.eventType, duration, metadata)
+ } else {
+ this.timingsQueue.push([duration, metadata])
+ }
+ }
+}
diff --git a/packages/fuzzy-finder/menus/fuzzy-finder.cson b/packages/fuzzy-finder/menus/fuzzy-finder.cson
new file mode 100644
index 0000000000..2ed30f59c0
--- /dev/null
+++ b/packages/fuzzy-finder/menus/fuzzy-finder.cson
@@ -0,0 +1,8 @@
+'menu': [
+ 'label': 'Find'
+ 'submenu': [
+ { 'label': 'Find Buffer', 'command': 'fuzzy-finder:toggle-buffer-finder' }
+ { 'label': 'Find File', 'command': 'fuzzy-finder:toggle-file-finder' }
+ { 'label': 'Find Modified File', 'command': 'fuzzy-finder:toggle-git-status-finder' }
+ ]
+]
diff --git a/packages/fuzzy-finder/package-lock.json b/packages/fuzzy-finder/package-lock.json
new file mode 100644
index 0000000000..4cbac07352
--- /dev/null
+++ b/packages/fuzzy-finder/package-lock.json
@@ -0,0 +1,5342 @@
+{
+ "name": "fuzzy-finder",
+ "version": "1.14.3",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "fuzzy-finder",
+ "version": "1.14.3",
+ "license": "MIT",
+ "dependencies": {
+ "@atom/fuzzy-native": "^1.1.2",
+ "async": "0.2.6",
+ "atom-select-list": "^0.7.0",
+ "fs-plus": "^3.0.0",
+ "fuzzaldrin": "^2.0",
+ "fuzzaldrin-plus": "^0.6.0",
+ "humanize-plus": "~1.8.2",
+ "minimatch": "~3.0.3",
+ "temp": "~0.8.1",
+ "underscore-plus": "^1.7.0",
+ "vscode-ripgrep": "^1.2.5",
+ "wrench": "^1.5"
+ },
+ "devDependencies": {
+ "sinon": "9.0.3",
+ "standard": "^10.0.3"
+ },
+ "engines": {
+ "atom": "*"
+ }
+ },
+ "node_modules/@atom/fuzzy-native": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@atom/fuzzy-native/-/fuzzy-native-1.2.1.tgz",
+ "integrity": "sha512-ABUIbeQqfoA4WUK+PAsspM9jLaGlj0wjyIc9CIi1OMAHv71/vqrpJHPX2fHWiREEXYxwh/CBCshhkOWESbnNnQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "nan": "^2.14.2"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+ "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@sinonjs/formatio": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
+ "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^5.0.2"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz",
+ "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/text-encoding": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
+ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^3.0.4"
+ }
+ },
+ "node_modules/acorn-jsx/node_modules/acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
+ "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==",
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==",
+ "dev": true,
+ "dependencies": {
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": ">=4.10.0"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/array.prototype.find": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.2.1.tgz",
+ "integrity": "sha512-I2ri5Z9uMpMvnsNrHre9l3PaX+z9D0/z6F7Yt2u15q7wt0I62g5kX6xUKR1SJiefgG+u2/gJUmM8B47XRvQR6w==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/async": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz",
+ "integrity": "sha512-LTdAJ0KBRK5o4BlBlUoGvfGNOMON+NLbONgDZk80SX0G8LQZyjN+74nNADIpQ/+rxun6+fYm7z4vIzAB51UKUA=="
+ },
+ "node_modules/atom-select-list": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.7.2.tgz",
+ "integrity": "sha512-a707OB1DhLGjzqtFrtMQKH7BBxFuCh8UBoUWxgFOrLrSwVh3g+/TlVPVDOz12+U0mDu3mIrnYLqQyhywQOTxhw==",
+ "dependencies": {
+ "etch": "^0.12.6",
+ "fuzzaldrin": "^2.1.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ }
+ },
+ "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/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "deprecated": "CircularJSON is in maintenance only, flatted is its successor.",
+ "dev": true
+ },
+ "node_modules/cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cli-width": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+ "dev": true
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8"
+ ],
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
+ },
+ "node_modules/d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dev": true,
+ "dependencies": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/debug-log": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz",
+ "integrity": "sha512-gV/pe1YIaKNgLYnd1g9VNW80tcb7oV5qvNUxG7NM8rbDpnl6RGunzlAtlGSb0wEs3nesu2vHNiX9TSsZ+Y+RjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "dependencies": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/deglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz",
+ "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==",
+ "dev": true,
+ "dependencies": {
+ "find-root": "^1.0.0",
+ "glob": "^7.0.5",
+ "ignore": "^3.0.9",
+ "pkg-config": "^1.1.0",
+ "run-parallel": "^1.1.2",
+ "uniq": "^1.0.1"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.21.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz",
+ "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.1.3",
+ "get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.4",
+ "is-array-buffer": "^3.0.1",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.10",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.2",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.4.3",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trimend": "^1.0.6",
+ "string.prototype.trimstart": "^1.0.6",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+ "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+ "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "dev": true,
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
+ "dev": true,
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-set": "~0.1.5",
+ "es6-symbol": "~3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "node_modules/es6-set": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz",
+ "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
+ "dev": true,
+ "dependencies": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.62",
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "^3.1.3",
+ "event-emitter": "^0.3.5",
+ "type": "^2.7.2"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/es6-set/node_modules/type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "dev": true
+ },
+ "node_modules/es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dev": true,
+ "dependencies": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "node_modules/es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "dev": true,
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==",
+ "dev": true,
+ "dependencies": {
+ "es6-map": "^0.1.3",
+ "es6-weak-map": "^2.0.1",
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz",
+ "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==",
+ "dev": true,
+ "dependencies": {
+ "babel-code-frame": "^6.16.0",
+ "chalk": "^1.1.3",
+ "concat-stream": "^1.5.2",
+ "debug": "^2.1.1",
+ "doctrine": "^2.0.0",
+ "escope": "^3.6.0",
+ "espree": "^3.4.0",
+ "esquery": "^1.0.0",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "glob": "^7.0.3",
+ "globals": "^9.14.0",
+ "ignore": "^3.2.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^0.12.0",
+ "is-my-json-valid": "^2.10.0",
+ "is-resolvable": "^1.0.0",
+ "js-yaml": "^3.5.1",
+ "json-stable-stringify": "^1.0.0",
+ "levn": "^0.3.0",
+ "lodash": "^4.0.0",
+ "mkdirp": "^0.5.0",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.1",
+ "pluralize": "^1.2.1",
+ "progress": "^1.1.8",
+ "require-uncached": "^1.0.2",
+ "shelljs": "^0.7.5",
+ "strip-bom": "^3.0.0",
+ "strip-json-comments": "~2.0.1",
+ "table": "^3.7.8",
+ "text-table": "~0.2.0",
+ "user-home": "^2.0.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-config-standard": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz",
+ "integrity": "sha512-UkFojTV1o0GOe1edOEiuI5ccYLJSuNngtqSeClNzhsmG8KPJ+7mRxgtp2oYhqZAK/brlXMoCd+VgXViE0AfyKw==",
+ "dev": true,
+ "peerDependencies": {
+ "eslint": ">=3.19.0",
+ "eslint-plugin-import": ">=2.2.0",
+ "eslint-plugin-node": ">=4.2.2",
+ "eslint-plugin-promise": ">=3.5.0",
+ "eslint-plugin-standard": ">=3.0.0"
+ }
+ },
+ "node_modules/eslint-config-standard-jsx": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz",
+ "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==",
+ "dev": true,
+ "peerDependencies": {
+ "eslint": ">=3.19.0",
+ "eslint-plugin-react": ">=6.10.3"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz",
+ "integrity": "sha512-HI8ShtDIy7gON76Nr3bu4zl0DuCLPo1Fud9P2lltOQKeiAS2r5/o/l3y+V8HJ1cDLFSz+tHu7/V9fI5jirwlbw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.2.0",
+ "object-assign": "^4.0.1",
+ "resolve": "^1.1.6"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz",
+ "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz",
+ "integrity": "sha512-8HLeIYzOH4eltevxf+iC9Dtz/91yaeOqtlba5srcpQWLrv57F5NNG1RNLqAbpWJWDD4BxKuKjUveJY9W6Tbswg==",
+ "dev": true,
+ "dependencies": {
+ "builtin-modules": "^1.1.1",
+ "contains-path": "^0.1.0",
+ "debug": "^2.2.0",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.2.0",
+ "eslint-module-utils": "^2.0.0",
+ "has": "^1.0.1",
+ "lodash.cond": "^4.3.0",
+ "minimatch": "^3.0.3",
+ "pkg-up": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "2.x - 3.x"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-node": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz",
+ "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==",
+ "dev": true,
+ "dependencies": {
+ "ignore": "^3.0.11",
+ "minimatch": "^3.0.2",
+ "object-assign": "^4.0.1",
+ "resolve": "^1.1.7",
+ "semver": "5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": ">=3.1.0"
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz",
+ "integrity": "sha512-kqXN7i1wfx5j7XuFVzuX4W3XDCEyNDsbd+O5NXWIl+zTSP510rKn2Xk8OO6JhM1ivXbkse0tQf6jjSTLS58Prg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz",
+ "integrity": "sha512-vFfMSxJynKlgOhIVjhlZyibVUg442Aiv3482XPkgdYV90T8nD2QvxGXILZGwZHYMQ/l+A/De14O9D0qjDelSrg==",
+ "dev": true,
+ "dependencies": {
+ "array.prototype.find": "^2.0.1",
+ "doctrine": "^1.2.2",
+ "has": "^1.0.1",
+ "jsx-ast-utils": "^1.3.4",
+ "object.assign": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=0.10"
+ },
+ "peerDependencies": {
+ "eslint": "^2.0.0 || ^3.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-standard": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz",
+ "integrity": "sha512-JyT7wqVYlaHxnljWMT7CKa0R1QDQqArTi6g8kYnexTHHuK7x3Vg//kCepnoTgdT9x/kDbSluXMhJgjBvgVRLlQ==",
+ "dev": true,
+ "peerDependencies": {
+ "eslint": ">=3.19.0"
+ }
+ },
+ "node_modules/espree": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^5.5.0",
+ "acorn-jsx": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/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/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/esrecurse/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/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "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.12.8",
+ "resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz",
+ "integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ=="
+ },
+ "node_modules/event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "dev": true,
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "node_modules/exit-hook": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "dev": true,
+ "dependencies": {
+ "type": "^2.7.2"
+ }
+ },
+ "node_modules/ext/node_modules/type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "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/figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "dev": true
+ },
+ "node_modules/find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
+ "dev": true,
+ "dependencies": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+ "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+ "dev": true,
+ "dependencies": {
+ "circular-json": "^0.3.1",
+ "graceful-fs": "^4.1.2",
+ "rimraf": "~2.6.2",
+ "write": "^0.2.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/flat-cache/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/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "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.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/fuzzaldrin": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz",
+ "integrity": "sha512-zgllBYwfHR5P3CncJiGbGVPpa3iFYW1yuPaIv8DiTVRrcg5/6uETNL5zvIoKflG1aifXVUZTlIroDehw4WygGA=="
+ },
+ "node_modules/fuzzaldrin-plus": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz",
+ "integrity": "sha512-srIDThJHkdp3aPwJpR/HNzYZCRJwm07b/igxseoHSB7qR8e/gQp4F6lMGknE3TQI1Aq14TiFf/wzrHOp9LY/EA=="
+ },
+ "node_modules/generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "dev": true,
+ "dependencies": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "node_modules/generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==",
+ "dev": true,
+ "dependencies": {
+ "is-property": "^1.0.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+ "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/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/globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz",
+ "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==",
+ "dependencies": {
+ "agent-base": "5",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/https-proxy-agent/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=="
+ },
+ "node_modules/humanize-plus": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/humanize-plus/-/humanize-plus-1.8.2.tgz",
+ "integrity": "sha512-jaLeQyyzjjINGv7O9JJegjsaUcWjSj/1dcXvLEgU3pGdqCdP1PiC/uwr+saJXhTNBHZtmKnmpXyazgh+eceRxA==",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+ "dev": true
+ },
+ "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/inquirer": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+ "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^1.1.0",
+ "ansi-regex": "^2.0.0",
+ "chalk": "^1.0.0",
+ "cli-cursor": "^1.0.1",
+ "cli-width": "^2.0.0",
+ "figures": "^1.3.5",
+ "lodash": "^4.3.0",
+ "readline2": "^1.0.1",
+ "run-async": "^0.1.0",
+ "rx-lite": "^3.1.2",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.0",
+ "through": "^2.3.6"
+ }
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz",
+ "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz",
+ "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-typed-array": "^1.1.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "dev": true,
+ "dependencies": {
+ "number-is-nan": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-my-ip-valid": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz",
+ "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==",
+ "dev": true
+ },
+ "node_modules/is-my-json-valid": {
+ "version": "2.20.6",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz",
+ "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==",
+ "dev": true,
+ "dependencies": {
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "is-my-ip-valid": "^1.0.0",
+ "jsonpointer": "^5.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
+ "dev": true
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+ "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
+ },
+ "node_modules/js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz",
+ "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==",
+ "dev": true,
+ "dependencies": {
+ "jsonify": "^0.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jsonify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
+ "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jsonpointer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
+ "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz",
+ "integrity": "sha512-0LwSmMlQjjUdXsdlyYhEfBJCn2Chm0zgUBmfmf1++KUULh+JOdlzrZfiwe2zmlVJx44UF+KX/B/odBoeK9hxmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/just-extend": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
+ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
+ "dev": true
+ },
+ "node_modules/levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/locate-path/node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.cond": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
+ "integrity": "sha512-RWjUhzGbzG/KfDwk+onqdXvrsNv47G9UCMJgSKalPTSqJQyxZhQophG9jgqLf+15TIbZ5a/yG2YKOWsH3dVy9A==",
+ "dev": true
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+ "dev": true
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+ "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+ "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.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "node_modules/mute-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+ "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==",
+ "dev": true
+ },
+ "node_modules/nan": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
+ },
+ "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/next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+ "dev": true
+ },
+ "node_modules/nise": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz",
+ "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0",
+ "@sinonjs/fake-timers": "^6.0.0",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "node_modules/number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/onetime": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
+ "dev": true,
+ "dependencies": {
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==",
+ "dev": true
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dev": true,
+ "dependencies": {
+ "isarray": "0.0.1"
+ }
+ },
+ "node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "dev": true,
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-config": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz",
+ "integrity": "sha512-ft/WI9YK6FuTuw4Ql+QUaNXtm/ASQNqDUUsZEgFZKyFpW6amyP8Gx01xrRs8KdiNbbqXfYxkOXplpq1euWbOjw==",
+ "dev": true,
+ "dependencies": {
+ "debug-log": "^1.0.0",
+ "find-root": "^1.0.0",
+ "xtend": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/pkg-up": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
+ "integrity": "sha512-L+d849d9lz20hnRpUnWBRXOh+mAvygQpK7UuXiw+6QbPwL55RVgl+G+V936wCzs/6J7fj0pvgLY9OknZ+FqaNA==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==",
+ "dev": true
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "node_modules/progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "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/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "node_modules/readline2": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+ "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==",
+ "dev": true,
+ "dependencies": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "mute-stream": "0.0.5"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+ "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "functions-have-names": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==",
+ "dev": true,
+ "dependencies": {
+ "caller-path": "^0.1.0",
+ "resolve-from": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==",
+ "dev": true,
+ "dependencies": {
+ "exit-hook": "^1.0.0",
+ "onetime": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/run-async": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+ "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0"
+ }
+ },
+ "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/rx-lite": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==",
+ "dev": true
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+ "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/shelljs": {
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz",
+ "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ },
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "iojs": "*",
+ "node": ">=0.11.0"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sinon": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz",
+ "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.2",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@sinonjs/formatio": "^5.0.1",
+ "@sinonjs/samsam": "^5.1.0",
+ "diff": "^4.0.2",
+ "nise": "^4.0.4",
+ "supports-color": "^7.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "node_modules/standard": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz",
+ "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==",
+ "dev": true,
+ "dependencies": {
+ "eslint": "~3.19.0",
+ "eslint-config-standard": "10.2.1",
+ "eslint-config-standard-jsx": "4.0.2",
+ "eslint-plugin-import": "~2.2.0",
+ "eslint-plugin-node": "~4.2.2",
+ "eslint-plugin-promise": "~3.5.0",
+ "eslint-plugin-react": "~6.10.0",
+ "eslint-plugin-standard": "~3.0.1",
+ "standard-engine": "~7.0.0"
+ },
+ "bin": {
+ "standard": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/standard-engine": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz",
+ "integrity": "sha512-d/NYzmZxQRxbcoCqlbI9gEMPYq7TLsU6Ywpki54xhedEd0GC4G02j1B7mlexb7HovqRtAtcUPTLQx2MnCO/uyA==",
+ "dev": true,
+ "dependencies": {
+ "deglob": "^2.1.0",
+ "get-stdin": "^5.0.1",
+ "minimist": "^1.1.0",
+ "pkg-conf": "^2.0.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "dev": true,
+ "dependencies": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
+ "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
+ "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/table": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^4.7.0",
+ "ajv-keywords": "^1.0.0",
+ "chalk": "^1.1.1",
+ "lodash": "^4.0.0",
+ "slice-ansi": "0.0.4",
+ "string-width": "^2.0.0"
+ }
+ },
+ "node_modules/table/node_modules/ansi-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/table/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/table/node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/table/node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/temp": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz",
+ "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==",
+ "dependencies": {
+ "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==",
+ "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==",
+ "dev": true
+ },
+ "node_modules/type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+ "dev": true
+ },
+ "node_modules/type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+ "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "dev": true
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==",
+ "dev": true
+ },
+ "node_modules/user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==",
+ "dev": true,
+ "dependencies": {
+ "os-homedir": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "node_modules/vscode-ripgrep": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/vscode-ripgrep/-/vscode-ripgrep-1.13.2.tgz",
+ "integrity": "sha512-RlK9U87EokgHfiOjDQ38ipQQX936gWOcWPQaJpYf+kAkz1PQ1pK2n7nhiscdOmLu6XGjTs7pWFJ/ckonpN7twQ==",
+ "deprecated": "This package has been renamed to @vscode/ripgrep, please update to the new name",
+ "hasInstallScript": true,
+ "dependencies": {
+ "https-proxy-agent": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+ "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/wrench": {
+ "version": "1.5.9",
+ "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.5.9.tgz",
+ "integrity": "sha512-QH+8W9n0UGDAxnRDOkQzG1N277GTaBgMDNdckluqnAY773njfs1gfo867IbMMbGjOZZof+zlRIUeQ9XN8VUHUQ==",
+ "deprecated": "wrench.js is deprecated! You should check out fs-extra (https://github.com/jprichardson/node-fs-extra) for any operations you were using wrench for. Thanks for all the usage over the years.",
+ "engines": {
+ "node": ">=0.1.97"
+ }
+ },
+ "node_modules/write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==",
+ "dev": true,
+ "dependencies": {
+ "mkdirp": "^0.5.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ }
+ },
+ "dependencies": {
+ "@atom/fuzzy-native": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@atom/fuzzy-native/-/fuzzy-native-1.2.1.tgz",
+ "integrity": "sha512-ABUIbeQqfoA4WUK+PAsspM9jLaGlj0wjyIc9CIi1OMAHv71/vqrpJHPX2fHWiREEXYxwh/CBCshhkOWESbnNnQ==",
+ "requires": {
+ "nan": "^2.14.2"
+ }
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+ "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@sinonjs/formatio": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
+ "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^5.0.2"
+ }
+ },
+ "@sinonjs/samsam": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz",
+ "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "@sinonjs/text-encoding": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
+ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^3.0.4"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==",
+ "dev": true
+ }
+ }
+ },
+ "agent-base": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
+ "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g=="
+ },
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==",
+ "dev": true,
+ "requires": {
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==",
+ "dev": true,
+ "requires": {}
+ },
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array.prototype.find": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.2.1.tgz",
+ "integrity": "sha512-I2ri5Z9uMpMvnsNrHre9l3PaX+z9D0/z6F7Yt2u15q7wt0I62g5kX6xUKR1SJiefgG+u2/gJUmM8B47XRvQR6w==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ }
+ },
+ "async": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz",
+ "integrity": "sha512-LTdAJ0KBRK5o4BlBlUoGvfGNOMON+NLbONgDZk80SX0G8LQZyjN+74nNADIpQ/+rxun6+fYm7z4vIzAB51UKUA=="
+ },
+ "atom-select-list": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.7.2.tgz",
+ "integrity": "sha512-a707OB1DhLGjzqtFrtMQKH7BBxFuCh8UBoUWxgFOrLrSwVh3g+/TlVPVDOz12+U0mDu3mIrnYLqQyhywQOTxhw==",
+ "requires": {
+ "etch": "^0.12.6",
+ "fuzzaldrin": "^2.1.0"
+ }
+ },
+ "available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ }
+ },
+ "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"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
+ "dev": true
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^0.2.0"
+ }
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "dev": true
+ }
+ }
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^1.0.1"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+ "dev": true
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "debug-log": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz",
+ "integrity": "sha512-gV/pe1YIaKNgLYnd1g9VNW80tcb7oV5qvNUxG7NM8rbDpnl6RGunzlAtlGSb0wEs3nesu2vHNiX9TSsZ+Y+RjA==",
+ "dev": true
+ },
+ "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
+ },
+ "define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "requires": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "deglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz",
+ "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==",
+ "dev": true,
+ "requires": {
+ "find-root": "^1.0.0",
+ "glob": "^7.0.5",
+ "ignore": "^3.0.9",
+ "pkg-config": "^1.1.0",
+ "run-parallel": "^1.1.2",
+ "uniq": "^1.0.1"
+ }
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.21.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz",
+ "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.1.3",
+ "get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.4",
+ "is-array-buffer": "^3.0.1",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.10",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.2",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.4.3",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trimend": "^1.0.6",
+ "string.prototype.trimstart": "^1.0.6",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.9"
+ }
+ },
+ "es-set-tostringtag": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+ "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "es-shim-unscopables": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+ "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-set": "~0.1.5",
+ "es6-symbol": "~3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "es6-set": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz",
+ "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.62",
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "^3.1.3",
+ "event-emitter": "^0.3.5",
+ "type": "^2.7.2"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "dev": true
+ }
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dev": true,
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==",
+ "dev": true,
+ "requires": {
+ "es6-map": "^0.1.3",
+ "es6-weak-map": "^2.0.1",
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint": {
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz",
+ "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.16.0",
+ "chalk": "^1.1.3",
+ "concat-stream": "^1.5.2",
+ "debug": "^2.1.1",
+ "doctrine": "^2.0.0",
+ "escope": "^3.6.0",
+ "espree": "^3.4.0",
+ "esquery": "^1.0.0",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "glob": "^7.0.3",
+ "globals": "^9.14.0",
+ "ignore": "^3.2.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^0.12.0",
+ "is-my-json-valid": "^2.10.0",
+ "is-resolvable": "^1.0.0",
+ "js-yaml": "^3.5.1",
+ "json-stable-stringify": "^1.0.0",
+ "levn": "^0.3.0",
+ "lodash": "^4.0.0",
+ "mkdirp": "^0.5.0",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.1",
+ "pluralize": "^1.2.1",
+ "progress": "^1.1.8",
+ "require-uncached": "^1.0.2",
+ "shelljs": "^0.7.5",
+ "strip-bom": "^3.0.0",
+ "strip-json-comments": "~2.0.1",
+ "table": "^3.7.8",
+ "text-table": "~0.2.0",
+ "user-home": "^2.0.0"
+ }
+ },
+ "eslint-config-standard": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz",
+ "integrity": "sha512-UkFojTV1o0GOe1edOEiuI5ccYLJSuNngtqSeClNzhsmG8KPJ+7mRxgtp2oYhqZAK/brlXMoCd+VgXViE0AfyKw==",
+ "dev": true,
+ "requires": {}
+ },
+ "eslint-config-standard-jsx": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz",
+ "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==",
+ "dev": true,
+ "requires": {}
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz",
+ "integrity": "sha512-HI8ShtDIy7gON76Nr3bu4zl0DuCLPo1Fud9P2lltOQKeiAS2r5/o/l3y+V8HJ1cDLFSz+tHu7/V9fI5jirwlbw==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.2.0",
+ "object-assign": "^4.0.1",
+ "resolve": "^1.1.6"
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz",
+ "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz",
+ "integrity": "sha512-8HLeIYzOH4eltevxf+iC9Dtz/91yaeOqtlba5srcpQWLrv57F5NNG1RNLqAbpWJWDD4BxKuKjUveJY9W6Tbswg==",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "^1.1.1",
+ "contains-path": "^0.1.0",
+ "debug": "^2.2.0",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.2.0",
+ "eslint-module-utils": "^2.0.0",
+ "has": "^1.0.1",
+ "lodash.cond": "^4.3.0",
+ "minimatch": "^3.0.3",
+ "pkg-up": "^1.0.0"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-node": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz",
+ "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==",
+ "dev": true,
+ "requires": {
+ "ignore": "^3.0.11",
+ "minimatch": "^3.0.2",
+ "object-assign": "^4.0.1",
+ "resolve": "^1.1.7",
+ "semver": "5.3.0"
+ }
+ },
+ "eslint-plugin-promise": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz",
+ "integrity": "sha512-kqXN7i1wfx5j7XuFVzuX4W3XDCEyNDsbd+O5NXWIl+zTSP510rKn2Xk8OO6JhM1ivXbkse0tQf6jjSTLS58Prg==",
+ "dev": true
+ },
+ "eslint-plugin-react": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz",
+ "integrity": "sha512-vFfMSxJynKlgOhIVjhlZyibVUg442Aiv3482XPkgdYV90T8nD2QvxGXILZGwZHYMQ/l+A/De14O9D0qjDelSrg==",
+ "dev": true,
+ "requires": {
+ "array.prototype.find": "^2.0.1",
+ "doctrine": "^1.2.2",
+ "has": "^1.0.1",
+ "jsx-ast-utils": "^1.3.4",
+ "object.assign": "^4.0.4"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-standard": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz",
+ "integrity": "sha512-JyT7wqVYlaHxnljWMT7CKa0R1QDQqArTi6g8kYnexTHHuK7x3Vg//kCepnoTgdT9x/kDbSluXMhJgjBvgVRLlQ==",
+ "dev": true,
+ "requires": {}
+ },
+ "espree": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.5.0",
+ "acorn-jsx": "^3.0.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true
+ }
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "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
+ },
+ "etch": {
+ "version": "0.12.8",
+ "resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz",
+ "integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ=="
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "exit-hook": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==",
+ "dev": true
+ },
+ "ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "dev": true,
+ "requires": {
+ "type": "^2.7.2"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
+ "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
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
+ "dev": true,
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+ "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+ "dev": true,
+ "requires": {
+ "circular-json": "^0.3.1",
+ "graceful-fs": "^4.1.2",
+ "rimraf": "~2.6.2",
+ "write": "^0.2.1"
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "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=="
+ }
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true
+ },
+ "fuzzaldrin": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz",
+ "integrity": "sha512-zgllBYwfHR5P3CncJiGbGVPpa3iFYW1yuPaIv8DiTVRrcg5/6uETNL5zvIoKflG1aifXVUZTlIroDehw4WygGA=="
+ },
+ "fuzzaldrin-plus": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz",
+ "integrity": "sha512-srIDThJHkdp3aPwJpR/HNzYZCRJwm07b/igxseoHSB7qR8e/gQp4F6lMGknE3TQI1Aq14TiFf/wzrHOp9LY/EA=="
+ },
+ "generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.0"
+ }
+ },
+ "get-intrinsic": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+ "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==",
+ "dev": true
+ },
+ "get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3"
+ }
+ },
+ "gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.3"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "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
+ },
+ "has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true
+ },
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "https-proxy-agent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz",
+ "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==",
+ "requires": {
+ "agent-base": "5",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "humanize-plus": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/humanize-plus/-/humanize-plus-1.8.2.tgz",
+ "integrity": "sha512-jaLeQyyzjjINGv7O9JJegjsaUcWjSj/1dcXvLEgU3pGdqCdP1PiC/uwr+saJXhTNBHZtmKnmpXyazgh+eceRxA=="
+ },
+ "ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+ "dev": true
+ },
+ "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=="
+ },
+ "inquirer": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+ "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^1.1.0",
+ "ansi-regex": "^2.0.0",
+ "chalk": "^1.0.0",
+ "cli-cursor": "^1.0.1",
+ "cli-width": "^2.0.0",
+ "figures": "^1.3.5",
+ "lodash": "^4.3.0",
+ "readline2": "^1.0.1",
+ "run-async": "^0.1.0",
+ "rx-lite": "^3.1.2",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.0",
+ "through": "^2.3.6"
+ }
+ },
+ "internal-slot": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz",
+ "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ }
+ },
+ "interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true
+ },
+ "is-array-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz",
+ "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
+ },
+ "is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true
+ },
+ "is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-my-ip-valid": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz",
+ "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.20.6",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz",
+ "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==",
+ "dev": true,
+ "requires": {
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "is-my-ip-valid": "^1.0.0",
+ "jsonpointer": "^5.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true
+ },
+ "is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "is-typed-array": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+ "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz",
+ "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==",
+ "dev": true,
+ "requires": {
+ "jsonify": "^0.0.1"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
+ "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
+ "dev": true
+ },
+ "jsonpointer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
+ "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
+ "dev": true
+ },
+ "jsx-ast-utils": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz",
+ "integrity": "sha512-0LwSmMlQjjUdXsdlyYhEfBJCn2Chm0zgUBmfmf1++KUULh+JOdlzrZfiwe2zmlVJx44UF+KX/B/odBoeK9hxmw==",
+ "dev": true
+ },
+ "just-extend": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
+ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "dependencies": {
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "lodash.cond": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
+ "integrity": "sha512-RWjUhzGbzG/KfDwk+onqdXvrsNv47G9UCMJgSKalPTSqJQyxZhQophG9jgqLf+15TIbZ5a/yG2YKOWsH3dVy9A==",
+ "dev": true
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+ "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
+ },
+ "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.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+ "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+ "dev": true
+ },
+ "nise": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz",
+ "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0",
+ "@sinonjs/fake-timers": "^6.0.0",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true
+ },
+ "object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "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"
+ }
+ },
+ "onetime": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==",
+ "dev": true
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "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-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ }
+ }
+ },
+ "pkg-config": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz",
+ "integrity": "sha512-ft/WI9YK6FuTuw4Ql+QUaNXtm/ASQNqDUUsZEgFZKyFpW6amyP8Gx01xrRs8KdiNbbqXfYxkOXplpq1euWbOjw==",
+ "dev": true,
+ "requires": {
+ "debug-log": "^1.0.0",
+ "find-root": "^1.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "pkg-up": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
+ "integrity": "sha512-L+d849d9lz20hnRpUnWBRXOh+mAvygQpK7UuXiw+6QbPwL55RVgl+G+V936wCzs/6J7fj0pvgLY9OknZ+FqaNA==",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0"
+ }
+ },
+ "pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==",
+ "dev": true
+ },
+ "proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "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
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ }
+ }
+ },
+ "readline2": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+ "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "mute-stream": "0.0.5"
+ }
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
+ "regexp.prototype.flags": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+ "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==",
+ "dev": true,
+ "requires": {
+ "caller-path": "^0.1.0",
+ "resolve-from": "^1.0.0"
+ }
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==",
+ "dev": true,
+ "requires": {
+ "exit-hook": "^1.0.0",
+ "onetime": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "run-async": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+ "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0"
+ }
+ },
+ "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"
+ }
+ },
+ "rx-lite": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "safe-regex-test": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+ "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ }
+ },
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz",
+ "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ }
+ },
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
+ "sinon": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz",
+ "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.2",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@sinonjs/formatio": "^5.0.1",
+ "@sinonjs/samsam": "^5.1.0",
+ "diff": "^4.0.2",
+ "nise": "^4.0.4",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "standard": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz",
+ "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==",
+ "dev": true,
+ "requires": {
+ "eslint": "~3.19.0",
+ "eslint-config-standard": "10.2.1",
+ "eslint-config-standard-jsx": "4.0.2",
+ "eslint-plugin-import": "~2.2.0",
+ "eslint-plugin-node": "~4.2.2",
+ "eslint-plugin-promise": "~3.5.0",
+ "eslint-plugin-react": "~6.10.0",
+ "eslint-plugin-standard": "~3.0.1",
+ "standard-engine": "~7.0.0"
+ }
+ },
+ "standard-engine": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz",
+ "integrity": "sha512-d/NYzmZxQRxbcoCqlbI9gEMPYq7TLsU6Ywpki54xhedEd0GC4G02j1B7mlexb7HovqRtAtcUPTLQx2MnCO/uyA==",
+ "dev": true,
+ "requires": {
+ "deglob": "^2.1.0",
+ "get-stdin": "^5.0.1",
+ "minimist": "^1.1.0",
+ "pkg-conf": "^2.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
+ "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
+ "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "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"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "table": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^4.7.0",
+ "ajv-keywords": "^1.0.0",
+ "chalk": "^1.1.1",
+ "lodash": "^4.0.0",
+ "slice-ansi": "0.0.4",
+ "string-width": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "temp": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz",
+ "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==",
+ "requires": {
+ "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==",
+ "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==",
+ "dev": true
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "typed-array-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+ "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "dev": true
+ },
+ "unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ }
+ },
+ "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"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==",
+ "dev": true
+ },
+ "user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "vscode-ripgrep": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/vscode-ripgrep/-/vscode-ripgrep-1.13.2.tgz",
+ "integrity": "sha512-RlK9U87EokgHfiOjDQ38ipQQX936gWOcWPQaJpYf+kAkz1PQ1pK2n7nhiscdOmLu6XGjTs7pWFJ/ckonpN7twQ==",
+ "requires": {
+ "https-proxy-agent": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "requires": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ }
+ },
+ "which-typed-array": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+ "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "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
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "wrench": {
+ "version": "1.5.9",
+ "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.5.9.tgz",
+ "integrity": "sha512-QH+8W9n0UGDAxnRDOkQzG1N277GTaBgMDNdckluqnAY773njfs1gfo867IbMMbGjOZZof+zlRIUeQ9XN8VUHUQ=="
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ }
+ }
+}
diff --git a/packages/fuzzy-finder/package.json b/packages/fuzzy-finder/package.json
new file mode 100644
index 0000000000..ff4b6b036e
--- /dev/null
+++ b/packages/fuzzy-finder/package.json
@@ -0,0 +1,74 @@
+{
+ "name": "fuzzy-finder",
+ "version": "1.14.3",
+ "main": "./lib/main",
+ "description": "Open an editor to a file in the project with `cmd-t`.",
+ "repository": "https://github.com/pulsar-edit/fuzzy-finder",
+ "license": "MIT",
+ "dependencies": {
+ "@pulsar-edit/fuzzy-native": "https://github.com/pulsar-edit/fuzzy-native.git#13d2e5f",
+ "atom-select-list": "^0.7.0",
+ "fs-plus": "^3.0.0",
+ "minimatch": "~3.0.3",
+ "underscore-plus": "^1.7.0",
+ "vscode-ripgrep": "^1.2.5",
+ "wrench": "^1.5"
+ },
+ "devDependencies": {
+ "async": "0.2.6",
+ "temp": "~0.8.1",
+ "sinon": "9.0.3"
+ },
+ "engines": {
+ "atom": "*"
+ },
+ "consumedServices": {
+ "teletype": {
+ "versions": {
+ "0.0.1": "consumeTeletype"
+ }
+ },
+ "atom.file-icons": {
+ "versions": {
+ "1.0.0": "consumeFileIcons"
+ }
+ },
+ "file-icons.element-icons": {
+ "versions": {
+ "1.0.0": "consumeElementIcons"
+ }
+ },
+ "metrics-reporter": {
+ "versions": {
+ "^1.1.0": "consumeMetricsReporter"
+ }
+ }
+ },
+ "configSchema": {
+ "ignoredNames": {
+ "type": "array",
+ "default": [],
+ "description": "List of string glob patterns. Files and directories matching these patterns will be ignored. This list is merged with the list defined by the core `Ignored Names` config setting. Example: `.git, ._*, Thumbs.db`."
+ },
+ "searchAllPanes": {
+ "type": "boolean",
+ "default": false,
+ "description": "Search all panes when opening files. If disabled, only the active pane is searched. Holding `shift` inverts this setting."
+ },
+ "preserveLastSearch": {
+ "type": "boolean",
+ "default": false,
+ "description": "Remember the typed query when closing the fuzzy finder and use that as the starting query next time the fuzzy finder is opened."
+ },
+ "useRipGrep": {
+ "type": "boolean",
+ "default": true,
+ "description": "Use the substantially faster `ripgrep` crawler."
+ },
+ "prefillFromSelection": {
+ "type": "boolean",
+ "default": false,
+ "description": "Prefills search query with selected in current editor text"
+ }
+ }
+}
diff --git a/packages/fuzzy-finder/spec/async-spec-helpers.js b/packages/fuzzy-finder/spec/async-spec-helpers.js
new file mode 100644
index 0000000000..8be55f49fc
--- /dev/null
+++ b/packages/fuzzy-finder/spec/async-spec-helpers.js
@@ -0,0 +1,65 @@
+exports.beforeEach = function (fn) {
+ global.beforeEach(function () {
+ const result = fn()
+ if (result instanceof Promise) {
+ waitsForPromise(() => result)
+ }
+ })
+}
+
+exports.afterEach = function (fn) {
+ global.afterEach(function () {
+ const result = fn()
+ if (result instanceof Promise) {
+ waitsForPromise(() => result)
+ }
+ })
+}
+
+for (const name of ['it', 'fit', 'ffit', 'fffit']) {
+ module.exports[name] = function (description, fn) {
+ if (fn === undefined) {
+ global[name](description)
+ return
+ }
+
+ global[name](description, function () {
+ const result = fn()
+ if (result instanceof Promise) {
+ waitsForPromise(() => result)
+ }
+ })
+ }
+}
+
+exports.conditionPromise = async function (condition, description = 'anonymous condition') {
+ const startTime = Date.now()
+
+ while (true) {
+ await exports.timeoutPromise(100)
+
+ if (await condition()) {
+ return
+ }
+
+ if (Date.now() - startTime > 5000) {
+ throw new Error('Timed out waiting on ' + description)
+ }
+ }
+}
+
+exports.timeoutPromise = function (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/fuzzy-finder/spec/buffer-view-spec.js b/packages/fuzzy-finder/spec/buffer-view-spec.js
new file mode 100644
index 0000000000..45a870eae1
--- /dev/null
+++ b/packages/fuzzy-finder/spec/buffer-view-spec.js
@@ -0,0 +1,31 @@
+const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./async-spec-helpers') // eslint-disable-line no-unused-vars
+const path = require('path')
+const temp = require('temp').track()
+const BufferView = require('../lib/buffer-view')
+
+describe('BufferView', () => {
+ it('shows the avatar for editors that are remote', async () => {
+ const bufferView = new BufferView({incrementCounter: () => {}})
+
+ const localEditor1 = await atom.workspace.open(path.join(temp.path(), 'a'))
+ const localEditor2 = await atom.workspace.open(path.join(temp.path(), 'b'))
+ const remoteEditor1 = await atom.workspace.open(path.join(temp.path(), 'c'))
+ remoteEditor1.getURI = () => 'remote1-uri'
+ const fakeTeletypeService = {
+ async getRemoteEditors () {
+ return [
+ {uri: 'remote1-uri', path: 'remote1-path', hostGitHubUsername: 'user-1'},
+ {uri: 'remote2-uri', path: 'remote2-path', hostGitHubUsername: 'user-2'}
+ ]
+ }
+ }
+ bufferView.setTeletypeService(fakeTeletypeService)
+ await bufferView.toggle()
+
+ expect(bufferView.items).toEqual([
+ {uri: localEditor1.getURI(), filePath: localEditor1.getPath(), label: localEditor1.getPath()},
+ {uri: localEditor2.getURI(), filePath: localEditor2.getPath(), label: localEditor2.getPath()},
+ {uri: 'remote1-uri', filePath: 'remote1-path', label: '@user-1: remote1-path', ownerGitHubUsername: 'user-1'}
+ ])
+ })
+})
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/dir/a b/packages/fuzzy-finder/spec/fixtures/root-dir1/dir/a
new file mode 100644
index 0000000000..2c0809b9dc
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/dir/a
@@ -0,0 +1,3 @@
+aaa bbb
+cc aa cc
+dollar$bill
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/a.txt b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/a.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/dir/b.txt b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/dir/b.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/file.txt b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/file.txt
new file mode 100644
index 0000000000..66dc9051da
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/file.txt
@@ -0,0 +1 @@
+undefined
\ No newline at end of file
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/HEAD b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/HEAD
new file mode 100644
index 0000000000..cb089cd89a
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/config b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/config
new file mode 100644
index 0000000000..af107929f2
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/config
@@ -0,0 +1,6 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/index b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/index
new file mode 100644
index 0000000000..67a98bd9f0
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/index differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/28/569d0a51e27dd112c0d4994c1e2914dd0db754 b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/28/569d0a51e27dd112c0d4994c1e2914dd0db754
new file mode 100644
index 0000000000..169ad87fa4
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/28/569d0a51e27dd112c0d4994c1e2914dd0db754 differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7 b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
new file mode 100644
index 0000000000..ba1f06fc0e
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7 differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/97/ff2919c02606bcad55588f3fa723b5a357470f b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/97/ff2919c02606bcad55588f3fa723b5a357470f
new file mode 100644
index 0000000000..b6cb9859fd
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/97/ff2919c02606bcad55588f3fa723b5a357470f differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100644
index 0000000000..7112238943
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/ec/5e386905ff2d36e291086a1207f2585aaa8920 b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/ec/5e386905ff2d36e291086a1207f2585aaa8920
new file mode 100644
index 0000000000..4010ee8c26
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/ec/5e386905ff2d36e291086a1207f2585aaa8920 differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1 b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
new file mode 100644
index 0000000000..eaf6eeff30
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1 differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/refs/heads/master b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/refs/heads/master
new file mode 100644
index 0000000000..99d7260057
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/git.git/refs/heads/master
@@ -0,0 +1 @@
+97ff2919c02606bcad55588f3fa723b5a357470f
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/other.txt b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/other.txt
new file mode 100644
index 0000000000..ffc8218bd2
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/git/working-dir/other.txt
@@ -0,0 +1 @@
+Full of text
\ No newline at end of file
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.gif b/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.gif
new file mode 100755
index 0000000000..9935f82104
Binary files /dev/null and b/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.gif differ
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.js b/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.js
new file mode 100644
index 0000000000..fb33b0b43b
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/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));
+};
\ No newline at end of file
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.txt b/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.txt
new file mode 100644
index 0000000000..3e715502b9
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir1/sample.txt
@@ -0,0 +1 @@
+Some text.
diff --git a/packages/fuzzy-finder/spec/fixtures/root-dir2/sample.html b/packages/fuzzy-finder/spec/fixtures/root-dir2/sample.html
new file mode 100644
index 0000000000..138906e71b
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fixtures/root-dir2/sample.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/fuzzy-finder/spec/fuzzy-finder-spec.js b/packages/fuzzy-finder/spec/fuzzy-finder-spec.js
new file mode 100644
index 0000000000..652f2434ac
--- /dev/null
+++ b/packages/fuzzy-finder/spec/fuzzy-finder-spec.js
@@ -0,0 +1,1795 @@
+const net = require('net')
+const path = require('path')
+const _ = require('underscore-plus')
+const etch = require('etch')
+const fs = require('fs')
+const os = require('os')
+const sinon = require('sinon')
+const temp = require('temp')
+const wrench = require('wrench')
+
+const fuzzyFinderPackage = require('..')
+const PathLoader = require('../lib/path-loader')
+const DefaultFileIcons = require('../lib/default-file-icons')
+const getIconServices = require('../lib/get-icon-services')
+const {Disposable} = require('atom')
+
+const {it, fit, ffit, afterEach, beforeEach, conditionPromise} = require('./async-spec-helpers') // eslint-disable-line no-unused-vars
+
+function rmrf (_path) {
+ if (fs.statSync(_path).isDirectory()) {
+ _.each(fs.readdirSync(_path), (child) => rmrf(path.join(_path, child)))
+ fs.rmdirSync(_path)
+ } else {
+ fs.unlinkSync(_path)
+ }
+}
+
+function getOrScheduleUpdatePromise () {
+ return new Promise((resolve) => etch.getScheduler().updateDocument(resolve))
+}
+
+const genPromiseToCheck = fn => new Promise(resolve => {
+ const interval = setInterval(() => { if(fn()) resolve() }, 100)
+ setTimeout(() => clearInterval(interval), 4000)
+})
+
+describe('FuzzyFinder', () => {
+ let disposable, reporterStub
+ let rootDir1, rootDir2
+ let fuzzyFinder, projectView, bufferView, gitStatusView, workspaceElement, fixturesPath
+ const filesPromise = () => genPromiseToCheck( () =>
+ gitStatusView?.element?.querySelectorAll('.file')?.length ||
+ bufferView?.element?.querySelectorAll('.file')?.length ||
+ projectView?.element?.querySelectorAll('.file')?.length
+ )
+
+ beforeEach(async () => {
+ reporterStub = {
+ addTiming: sinon.spy(),
+ incrementCounter: () => {}
+ }
+ disposable = fuzzyFinderPackage.consumeMetricsReporter(reporterStub)
+
+ const ancestorDir = fs.realpathSync(temp.mkdirSync())
+ rootDir1 = path.join(ancestorDir, 'root-dir1')
+ rootDir2 = path.join(ancestorDir, 'root-dir2')
+
+ fixturesPath = atom.project.getPaths()[0]
+
+ wrench.copyDirSyncRecursive(
+ path.join(fixturesPath, 'root-dir1'),
+ rootDir1,
+ {forceDelete: true}
+ )
+
+ wrench.copyDirSyncRecursive(
+ path.join(fixturesPath, 'root-dir2'),
+ rootDir2,
+ {forceDelete: true}
+ )
+
+ atom.project.setPaths([rootDir1, rootDir2])
+
+ workspaceElement = atom.views.getView(atom.workspace)
+
+ await atom.workspace.open(path.join(rootDir1, 'sample.js'))
+
+ const pack = await atom.packages.activatePackage('fuzzy-finder')
+ fuzzyFinder = pack.mainModule
+ bufferView = fuzzyFinder.createBufferView()
+ gitStatusView = fuzzyFinder.createGitStatusView()
+
+ jasmine.useRealClock()
+ })
+
+ afterEach(() => {
+ if (disposable) {
+ disposable.dispose()
+ }
+ })
+
+ async function waitForPathsToDisplay (fuzzyFinderView) {
+ return conditionPromise(() => fuzzyFinderView.element.querySelectorAll('li').length > 0)
+ }
+
+ async function waitForReCrawlerToFinish (fuzzyFinderView) {
+ return conditionPromise(
+ () => !fuzzyFinderView.element.querySelector('.loading .loading-message')
+ )
+ }
+
+ function waitForInitialCrawlerToFinish (fuzzyFinder) {
+ return new Promise(
+ resolve => fuzzyFinder.loadPathsTask.on('task:completed', () => resolve())
+ )
+ }
+
+ function eachFilePath (dirPaths, fn) {
+ for (let dirPath of dirPaths) {
+ wrench.readdirSyncRecursive(dirPath).filter((filePath) => {
+ const fullPath = path.join(dirPath, filePath)
+ if (fs.statSync(fullPath).isFile()) {
+ fn(filePath)
+ }
+ })
+ }
+ }
+
+ function parseResults (elementContainer) {
+ return Array.from(elementContainer.querySelectorAll('li')).map(
+ element => ({
+ label: element.querySelector('.primary-line').textContent,
+ description: element.querySelector('.secondary-line').textContent
+ })
+ )
+ }
+
+ for (const useRipGrep of [true, false]) {
+ describe(`file-finder behavior (ripgrep=${useRipGrep})`, () => {
+ beforeEach(async () => {
+ projectView = fuzzyFinder.createProjectView()
+
+ atom.config.set('fuzzy-finder.useRipGrep', useRipGrep)
+ sinon.stub(os, 'cpus').returns({length: 1})
+
+ await projectView.selectListView.update({maxResults: null})
+ })
+
+ afterEach(() => {
+ os.cpus.restore()
+ })
+
+ describe('toggling', () => {
+ describe('when the project has multiple paths', () => {
+ it('shows or hides the fuzzy-finder and returns focus to the active editor if it is already showing', async () => {
+ jasmine.attachToDOM(workspaceElement)
+
+ expect(atom.workspace.panelForItem(projectView)).toBeNull()
+ atom.workspace.getActivePane().splitRight({copyActiveItem: true})
+ const [editor1, editor2] = atom.workspace.getTextEditors()
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ expect(projectView.selectListView.refs.queryEditor.element).toHaveFocus()
+ projectView.selectListView.refs.queryEditor.insertText('this should not show up next time we toggle')
+
+ await projectView.toggle()
+
+ expect(atom.views.getView(editor1)).not.toHaveFocus()
+ expect(atom.views.getView(editor2)).toHaveFocus()
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(false)
+
+ await projectView.toggle()
+
+ expect(projectView.selectListView.refs.queryEditor.getText()).toBe('')
+ })
+
+ it('shows all files for the current project and selects the first', async () => {
+ jasmine.attachToDOM(workspaceElement)
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ eachFilePath([rootDir1, rootDir2], (filePath) => {
+ const item = Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes(filePath))
+ expect(item).toExist()
+ const nameDiv = item.querySelector('div:first-child')
+ expect(nameDiv.dataset.name).toBe(path.basename(filePath))
+ expect(nameDiv.textContent).toBe(path.basename(filePath))
+ })
+
+ expect(projectView.element.querySelector('.loading')).not.toBeVisible()
+ })
+
+ it("shows each file's path, including which root directory it's in", async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ eachFilePath([rootDir1], (filePath) => {
+ const item = Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes(filePath))
+ expect(item).toExist()
+ expect(item.querySelectorAll('div')[1].textContent).toBe(path.join(path.basename(rootDir1), filePath))
+ })
+
+ eachFilePath([rootDir2], (filePath) => {
+ const item = Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes(filePath))
+ expect(item).toExist()
+ expect(item.querySelectorAll('div')[1].textContent).toBe(path.join(path.basename(rootDir2), filePath))
+ })
+ })
+
+ it('only creates a single path loader task', async () => {
+ spyOn(PathLoader, 'startTask').andCallThrough()
+
+ await projectView.toggle() // Show
+
+ await projectView.toggle() // Hide
+
+ await projectView.toggle() // Show again
+
+ expect(PathLoader.startTask.callCount).toBe(1)
+ })
+
+ it('puts the last opened path first', async () => {
+ await atom.workspace.open('sample.txt')
+ await atom.workspace.open('sample.js')
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ const results = projectView.element.querySelectorAll('li')
+
+ expect(results[0].textContent).toContain('sample.txt')
+ expect(results[results.length - 1].textContent).toContain('sample.html')
+ })
+
+ it('displays paths correctly if the last-opened path is not part of the project (regression)', async () => {
+ await atom.workspace.open('foo.txt')
+ await atom.workspace.open('sample.js')
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+ })
+
+ describe('symlinks on #darwin or #linux', () => {
+ let junkDirPath, junkFilePath
+
+ beforeEach(() => {
+ junkDirPath = fs.realpathSync(temp.mkdirSync('junk-1'))
+ junkFilePath = path.join(junkDirPath, 'file.txt')
+ fs.writeFileSync(junkFilePath, 'txt')
+ fs.writeFileSync(path.join(junkDirPath, 'a'), 'txt')
+
+ const brokenFilePath = path.join(junkDirPath, 'delete.txt')
+ fs.writeFileSync(brokenFilePath, 'delete-me')
+
+ fs.symlinkSync(junkFilePath, atom.project.getDirectories()[0].resolve('symlink-to-file'))
+ fs.symlinkSync(junkDirPath, atom.project.getDirectories()[0].resolve('symlink-to-dir'))
+ fs.symlinkSync(brokenFilePath, atom.project.getDirectories()[0].resolve('broken-symlink'))
+
+ fs.symlinkSync(atom.project.getDirectories()[0].resolve('sample.txt'), atom.project.getDirectories()[0].resolve('symlink-to-internal-file'))
+ fs.symlinkSync(atom.project.getDirectories()[0].resolve('dir'), atom.project.getDirectories()[0].resolve('symlink-to-internal-dir'))
+ fs.symlinkSync(atom.project.getDirectories()[0].resolve('..'), atom.project.getDirectories()[0].resolve('symlink-to-project-dir-ancestor'))
+
+ fs.unlinkSync(brokenFilePath)
+ })
+
+ it('indexes project paths that are symlinks', async () => {
+ const symlinkProjectPath = path.join(junkDirPath, 'root-dir-symlink')
+ fs.symlinkSync(atom.project.getPaths()[0], symlinkProjectPath)
+
+ atom.project.setPaths([symlinkProjectPath])
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('sample.txt'))).toBeDefined()
+ })
+
+ it('includes symlinked file paths', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ const results = Array.from(projectView.element.querySelectorAll('li'))
+ const sourceSymlink = results.find(a => a.textContent.includes('symlink-to-internal-file'))
+ const destSymlink = results.find(a => a.textContent.includes('symlink-to-file'))
+
+ expect(destSymlink).toBeDefined()
+
+ // The behaviour when ripgrep is enabled is slightly different.
+ if (useRipGrep) {
+ expect(sourceSymlink).toBeDefined()
+ } else {
+ expect(sourceSymlink).not.toBeDefined()
+ }
+ })
+
+ it('excludes symlinked folder paths if followSymlinks is false', async () => {
+ atom.config.set('core.followSymlinks', false)
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ const results = Array.from(projectView.element.querySelectorAll('li'))
+
+ expect(results.find(a => a.textContent.includes('symlink-to-dir'))).not.toBeDefined()
+ expect(results.find(a => a.textContent.includes('symlink-to-dir/a'))).not.toBeDefined()
+ expect(results.find(a => a.textContent.includes('symlink-to-internal-dir'))).not.toBeDefined()
+ expect(results.find(a => a.textContent.includes('symlink-to-internal-dir/a'))).not.toBeDefined()
+ })
+
+ it('includes symlinked folder paths if followSymlinks is true', async () => {
+ atom.config.set('core.followSymlinks', true)
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ const results = Array.from(projectView.element.querySelectorAll('li'))
+ const sourceSymlink = results.find(a => a.textContent.includes('symlink-to-internal-dir/a'))
+ const destSymlink = results.find(a => a.textContent.includes('symlink-to-dir/a'))
+
+ expect(destSymlink).toBeDefined()
+
+ // The behaviour when ripgrep is enabled is slightly different.
+ if (useRipGrep) {
+ expect(sourceSymlink).toBeDefined()
+ } else {
+ expect(sourceSymlink).not.toBeDefined()
+ }
+ })
+ })
+
+ describe('socket files on #darwin or #linux', () => {
+ let socketServer, socketPath
+
+ beforeEach(() => new Promise((resolve, reject) => {
+ socketServer = net.createServer(() => {})
+ socketPath = path.join(rootDir1, 'some.sock')
+ socketServer.on('listening', resolve)
+ socketServer.on('error', reject)
+ socketServer.listen(socketPath)
+ }))
+
+ afterEach(() => new Promise(resolve => socketServer.close(resolve)))
+
+ it('does not interfere with ability to load files', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('a'))).toBeDefined()
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('some.sock'))).not.toBeDefined()
+ })
+ })
+
+ it('ignores paths that match entries in config.fuzzy-finder.ignoredNames', async () => {
+ atom.config.set('fuzzy-finder.ignoredNames', ['sample.js', '*.txt'])
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('sample.js'))).not.toBeDefined()
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('sample.txt'))).not.toBeDefined()
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('a'))).toBeDefined()
+ })
+
+ it("only shows a given path once, even if it's within multiple root folders", async () => {
+ const childDir1 = path.join(rootDir1, 'a-child')
+ const childFile1 = path.join(childDir1, 'child-file.txt')
+ fs.mkdirSync(childDir1)
+ fs.writeFileSync(childFile1, 'stuff')
+ atom.project.addPath(childDir1)
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).filter(a => a.textContent.includes('child-file.txt')).length).toBe(1)
+ })
+
+ it('returns all the results if they have the same relative path across multiple root folders', async () => {
+ fs.writeFileSync(path.join(rootDir1, 'whatever.js'), 'stuff')
+ fs.writeFileSync(path.join(rootDir2, 'whatever.js'), 'stuff')
+
+ await projectView.toggle()
+ await waitForPathsToDisplay(projectView)
+
+ await projectView.selectListView.refs.queryEditor.setText('whatever.js')
+ await getOrScheduleUpdatePromise()
+
+ // Sort results by path to ensure test is deterministic
+ const results = parseResults(projectView.element)
+ .sort((a, b) => a.description.localeCompare(b.description))
+ expect(results).toEqual([
+ {label: 'whatever.js', description: path.join('root-dir1', 'whatever.js')},
+ {label: 'whatever.js', description: path.join('root-dir2', 'whatever.js')}
+ ])
+ })
+
+ it('returns all the results if they have the same relative path across multiple root folders with the same name', async () => {
+ const ancestorDir = fs.realpathSync(temp.mkdirSync())
+ const rootDir3 = path.join(ancestorDir, 'root-dir1')
+ fs.mkdirSync(rootDir3)
+
+ fs.writeFileSync(path.join(rootDir1, 'whatever.js'), 'stuff')
+ fs.writeFileSync(path.join(rootDir3, 'whatever.js'), 'stuff')
+
+ atom.project.addPath(rootDir3)
+
+ await projectView.toggle()
+ await waitForPathsToDisplay(projectView)
+
+ await projectView.selectListView.refs.queryEditor.setText('whatever.js')
+ await getOrScheduleUpdatePromise()
+
+ expect(parseResults(projectView.element)).toEqual([
+ {label: 'whatever.js', description: path.join('root-dir1', 'whatever.js')},
+ {label: 'whatever.js', description: path.join('root-dir1', 'whatever.js')}
+ ])
+ })
+ })
+
+ describe('when the project only has one path', () => {
+ beforeEach(() => atom.project.setPaths([rootDir1]))
+
+ it("doesn't show the name of each file's root directory", async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ const items = Array.from(projectView.element.querySelectorAll('li'))
+ eachFilePath([rootDir1], (filePath) => {
+ const item = items.find(a => a.textContent.includes(filePath))
+ expect(item).toExist()
+ expect(item).not.toHaveText(path.basename(rootDir1))
+ })
+ })
+ })
+
+ describe('when the project has no path', () => {
+ beforeEach(() => {
+ jasmine.attachToDOM(workspaceElement)
+ atom.project.setPaths([])
+ })
+
+ it('shows an empty message with no files in the list', async () => {
+ await projectView.toggle()
+
+ expect(projectView.selectListView.refs.emptyMessage).toBeVisible()
+ expect(projectView.selectListView.refs.emptyMessage.textContent).toBe('Project is empty')
+ expect(projectView.element.querySelectorAll('li').length).toBe(0)
+ })
+ })
+ })
+
+ describe("when a project's root path is unlinked", () => {
+ beforeEach(() => {
+ if (fs.existsSync(rootDir1)) { rmrf(rootDir1) }
+ if (fs.existsSync(rootDir2)) { rmrf(rootDir2) }
+ })
+
+ it('posts an error notification', async () => {
+ spyOn(atom.notifications, 'addError')
+ await projectView.toggle()
+
+ await conditionPromise(() => atom.workspace.panelForItem(projectView).isVisible())
+ expect(atom.notifications.addError).toHaveBeenCalled()
+ })
+ })
+
+ describe('when a path selection is confirmed', () => {
+ it('opens the file associated with that path in that split', async () => {
+ jasmine.attachToDOM(workspaceElement)
+ const editor1 = atom.workspace.getActiveTextEditor()
+ atom.workspace.getActivePane().splitRight({copyActiveItem: true})
+ const editor2 = atom.workspace.getActiveTextEditor()
+ const expectedPath = atom.project.getDirectories()[0].resolve('dir/a')
+
+ await projectView.toggle()
+
+ projectView.confirm({uri: expectedPath})
+
+ await conditionPromise(() => atom.workspace.getActivePane().getItems().length === 2)
+
+ const editor3 = atom.workspace.getActiveTextEditor()
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(false)
+ expect(editor1.getPath()).not.toBe(expectedPath)
+ expect(editor2.getPath()).not.toBe(expectedPath)
+ expect(editor3.getPath()).toBe(expectedPath)
+ expect(atom.views.getView(editor3)).toHaveFocus()
+ })
+
+ describe('when the selected path is a directory', () =>
+ it("leaves the the tree view open, doesn't open the path in the editor, and displays an error", async () => {
+ jasmine.attachToDOM(workspaceElement)
+ const editorPath = atom.workspace.getActiveTextEditor().getPath()
+ await projectView.toggle()
+
+ projectView.confirm({uri: atom.project.getDirectories()[0].resolve('dir')})
+ expect(projectView.element.parentElement).toBeDefined()
+ expect(atom.workspace.getActiveTextEditor().getPath()).toBe(editorPath)
+
+ await conditionPromise(() => projectView.selectListView.refs.errorMessage)
+
+ jasmine.useMockClock()
+
+ advanceClock(2000)
+
+ await conditionPromise(() => !projectView.selectListView.refs.errorMessage)
+ })
+ )
+ })
+
+ describe('buffer-finder behavior', () => {
+ describe('toggling', () => {
+ describe('when there are pane items with paths', () => {
+ beforeEach(async () => {
+ jasmine.attachToDOM(workspaceElement)
+
+ await atom.workspace.open('sample.txt')
+ })
+
+ it("shows the FuzzyFinder if it isn't showing, or hides it and returns focus to the active editor", async () => {
+ expect(atom.workspace.panelForItem(bufferView)).toBeNull()
+ atom.workspace.getActivePane().splitRight({copyActiveItem: true})
+ const [editor1, editor2, editor3] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+ expect(atom.workspace.getActivePaneItem()).toBe(editor3)
+
+ expect(atom.views.getView(editor3)).toHaveFocus()
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ expect(workspaceElement.querySelector('.fuzzy-finder')).toHaveFocus()
+ bufferView.selectListView.refs.queryEditor.insertText('this should not show up next time we toggle')
+
+ await bufferView.toggle()
+
+ expect(atom.views.getView(editor3)).toHaveFocus()
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(false)
+
+ await bufferView.toggle()
+
+ expect(bufferView.selectListView.refs.queryEditor.getText()).toBe('')
+ })
+
+ it('lists the paths of the current items, sorted by most recently opened but with the current item last', async () => {
+ await atom.workspace.open('sample-with-tabs.coffee')
+
+ bufferView.toggle()
+ await filesPromise()
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ expect([...bufferView.element.querySelectorAll('li > div.file')]
+ .map(e => e.textContent))
+ .toEqual(['sample.txt', 'sample.js', 'sample-with-tabs.coffee'])
+
+ await bufferView.toggle()
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(false)
+
+ await atom.workspace.open('sample.txt')
+ bufferView.toggle()
+ await genPromiseToCheck(() =>
+ bufferView?.element?.querySelector('li > div.file')
+ ?.innerText?.match(/sample-with-tabs/)
+ )
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ expect([...bufferView.element.querySelectorAll('li > div.file')]
+ .map(e => e.textContent))
+ .toEqual(['sample-with-tabs.coffee', 'sample.js', 'sample.txt'])
+ expect(bufferView.element.querySelector('li')).toHaveClass('selected')
+ })
+
+ it('serializes the list of paths and their last opened time', async () => {
+ await atom.workspace.open('sample-with-tabs.coffee')
+ await bufferView.toggle()
+ await atom.workspace.open('sample.js')
+ await bufferView.toggle()
+ await atom.workspace.open()
+ await atom.packages.deactivatePackage('fuzzy-finder')
+
+ let states = _.map(atom.packages.getPackageState('fuzzy-finder'), (path, time) => [path, time])
+ expect(states.length).toBe(3)
+ states = _.sortBy(states, (path, time) => -time)
+
+ const paths = ['sample-with-tabs.coffee', 'sample.txt', 'sample.js']
+ for (let [time, bufferPath] of states) {
+ expect(_.last(bufferPath.split(path.sep))).toBe(paths.shift())
+ expect(time).toBeGreaterThan(50000)
+ }
+ })
+ })
+
+ describe('when there are only panes with anonymous items', () =>
+ it('does not open', async () => {
+ atom.workspace.getActivePane().destroy()
+ await atom.workspace.open()
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView)).toBeNull()
+ })
+ )
+
+ describe('when there are no pane items', () =>
+ it('does not open', async () => {
+ atom.workspace.getActivePane().destroy()
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView)).toBeNull()
+ })
+ )
+
+ describe('when multiple sessions are opened on the same path', () =>
+ it('does not display duplicates for that path in the list', async () => {
+ await atom.workspace.open('sample.js')
+
+ atom.workspace.getActivePane().splitRight({copyActiveItem: true})
+
+ bufferView.toggle()
+ await filesPromise()
+ expect(Array.from(bufferView.element.querySelectorAll('li > div.file')).map(e => e.textContent)).toEqual(['sample.js'])
+ })
+ )
+ })
+
+ describe('when a path selection is confirmed', () => {
+ let editor1, editor2, editor3
+
+ beforeEach(async () => {
+ jasmine.attachToDOM(workspaceElement)
+ atom.workspace.getActivePane().splitRight({copyActiveItem: true})
+
+ await atom.workspace.open('sample.txt');
+
+ [editor1, editor2, editor3] = atom.workspace.getTextEditors()
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor3)
+
+ atom.commands.dispatch(atom.views.getView(editor2), 'pane:show-previous-item')
+
+ await bufferView.toggle()
+ })
+
+ describe('when the active pane has an item for the selected path', () =>
+ it('switches to the item for the selected path', async () => {
+ const expectedPath = atom.project.getDirectories()[0].resolve('sample.txt')
+ bufferView.confirm({uri: expectedPath})
+
+ await conditionPromise(() => atom.workspace.getActiveTextEditor().getPath() === expectedPath)
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(false)
+ expect(editor1.getPath()).not.toBe(expectedPath)
+ expect(editor2.getPath()).not.toBe(expectedPath)
+ expect(editor3.getPath()).toBe(expectedPath)
+ expect(atom.views.getView(editor3)).toHaveFocus()
+ })
+ )
+
+ describe('when the active pane does not have an item for the selected path and fuzzy-finder.searchAllPanes is false', () =>
+ it('adds a new item to the active pane for the selected path', async () => {
+ const expectedPath = atom.project.getDirectories()[0].resolve('sample.txt')
+
+ await bufferView.toggle()
+
+ atom.views.getView(editor1).focus()
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ bufferView.confirm({uri: expectedPath}, atom.config.get('fuzzy-finder.searchAllPanes'))
+
+ await conditionPromise(() => atom.workspace.getActivePane().getItems().length === 2)
+
+ const editor4 = atom.workspace.getActiveTextEditor()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(false)
+
+ expect(editor4).not.toBe(editor1)
+ expect(editor4).not.toBe(editor2)
+ expect(editor4).not.toBe(editor3)
+
+ expect(editor4.getPath()).toBe(expectedPath)
+ expect(atom.views.getView(editor4)).toHaveFocus()
+ })
+ )
+
+ describe('when the active pane does not have an item for the selected path and fuzzy-finder.searchAllPanes is true', () => {
+ beforeEach(() => atom.config.set('fuzzy-finder.searchAllPanes', true))
+
+ it('switches to the pane with the item for the selected path', async () => {
+ const expectedPath = atom.project.getDirectories()[0].resolve('sample.txt')
+ let originalPane = null
+
+ await bufferView.toggle()
+
+ atom.views.getView(editor1).focus()
+ originalPane = atom.workspace.getActivePane()
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ bufferView.confirm({uri: expectedPath}, {searchAllPanes: atom.config.get('fuzzy-finder.searchAllPanes')})
+
+ await conditionPromise(() => atom.workspace.getActiveTextEditor().getPath() === expectedPath)
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(false)
+ expect(atom.workspace.getActivePane()).not.toBe(originalPane)
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor3)
+ expect(atom.workspace.getPaneItems().length).toBe(3)
+ })
+ })
+ })
+ })
+
+ describe('common behavior between file and buffer finder', () =>
+ describe('when the fuzzy finder is cancelled', () => {
+ describe('when an editor is open', () =>
+ it('detaches the finder and focuses the previously focused element', async () => {
+ jasmine.attachToDOM(workspaceElement)
+ const activeEditor = atom.workspace.getActiveTextEditor()
+
+ await projectView.toggle()
+
+ expect(projectView.element.parentElement).toBeDefined()
+ expect(projectView.selectListView.refs.queryEditor.element).toHaveFocus()
+
+ projectView.cancel()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(false)
+ expect(atom.views.getView(activeEditor)).toHaveFocus()
+ })
+ )
+
+ describe('when no editors are open', () =>
+ it('detaches the finder and focuses the previously focused element', async () => {
+ jasmine.attachToDOM(workspaceElement)
+ atom.workspace.getActivePane().destroy()
+
+ const inputView = document.createElement('input')
+ workspaceElement.appendChild(inputView)
+ inputView.focus()
+
+ await projectView.toggle()
+
+ expect(projectView.element.parentElement).toBeDefined()
+ expect(projectView.selectListView.refs.queryEditor.element).toHaveFocus()
+ projectView.cancel()
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(false)
+ expect(inputView).toHaveFocus()
+ })
+ )
+ })
+ )
+
+ describe('cached file paths', () => {
+ beforeEach(() => {
+ spyOn(PathLoader, 'startTask').andCallThrough()
+ spyOn(atom.workspace, 'getTextEditors').andCallThrough()
+ })
+
+ it('caches file paths after first time', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(PathLoader.startTask).toHaveBeenCalled()
+ PathLoader.startTask.reset()
+
+ await projectView.toggle()
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(PathLoader.startTask).not.toHaveBeenCalled()
+ })
+
+ it("doesn't cache buffer paths", async () => {
+ await bufferView.toggle()
+
+ await waitForPathsToDisplay(bufferView)
+
+ expect(atom.workspace.getTextEditors).toHaveBeenCalled()
+ atom.workspace.getTextEditors.reset()
+
+ await bufferView.toggle()
+
+ await bufferView.toggle()
+
+ await waitForPathsToDisplay(bufferView)
+
+ expect(atom.workspace.getTextEditors).toHaveBeenCalled()
+ })
+
+ it('busts the cache when the window gains focus', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(PathLoader.startTask).toHaveBeenCalled()
+ PathLoader.startTask.reset()
+ window.dispatchEvent(new CustomEvent('focus'))
+ await projectView.toggle()
+
+ await projectView.toggle()
+
+ expect(PathLoader.startTask).toHaveBeenCalled()
+ })
+
+ it('busts the cache when the project path changes', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(PathLoader.startTask).toHaveBeenCalled()
+ PathLoader.startTask.reset()
+ atom.project.setPaths([temp.mkdirSync('atom')])
+
+ await projectView.toggle()
+
+ await projectView.toggle()
+
+ expect(PathLoader.startTask).toHaveBeenCalled()
+
+ await waitForReCrawlerToFinish(projectView)
+
+ expect(projectView.element.querySelectorAll('li').length).toBe(0)
+ })
+
+ describe('the initial load paths task started during package activation', () => {
+ beforeEach(async () => {
+ fuzzyFinder.projectView.destroy()
+ fuzzyFinder.projectView = null
+ fuzzyFinder.startLoadPathsTask()
+
+ await conditionPromise(() => fuzzyFinder.projectPaths)
+ })
+
+ it('passes the indexed paths into the project view when it is created', () => {
+ const {projectPaths} = fuzzyFinder
+ expect(projectPaths.length).toBe(19)
+ projectView = fuzzyFinder.createProjectView()
+ expect(projectView.paths).toBe(projectPaths)
+ expect(projectView.reloadPaths).toBe(false)
+ })
+
+ it('busts the cached paths when the project paths change', () => {
+ atom.project.setPaths([])
+
+ const {projectPaths} = fuzzyFinder
+ expect(projectPaths).toBe(null)
+
+ projectView = fuzzyFinder.createProjectView()
+ expect(projectView.paths).toBe(null)
+ expect(projectView.reloadPaths).toBe(true)
+ })
+ })
+ })
+
+ describe('opening a path into a split', () => {
+ it('opens the path by splitting the active editor left', async () => {
+ expect(atom.workspace.getCenter().getPanes().length).toBe(1)
+ let filePath = null
+
+ await bufferView.toggle();
+
+ ({filePath} = bufferView.selectListView.getSelectedItem())
+ atom.commands.dispatch(bufferView.element, 'pane:split-left')
+
+ await conditionPromise(() => atom.workspace.getCenter().getPanes().length === 2)
+
+ await conditionPromise(() => atom.workspace.getActiveTextEditor())
+
+ const [leftPane, rightPane] = atom.workspace.getCenter().getPanes() // eslint-disable-line no-unused-vars
+ expect(atom.workspace.getActivePane()).toBe(leftPane)
+ expect(atom.workspace.getActiveTextEditor().getPath()).toBe(atom.project.getDirectories()[0].resolve(filePath))
+ })
+
+ it('opens the path by splitting the active editor right', async () => {
+ expect(atom.workspace.getCenter().getPanes().length).toBe(1)
+ let filePath = null
+
+ await bufferView.toggle();
+
+ ({filePath} = bufferView.selectListView.getSelectedItem())
+ atom.commands.dispatch(bufferView.element, 'pane:split-right')
+
+ await conditionPromise(() => atom.workspace.getCenter().getPanes().length === 2)
+
+ await conditionPromise(() => atom.workspace.getActiveTextEditor())
+
+ const [leftPane, rightPane] = atom.workspace.getCenter().getPanes() // eslint-disable-line no-unused-vars
+ expect(atom.workspace.getActivePane()).toBe(rightPane)
+ expect(atom.workspace.getActiveTextEditor().getPath()).toBe(atom.project.getDirectories()[0].resolve(filePath))
+ })
+
+ it('opens the path by splitting the active editor up', async () => {
+ expect(atom.workspace.getCenter().getPanes().length).toBe(1)
+ let filePath = null
+
+ await bufferView.toggle();
+
+ ({filePath} = bufferView.selectListView.getSelectedItem())
+ atom.commands.dispatch(bufferView.element, 'pane:split-up')
+
+ await conditionPromise(() => atom.workspace.getCenter().getPanes().length === 2)
+
+ await conditionPromise(() => atom.workspace.getActiveTextEditor())
+
+ const [topPane, bottomPane] = atom.workspace.getCenter().getPanes() // eslint-disable-line no-unused-vars
+ expect(atom.workspace.getActivePane()).toBe(topPane)
+ expect(atom.workspace.getActiveTextEditor().getPath()).toBe(atom.project.getDirectories()[0].resolve(filePath))
+ })
+
+ it('opens the path by splitting the active editor down', async () => {
+ expect(atom.workspace.getCenter().getPanes().length).toBe(1)
+ let filePath = null
+
+ await bufferView.toggle();
+
+ ({filePath} = bufferView.selectListView.getSelectedItem())
+ atom.commands.dispatch(bufferView.element, 'pane:split-down')
+
+ await conditionPromise(() => atom.workspace.getCenter().getPanes().length === 2)
+
+ await conditionPromise(() => atom.workspace.getActiveTextEditor())
+
+ const [topPane, bottomPane] = atom.workspace.getCenter().getPanes() // eslint-disable-line no-unused-vars
+ expect(atom.workspace.getActivePane()).toBe(bottomPane)
+ expect(atom.workspace.getActiveTextEditor().getPath()).toBe(atom.project.getDirectories()[0].resolve(filePath))
+ })
+ })
+
+ describe('when the query contains a colon', () => {
+ beforeEach(async () => {
+ jasmine.attachToDOM(workspaceElement)
+ expect(atom.workspace.panelForItem(projectView)).toBeNull()
+
+ await atom.workspace.open('sample.txt')
+
+ const [editor1, editor2] = atom.workspace.getTextEditors()
+ editor1.setCursorBufferPosition([8, 3])
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor2)
+ expect(editor1.getCursorBufferPosition()).toEqual([8, 3])
+ })
+
+ describe('when the colon is followed by numbers', () => {
+ describe('when the numbers are not followed by another colon', () => {
+ describe('when the filter text has a file path', () => {
+ it('opens the selected path to that line number', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.setText('sample.js:4')
+
+ await getOrScheduleUpdatePromise()
+
+ const {filePath} = bufferView.selectListView.getSelectedItem()
+ expect(atom.project.getDirectories()[0].resolve(filePath)).toBe(editor1.getPath())
+
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([3, 4])
+ })
+ })
+
+ describe("when the filter text doesn't have a file path", () => {
+ it('moves the cursor in the active editor to that line number', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText(':4')
+
+ await getOrScheduleUpdatePromise()
+
+ expect(bufferView.element.querySelectorAll('li').length).toBe(0)
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([3, 4])
+ })
+ })
+ })
+
+ describe('when the numbers are followed by another colon', () => {
+ describe('when the colon is followed by more numbers', () => {
+ describe('when the filter text has a file path', () => {
+ it('opens the selected path to that line number and column', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.setText('sample.js:4:6')
+
+ await getOrScheduleUpdatePromise()
+
+ const {filePath} = bufferView.selectListView.getSelectedItem()
+ expect(atom.project.getDirectories()[0].resolve(filePath)).toBe(editor1.getPath())
+
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([3, 6])
+ })
+ })
+
+ describe("when the filter text doesn't have a file path", () => {
+ it('moves the cursor in the active editor to that line number and column', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText(':4:6')
+
+ await getOrScheduleUpdatePromise()
+
+ expect(bufferView.selectListView.refs.emptyMessage.innerText).toEqual(
+ 'Jump to line and column in active editor'
+ )
+ expect(bufferView.element.querySelectorAll('li').length).toBe(0)
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([3, 6])
+ })
+ })
+ })
+
+ describe('when the colon is not followed by more numbers', () => {
+ describe('when the filter text has a file path', () => {
+ it('opens the file, jumps to the first character of the line and does not throw an error', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.setText('sample.js:5:a')
+
+ await getOrScheduleUpdatePromise()
+
+ const {filePath} = bufferView.selectListView.getSelectedItem()
+ expect(atom.project.getDirectories()[0].resolve(filePath)).toBe(editor1.getPath())
+
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([4, 4])
+ })
+ })
+
+ describe("when the filter text doesn't have a file path", () => {
+ it('jumps to the first character of the line and does not throw an error', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.setText(':5:a')
+
+ await getOrScheduleUpdatePromise()
+
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([4, 4])
+ })
+ })
+ })
+ })
+ })
+
+ describe('when the colon is not followed by numbers', () => {
+ describe('when the filter text has a file path', () => {
+ it('opens the file and does not throw an error', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.setText('sample.js:a')
+
+ await getOrScheduleUpdatePromise()
+
+ const {filePath} = bufferView.selectListView.getSelectedItem()
+ expect(atom.project.getDirectories()[0].resolve(filePath)).toBe(editor1.getPath())
+
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([8, 3])
+ })
+ })
+
+ describe("when the filter text doesn't have a file path", () => {
+ it('shows an error and does not move the cursor', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.setText('::')
+
+ await getOrScheduleUpdatePromise()
+
+ expect(bufferView.selectListView.refs.errorMessage.innerText).toEqual('Invalid line number')
+
+ expect(bufferView.element.querySelectorAll('li').length).toBe(0)
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'core:confirm')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+ expect(editor1.getCursorBufferPosition()).toEqual([8, 3])
+ })
+
+ it('updates the message when the error gets resolved', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ const emptyMessage = 'Jump to line in active editor'
+ const errorMessage = 'Invalid line number'
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+
+ bufferView.selectListView.refs.queryEditor.setText(':42')
+ await getOrScheduleUpdatePromise()
+ expect(bufferView.selectListView.refs.emptyMessage.innerText).toEqual(emptyMessage)
+ expect(bufferView.selectListView.refs.errorMessage).toBeUndefined()
+
+ bufferView.selectListView.refs.queryEditor.setText(':42a')
+ await getOrScheduleUpdatePromise()
+ expect(bufferView.selectListView.refs.emptyMessage).toBeUndefined()
+ expect(bufferView.selectListView.refs.errorMessage.innerText).toEqual(errorMessage)
+
+ bufferView.selectListView.refs.queryEditor.setText(':42')
+ await getOrScheduleUpdatePromise()
+ expect(bufferView.selectListView.refs.emptyMessage.innerText).toEqual(emptyMessage)
+ expect(bufferView.selectListView.refs.errorMessage).toBeUndefined()
+ })
+
+ it('shows a specific error message when the column is invalid', async () => {
+ const [editor1] = atom.workspace.getTextEditors()
+ const errorMessage = 'Invalid column number'
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+
+ bufferView.selectListView.refs.queryEditor.setText(':42:12a')
+ await getOrScheduleUpdatePromise()
+ expect(bufferView.selectListView.refs.emptyMessage).toBeUndefined()
+ expect(bufferView.selectListView.refs.errorMessage.innerText).toEqual(errorMessage)
+ })
+
+ it('shows a more specific message when jumping to line and column', async () => {
+ const [editor1] = atom.workspace.getTextEditors()
+ const emptyColumnMessage = 'Jump to line and column in active editor'
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+
+ bufferView.selectListView.refs.queryEditor.setText(':42:')
+ await getOrScheduleUpdatePromise()
+ expect(bufferView.selectListView.refs.emptyMessage.innerText).toEqual(emptyColumnMessage)
+
+ bufferView.selectListView.refs.queryEditor.setText(':42:12')
+ await getOrScheduleUpdatePromise()
+ expect(bufferView.selectListView.refs.emptyMessage.innerText).toEqual(emptyColumnMessage)
+ })
+ })
+ })
+ })
+
+ describe('match highlighting', () => {
+ beforeEach(async () => {
+ jasmine.attachToDOM(workspaceElement)
+ await bufferView.toggle()
+ })
+
+ it('highlights an exact match', async () => {
+ bufferView.selectListView.refs.queryEditor.setText('sample.js')
+
+ await getOrScheduleUpdatePromise()
+
+ const resultView = bufferView.element.querySelector('li')
+ const primaryMatches = resultView.querySelectorAll('.primary-line .character-match')
+ const secondaryMatches = resultView.querySelectorAll('.secondary-line .character-match')
+ expect(primaryMatches.length).toBe(1)
+ expect(primaryMatches[primaryMatches.length - 1].textContent).toBe('sample.js')
+ // Use `toBeGreaterThan` because dir may have some characters in it
+ expect(secondaryMatches.length).toBeGreaterThan(0)
+ expect(secondaryMatches[secondaryMatches.length - 1].textContent).toBe('sample.js')
+ })
+
+ it('highlights a partial match', async () => {
+ bufferView.selectListView.refs.queryEditor.setText('sample')
+
+ await getOrScheduleUpdatePromise()
+
+ const resultView = bufferView.element.querySelector('li')
+ const primaryMatches = resultView.querySelectorAll('.primary-line .character-match')
+ const secondaryMatches = resultView.querySelectorAll('.secondary-line .character-match')
+ expect(primaryMatches.length).toBe(1)
+ expect(primaryMatches[primaryMatches.length - 1].textContent).toBe('sample')
+ // Use `toBeGreaterThan` because dir may have some characters in it
+ expect(secondaryMatches.length).toBeGreaterThan(0)
+ expect(secondaryMatches[secondaryMatches.length - 1].textContent).toBe('sample')
+ })
+
+ it('highlights multiple matches in the file name', async () => {
+ bufferView.selectListView.refs.queryEditor.setText('samplejs')
+
+ await getOrScheduleUpdatePromise()
+
+ const resultView = bufferView.element.querySelector('li')
+ const primaryMatches = resultView.querySelectorAll('.primary-line .character-match')
+ const secondaryMatches = resultView.querySelectorAll('.secondary-line .character-match')
+ expect(primaryMatches.length).toBe(2)
+ expect(primaryMatches[0].textContent).toBe('sample')
+ expect(primaryMatches[primaryMatches.length - 1].textContent).toBe('js')
+ // Use `toBeGreaterThan` because dir may have some characters in it
+ expect(secondaryMatches.length).toBeGreaterThan(1)
+ expect(secondaryMatches[secondaryMatches.length - 1].textContent).toBe('js')
+ })
+
+ it('highlights matches in the directory and file name', async () => {
+ spyOn(bufferView, 'projectRelativePathsForFilePaths').andCallFake((paths) => paths)
+ bufferView.selectListView.refs.queryEditor.setText('root-dirsample')
+
+ await bufferView.setItems([
+ {
+ filePath: path.join('test', 'root-dir1', 'sample.js'),
+ label: path.join('root-dir1', 'sample.js')
+ }
+ ])
+
+ await filesPromise()
+ const resultView = bufferView.element.querySelector('li')
+ const primaryMatches = resultView.querySelectorAll('.primary-line .character-match')
+ const secondaryMatches = resultView.querySelectorAll('.secondary-line .character-match')
+ expect(primaryMatches.length).toBe(1)
+ expect(primaryMatches[primaryMatches.length - 1].textContent).toBe('sample')
+ expect(secondaryMatches.length).toBe(2)
+ expect(secondaryMatches[0].textContent).toBe('root-dir')
+ expect(secondaryMatches[secondaryMatches.length - 1].textContent).toBe('sample')
+ })
+
+ describe('when splitting panes', () => {
+ it('opens the selected path to that line number in a new pane', async () => {
+ const [editor1, editor2] = atom.workspace.getTextEditors() // eslint-disable-line no-unused-vars
+
+ await atom.workspace.open('sample.js')
+
+ expect(atom.workspace.getActiveTextEditor()).toBe(editor1)
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText(':4')
+
+ await getOrScheduleUpdatePromise()
+
+ expect(bufferView.element.querySelectorAll('li').length).toBe(0)
+ spyOn(bufferView, 'moveToCaretPosition').andCallThrough()
+ atom.commands.dispatch(bufferView.element, 'pane:split-left')
+
+ await conditionPromise(() => bufferView.moveToCaretPosition.callCount > 0)
+
+ expect(atom.workspace.getActiveTextEditor()).not.toBe(editor1)
+ expect(atom.workspace.getActiveTextEditor().getPath()).toBe(editor1.getPath())
+ expect(atom.workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual([3, 4])
+ })
+ })
+ })
+
+ describe('preserve last search', () => {
+ it('does not preserve last search by default', async () => {
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText('this should not show up next time we open finder')
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(false)
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ expect(projectView.selectListView.getQuery()).toBe('')
+ })
+
+ it('preserves last search when the config is set', async () => {
+ atom.config.set('fuzzy-finder.preserveLastSearch', true)
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ projectView.selectListView.refs.queryEditor.insertText('this should show up next time we open finder')
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(false)
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ expect(projectView.selectListView.getQuery()).toBe('this should show up next time we open finder')
+ expect(projectView.selectListView.refs.queryEditor.getSelectedText()).toBe('this should show up next time we open finder')
+ })
+ })
+
+ describe('prefill query from selection', () => {
+ it('should not be enabled by default', async () => {
+ await atom.workspace.open()
+
+ atom.workspace.getActiveTextEditor().setText('sample.txt')
+ atom.workspace.getActiveTextEditor().setSelectedBufferRange([[0, 0], [0, 10]])
+ expect(atom.workspace.getActiveTextEditor().getSelectedText()).toBe('sample.txt')
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ expect(projectView.selectListView.getQuery()).toBe('')
+ expect(projectView.selectListView.refs.queryEditor.getSelectedText()).toBe('')
+ })
+
+ it('takes selection from active editor and prefills query with it', async () => {
+ atom.config.set('fuzzy-finder.prefillFromSelection', true)
+
+ await atom.workspace.open()
+
+ atom.workspace.getActiveTextEditor().setText('sample.txt')
+ atom.workspace.getActiveTextEditor().setSelectedBufferRange([[0, 0], [0, 10]])
+ expect(atom.workspace.getActiveTextEditor().getSelectedText()).toBe('sample.txt')
+
+ await projectView.toggle()
+
+ expect(atom.workspace.panelForItem(projectView).isVisible()).toBe(true)
+ expect(projectView.selectListView.getQuery()).toBe('sample.txt')
+ expect(projectView.selectListView.refs.queryEditor.getSelectedText()).toBe('sample.txt')
+ })
+ })
+
+ describe('default file icons', () => {
+ it('shows a text icon for text-based formats', async () => {
+ await atom.workspace.open('sample.js')
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText('js')
+
+ await getOrScheduleUpdatePromise()
+
+ const firstResult = bufferView.element.querySelector('li .primary-line')
+ expect(DefaultFileIcons.iconClassForPath(firstResult.dataset.path)).toBe('icon-file-text')
+ })
+
+ it('shows an image icon for graphic formats', async () => {
+ await atom.workspace.open('sample.gif')
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText('gif')
+
+ await getOrScheduleUpdatePromise()
+
+ const firstResult = bufferView.element.querySelector('li .primary-line')
+ expect(DefaultFileIcons.iconClassForPath(firstResult.dataset.path)).toBe('icon-file-media')
+ })
+ })
+
+ describe('icon services', () => {
+ describe('atom.file-icons', () => {
+ it('has a default handler', () => {
+ expect(getIconServices().fileIcons).toBe(DefaultFileIcons)
+ })
+
+ it('allows services to replace the default handler', async () => {
+ const provider = {iconClassForPath: () => 'foo bar'}
+ const disposable = atom.packages.serviceHub.provide('atom.file-icons', '1.0.0', provider)
+ expect(getIconServices().fileIcons).toBe(provider)
+
+ await atom.workspace.open('sample.js')
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText('js')
+
+ await getOrScheduleUpdatePromise()
+
+ const firstResult = bufferView.element.querySelector('li .primary-line')
+ expect(firstResult).toBeDefined()
+ expect(firstResult.className).toBe('primary-line file icon foo bar')
+ disposable.dispose()
+ expect(getIconServices().fileIcons).toBe(DefaultFileIcons)
+ })
+ })
+
+ describe('file-icons.element-icons', () => {
+ it('has no default handler', () => {
+ expect(getIconServices().elementIcons).toBe(null)
+ })
+
+ it('uses the element-icon service if available', async () => {
+ const provider = element => {
+ element.classList.add('foo', 'bar')
+ return new Disposable(() => {
+ element.classList.remove('foo', 'bar')
+ })
+ }
+ const disposable = atom.packages.serviceHub.provide('file-icons.element-icons', '1.0.0', provider)
+ expect(getIconServices().elementIcons).toBe(provider)
+
+ await atom.workspace.open('sample.js')
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText('js')
+
+ await getOrScheduleUpdatePromise()
+
+ const firstResult = bufferView.element.querySelector('li .primary-line')
+ expect(firstResult).toBeDefined()
+ expect(firstResult.className).toBe('primary-line file icon foo bar')
+ disposable.dispose()
+ expect(getIconServices().elementIcons).toBe(null)
+ expect(firstResult.classList).not.toBe('primary-line file icon foo bar')
+ })
+ })
+
+ describe('when both services are provided', () => {
+ it('gives priority to the element-icon service', async () => {
+ const basicProvider = {iconClassForPath: () => 'foo'}
+ const elementProvider = element => {
+ element.classList.add('bar')
+ return new Disposable(() => {
+ element.classList.remove('bar')
+ })
+ }
+ spyOn(basicProvider, 'iconClassForPath').andCallThrough()
+ atom.packages.serviceHub.provide('atom.file-icons', '1.0.0', basicProvider)
+ atom.packages.serviceHub.provide('file-icons.element-icons', '1.0.0', elementProvider)
+ expect(getIconServices().fileIcons).toBe(basicProvider)
+ expect(getIconServices().elementIcons).toBe(elementProvider)
+
+ await atom.workspace.open('sample.js')
+
+ await bufferView.toggle()
+
+ expect(atom.workspace.panelForItem(bufferView).isVisible()).toBe(true)
+ bufferView.selectListView.refs.queryEditor.insertText('js')
+
+ await getOrScheduleUpdatePromise()
+
+ const firstResult = bufferView.element.querySelector('li .primary-line')
+ expect(firstResult).toBeDefined()
+ expect(firstResult.className).toBe('primary-line file icon bar')
+ expect(basicProvider.iconClassForPath).not.toHaveBeenCalled()
+ })
+ })
+ })
+
+ describe('Git integration', () => {
+ let projectPath, gitRepository, gitDirectory
+
+ beforeEach(() => {
+ projectPath = atom.project.getDirectories()[0].resolve('git/working-dir')
+ fs.renameSync(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
+ atom.project.setPaths([rootDir2, projectPath])
+
+ gitDirectory = atom.project.getDirectories()[1]
+ gitRepository = atom.project.getRepositories()[1]
+
+ return new Promise(
+ resolve => gitRepository.onDidChangeStatuses(resolve)
+ )
+ })
+
+ describe('git-status-finder behavior', () => {
+ let originalPath, newPath
+
+ beforeEach(async () => {
+ jasmine.attachToDOM(workspaceElement)
+
+ await atom.workspace.open(path.join(projectPath, 'a.txt'))
+
+ const editor = atom.workspace.getActiveTextEditor()
+ originalPath = editor.getPath()
+ fs.writeFileSync(originalPath, 'making a change for the better')
+ gitRepository.getPathStatus(originalPath)
+
+ newPath = atom.project.getDirectories()[1].resolve('newsample.js')
+ fs.writeFileSync(newPath, '')
+ gitRepository.getPathStatus(newPath)
+ })
+
+ it('displays all new and modified paths', async () => {
+ expect(atom.workspace.panelForItem(gitStatusView)).toBeNull()
+ await gitStatusView.toggle()
+
+ await filesPromise()
+ expect(atom.workspace.panelForItem(gitStatusView).isVisible()).toBe(true)
+ expect(gitStatusView.element.querySelectorAll('.file').length).toBe(4)
+ expect(gitStatusView.element.querySelectorAll('.status.status-modified').length).toBe(1)
+ expect(gitStatusView.element.querySelectorAll('.status.status-added').length).toBe(3)
+ })
+ })
+
+ describe('status decorations', () => {
+ let originalPath, editor, newPath
+
+ beforeEach(async () => {
+ jasmine.attachToDOM(workspaceElement)
+
+ await atom.workspace.open(path.join(projectPath, 'a.txt'))
+
+ editor = atom.workspace.getActiveTextEditor()
+ originalPath = editor.getPath()
+ newPath = gitDirectory.resolve('newsample.js')
+ fs.writeFileSync(newPath, '')
+ fs.writeFileSync(originalPath, 'a change')
+ })
+
+ describe('when a modified file is shown in the list', () =>
+ it('displays the modified icon', async () => {
+ gitRepository.getPathStatus(editor.getPath())
+
+ bufferView.toggle()
+ await filesPromise()
+ expect(bufferView.element.querySelectorAll('.status.status-modified').length).toBe(1)
+ expect(bufferView.element.querySelector('.status.status-modified').closest('li').querySelector('.file').textContent).toBe('a.txt')
+ })
+ )
+
+ describe('when a new file is shown in the list', () =>
+ it('displays the new icon', async () => {
+ await atom.workspace.open(path.join(projectPath, 'newsample.js'))
+
+ gitRepository.getPathStatus(editor.getPath())
+
+ bufferView.toggle()
+ await filesPromise()
+ expect(bufferView.element.querySelectorAll('.status.status-added').length).toBe(1)
+ expect(bufferView.element.querySelector('.status.status-added').closest('li').querySelector('.file').textContent).toBe('newsample.js')
+ })
+ )
+ })
+
+ describe('when core.excludeVcsIgnoredPaths is set to true', () => {
+ beforeEach(() => atom.config.set('core.excludeVcsIgnoredPaths', true))
+
+ describe("when the project's path is the repository's working directory", () => {
+ beforeEach(() => {
+ const ignoreFile = path.join(projectPath, '.gitignore')
+ fs.writeFileSync(ignoreFile, 'ignored.txt')
+
+ const ignoredFile = path.join(projectPath, 'ignored.txt')
+ fs.writeFileSync(ignoredFile, 'ignored text')
+ })
+
+ it('excludes paths that are git ignored', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('ignored.txt'))).not.toBeDefined()
+ })
+ })
+
+ describe("when the project's path is a subfolder of the repository's working directory", () => {
+ beforeEach(() => {
+ atom.project.setPaths([gitDirectory.resolve('dir')])
+ const ignoreFile = path.join(projectPath, '.gitignore')
+ fs.writeFileSync(ignoreFile, 'b.txt')
+ })
+
+ if (useRipGrep) {
+ it('does excludes paths that are git ignored', async () => {
+ fs.writeFileSync(path.join(projectPath, 'dir', 'a.txt'), 'something')
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('b.txt'))).not.toBeDefined()
+ })
+ } else {
+ it('does not exclude paths that are git ignored', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('b.txt'))).toBeDefined()
+ })
+ }
+ })
+
+ describe('when the .gitignore matches parts of the path to the root folder', () => {
+ beforeEach(() => {
+ const ignoreFile = path.join(projectPath, '.gitignore')
+ fs.writeFileSync(ignoreFile, path.basename(projectPath))
+ })
+
+ it('only applies the .gitignore patterns to relative paths within the root folder', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('file.txt'))).toBeDefined()
+ })
+ })
+
+ describe('when core.ignoredNames does not have .git in its glob patterns', () => {
+ beforeEach(() => {
+ atom.config.set('core.ignoredNames', [])
+ })
+
+ it('still ignores .git directory', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a =>
+ a.textContent.includes('HEAD'))).not.toBeDefined()
+ })
+ })
+ })
+
+ describe('when core.excludeVcsIgnoredPaths is set to false', () => {
+ beforeEach(() => atom.config.set('core.excludeVcsIgnoredPaths', false))
+
+ describe("when the project's path is the repository's working directory", () => {
+ beforeEach(() => {
+ const ignoreFile = path.join(projectPath, '.gitignore')
+ fs.writeFileSync(ignoreFile, 'ignored.txt')
+
+ const ignoredFile = path.join(projectPath, 'ignored.txt')
+ fs.writeFileSync(ignoredFile, 'ignored text')
+ })
+
+ it("doesn't exclude paths that are git ignored", async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('ignored.txt'))).toBeDefined()
+ })
+ })
+ })
+
+ describe('logging of metrics events', () => {
+ it('logs the crawling time', async () => {
+ // After setting the reporter it may receive some old events from previous tests
+ // that we want to discard.
+ reporterStub.addTiming.resetHistory()
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(reporterStub.addTiming.firstCall.args[0]).toEqual('fuzzy-finder-v1')
+ expect(reporterStub.addTiming.firstCall.args[2]).toEqual(
+ {ec: 'time-to-crawl', el: useRipGrep ? 'ripgrep' : 'fs', ev: 5}
+ )
+ })
+
+ it('queues the events until a reporter is set', async () => {
+ // After setting the reporter it may receive some old events from previous tests
+ // that we want to discard.
+ reporterStub.addTiming.resetHistory()
+
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ fuzzyFinderPackage.consumeMetricsReporter(reporterStub)
+
+ expect(reporterStub.addTiming.firstCall.args[0]).toEqual('fuzzy-finder-v1')
+ expect(reporterStub.addTiming.firstCall.args[2]).toEqual(
+ {ec: 'time-to-crawl', el: useRipGrep ? 'ripgrep' : 'fs', ev: 5}
+ )
+ })
+ })
+ })
+
+ describe('error handling', () => {
+ beforeEach(() => {
+ const junkDirPath = fs.realpathSync(temp.mkdirSync('junk-1'))
+ const brokenFilePath = path.join(junkDirPath, 'delete.txt')
+ fs.writeFileSync(brokenFilePath, 'delete-me')
+
+ for (let i = 0; i < 1000; i++) {
+ fs.symlinkSync(brokenFilePath, atom.project.getDirectories()[0].resolve('broken-symlink-' + i))
+ }
+
+ fs.unlinkSync(brokenFilePath)
+ })
+
+ it('copes with a lot of errors during indexing', async () => {
+ await projectView.toggle()
+
+ await waitForPathsToDisplay(projectView)
+
+ expect(projectView.element.querySelector('.loading')).not.toBeVisible()
+ })
+ })
+ })
+ }
+
+ it('shows all files for the current project once the initial crawler has finished', async () => {
+ await waitForInitialCrawlerToFinish(fuzzyFinder)
+
+ projectView = fuzzyFinder.createProjectView()
+ jasmine.attachToDOM(workspaceElement)
+
+ await projectView.selectListView.update({maxResults: null})
+ await projectView.toggle()
+
+ expect(projectView.element.querySelector('.loading')).not.toBeVisible()
+
+ await waitForPathsToDisplay(projectView)
+
+ eachFilePath([rootDir1, rootDir2], (filePath) => {
+ const item = Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes(filePath))
+ expect(item).toExist()
+ const nameDiv = item.querySelector('div:first-child')
+ expect(nameDiv.dataset.name).toBe(path.basename(filePath))
+ expect(nameDiv.textContent).toBe(path.basename(filePath))
+ })
+
+ expect(projectView.element.querySelector('.loading')).not.toBeVisible()
+ })
+})
diff --git a/packages/fuzzy-finder/spec/project-view-spec.js b/packages/fuzzy-finder/spec/project-view-spec.js
new file mode 100644
index 0000000000..b440329084
--- /dev/null
+++ b/packages/fuzzy-finder/spec/project-view-spec.js
@@ -0,0 +1,86 @@
+const {it, fit, ffit, fffit, beforeEach, afterEach, conditionPromise} = require('./async-spec-helpers') // eslint-disable-line no-unused-vars
+const fs = require('fs')
+const os = require('os')
+const path = require('path')
+const sinon = require('sinon')
+const temp = require('temp').track()
+const ProjectView = require('../lib/project-view')
+const ReporterProxy = require('../lib/reporter-proxy')
+
+const metricsReporter = new ReporterProxy()
+
+describe('ProjectView', () => {
+ beforeEach(() => {
+ jasmine.useRealClock()
+
+ // Limit concurrency on the crawler to avoid indeterminism.
+ sinon.stub(os, 'cpus').returns({length: 1})
+ })
+
+ afterEach(() => {
+ os.cpus.restore()
+ })
+
+ it('includes remote editors when teletype is enabled', async () => {
+ const projectView = new ProjectView([], metricsReporter)
+
+ const projectPath = fs.realpathSync(temp.mkdirSync())
+ const file1Path = path.join(projectPath, 'a')
+ fs.writeFileSync(file1Path, 'a')
+ const file2Path = path.join(projectPath, 'b')
+ fs.writeFileSync(file2Path, 'b')
+ atom.project.setPaths([projectPath])
+
+ projectView.setTeletypeService({
+ async getRemoteEditors () {
+ return [
+ {uri: 'remote1-uri', path: 'remote1-path', hostGitHubUsername: 'user-1'},
+ {uri: 'remote2-uri', path: 'remote2-path', hostGitHubUsername: 'user-2'}
+ ]
+ }
+ })
+
+ projectView.toggle()
+ await conditionPromise(() => projectView.items.length === 4)
+ expect(projectView.items).toEqual([
+ {uri: 'remote1-uri', filePath: 'remote1-path', label: '@user-1: remote1-path', ownerGitHubUsername: 'user-1'},
+ {uri: 'remote2-uri', filePath: 'remote2-path', label: '@user-2: remote2-path', ownerGitHubUsername: 'user-2'},
+ {uri: file1Path, filePath: file1Path, label: 'a'},
+ {uri: file2Path, filePath: file2Path, label: 'b'}
+ ])
+ })
+
+ it('shows remote editors even when there is no open project', async () => {
+ const projectView = new ProjectView([], metricsReporter)
+
+ atom.project.setPaths([])
+ projectView.setTeletypeService({
+ async getRemoteEditors () {
+ return [
+ {uri: 'remote1-uri', path: 'remote1-path', hostGitHubUsername: 'user-1'},
+ {uri: 'remote2-uri', path: 'remote2-path', hostGitHubUsername: 'user-2'}
+ ]
+ }
+ })
+
+ await projectView.toggle()
+ expect(projectView.items).toEqual([
+ {uri: 'remote1-uri', filePath: 'remote1-path', label: '@user-1: remote1-path', ownerGitHubUsername: 'user-1'},
+ {uri: 'remote2-uri', filePath: 'remote2-path', label: '@user-2: remote2-path', ownerGitHubUsername: 'user-2'}
+ ])
+ })
+
+ it('gracefully defaults to empty list if teletype is unable to provide remote editors', async () => {
+ const projectView = new ProjectView([], metricsReporter)
+
+ atom.project.setPaths([])
+ projectView.setTeletypeService({
+ async getRemoteEditors () {
+ return null
+ }
+ })
+
+ await projectView.toggle()
+ expect(projectView.items).toEqual([])
+ })
+})
diff --git a/packages/fuzzy-finder/styles/fuzzy-finder.less b/packages/fuzzy-finder/styles/fuzzy-finder.less
new file mode 100644
index 0000000000..e768deac5a
--- /dev/null
+++ b/packages/fuzzy-finder/styles/fuzzy-finder.less
@@ -0,0 +1,27 @@
+@import "ui-variables";
+
+// Highlight matched text
+.fuzzy-finder .list-group .character-match {
+ color: @text-color-highlight;
+ font-weight: bold;
+}
+
+.FuzzyFinderResult {
+ position: relative;
+
+ @size: 28px;
+
+ &.has-avatar {
+ // add some extra space for the avatar
+ padding-right: @size + (@component-padding * 2) !important;
+ }
+
+ &-avatar {
+ position: absolute !important;
+ border-radius: @size;
+ width: @size;
+ top: 50%;
+ margin-top: -(@size / 2);
+ right: @component-padding;
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 3ef2190180..c9d6b7a5a6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -29,13 +29,6 @@
dependencies:
"@babel/core" "7.x"
-"@atom/fuzzy-native@^1.1.2":
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/@atom/fuzzy-native/-/fuzzy-native-1.2.1.tgz#2a773bfa230da99e65c6708218b09bbd78293191"
- integrity sha512-ABUIbeQqfoA4WUK+PAsspM9jLaGlj0wjyIc9CIi1OMAHv71/vqrpJHPX2fHWiREEXYxwh/CBCshhkOWESbnNnQ==
- dependencies:
- nan "^2.14.2"
-
"@atom/source-map-support@^0.3.4":
version "0.3.4"
resolved "https://registry.yarnpkg.com/@atom/source-map-support/-/source-map-support-0.3.4.tgz#55ccbe0e64b2c742c5b333f357f9a93161145cfd"
@@ -1583,6 +1576,12 @@
"@types/node" "*"
playwright-core "1.22.2"
+"@pulsar-edit/fuzzy-native@https://github.com/pulsar-edit/fuzzy-native.git#13d2e5f":
+ version "1.2.1"
+ resolved "https://github.com/pulsar-edit/fuzzy-native.git#13d2e5fe348bc0a38bbec1de86d43940893010c8"
+ dependencies:
+ nan "2.17.0"
+
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
@@ -2256,11 +2255,6 @@ async-exit-hook@^2.0.1:
resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3"
integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==
-async@0.2.6:
- version "0.2.6"
- resolved "https://registry.yarnpkg.com/async/-/async-0.2.6.tgz#ad3f373d9249ae324881565582bc90e152abbd68"
- integrity sha512-LTdAJ0KBRK5o4BlBlUoGvfGNOMON+NLbONgDZk80SX0G8LQZyjN+74nNADIpQ/+rxun6+fYm7z4vIzAB51UKUA==
-
async@3.2.4, async@^3.2.0, async@^3.2.3:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
@@ -4802,24 +4796,18 @@ fuzzaldrin-plus@^0.6.0:
resolved "https://registry.yarnpkg.com/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz#832f6489fbe876769459599c914a670ec22947ee"
integrity sha512-srIDThJHkdp3aPwJpR/HNzYZCRJwm07b/igxseoHSB7qR8e/gQp4F6lMGknE3TQI1Aq14TiFf/wzrHOp9LY/EA==
-fuzzaldrin@^2.0, fuzzaldrin@^2.1, fuzzaldrin@^2.1.0:
+fuzzaldrin@^2.1, fuzzaldrin@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz#90204c3e2fdaa6941bb28d16645d418063a90e9b"
integrity sha512-zgllBYwfHR5P3CncJiGbGVPpa3iFYW1yuPaIv8DiTVRrcg5/6uETNL5zvIoKflG1aifXVUZTlIroDehw4WygGA==
-"fuzzy-finder@https://codeload.github.com/atom/fuzzy-finder/legacy.tar.gz/refs/tags/v1.14.3":
+"fuzzy-finder@file:packages/fuzzy-finder":
version "1.14.3"
- resolved "https://codeload.github.com/atom/fuzzy-finder/legacy.tar.gz/refs/tags/v1.14.3#7cd40191b8930bb49039a860ab868f554f90f41d"
dependencies:
- "@atom/fuzzy-native" "^1.1.2"
- async "0.2.6"
+ "@pulsar-edit/fuzzy-native" "https://github.com/pulsar-edit/fuzzy-native.git#13d2e5f"
atom-select-list "^0.7.0"
fs-plus "^3.0.0"
- fuzzaldrin "^2.0"
- fuzzaldrin-plus "^0.6.0"
- humanize-plus "~1.8.2"
minimatch "~3.0.3"
- temp "~0.8.1"
underscore-plus "^1.7.0"
vscode-ripgrep "^1.2.5"
wrench "^1.5"
@@ -7030,7 +7018,7 @@ nan@2.14.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
-nan@^2.10.0, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0, nan@^2.14.1, nan@^2.14.2:
+nan@2.17.0, nan@^2.10.0, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0, nan@^2.14.1, nan@^2.14.2:
version "2.17.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==