├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── README.md ├── package.json ├── prettier.config.js ├── resources ├── create.svg ├── logo.svg ├── merge.svg └── open.svg ├── src ├── BaseDocumentTreeProvider.ts ├── DebugManager.ts ├── DetailsViewContainer.ts ├── DiagnosticCollector.ts ├── Diff.ts ├── DisposableCollection.ts ├── DocumentLinkProvider.ts ├── DocumentTreeProvider.ts ├── FeedTreeProvider.ts ├── HistoryTreeProvider.ts ├── HypercoreFS.ts ├── HypermergeExplorer.ts ├── HypermergeFS.ts ├── HypermergeUriHandler.ts ├── HypermergeWrapper.ts ├── LedgerTreeProvider.ts ├── MetadataTreeProvider.ts └── extension.ts ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | default 4 | *.log 5 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": ["esbenp.prettier-vscode"], 7 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 8 | "unwantedRecommendations": [] 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": [ 11 | "--extensionDevelopmentPath=${workspaceRoot}" 12 | ], 13 | "stopOnEntry": false, 14 | "sourceMaps": true, 15 | "outFiles": [ 16 | "${workspaceRoot}/out/src/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: watch" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "identifier": "npm:watch", 8 | "type": "npm", 9 | "script": "watch", 10 | "problemMatcher": [ 11 | "$tsc-watch" 12 | ], 13 | "isBackground": true 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | vsc-extension-quickstart.md 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hypermerge for VSCode 2 | 3 | Browse & edit Hypermerge documents. This VSCode extension was built to work with [Farm][farm] but should be mostly compatible with Capstone, PushPin, and other Hypermerge projects (though support is subject to the vagaries of research software version drift.) 4 | 5 | This extension is not currently available in the VSCode extension marketplace because it requires platform-specific native dependencies. The best way to experience it is to: 6 | 7 | - Check out this repository. 8 | - Run `yarn` to install dependencies. 9 | - Open the repository in vscode (e.g. `$ code .` or just via `Open Folder...`) 10 | - Go to Debug -> Start Debugging (F5) in the menu. 11 | - A second, new VSCode window will open running the extension version you just built. You'll be able to put breakpoints in the code and see debug output in your original window. The new window's title will include \[Extension Development\] so you can recognize it. 12 | 13 | You're off to the races! 14 | 15 | ## Using Hypermerge for VSCode 16 | 17 | This extension allows you to open Hypermerge documents, edit them, and browse their history. It does so by introducing a new activity panel linked on the left-hand of your VSCode window with an icon that looks like a "merge" road sign. 18 | 19 | Clicking on that icon will show you several subpanels. The first and most important is HypermergeFS. 20 | 21 | ### HypermergeFS 22 | 23 | From this view you can load and traverse documents. Documents appear primarily at the root of this tree structure and are prefixed by the first five characters of their name. (For example: `Editable Title Code [2Kgzz]`.) You can click any document listed to open it as a text buffer in the main window. 24 | 25 | Sub-documents can be displayed as buffers as well, and leaf nodes -- plain strings, for example -- will appear as simple text buffers for editing. 26 | 27 | ### Text buffers 28 | 29 | When you open a hypermerge document (or subdocument), you'll see the document as though it were a JSON file. Under the hood, Hypermerge documents aren't really JSON files, they're really just data structures, but we map them to a sort of pseudo-JSON for editing in the IDE. As changes arrive you should see the buffer updating, and if you make changes, when you save that buffer, we parse the result back to a Javascript object and then compare it to the old document to produce a set of changes that are written. 30 | 31 | ### Metadata & Feeds 32 | 33 | These two panels give additional visibility into the state of the currently visible document. They show the key for the local actor which the VSCode plugin creates to save changes made in that client, the current vector clock representing all the applied changes for the data you're viewing, and a list of feeds where you can see not only the actual blocks which make up the 34 | 35 | Hypermerge can open arbitrary hypermerge files and treat them as both JSON and nested directory structures. You'll see a "Hypermerge" panel appear in the filesystem / document browser tab. From there you can either import URLs or create new documents. While looking at a Hypermerge document you should see a Hypermerge details pane appear in the list of views on the left navigation bar. Clicking it will display a special panel with details about the hypermerge document you're currently viewing, including providing a mechanism for navigating the document's history. 36 | 37 | # Project Admin 38 | 39 | ## Publishing a Release 40 | 41 | You'll want to [follow the instructions](https://code.visualstudio.com/docs/extensions/publish-extension) in the VSCE user manual, but to publish after setting up your Personal Access Token, run `vsce publish --yarn`. 42 | 43 | *Note: Releases with binary dependencies like utp-native don't work very well in the VSCode extension marketplace at the moment, since you can only include a single platform's binaries there.* 44 | 45 | ## UTP-native binary dependencies 46 | 47 | One of the trickier requirements of this project is the C library `utp-native`. UTP is a high performance protocol similar to TCP but carried over UDP originally designed to improve Bittorrent bandwidth sharing. Both libraries should be automatically compiled during yarn invocation, but if you run into issues with it you might try the following commands: 48 | 49 | NB: The Electron version changes from time to time with new VSCode releases. The correct version string can be found in the "About" panel in VSCode. 50 | 51 | ``` 52 | $ npx electron-rebuild --version 7.2.4 -f 53 | ``` 54 | 55 | or if that's not working, 56 | 57 | ``` 58 | yarn add utp-native --runtime=electron --target=7.2.4 --disturl=https://atom.io/download/atom-shell --build-from-source 59 | ``` 60 | 61 | This trickiness is required (for now) because this library has to be compiled against the exact binary version of Node used by VSCode's Electron, otherwise the extension will throw an exception on startup. 62 | 63 | [farm]: https://github.com/inkandswitch/farm 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hypermerge", 3 | "displayName": "Hypermerge", 4 | "description": "Browse and edit a Hypermerge document tree.", 5 | "version": "0.3.0", 6 | "publisher": "inkandswitch", 7 | "repository": { 8 | "url": "https://github.com/inkandswitch/vscode-hypermerge.git", 9 | "type": "git" 10 | }, 11 | "engines": { 12 | "vscode": "^1.30.0" 13 | }, 14 | "categories": [ 15 | "Other" 16 | ], 17 | "activationEvents": [ 18 | "onFileSystem:hypermerge", 19 | "onFileSystem:hypercore", 20 | "onView:hypermergeExplorer", 21 | "onView:hypermergeLedger", 22 | "onUri" 23 | ], 24 | "main": "./out/src/extension", 25 | "contributes": { 26 | "configuration": { 27 | "title": "Hypermerge", 28 | "properties": { 29 | "hypermerge.sortOrder": { 30 | "type": "string", 31 | "enum": [ 32 | "Title (Not Implemented)", 33 | "Key" 34 | ], 35 | "default": "Key", 36 | "description": "Sorting order for documents in the HypermergeFS tree." 37 | }, 38 | "hypermerge.debug": { 39 | "type": "string", 40 | "default": "", 41 | "description": "A comma-separated glob string for enabling debug channels. See the 'debug' npm module. If you're unsure, try '*'." 42 | }, 43 | "hypermerge.roots": { 44 | "type": "array", 45 | "items": { 46 | "type": "string", 47 | "format": "uri" 48 | }, 49 | "uniqueItems": true, 50 | "default": [], 51 | "description": "A list of document URLs to display as roots in your document tree." 52 | } 53 | } 54 | }, 55 | "commands": [ 56 | { 57 | "command": "hypermerge.open", 58 | "category": "Hypermerge", 59 | "title": "Open document", 60 | "icon": { 61 | "dark": "resources/open.svg", 62 | "light": "resources/open.svg" 63 | } 64 | }, 65 | { 66 | "command": "hypermerge.addRoot", 67 | "category": "Hypermerge", 68 | "title": "Add document as root", 69 | "icon": { 70 | "dark": "resources/open.svg", 71 | "light": "resources/open.svg" 72 | } 73 | }, 74 | { 75 | "command": "hypermerge.removeRoot", 76 | "category": "Hypermerge", 77 | "title": "Remove document from roots" 78 | }, 79 | { 80 | "command": "hypermerge.openRoot", 81 | "category": "Hypermerge", 82 | "title": "Open document and add as root", 83 | "icon": { 84 | "dark": "resources/open.svg", 85 | "light": "resources/open.svg" 86 | } 87 | }, 88 | { 89 | "command": "hypermerge.createRoot", 90 | "category": "Hypermerge", 91 | "title": "Create document and add as root", 92 | "icon": { 93 | "dark": "resources/create.svg", 94 | "light": "resources/create.svg" 95 | } 96 | }, 97 | { 98 | "command": "hypermerge.create", 99 | "category": "Hypermerge", 100 | "title": "Create document", 101 | "icon": { 102 | "dark": "resources/create.svg", 103 | "light": "resources/create.svg" 104 | } 105 | }, 106 | { 107 | "command": "hypermerge.destroy", 108 | "category": "Hypermerge", 109 | "title": "Destroy document" 110 | }, 111 | { 112 | "command": "hypermerge.copyUrl", 113 | "category": "Hypermerge", 114 | "title": "Copy document URL" 115 | }, 116 | { 117 | "command": "hypermerge.forkUrl", 118 | "category": "Hypermerge", 119 | "title": "Create a fork of this document" 120 | }, 121 | { 122 | "command": "hypermerge.followUrl", 123 | "category": "Hypermerge", 124 | "title": "Create a follower of this document" 125 | }, 126 | { 127 | "command": "hypermerge.view", 128 | "category": "Hypermerge", 129 | "title": "View document" 130 | }, 131 | { 132 | "command": "hypermerge.preview", 133 | "category": "Hypermerge", 134 | "title": "Preview this document" 135 | }, 136 | { 137 | "command": "hypermerge.createKey", 138 | "category": "Hypermerge", 139 | "title": "Create new key" 140 | }, 141 | { 142 | "command": "hypermerge.refresh", 143 | "category": "Hypermerge", 144 | "title": "Refresh documents" 145 | } 146 | ], 147 | "menus": { 148 | "commandPalette": [ 149 | { 150 | "command": "hypermerge.open" 151 | }, 152 | { 153 | "command": "hypermerge.createKey", 154 | "when": "resourceScheme == hypermerge" 155 | }, 156 | { 157 | "command": "hypermerge.addRoot", 158 | "when": "resourceScheme == hypermerge" 159 | } 160 | ], 161 | "view/title": [ 162 | { 163 | "command": "hypermerge.open", 164 | "when": "view == hypermergeLedger", 165 | "group": "navigation" 166 | }, 167 | { 168 | "command": "hypermerge.create", 169 | "when": "view == hypermergeLedger", 170 | "group": "navigation" 171 | }, 172 | { 173 | "command": "hypermerge.openRoot", 174 | "when": "view == hypermergeExplorer", 175 | "group": "navigation" 176 | }, 177 | { 178 | "command": "hypermerge.createRoot", 179 | "when": "view == hypermergeExplorer", 180 | "group": "navigation" 181 | } 182 | ], 183 | "view/item/context": [ 184 | { 185 | "command": "hypermerge.view", 186 | "when": "view == hypermergeExplorer", 187 | "group": "navigation" 188 | }, 189 | { 190 | "command": "hypermerge.removeRoot", 191 | "when": "view == hypermergeExplorer" 192 | }, 193 | { 194 | "command": "hypermerge.copyUrl", 195 | "when": "view == hypermergeExplorer" 196 | }, 197 | { 198 | "command": "hypermerge.forkUrl", 199 | "when": "view == hypermergeExplorer" 200 | }, 201 | { 202 | "command": "hypermerge.followUrl", 203 | "when": "view == hypermergeExplorer" 204 | }, 205 | { 206 | "command": "hypermerge.view", 207 | "when": "view == hypermergeLedger", 208 | "group": "navigation" 209 | }, 210 | { 211 | "command": "hypermerge.destroy", 212 | "when": "view == hypermergeLedger" 213 | }, 214 | { 215 | "command": "hypermerge.copyUrl", 216 | "when": "view == hypermergeLedger" 217 | }, 218 | { 219 | "command": "hypermerge.forkUrl", 220 | "when": "view == hypermergeLedger" 221 | }, 222 | { 223 | "command": "hypermerge.followUrl", 224 | "when": "view == hypermergeLedger" 225 | }, 226 | { 227 | "command": "hypermerge.addRoot", 228 | "when": "view == hypermergeLedger" 229 | } 230 | ] 231 | }, 232 | "viewsContainers": { 233 | "activitybar": [ 234 | { 235 | "id": "hypermergeDetails", 236 | "title": "Hypermerge", 237 | "icon": "resources/merge.svg" 238 | } 239 | ] 240 | }, 241 | "views": { 242 | "explorer": [ 243 | { 244 | "id": "hypermergeExplorer", 245 | "name": "Hypermerge Documents" 246 | } 247 | ], 248 | "hypermergeDetails": [ 249 | { 250 | "id": "hypermergeLedger", 251 | "name": "Ledger Documents" 252 | }, 253 | { 254 | "id": "hypermergeMetadata", 255 | "name": "Metadata" 256 | }, 257 | { 258 | "id": "hypermergeFeeds", 259 | "name": "Feeds" 260 | }, 261 | { 262 | "id": "hypermergeHistory", 263 | "name": "History" 264 | } 265 | ] 266 | } 267 | }, 268 | "scripts": { 269 | "vscode:prepublish": "npm run compile", 270 | "compile": "tsc -p ./", 271 | "watch": "tsc -watch -p ./", 272 | "format": "prettier --write 'src/**/*.ts'" 273 | }, 274 | "devDependencies": { 275 | "@types/node": "^10.2.0", 276 | "electron-rebuild": "^1.8.6", 277 | "prettier": "^1.16.1", 278 | "typescript": "^3.1.4" 279 | }, 280 | "dependencies": { 281 | "@types/better-sqlite3": "^5.4.0", 282 | "@types/pretty-bytes": "^5.1.0", 283 | "@types/vscode": "^1.46.0", 284 | "automerge": "^0.9.1", 285 | "bs58": "^4.0.1", 286 | "clipboardy": "^1.2.3", 287 | "hypermerge": "github:automerge/hypermerge", 288 | "hyperswarm": "^2.2.0", 289 | "jsonc-parser": "^2.0.2", 290 | "odiff": "github:inkandswitch/odiff", 291 | "pretty-bytes": "^5.1.0", 292 | "random-access-file": "^2.0.1", 293 | "random-access-memory": "^3.0.0", 294 | "utp-native": "^2.1.4", 295 | "ws": "^6.1.0" 296 | }, 297 | "__metadata": { 298 | "id": "b46e5495-640d-4264-87b9-9182d116ac0b", 299 | "publisherDisplayName": "Ink & Switch", 300 | "publisherId": "1e6dd501-608b-4085-b833-2148715b1d7d" 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | overrides: [ 3 | { 4 | files: "*.{ts,js}", 5 | options: { 6 | semi: false, 7 | trailingComma: "all", 8 | }, 9 | }, 10 | ], 11 | } 12 | -------------------------------------------------------------------------------- /resources/create.svg: -------------------------------------------------------------------------------- 1 | 3 | ]> -------------------------------------------------------------------------------- /resources/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/merge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/BaseDocumentTreeProvider.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { Uri } from "vscode" 3 | import { HypermergeWrapper, interpretHypermergeUri } from "./HypermergeWrapper" 4 | import { URL } from "url" 5 | 6 | export type HypermergeNodeKey = string 7 | 8 | export enum SortOrder { 9 | Title, 10 | Key, 11 | } 12 | 13 | export default abstract class BaseDocumentTreeProvider 14 | implements vscode.TreeDataProvider { 15 | protected _onDidChangeTreeData = new vscode.EventEmitter< 16 | HypermergeNodeKey | undefined 17 | >() 18 | readonly onDidChangeTreeData = this._onDidChangeTreeData.event 19 | 20 | protected sortOrder: SortOrder 21 | protected loaded = new Set() 22 | 23 | constructor(protected readonly hypermergeWrapper: HypermergeWrapper) { 24 | this.hypermergeWrapper = hypermergeWrapper 25 | this.sortOrder = SortOrder.Title 26 | } 27 | 28 | public abstract async roots(): Promise 29 | public abstract addRoot(resourceUri: string): void 30 | public abstract removeRoot(resourceUri: string): void 31 | 32 | public updateSortOrder(sortOrder: SortOrder) { 33 | this.sortOrder = sortOrder 34 | } 35 | 36 | public refresh(resourceUri?: string): any { 37 | this._onDidChangeTreeData.fire(resourceUri) 38 | } 39 | 40 | public async getTreeItem( 41 | element: HypermergeNodeKey, 42 | ): Promise { 43 | const resourceUri = Uri.parse(element) 44 | const details = interpretHypermergeUri(resourceUri) 45 | 46 | // Handle bad URLs. 47 | if (!details) { 48 | return { label: "" } 49 | } 50 | 51 | let { docId, keyPath, docUrl } = details 52 | 53 | let tooltip = element 54 | let description = docId.slice(0, 5) 55 | 56 | if (!this.loaded.has(docId)) { 57 | this.hypermergeWrapper.watchDocumentUri(vscode.Uri.parse(docUrl), doc => { 58 | this.loaded.add(docId) 59 | this.refresh(docUrl) 60 | }) 61 | 62 | const collapsibleState = vscode.TreeItemCollapsibleState.None 63 | return { 64 | label: `(Loading...)`, 65 | description, 66 | tooltip, 67 | // id: element, 68 | resourceUri, 69 | collapsibleState, 70 | command: { 71 | command: "hypermerge.view", 72 | arguments: [resourceUri.toString(), { preview: true }], 73 | title: "View Document", 74 | }, 75 | } 76 | } 77 | 78 | const doc = await this.hypermergeWrapper.openDocumentUri(resourceUri) 79 | 80 | let content = doc 81 | 82 | let label 83 | if (keyPath.length) { 84 | label = keyPath.pop() 85 | } else if (content.title) { 86 | // label = `[${docId.slice(0, 5)}] ${content.title}` 87 | label = `${content.title}` 88 | } else { 89 | label = `(No title)` 90 | } 91 | 92 | const collapsibleState = 93 | content != null && typeof content === "object" 94 | ? vscode.TreeItemCollapsibleState.Collapsed 95 | : vscode.TreeItemCollapsibleState.None 96 | 97 | // // NOTE: maybe too clever, but worth trying out. 98 | // // Makes it so that clicking on the root of a code doc opens the code 99 | // const newUri = 100 | // typeof content === "object" && "Source.elm" in content 101 | // ? resourceUri.with({ path: resourceUri.path + "/Source.elm" }) 102 | // : resourceUri 103 | const newUri = resourceUri 104 | 105 | return { 106 | label, 107 | // id: element, 108 | description, 109 | tooltip, 110 | resourceUri, 111 | collapsibleState, 112 | command: { 113 | command: "hypermerge.view", 114 | arguments: [newUri.toString(), { preview: true }], 115 | title: "View Document", 116 | }, 117 | } 118 | } 119 | 120 | attemptToInterpretUrl(str: string): { docId?: string; keyPath?: string[] } { 121 | if (str.length > 2000 || str.includes("\n")) return {} 122 | 123 | try { 124 | return interpretHypermergeUri(Uri.parse(str)) || {} 125 | } catch (e) { 126 | return {} 127 | } 128 | } 129 | 130 | public async getChildren( 131 | element?: HypermergeNodeKey, 132 | ): Promise { 133 | return element ? this.getDocumentChildren(element) : this.roots() 134 | } 135 | 136 | public getParent(element: HypermergeNodeKey): HypermergeNodeKey | null { 137 | // there isn't necessarily a parent for a particular node in our system.. 138 | // or at least not the way i'm currently modeling it 139 | // XX: the node key should arguably be a path of some kind? 140 | return null 141 | } 142 | 143 | protected async getDocumentChildren( 144 | node: HypermergeNodeKey, 145 | ): Promise { 146 | const uri = Uri.parse(node) 147 | 148 | const content = await this.hypermergeWrapper.openDocumentUri(uri) 149 | 150 | if (typeof content !== "object") { 151 | return [] 152 | } 153 | 154 | const children = Object.keys(content) 155 | const childNodes = children.map(child => { 156 | if (typeof content[child] === "string") { 157 | const { docId = null } = this.attemptToInterpretUrl(content[child]) 158 | 159 | if (docId) return "hypermerge:/" + docId 160 | } 161 | 162 | // this builds a new child URL and ditches the label if it exists. 163 | return new URL(node + "/" + child).toString() 164 | }) 165 | return childNodes 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/DebugManager.ts: -------------------------------------------------------------------------------- 1 | import { Disposable, OutputChannel, workspace } from "vscode" 2 | import Debug from "debug" 3 | import { format } from "util" 4 | import DisposableCollection from "./DisposableCollection" 5 | 6 | export default class DebugManager implements Disposable { 7 | subscriptions = new DisposableCollection() 8 | 9 | constructor(output: OutputChannel) { 10 | Debug.log = (str, ...args) => { 11 | output.appendLine(format(str, ...args)) 12 | } 13 | 14 | this.subscriptions.push( 15 | workspace.onDidChangeConfiguration(e => { 16 | if (e.affectsConfiguration("hypermerge.debug")) { 17 | this.updateDebug() 18 | } 19 | }), 20 | ) 21 | 22 | this.updateDebug() 23 | } 24 | 25 | dispose() { 26 | this.subscriptions.dispose() 27 | } 28 | 29 | updateDebug() { 30 | const setting = workspace 31 | .getConfiguration("hypermerge") 32 | .get("debug", "") 33 | 34 | Debug.enable(setting) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/DetailsViewContainer.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { HypermergeWrapper } from "./HypermergeWrapper" 3 | 4 | import HistoryTreeProvider from "./HistoryTreeProvider" 5 | import MetadataTreeProvider from "./MetadataTreeProvider" 6 | import FeedTreeProvider from "./FeedTreeProvider" 7 | import DisposableCollection from "./DisposableCollection" 8 | 9 | export default class DetailsViewContainer implements vscode.Disposable { 10 | subscriptions = new DisposableCollection() 11 | feedDataProvider = new FeedTreeProvider(this.hypermergeWrapper) 12 | metadataDataProvider = new MetadataTreeProvider(this.hypermergeWrapper) 13 | historyDataProvider = new HistoryTreeProvider(this.hypermergeWrapper) 14 | 15 | constructor(private hypermergeWrapper: HypermergeWrapper) { 16 | vscode.window.createTreeView("hypermergeMetadata", { 17 | treeDataProvider: this.metadataDataProvider, 18 | }) 19 | 20 | const feedView = vscode.window.createTreeView("hypermergeFeeds", { 21 | treeDataProvider: this.feedDataProvider, 22 | }) 23 | 24 | vscode.window.createTreeView("hypermergeHistory", { 25 | treeDataProvider: this.historyDataProvider, 26 | }) 27 | 28 | this.subscriptions.push( 29 | feedView, 30 | this.feedDataProvider, 31 | vscode.window.onDidChangeActiveTextEditor(() => 32 | this.onActiveEditorChanged(), 33 | ), 34 | ) 35 | 36 | this.onActiveEditorChanged() // call it the first time on startup 37 | } 38 | 39 | show(uri: vscode.Uri) { 40 | this.feedDataProvider.show(uri) 41 | this.metadataDataProvider.show(uri) 42 | this.historyDataProvider.show(uri) 43 | } 44 | 45 | dispose() { 46 | this.subscriptions.dispose() 47 | } 48 | 49 | private onActiveEditorChanged() { 50 | const { activeTextEditor } = vscode.window 51 | 52 | if (!activeTextEditor) return 53 | 54 | this.show(activeTextEditor.document.uri) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/DiagnosticCollector.ts: -------------------------------------------------------------------------------- 1 | "use strict" 2 | import * as vscode from "vscode" 3 | import { HypermergeWrapper } from "./HypermergeWrapper" 4 | 5 | export default class DiagnosticCollector { 6 | constructor( 7 | context: vscode.ExtensionContext, 8 | hypermergeWrapper: HypermergeWrapper, 9 | ) { 10 | const diagnosticCollection = vscode.languages.createDiagnosticCollection( 11 | "hypermerge", 12 | ) 13 | 14 | hypermergeWrapper.addListener("update", (uri, doc) => { 15 | try { 16 | // we always clear, since an update means a new document. 17 | diagnosticCollection.clear() 18 | 19 | const { hypermergeFsDiagnostics } = doc 20 | 21 | if (hypermergeFsDiagnostics) { 22 | for (const [target, items] of Object.entries( 23 | hypermergeFsDiagnostics, 24 | )) { 25 | if (!Array.isArray(items)) return 26 | 27 | const diagnostics = (items as any[]).map(item => { 28 | const severity = 29 | item.severity.toLowerCase() === "warning" 30 | ? vscode.DiagnosticSeverity.Warning 31 | : vscode.DiagnosticSeverity.Error 32 | 33 | const message = item.message 34 | 35 | const range = new vscode.Range( 36 | item.startLine, 37 | item.startColumn, 38 | item.endLine, 39 | item.endColumn, 40 | ) 41 | return new vscode.Diagnostic(range, message, severity) 42 | }) 43 | 44 | const targetUri = uri.with({ path: uri.path + "/" + target }) 45 | diagnosticCollection.set(targetUri, diagnostics) 46 | } 47 | } 48 | } catch (e) { 49 | console.log(e) 50 | } 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Diff.ts: -------------------------------------------------------------------------------- 1 | import odiff from "odiff" 2 | 3 | // not exported by odiff: 4 | export interface Change { 5 | type: "set" | "unset" | "add" | "rm" 6 | path: Array 7 | val: any 8 | index: number 9 | vals: any[] 10 | num: number 11 | } 12 | 13 | export function apply(lhs: any, rhs: any) { 14 | return applyChanges(lhs, getChanges(lhs, rhs)) 15 | } 16 | 17 | export function getChanges(lhs: any, rhs: any): Change[] { 18 | return odiff(lhs, rhs) 19 | } 20 | 21 | export function applyChanges(v: any, changes: Change[]) { 22 | for (let i = 0, l = changes.length; i < l; i++) { 23 | applyChange(v, changes[i]) 24 | } 25 | } 26 | 27 | export function applyChange(root: any, ch: Change) { 28 | const key: any = ch.path.pop() 29 | let obj: any = root 30 | 31 | // handles empty keypath: 32 | if (key == null && ch.type === "set") { 33 | Object.assign(root, ch.val) 34 | return 35 | } 36 | 37 | // get the obj at the keypath (minus the key popped above) 38 | for (let i = 0; i < ch.path.length; i++) { 39 | const k = ch.path[i] 40 | obj = obj[k] 41 | } 42 | 43 | switch (ch.type) { 44 | case "set": 45 | if (key != null) obj[key] = ch.val 46 | break 47 | 48 | case "unset": 49 | if (key != null) delete obj[key] 50 | break 51 | 52 | case "add": 53 | obj[key].splice(ch.index, 0, ...ch.vals) 54 | break 55 | 56 | case "rm": 57 | obj[key].splice(ch.index, ch.num) 58 | 59 | break 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/DisposableCollection.ts: -------------------------------------------------------------------------------- 1 | import { Disposable } from "vscode" 2 | 3 | export default class DisposableCollection implements Disposable { 4 | all: Disposable[] = [] 5 | 6 | push(...disps: Disposable[]): this { 7 | this.all.push(...disps) 8 | return this 9 | } 10 | 11 | dispose() { 12 | let item: Disposable | undefined 13 | 14 | while ((item = this.all.pop())) { 15 | item.dispose() 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DocumentLinkProvider.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DocumentLinkProvider, 3 | ProviderResult, 4 | DocumentLink, 5 | TextDocument, 6 | CancellationToken, 7 | Range, 8 | Uri, 9 | } from "vscode" 10 | import { visit, getLocation } from "jsonc-parser" 11 | 12 | export default class HypermergeDocumentLinkProvider 13 | implements DocumentLinkProvider { 14 | provideDocumentLinks( 15 | document: TextDocument, 16 | token: CancellationToken, 17 | ): ProviderResult { 18 | const regex = /hypermerge:(\/[\w\.]+)+/g 19 | const text = document.getText() 20 | const links: DocumentLink[] = [] 21 | let match: RegExpExecArray | null 22 | 23 | while ((match = regex.exec(text))) { 24 | const range = getRange(document, match.index, match[0].length) 25 | links.push(new DocumentLink(range, Uri.parse(match[0]))) 26 | } 27 | 28 | if (document.uri.scheme === "hypermerge" && isJson(document)) { 29 | try { 30 | visit(text, { 31 | onObjectProperty(property, offset, length) { 32 | const location = getLocation(text, offset) 33 | const path = document.uri.path + "/" + location.path.join("/") 34 | const range = getRange(document, offset + 1, length - 2) 35 | links.push(new DocumentLink(range, document.uri.with({ path }))) 36 | }, 37 | }) 38 | } catch { 39 | // Do nothing 40 | } 41 | } 42 | 43 | return links 44 | } 45 | } 46 | 47 | function getRange( 48 | document: TextDocument, 49 | offset: number, 50 | length: number, 51 | ): Range { 52 | const start = document.positionAt(offset) 53 | const end = document.positionAt(offset + length) 54 | return new Range(start, end) 55 | } 56 | 57 | function isJson(document: TextDocument): boolean { 58 | return document.languageId === "json" || document.languageId === "jsonc" 59 | } 60 | -------------------------------------------------------------------------------- /src/DocumentTreeProvider.ts: -------------------------------------------------------------------------------- 1 | import BaseDocumentTreeProvider, { 2 | HypermergeNodeKey, 3 | SortOrder, 4 | } from "./BaseDocumentTreeProvider" 5 | import { workspace, Uri, ConfigurationTarget } from "vscode" 6 | import { HypermergeWrapper } from "./HypermergeWrapper" 7 | 8 | export { HypermergeNodeKey, SortOrder } 9 | 10 | export default class DocumentTreeProvider extends BaseDocumentTreeProvider { 11 | constructor(hypermergeWrapper: HypermergeWrapper) { 12 | super(hypermergeWrapper) 13 | 14 | workspace.onDidChangeConfiguration(e => { 15 | if (e.affectsConfiguration("hypermerge.roots")) { 16 | this.refresh() 17 | } 18 | }) 19 | } 20 | 21 | async roots(): Promise { 22 | return this.config().get("roots", []) 23 | } 24 | 25 | async addRoot(resourceUri: string) { 26 | this.hypermergeWrapper.openDocumentUri(Uri.parse(resourceUri)) 27 | const roots = await this.roots() 28 | const newRoots = [ 29 | resourceUri, 30 | ...roots.filter(root => root !== resourceUri), 31 | ] 32 | 33 | this.config().update("roots", newRoots, ConfigurationTarget.Global) 34 | } 35 | 36 | async removeRoot(resourceUri: string) { 37 | const roots = await this.roots() 38 | const newRoots = roots.filter(root => root !== resourceUri) 39 | 40 | this.config().update("roots", newRoots, ConfigurationTarget.Global) 41 | } 42 | 43 | config() { 44 | return workspace.getConfiguration("hypermerge") 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/FeedTreeProvider.ts: -------------------------------------------------------------------------------- 1 | import { 2 | TreeDataProvider, 3 | EventEmitter, 4 | Uri, 5 | Disposable, 6 | TreeItem, 7 | TreeItemCollapsibleState, 8 | ProviderResult, 9 | } from "vscode" 10 | import prettyBytes from "pretty-bytes" 11 | 12 | import { HypermergeWrapper, interpretHypermergeUri } from "./HypermergeWrapper" 13 | import { Actor } from "hypermerge/dist/Actor" 14 | import { Feed } from "hypermerge/dist/FeedStore" 15 | import { DocId } from "hypermerge/dist/Misc" 16 | 17 | interface ErrorNode { 18 | type: "Error" 19 | message: string 20 | } 21 | 22 | interface FeedNode { 23 | type: "Feed" 24 | feed: Feed 25 | } 26 | 27 | interface BlocksNode { 28 | type: "Blocks" 29 | feed: Feed 30 | } 31 | 32 | interface BlockNode { 33 | type: "Block" 34 | feed: Feed 35 | index: number 36 | } 37 | 38 | interface InfoNode { 39 | type: "Info" 40 | info: TreeItem 41 | } 42 | 43 | export type Node = 44 | | FeedNode 45 | | ErrorNode 46 | | BlocksNode 47 | | BlockNode 48 | | InfoNode 49 | 50 | export default class FeedTreeProvider 51 | implements TreeDataProvider, Disposable { 52 | private _onDidChangeTreeData = new EventEmitter() 53 | readonly onDidChangeTreeData = this._onDidChangeTreeData.event 54 | 55 | private activeDocumentUri: Uri | undefined 56 | private interval: NodeJS.Timeout 57 | 58 | constructor(private hypermergeWrapper: HypermergeWrapper) { 59 | // Fairly hacky but it seems to work just fine. 60 | // Feels like too much work to manage listeners for all this stuff. 61 | this.interval = setInterval(() => this.refresh(), 2000) 62 | } 63 | 64 | public dispose() { 65 | clearInterval(this.interval) 66 | } 67 | 68 | get activeDocId(): DocId | undefined { 69 | const uri = this.activeDocumentUri 70 | if (!uri) return 71 | 72 | const details = interpretHypermergeUri(uri) 73 | if (!details) return 74 | 75 | return details.docId 76 | } 77 | 78 | public show(uri: Uri): void { 79 | if (uri.scheme !== "hypermerge") return 80 | 81 | this.activeDocumentUri = uri 82 | this.refresh() 83 | } 84 | 85 | public refresh(key?: Node): any { 86 | this._onDidChangeTreeData.fire(key) 87 | } 88 | 89 | public getTreeItem(node: Node): TreeItem | Thenable { 90 | const State = TreeItemCollapsibleState 91 | 92 | switch (node.type) { 93 | case "Error": 94 | return { 95 | label: `Error: ${node.message}`, 96 | } 97 | 98 | case "Feed": 99 | return { 100 | collapsibleState: State.Expanded, 101 | label: node.feed.id.slice(0, 8), 102 | description: node.feed.writable ? "Writable" : "Readonly", 103 | id: `Feed/${node.feed.id}`, 104 | } 105 | 106 | case "Blocks": { 107 | const { feed } = node.feed as any 108 | return { 109 | label: `${feed.downloaded(0, feed.length)} / ${feed.length} Blocks`, 110 | collapsibleState: State.Collapsed, 111 | description: prettyBytes(feed.byteLength), 112 | id: `Blocks/${node.feed.id}`, 113 | } 114 | } 115 | 116 | case "Block": { 117 | const resourceUri = Uri.parse( 118 | `hypercore:/${node.feed.id}/${node.index}.json`, 119 | ) 120 | const isDownloaded = node.feed.has(node.index) 121 | 122 | return blockSize(node.feed, node.index) 123 | .catch(_ => 0) 124 | .then(bytes => { 125 | const size = bytes ? prettyBytes(bytes) : "" 126 | 127 | return { 128 | label: "Block " + node.index, 129 | collapsibleState: State.None, 130 | description: isDownloaded ? `✓ ${size}` : "Missing", 131 | id: `Block/${node.feed.id}/${node.index}`, 132 | resourceUri, 133 | command: { 134 | command: "vscode.open", 135 | arguments: [resourceUri], 136 | title: "View contents", 137 | }, 138 | } 139 | }) 140 | } 141 | 142 | case "Info": { 143 | return node.info 144 | } 145 | } 146 | } 147 | 148 | attemptToInterpretUrl(str: string): { docId?: string; keyPath?: string[] } { 149 | if (str.length > 2000 || str.includes("\n")) return {} 150 | 151 | try { 152 | return interpretHypermergeUri(Uri.parse(str)) || {} 153 | } catch (e) { 154 | return {} 155 | } 156 | } 157 | 158 | public getChildren(node?: Node): ProviderResult { 159 | const docId = this.activeDocId 160 | if (!docId) return [] 161 | 162 | if (!node) { 163 | const { repo } = this.hypermergeWrapper 164 | const back = repo.back.docs.get(docId) 165 | 166 | if (!back) return [errorNode("Could not find Doc")] 167 | 168 | const actors = repo.back.docActors(back) 169 | 170 | return actors.map(feedNode) 171 | } 172 | 173 | switch (node.type) { 174 | case "Feed": 175 | return [ 176 | { type: "Blocks", feed: node.feed }, 177 | ] 178 | 179 | case "Blocks": 180 | return Array(node.feed.length) 181 | .fill(0) 182 | .map((_, i) => blockNode(node.feed, i)) 183 | 184 | default: 185 | return [] 186 | } 187 | } 188 | 189 | public getParent(element: Node): Node | null { 190 | // there isn't necessarily a parent for a particular node in our system.. 191 | // or at least not the way i'm currently modeling it 192 | // XX: the node key should arguably be a path of some kind? 193 | return null 194 | } 195 | } 196 | 197 | function blockSize(feed: any, index: number): Promise { 198 | return new Promise((res, rej) => { 199 | feed._storage.dataOffset( 200 | index, 201 | [], 202 | (err: any, offset: number, size: number) => { 203 | if (err) return rej(err) 204 | res(size) 205 | }, 206 | ) 207 | }) 208 | } 209 | 210 | function errorNode(message: string): ErrorNode { 211 | return { type: "Error", message } 212 | } 213 | 214 | function feedNode(feed: Feed): FeedNode { 215 | return { type: "Feed", feed } 216 | } 217 | 218 | function blockNode(feed: Feed, index: number): BlockNode { 219 | return { type: "Block", feed, index } 220 | } 221 | 222 | function infoNode(info: TreeItem): InfoNode { 223 | return { type: "Info", info } 224 | } 225 | 226 | function connectionInfo(peer: any) { 227 | try { 228 | const conn = peer.stream.stream._readableState.pipes 229 | 230 | if (!conn) return 231 | 232 | if (conn._utp) { 233 | const localAddress = conn._utp.address() 234 | return { 235 | type: "UTP", 236 | readyState: true, 237 | local: { 238 | ip: localAddress.address, 239 | port: localAddress.port, 240 | }, 241 | remote: { 242 | ip: conn.remoteAddress, 243 | port: conn.remotePort, 244 | }, 245 | bytes: { 246 | read: -1, 247 | written: -1, 248 | }, 249 | } 250 | } 251 | 252 | return { 253 | type: conn._handle.constructor.name, 254 | readyState: conn.readyState, 255 | local: { 256 | ip: conn.localAddress, 257 | port: conn.localPort, 258 | }, 259 | remote: { 260 | ip: conn.remoteAddress, 261 | port: conn.remotePort, 262 | }, 263 | bytes: { 264 | read: conn.bytesRead, 265 | written: conn.bytesWritten, 266 | }, 267 | } 268 | } catch (e) { 269 | console.log("non-breaking connectionInfo error –", e) 270 | return 271 | } 272 | } 273 | 274 | function join(...items: any[]): string { 275 | return items.filter(x => x != null && x != "").join(" ") 276 | } 277 | -------------------------------------------------------------------------------- /src/HistoryTreeProvider.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { HypermergeWrapper, interpretHypermergeUri } from "./HypermergeWrapper" 3 | 4 | export type HypermergeHistoryKey = string 5 | 6 | export default class HistoryTreeProvider 7 | implements vscode.TreeDataProvider { 8 | private _onDidChangeTreeData: vscode.EventEmitter< 9 | HypermergeHistoryKey | undefined 10 | > = new vscode.EventEmitter() 11 | readonly onDidChangeTreeData: vscode.Event< 12 | HypermergeHistoryKey | undefined 13 | > = this._onDidChangeTreeData.event 14 | 15 | private activeDocumentUri: vscode.Uri | undefined 16 | 17 | constructor(private readonly hypermergeWrapper: HypermergeWrapper) { 18 | this.hypermergeWrapper = hypermergeWrapper 19 | 20 | // XXX looks like this might be broken 21 | this.hypermergeWrapper.addListener("update", updatedDocumentUri => { 22 | if ( 23 | this.activeDocumentUri && 24 | this.activeDocumentUri.toString() === updatedDocumentUri.toString() 25 | ) { 26 | this._onDidChangeTreeData.fire(undefined) 27 | } 28 | }) 29 | } 30 | 31 | public show(uri: vscode.Uri): void { 32 | if (uri.scheme !== "hypermerge") return 33 | 34 | this.activeDocumentUri = uri 35 | this.refresh() 36 | } 37 | 38 | public refresh(key?: HypermergeHistoryKey): any { 39 | this._onDidChangeTreeData.fire(key) 40 | } 41 | 42 | public getTreeItem(element: HypermergeHistoryKey): vscode.TreeItem { 43 | const collapsibleState = vscode.TreeItemCollapsibleState.None 44 | 45 | if (!this.activeDocumentUri) { 46 | console.log("How can we be here?") 47 | return { label: "No open hypermerge doc " } 48 | } 49 | 50 | const resourceUri = this.activeDocumentUri.with({ 51 | query: "history=" + element, 52 | }) 53 | return { 54 | label: "history=" + element, 55 | resourceUri, 56 | collapsibleState, 57 | command: { 58 | command: "hypermerge.preview", 59 | arguments: [resourceUri], 60 | title: "Open Hypermerge Document", 61 | }, 62 | } 63 | } 64 | 65 | attemptToInterpretUrl(str: string): { docId?: string; keyPath?: string[] } { 66 | if (str.length > 2000 || str.includes("\n")) return {} 67 | 68 | try { 69 | return interpretHypermergeUri(vscode.Uri.parse(str)) || {} 70 | } catch (e) { 71 | return {} 72 | } 73 | } 74 | 75 | public getChildren( 76 | element?: HypermergeHistoryKey, 77 | ): HypermergeHistoryKey[] | Thenable { 78 | // History is flat -- only return children for the root node 79 | if (element) { 80 | return [] 81 | } 82 | 83 | // Make sure we're in a valid hypermerge document. 84 | if (!this.activeDocumentUri) { 85 | return ["no active hypermerge doc"] 86 | } 87 | const details = interpretHypermergeUri(this.activeDocumentUri) 88 | if (!details) { 89 | return ["bad URI"] 90 | } 91 | 92 | // Create an array of results. 93 | const { docUrl } = details 94 | return new Promise(resolve => { 95 | this.hypermergeWrapper.repo.meta(docUrl, meta => { 96 | const n = meta && meta.type == "Document" ? meta.history : 0 97 | const history = [...Array(n).keys()] 98 | .reverse() 99 | .map(i => (i + 1).toString()) 100 | resolve(history) 101 | }) 102 | }) 103 | } 104 | 105 | public getParent(element: HypermergeHistoryKey): HypermergeHistoryKey | null { 106 | // there isn't necessarily a parent for a particular node in our system.. 107 | // or at least not the way i'm currently modeling it 108 | // XX: the node key should arguably be a path of some kind? 109 | return null 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/HypercoreFS.ts: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | import * as vscode from "vscode" 4 | import { HypermergeWrapper } from "./HypermergeWrapper" 5 | import { RepoBackend } from "hypermerge" 6 | import * as Block from "hypermerge/dist/Block" 7 | import { FeedId } from "hypermerge/dist/FeedStore" 8 | 9 | export default class HypercoreFS implements vscode.FileSystemProvider { 10 | back: RepoBackend 11 | 12 | constructor(hypermergeWrapper: HypermergeWrapper) { 13 | this.back = hypermergeWrapper.repo.back 14 | } 15 | 16 | // --- manage file metadata 17 | 18 | async stat(uri: vscode.Uri): Promise { 19 | const details = parseUri(uri) 20 | 21 | if (!details) throw vscode.FileSystemError.FileNotFound(uri) 22 | 23 | const { feedId, blockIndex } = details 24 | 25 | if (blockIndex == null) throw vscode.FileSystemError.FileNotFound(uri) 26 | 27 | const feed = await this.back.feeds.getFeed(feedId) 28 | if (!feed) throw vscode.FileSystemError.FileNotFound(uri) 29 | 30 | if (!feed.has(blockIndex)) 31 | throw vscode.FileSystemError.FileNotFound(uri) 32 | 33 | return { 34 | ctime: Date.now(), 35 | mtime: Date.now(), 36 | size: 0, 37 | type: vscode.FileType.SymbolicLink, 38 | } 39 | } 40 | 41 | readDirectory(uri: vscode.Uri): [string, vscode.FileType][] { 42 | throw vscode.FileSystemError.NoPermissions 43 | } 44 | 45 | // --- manage file contents 46 | 47 | async readFile(uri: vscode.Uri): Promise { 48 | const details = parseUri(uri) 49 | 50 | if (!details) throw vscode.FileSystemError.FileNotFound(uri) 51 | 52 | const { feedId, blockIndex } = details 53 | 54 | if (blockIndex == null) throw vscode.FileSystemError.FileNotFound(uri) 55 | 56 | const feed = await this.back.feeds.getFeed(feedId) 57 | 58 | if (!feed) throw vscode.FileSystemError.FileNotFound(uri) 59 | 60 | if (!feed.has(blockIndex)) 61 | throw vscode.FileSystemError.FileNotFound(uri) 62 | 63 | return new Promise((res, rej) => { 64 | ;(feed).get( 65 | blockIndex, 66 | { wait: false }, 67 | (err: Error | null, data?: Uint8Array) => { 68 | if (err) return rej(err) 69 | if (!data) return rej(new Error("Missing data")) 70 | 71 | try { 72 | const obj = Block.unpack(data) 73 | data = Buffer.from(JSON.stringify(obj, undefined, 2)) 74 | } catch (e) { 75 | // not JSON data. should be fine to just continue 76 | } 77 | 78 | if (data) res(data) 79 | }, 80 | ) 81 | }) 82 | } 83 | 84 | writeFile( 85 | uri: vscode.Uri, 86 | content: Uint8Array, 87 | options: { create: boolean; overwrite: boolean }, 88 | ): void { 89 | throw vscode.FileSystemError.NoPermissions 90 | } 91 | 92 | // --- manage files/folders 93 | 94 | rename( 95 | oldUri: vscode.Uri, 96 | newUri: vscode.Uri, 97 | options: { overwrite: boolean }, 98 | ): void { 99 | throw vscode.FileSystemError.NoPermissions 100 | } 101 | 102 | delete(uri: vscode.Uri): void { 103 | throw vscode.FileSystemError.NoPermissions 104 | } 105 | 106 | createDirectory(uri: vscode.Uri): void { 107 | throw vscode.FileSystemError.NoPermissions 108 | } 109 | 110 | // --- manage file events 111 | 112 | private _emitter = new vscode.EventEmitter() 113 | private _bufferedEvents: vscode.FileChangeEvent[] = [] 114 | private _fireSoonHandle: NodeJS.Timer 115 | 116 | readonly onDidChangeFile: vscode.Event = this 117 | ._emitter.event 118 | 119 | watch(resource: vscode.Uri, opts): vscode.Disposable { 120 | // ignore, fires for all changes... 121 | return new vscode.Disposable(() => {}) 122 | } 123 | } 124 | 125 | interface Details { 126 | feedId: FeedId 127 | blockIndex?: number 128 | } 129 | 130 | function parseUri(uri: vscode.Uri): Details | undefined { 131 | if (uri.scheme !== "hypercore") return 132 | 133 | const [_, feedId, indexString] = uri.path.split("/") 134 | 135 | if (!feedId) return 136 | 137 | const blockIndex = indexString ? parseInt(indexString, 10) : undefined 138 | 139 | return { 140 | feedId: feedId as FeedId, 141 | blockIndex, 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/HypermergeExplorer.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { Uri } from "vscode" 3 | import { HypermergeWrapper, interpretHypermergeUri } from "./HypermergeWrapper" 4 | import DocumentTreeProvider, { 5 | SortOrder, 6 | HypermergeNodeKey, 7 | } from "./DocumentTreeProvider" 8 | import LedgerTreeProvider from "./LedgerTreeProvider" 9 | import DisposableCollection from "./DisposableCollection" 10 | import DetailsViewContainer from "./DetailsViewContainer" 11 | const clipboardy = require("clipboardy") 12 | 13 | export default class HypermergeExplorer implements vscode.Disposable { 14 | // TODO: 15 | // better error reporting on invalid json 16 | subscriptions = new DisposableCollection() 17 | private detailsView: DetailsViewContainer 18 | private ledgerView: vscode.TreeView 19 | private documentView: vscode.TreeView 20 | private ledgerDataProvider: LedgerTreeProvider 21 | private documentDataProvider: DocumentTreeProvider 22 | 23 | constructor( 24 | context: vscode.ExtensionContext, 25 | hypermergeWrapper: HypermergeWrapper, 26 | ) { 27 | this.detailsView = new DetailsViewContainer(hypermergeWrapper) 28 | this.ledgerDataProvider = new LedgerTreeProvider(hypermergeWrapper) 29 | this.documentDataProvider = new DocumentTreeProvider(hypermergeWrapper) 30 | 31 | this.subscriptions.push(this.detailsView) 32 | 33 | // XXX disposable 34 | vscode.workspace.onDidChangeConfiguration(e => { 35 | if (e.affectsConfiguration("hypermerge.sortOrder")) { 36 | this.updateSortConfig() 37 | } 38 | }) 39 | 40 | this.updateSortConfig() 41 | 42 | this.ledgerView = vscode.window.createTreeView("hypermergeLedger", { 43 | treeDataProvider: this.ledgerDataProvider, 44 | }) 45 | 46 | this.documentView = vscode.window.createTreeView("hypermergeExplorer", { 47 | treeDataProvider: this.documentDataProvider, 48 | }) 49 | 50 | vscode.commands.registerCommand("hypermerge.refresh", () => { 51 | this.ledgerDataProvider.refresh() 52 | this.documentDataProvider.refresh() 53 | }) 54 | 55 | vscode.commands.registerCommand( 56 | "hypermerge.preview", 57 | (uriString: string) => { 58 | if (!this.validateURL(uriString)) { 59 | this.show(Uri.parse(uriString), { preview: true, aside: true }) 60 | } 61 | }, 62 | ) 63 | 64 | vscode.commands.registerCommand( 65 | "hypermerge.view", 66 | (uriString: string, opts?: any) => { 67 | if (!this.validateURL(uriString)) { 68 | this.show(Uri.parse(uriString), opts) 69 | } 70 | }, 71 | ) 72 | 73 | vscode.commands.registerCommand("hypermerge.create", async () => { 74 | const uri = hypermergeWrapper.createDocumentUri() 75 | this.ledgerDataProvider.refresh() 76 | this.show(uri) 77 | }) 78 | 79 | vscode.commands.registerCommand("hypermerge.createRoot", () => { 80 | const uri = hypermergeWrapper.createDocumentUri() 81 | 82 | this.documentDataProvider.addRoot(uri.toString()) 83 | this.ledgerDataProvider.refresh() // HACK 84 | 85 | this.show(uri) 86 | }) 87 | 88 | vscode.commands.registerCommand("hypermerge.addRoot", url => { 89 | const uri = this.findUri(url) 90 | if (!uri) return 91 | 92 | this.ledgerDataProvider.addRoot(uri.toString()) 93 | this.documentDataProvider.addRoot(uri.toString()) 94 | this.show(uri) 95 | }) 96 | 97 | vscode.commands.registerCommand("hypermerge.removeRoot", url => { 98 | const uri = this.findUri(url) 99 | if (!uri) return 100 | 101 | this.documentDataProvider.removeRoot(uri.toString()) 102 | }) 103 | 104 | vscode.commands.registerCommand("hypermerge.openRoot", async () => { 105 | const uriString = await vscode.window.showInputBox({ 106 | placeHolder: "Browse which hypermerge URL?", 107 | validateInput: this.validateURL, 108 | }) 109 | 110 | if (!uriString) return 111 | 112 | const parsedUri = Uri.parse(uriString) 113 | 114 | if (parsedUri.scheme === "farm" || parsedUri.scheme === "realm") { 115 | const [_, codeId, dataId]: string[] = 116 | uriString.match("(?:farm|realm)://(.+?)/(.+?)$") || [] 117 | 118 | if (!codeId || !dataId) { 119 | throw new Error("invalid Farm URL") 120 | } 121 | 122 | this.documentDataProvider.addRoot("hypermerge:/" + codeId) 123 | this.documentDataProvider.addRoot("hypermerge:/" + dataId) 124 | 125 | this.show(Uri.parse("hypermerge:/" + codeId + "/Source.elm")) 126 | this.show(Uri.parse("hypermerge:/" + dataId), { aside: true }) 127 | } else { 128 | this.documentDataProvider.addRoot(parsedUri.toString()) 129 | this.show(parsedUri) 130 | } 131 | }) 132 | 133 | vscode.commands.registerCommand( 134 | "hypermerge.open", 135 | async (uriString?: string) => { 136 | if (!uriString) { 137 | uriString = await vscode.window.showInputBox({ 138 | placeHolder: "Browse which hypermerge URL?", 139 | validateInput: this.validateURL, 140 | }) 141 | } 142 | 143 | if (!uriString) return 144 | 145 | const parsedUri = Uri.parse(uriString) 146 | 147 | if (parsedUri.scheme === "farm" || parsedUri.scheme === "realm") { 148 | const [_, codeId, dataId]: string[] = 149 | uriString.match("(?:farm|realm)://(.+?)/([^/]+?)$") || [] 150 | 151 | if (!codeId || !dataId) { 152 | throw new Error("invalid Farm URL") 153 | } 154 | 155 | this.show(Uri.parse("hypermerge:/" + codeId + "/Source.elm")) 156 | this.show(Uri.parse("hypermerge:/" + dataId), { aside: true }) 157 | } else { 158 | this.show(parsedUri) 159 | } 160 | }, 161 | ) 162 | 163 | vscode.commands.registerCommand("hypermerge.destroy", resourceUri => { 164 | this.ledgerDataProvider.removeRoot(resourceUri) 165 | this.documentDataProvider.removeRoot(resourceUri) 166 | }) 167 | 168 | vscode.commands.registerCommand("hypermerge.copyUrl", async resourceUrl => { 169 | const url = Uri.parse(resourceUrl) 170 | clipboardy.writeSync(url.toString()) 171 | }) 172 | 173 | vscode.commands.registerCommand("hypermerge.forkUrl", async resourceUrl => { 174 | const forkedUrl = Uri.parse(resourceUrl) 175 | const newUrl = await hypermergeWrapper.forkDocumentUri(forkedUrl) 176 | if (!newUrl) { 177 | // probably oughta print an error 178 | return 179 | } 180 | 181 | const uriString = newUrl.toString() 182 | if (uriString) { 183 | this.ledgerDataProvider.refresh() 184 | this.documentDataProvider.refresh() 185 | } 186 | }) 187 | 188 | vscode.commands.registerCommand( 189 | "hypermerge.followUrl", 190 | async resourceUrl => { 191 | const followedUrl = Uri.parse(resourceUrl) 192 | const newUrl = await hypermergeWrapper.followDocumentUri(followedUrl) 193 | if (!newUrl) { 194 | // probably oughta print an error 195 | return 196 | } 197 | 198 | const uriString = newUrl.toString() 199 | if (uriString) { 200 | this.ledgerDataProvider.refresh() 201 | this.documentDataProvider.refresh() 202 | } 203 | }, 204 | ) 205 | 206 | vscode.commands.registerCommand("hypermerge.revealResource", () => 207 | this.reveal(), 208 | ) 209 | 210 | vscode.commands.registerCommand( 211 | "hypermerge.createKey", 212 | async (url?: string) => { 213 | const uri = this.findUri(url) 214 | 215 | if (!uri) return 216 | 217 | const keyName = await vscode.window.showInputBox({ 218 | prompt: "What should the key be called?", 219 | placeHolder: "config", 220 | }) 221 | 222 | if (!keyName) return 223 | 224 | const newUri = hypermergeWrapper.changeDocumentUri( 225 | uri, 226 | (state: any) => { 227 | if (keyName in state) return 228 | state[keyName] = {} 229 | }, 230 | ) 231 | 232 | if (newUri) 233 | this.show(newUri.with({ path: newUri.path + "/" + keyName }), { 234 | aside: true, 235 | }) 236 | }, 237 | ) 238 | } 239 | 240 | updateSortConfig() { 241 | const newSort = vscode.workspace 242 | .getConfiguration("hypermerge") 243 | .get("sortOrder", "") 244 | const sortEnum = SortOrder[newSort] 245 | if (!sortEnum) { 246 | console.log("Bad sort order passed to config") 247 | return 248 | } 249 | if (!this.ledgerDataProvider) { 250 | return // this means there's probably a race condition on first startup 251 | } 252 | this.ledgerDataProvider.updateSortOrder(sortEnum) 253 | this.ledgerDataProvider.refresh() 254 | } 255 | 256 | validateURL(input: string) { 257 | let url, parts 258 | try { 259 | url = Uri.parse(input) 260 | parts = interpretHypermergeUri(url) 261 | } catch { 262 | return "invalid URL" 263 | } 264 | if ( 265 | !( 266 | url.scheme == "hypermerge" || 267 | url.scheme == "farm" || 268 | url.scheme == "realm" 269 | ) 270 | ) { 271 | return "invalid scheme -- must be a hypermerge URL" 272 | } 273 | if (url.path === "") { 274 | return "invalid format" 275 | } 276 | return "" // we can return a hint string if it's invalid 277 | } 278 | 279 | private show( 280 | uri: Uri, 281 | opts: { preview?: boolean; aside?: boolean } = {}, 282 | ): Thenable { 283 | this.detailsView.show(uri) 284 | 285 | return vscode.window.showTextDocument(uri, { 286 | preserveFocus: opts.preview, 287 | preview: !!opts.preview, 288 | viewColumn: opts.aside ? 2 : 1, 289 | }).then( 290 | () => { 291 | if (!opts.preview) this.reveal() 292 | }, 293 | err => { 294 | console.log(err) 295 | }, 296 | ) 297 | // TODO: weave this into the thenable chain 298 | } 299 | 300 | private async reveal(): Promise { 301 | const node = this.getNode() 302 | 303 | if (!node) return 304 | const roots = await this.documentDataProvider.roots() 305 | 306 | if (roots.indexOf(node) > -1) { 307 | return this.documentView.reveal(node) 308 | } else { 309 | return this.ledgerView.reveal(node) 310 | } 311 | } 312 | 313 | private findUri(uri?: string | Uri): Uri | undefined { 314 | if (typeof uri === "string") return Uri.parse(uri) 315 | if (uri) return uri 316 | 317 | const editor = vscode.window.activeTextEditor 318 | if (editor && editor.document.uri.scheme === "hypermerge") { 319 | return editor.document.uri 320 | } else { 321 | // return current selected tree node 322 | } 323 | } 324 | 325 | private getNode(): HypermergeNodeKey | null { 326 | const editor = vscode.window.activeTextEditor 327 | if (editor) { 328 | if (editor.document.uri.scheme === "hypermerge") { 329 | return editor.document.uri.toString() 330 | } 331 | } 332 | return null 333 | } 334 | 335 | dispose() { 336 | this.subscriptions.dispose() 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /src/HypermergeFS.ts: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | import * as vscode from "vscode" 4 | import { Text } from "automerge/frontend/text" 5 | import { HypermergeWrapper } from "./HypermergeWrapper" 6 | 7 | export default class HypermergeFS implements vscode.FileSystemProvider { 8 | hypermerge: HypermergeWrapper 9 | typeCache: Map 10 | 11 | constructor(hypermergeWrapper: HypermergeWrapper) { 12 | this.hypermerge = hypermergeWrapper 13 | this.typeCache = new Map() 14 | 15 | this.hypermerge.on("update", uri => { 16 | this._fireSoon({ type: vscode.FileChangeType.Changed, uri }) 17 | }) 18 | } 19 | 20 | // --- manage file metadata 21 | 22 | stat(uri: vscode.Uri): Thenable { 23 | // if (!this.hypermerge.exists(uri)) { 24 | // console.log(`Stating ${uri.toString()} - file not found`) 25 | // throw vscode.FileSystemError.FileNotFound(uri) 26 | // } 27 | 28 | return this.hypermerge 29 | .openDocumentUri(uri) 30 | .then(document => { 31 | if (document === undefined) { 32 | throw vscode.FileSystemError.FileNotFound(uri) 33 | } 34 | return { 35 | ctime: Date.now(), 36 | mtime: Date.now(), 37 | size: 0, 38 | type: vscode.FileType.SymbolicLink, 39 | } 40 | }) 41 | .catch(console.log) 42 | } 43 | 44 | readDirectory(uri: vscode.Uri): [string, vscode.FileType][] { 45 | throw vscode.FileSystemError.NoPermissions 46 | } 47 | 48 | // --- manage file contents 49 | 50 | readFile(uri: vscode.Uri): Thenable { 51 | return this.hypermerge 52 | .openDocumentUri(uri) 53 | .then(document => { 54 | console.log(typeof document) 55 | switch (typeof document) { 56 | case "string": 57 | this.typeCache.set(uri.toString(), "string") 58 | return Buffer.from(document) 59 | 60 | case "number": 61 | this.typeCache.set(uri.toString(), "number") 62 | return Buffer.from(String(document)) 63 | 64 | case "boolean": 65 | this.typeCache.set(uri.toString(), "boolean") 66 | return Buffer.from(String(document)) 67 | 68 | default: 69 | if (Array.isArray(document)) { 70 | this.typeCache.set(uri.toString(), "array") 71 | } else { 72 | this.typeCache.set(uri.toString(), "object") 73 | } 74 | 75 | function replacer(key, value) { 76 | console.log(`replace ${key}, ${value} (${value instanceof Text})`) 77 | if (value instanceof Text) { 78 | return value.join('') 79 | } 80 | return value 81 | } 82 | 83 | return Buffer.from(JSON.stringify(document, replacer, 2)) 84 | } 85 | }) 86 | .catch(err => { 87 | console.log(err) 88 | return Buffer.from("") 89 | }) 90 | } 91 | 92 | writeFile( 93 | uri: vscode.Uri, 94 | content: Uint8Array, 95 | options: { create: boolean; overwrite: boolean }, 96 | ): void { 97 | // not great 98 | if (uri.query) { 99 | throw vscode.FileSystemError.NoPermissions 100 | } 101 | 102 | switch (this.typeCache.get(uri.toString())) { 103 | case "string": 104 | this.hypermerge.setDocumentUri(uri, content.toString()) 105 | break 106 | 107 | case "number": 108 | this.hypermerge.setDocumentUri(uri, parseFloat(content.toString())) 109 | break 110 | 111 | case "boolean": { 112 | const contents = JSON.parse(content.toString()) 113 | if (typeof contents !== "boolean") throw new Error("Must be a boolean") 114 | this.hypermerge.setDocumentUri(uri, contents) 115 | break 116 | } 117 | 118 | case "array": { 119 | const contents = JSON.parse(content.toString()) 120 | if (!Array.isArray(contents)) throw new Error("Must be an array") 121 | this.hypermerge.setDocumentUri(uri, contents) 122 | break 123 | } 124 | 125 | default: { 126 | const contents = JSON.parse(content.toString()) 127 | this.hypermerge.setDocumentUri(uri, contents) 128 | break 129 | } 130 | } 131 | 132 | this._fireSoon({ type: vscode.FileChangeType.Changed, uri }) 133 | } 134 | 135 | // --- manage files/folders 136 | 137 | rename( 138 | oldUri: vscode.Uri, 139 | newUri: vscode.Uri, 140 | options: { overwrite: boolean }, 141 | ): void { 142 | // HMMM 143 | throw vscode.FileSystemError.NoPermissions 144 | } 145 | 146 | delete(uri: vscode.Uri): void { 147 | // HMMM 148 | throw vscode.FileSystemError.NoPermissions 149 | } 150 | 151 | createDirectory(uri: vscode.Uri): void { 152 | // need to have a dummy createDirectory for saving leaf nodes 153 | // for ... some reason 154 | return 155 | } 156 | 157 | // --- manage file events 158 | 159 | private _emitter = new vscode.EventEmitter() 160 | private _bufferedEvents: vscode.FileChangeEvent[] = [] 161 | private _fireSoonHandle: NodeJS.Timer 162 | 163 | readonly onDidChangeFile: vscode.Event = this 164 | ._emitter.event 165 | 166 | watch(resource: vscode.Uri, opts): vscode.Disposable { 167 | // ignore, fires for all changes... 168 | return new vscode.Disposable(() => {}) 169 | } 170 | 171 | private _fireSoon(...events: vscode.FileChangeEvent[]): void { 172 | this._bufferedEvents.push(...events) 173 | clearTimeout(this._fireSoonHandle) 174 | this._fireSoonHandle = setTimeout(() => { 175 | this._emitter.fire(this._bufferedEvents) 176 | this._bufferedEvents.length = 0 177 | }, 5) 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/HypermergeUriHandler.ts: -------------------------------------------------------------------------------- 1 | import { UriHandler, Uri, commands, OutputChannel } from "vscode" 2 | 3 | export default class HypermergeUriHandler implements UriHandler { 4 | output: OutputChannel 5 | constructor(output: OutputChannel) { 6 | this.output = output 7 | output.appendLine("HypermergeUriHandler registered") 8 | } 9 | 10 | handleUri(uri: Uri) { 11 | const uriString = decodeURIComponent(uri.path.replace(/^\//, "")) 12 | this.output.appendLine(`handling external uri: ${uriString}`) 13 | commands.executeCommand("hypermerge.open", uriString) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/HypermergeWrapper.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | 3 | import { Handle, Repo, ChangeFn, DocUrl } from "hypermerge" 4 | import { DocId } from "hypermerge/dist/Misc" 5 | import Hyperswarm from "hyperswarm" 6 | const raf = require("random-access-file") 7 | 8 | import { EventEmitter } from "events" 9 | import * as Diff from "./Diff" 10 | 11 | interface HypermergeNodeDetails { 12 | docId: DocId 13 | docUrl: DocUrl 14 | keyPath: string[] 15 | label?: string 16 | history?: number 17 | } 18 | 19 | export function interpretHypermergeUri( 20 | uri: vscode.Uri, 21 | ): HypermergeNodeDetails | null { 22 | if (uri.scheme === "hypermerge") { 23 | const [_, docId, ...keyPath] = uri.path.split("/") 24 | 25 | const input = new Map( 26 | uri.query.split("&").map( 27 | (pair): [string, string] => { 28 | const [key, value = ""] = pair.split("=") 29 | return [key, value] 30 | }, 31 | ), 32 | ) 33 | 34 | const historyString = input.get("history") 35 | const history = historyString ? parseInt(historyString, 10) : undefined 36 | 37 | const label = input.get("label") 38 | return { docId: docId as DocId, keyPath, label, history, docUrl: ("hypermerge:/" + docId) as DocUrl } 39 | } else if (uri.scheme === "capstone") { 40 | const pathElements = uri.path.split("/") 41 | const docId = pathElements[1] 42 | return { docId: docId as DocId, keyPath: [], docUrl: ("hypermerge:/" + docId) as DocUrl } 43 | } 44 | 45 | return null 46 | } 47 | 48 | const homedir = 49 | process.env[process.platform == "win32" ? "USERPROFILE" : "HOME"] 50 | const path = `${homedir}/.hypermergefs` 51 | const storage = raf 52 | 53 | export class HypermergeWrapper extends EventEmitter { 54 | repo = new Repo({ path }) 55 | handles: { [docUrl: string]: Handle } = {} 56 | 57 | constructor() { 58 | super() 59 | 60 | this.repo.setSwarm(Hyperswarm()) 61 | 62 | try { 63 | ;(global as any).repo = this.repo 64 | } catch (err) { 65 | console.log("Error in constructor", err) 66 | } 67 | } 68 | 69 | resolveSubDocument(doc: any, keyPath): any { 70 | let content = doc 71 | let key 72 | while ((key = keyPath.shift()) != null) { 73 | content = content[key] 74 | } 75 | return content 76 | } 77 | 78 | removeDocumentUri(uri: vscode.Uri) { 79 | const details = interpretHypermergeUri(uri) 80 | if (!details) { return } 81 | const { docUrl } = details 82 | 83 | delete this.handles[docUrl] 84 | this.repo.destroy(docUrl) 85 | } 86 | 87 | exists(uri: vscode.Uri): boolean { 88 | const { docUrl = null } = interpretHypermergeUri(uri) || {} 89 | if (!docUrl) { return false } 90 | return !!this.handles[docUrl] 91 | } 92 | 93 | changeDocumentUri( 94 | uri: vscode.Uri, 95 | fn: ChangeFn, 96 | ): vscode.Uri | undefined { 97 | const { docId = "", docUrl = "", keyPath = [] } = 98 | interpretHypermergeUri(uri) || {} 99 | 100 | if (!docUrl) return 101 | if (!this.handles[docUrl]) return 102 | 103 | this.handles[docUrl].change((doc: any) => { 104 | let state = this.resolveSubDocument(doc, keyPath) 105 | 106 | while (typeof state !== "object") { 107 | keyPath.pop() 108 | state = this.resolveSubDocument(doc, keyPath) 109 | } 110 | fn(state) 111 | }) 112 | 113 | return uri.with({ path: ["", docId, ...keyPath].join("/") }) 114 | } 115 | 116 | openDocumentUri(uri: vscode.Uri): Promise { 117 | const details = interpretHypermergeUri(uri) 118 | 119 | if (!details) { throw new Error("invalid doc URL") } 120 | const { docUrl, keyPath = [], history = undefined } = details 121 | 122 | const h = this.handles 123 | 124 | return new Promise((resolve, reject) => { 125 | const subDoc = doc => resolve(this.resolveSubDocument(doc, keyPath)) 126 | const progressCb = event => { 127 | console.log("Progress") 128 | console.log(event) 129 | } 130 | 131 | const update = doc => this.emit("update", uri, doc) 132 | 133 | if (history) { 134 | this.repo.materialize(docUrl, history, subDoc) 135 | } else { 136 | h[docUrl] = 137 | h[docUrl] || 138 | this.repo 139 | .open(docUrl) 140 | .subscribe(update) 141 | .subscribeProgress(progressCb) 142 | this.repo.doc(docUrl, subDoc) 143 | } 144 | }) 145 | } 146 | 147 | watchDocumentUri(uri: vscode.Uri, cb: (doc: any) => void): void { 148 | const details = interpretHypermergeUri(uri) 149 | if (!details) { throw new Error("no valid docURL") } 150 | const { docUrl, keyPath = [], history = undefined } = details 151 | 152 | const resolve = doc => cb(this.resolveSubDocument(doc, keyPath)) 153 | 154 | if (history) { 155 | this.repo.materialize(docUrl, history, resolve) 156 | } else { 157 | this.repo.open(docUrl).subscribe(resolve) 158 | } 159 | } 160 | 161 | createDocumentUri(props: object = {}): vscode.Uri { 162 | const docUrl = this.repo.create({ title: "New Document", ...props }) 163 | return vscode.Uri.parse(docUrl) 164 | } 165 | 166 | forkDocumentUri(forkedDoc: vscode.Uri): vscode.Uri | null { 167 | throw new Error("Not implemented, yet.") 168 | 169 | // const { docUrl = "", keyPath = [] } = 170 | // interpretHypermergeUri(forkedDoc) || {} 171 | // if (!docUrl) { 172 | // return null 173 | // } 174 | 175 | // const forkUrl = this.repo.fork(docUrl) 176 | // return vscode.Uri.parse(forkUrl) 177 | } 178 | 179 | followDocumentUri(followedDoc: vscode.Uri): vscode.Uri | null { 180 | throw new Error("Not implemented, yet.") 181 | 182 | // const { docUrl = "", keyPath = [] } = 183 | // interpretHypermergeUri(followedDoc) || {} 184 | 185 | // if (!docUrl) { 186 | // return null 187 | // } 188 | 189 | // const followId = this.repo.create() 190 | // this.repo.follow(followId, docUrl) 191 | // return vscode.Uri.parse(docUrl) 192 | } 193 | 194 | setDocumentUri(uri: vscode.Uri, newDoc: any) { 195 | const details = interpretHypermergeUri(uri) 196 | if (!details) { throw new Error("no valid docURL") } 197 | const { docUrl, keyPath = [], history = undefined } = details 198 | 199 | 200 | // we use any types because the VSCode plugin can't possibly know the document 201 | this.repo.change(docUrl, (doc: any) => { 202 | let content = doc 203 | let key: string | undefined 204 | while ((key = keyPath.shift()) != null) { 205 | // special case to assign leaf values :( 206 | // this needs more consideration 207 | if ( 208 | (typeof content[key] !== "object" || typeof newDoc !== "object") && 209 | keyPath.length === 0 210 | ) { 211 | content[key] = newDoc 212 | return 213 | } 214 | content = content[key] 215 | } 216 | 217 | Diff.apply(content, newDoc) 218 | }) 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /src/LedgerTreeProvider.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { Uri } from "vscode" 3 | 4 | import { HypermergeWrapper, interpretHypermergeUri } from "./HypermergeWrapper" 5 | import { URL } from "url" 6 | 7 | // This should be a string or other primitive value (despite the appeal of using a richer data type) 8 | // because the VSCode internal APIs put it into a Set and lose the ability to recognize equality otherwise. 9 | export type HypermergeNodeKey = string 10 | 11 | export enum SortOrder { 12 | Title, 13 | Key, 14 | } 15 | 16 | export default class LedgerTreeProvider 17 | implements vscode.TreeDataProvider { 18 | protected _onDidChangeTreeData = new vscode.EventEmitter< 19 | HypermergeNodeKey | undefined 20 | >() 21 | readonly onDidChangeTreeData = this._onDidChangeTreeData.event 22 | 23 | protected sortOrder: SortOrder 24 | protected loaded = new Set() 25 | // could use a titleCache to decide when to re-sort. 26 | 27 | constructor(protected readonly hypermergeWrapper: HypermergeWrapper) { 28 | this.hypermergeWrapper = hypermergeWrapper 29 | this.sortOrder = SortOrder.Title 30 | 31 | const { ledger }: any = this.hypermergeWrapper.repo.back.meta 32 | 33 | ledger.on("append", () => { 34 | this.refresh() 35 | }) 36 | } 37 | 38 | public updateSortOrder(sortOrder: SortOrder) { 39 | this.sortOrder = sortOrder 40 | } 41 | 42 | public refresh(resourceUri?: string): any { 43 | // let's put a debounce on this 44 | console.log("refresh: " + resourceUri) 45 | this._onDidChangeTreeData.fire(resourceUri) 46 | } 47 | 48 | public async getTreeItem( 49 | element: HypermergeNodeKey, 50 | ): Promise { 51 | const resourceUri = Uri.parse(element) 52 | const details = interpretHypermergeUri(resourceUri) 53 | 54 | // Handle bad URLs. 55 | if (!details) { 56 | return { label: "" } 57 | } 58 | 59 | let { docId, keyPath, docUrl } = details 60 | 61 | let tooltip = element 62 | let description = docId.slice(0, 5) 63 | 64 | if (!this.loaded.has(docId)) { 65 | this.hypermergeWrapper.watchDocumentUri(vscode.Uri.parse(docUrl), doc => { 66 | this.loaded.add(docId) 67 | this.refresh() 68 | }) 69 | 70 | const collapsibleState = vscode.TreeItemCollapsibleState.None 71 | return { 72 | label: `(Loading...)`, 73 | description, 74 | tooltip, 75 | // id: element, 76 | resourceUri, 77 | collapsibleState, 78 | command: { 79 | command: "hypermerge.view", 80 | arguments: [resourceUri.toString(), { preview: true }], 81 | title: "View Document", 82 | }, 83 | } 84 | } 85 | 86 | const doc = await this.hypermergeWrapper.openDocumentUri(resourceUri) 87 | 88 | let content = doc 89 | 90 | let label 91 | if (keyPath.length) { 92 | label = keyPath.pop() 93 | } else if (content.title) { 94 | // label = `[${docId.slice(0, 5)}] ${content.title}` 95 | label = `${content.title}` 96 | } else { 97 | label = `(No title)` 98 | } 99 | 100 | const collapsibleState = 101 | content != null && typeof content === "object" 102 | ? vscode.TreeItemCollapsibleState.Collapsed 103 | : vscode.TreeItemCollapsibleState.None 104 | 105 | const newUri = resourceUri 106 | 107 | return { 108 | label, 109 | // id: element, 110 | description, 111 | tooltip, 112 | resourceUri, 113 | collapsibleState, 114 | command: { 115 | command: "hypermerge.view", 116 | arguments: [newUri.toString(), { preview: true }], 117 | title: "View Document", 118 | }, 119 | } 120 | } 121 | 122 | attemptToInterpretUrl(str: string): { docId?: string; keyPath?: string[] } { 123 | if (str.length > 2000 || str.includes("\n")) return {} 124 | 125 | try { 126 | return interpretHypermergeUri(Uri.parse(str)) || {} 127 | } catch (e) { 128 | return {} 129 | } 130 | } 131 | 132 | public async getChildren( 133 | element?: HypermergeNodeKey, 134 | ): Promise { 135 | return element ? this.getDocumentChildren(element) : this.roots() 136 | } 137 | 138 | public getParent(element: HypermergeNodeKey): HypermergeNodeKey | null { 139 | // there isn't necessarily a parent for a particular node in our system.. 140 | // or at least not the way i'm currently modeling it 141 | // XX: the node key should arguably be a path of some kind? 142 | return null 143 | } 144 | 145 | protected async getDocumentChildren( 146 | node: HypermergeNodeKey, 147 | ): Promise { 148 | const uri = Uri.parse(node) 149 | 150 | const content = await this.hypermergeWrapper.openDocumentUri(uri) 151 | 152 | if (typeof content !== "object") { 153 | return [] 154 | } 155 | 156 | const children = Object.keys(content) 157 | const childNodes = children.map(child => { 158 | if (typeof content[child] === "string") { 159 | const { docId = null } = this.attemptToInterpretUrl(content[child]) 160 | 161 | if (docId) return "hypermerge:/" + docId 162 | } 163 | 164 | // this builds a new child URL and ditches the label if it exists. 165 | return new URL(node + "/" + child).toString() 166 | }) 167 | return childNodes 168 | } 169 | 170 | public async roots(): Promise { 171 | const repo = this.hypermergeWrapper.repo 172 | const meta = repo.back.meta 173 | const clocks = repo.back.clocks 174 | 175 | return new Promise(resolve => { 176 | meta.readyQ.push(() => { 177 | const docs = clocks.getAllDocumentIds(repo.id) 178 | const contentfulDocs = docs.map( async (docId) => { 179 | const nodeKey = "hypermerge:/" + docId 180 | if (!this.loaded.has(docId)) { 181 | return [nodeKey, null] 182 | } 183 | return [nodeKey, await this.hypermergeWrapper.openDocumentUri(Uri.parse(nodeKey))] 184 | }) 185 | 186 | const sortedDocs = Promise.all(contentfulDocs).then(loadedDocs => loadedDocs.sort((a: any, b: any) => { 187 | if (!a[1]) { 188 | return 1 189 | } 190 | if (!b[1]) { 191 | return -1 192 | } 193 | 194 | const aTitle = a[1].title 195 | const bTitle = b[1].title 196 | const aKey = a[0] 197 | const bKey = b[0] 198 | if (aTitle || bTitle) { 199 | if (!aTitle) return -1 200 | if (!bTitle) return 1 201 | if (aTitle > bTitle) { return 1 } 202 | if (aTitle < bTitle) { return -1 } 203 | } 204 | if (aKey > bKey) { 205 | return 1 206 | } 207 | if (aKey < bKey) { 208 | return -1 209 | } 210 | 211 | return 0 212 | })).then(sortedDocs => { 213 | resolve(sortedDocs.map(pair => pair[0] as string)) // unzip 214 | }) 215 | }) 216 | }) 217 | } 218 | 219 | public addRoot(resourceUri: string) { 220 | this.hypermergeWrapper.openDocumentUri(Uri.parse(resourceUri)) 221 | this.refresh() 222 | } 223 | 224 | public removeRoot(resourceUri: string) { 225 | const uri = Uri.parse(resourceUri) 226 | this.hypermergeWrapper.removeDocumentUri(uri) 227 | this.refresh() 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /src/MetadataTreeProvider.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode" 2 | import { HypermergeWrapper, interpretHypermergeUri } from "./HypermergeWrapper" 3 | 4 | export type HypermergeMetadataKey = string 5 | 6 | export default class MetadataTreeProvider 7 | implements vscode.TreeDataProvider { 8 | private _onDidChangeTreeData: vscode.EventEmitter< 9 | HypermergeMetadataKey | undefined 10 | > = new vscode.EventEmitter() 11 | readonly onDidChangeTreeData: vscode.Event< 12 | HypermergeMetadataKey | undefined 13 | > = this._onDidChangeTreeData.event 14 | 15 | private activeDocumentUri: vscode.Uri | undefined 16 | 17 | constructor(private readonly hypermergeWrapper: HypermergeWrapper) { 18 | this.hypermergeWrapper = hypermergeWrapper 19 | 20 | // XXX looks like this might be broken 21 | this.hypermergeWrapper.addListener("update", updatedDocumentUri => { 22 | if ( 23 | this.activeDocumentUri && 24 | this.activeDocumentUri.toString() === updatedDocumentUri.toString() 25 | ) { 26 | this._onDidChangeTreeData.fire(undefined) 27 | } 28 | }) 29 | } 30 | 31 | public show(uri: vscode.Uri): void { 32 | if (uri.scheme !== "hypermerge") return 33 | this.activeDocumentUri = uri 34 | this.refresh() 35 | } 36 | 37 | public refresh(key?: HypermergeMetadataKey): any { 38 | this._onDidChangeTreeData.fire(key) 39 | } 40 | 41 | public getTreeItem(element: HypermergeMetadataKey): vscode.TreeItem { 42 | const collapsibleState = vscode.TreeItemCollapsibleState.None 43 | 44 | // Make sure we're in a valid hypermerge document. 45 | if (!this.activeDocumentUri) { 46 | return { label: "no active hypermerge doc" } 47 | } 48 | const details = interpretHypermergeUri(this.activeDocumentUri) 49 | if (!details) { 50 | return { label: "bad URI" } 51 | } 52 | 53 | // Create an array of results. 54 | const { docId } = details 55 | if (element === "actor") { 56 | // const meta = this.hypermergeWrapper.repo.meta(docId)!; 57 | // this funciton is Async :/ - using a hack instead 58 | const actor = this.hypermergeWrapper.repo.front.docs.get(docId)!.actorId 59 | return { 60 | label: "Local Actor: " + actor, 61 | collapsibleState, 62 | } 63 | } 64 | if (element === "clocks") { 65 | return { 66 | label: "Current Vector Clock", 67 | collapsibleState: vscode.TreeItemCollapsibleState.Expanded, 68 | } 69 | } 70 | 71 | // elsewise we have a clock entry 72 | return { 73 | label: element, 74 | collapsibleState, 75 | } 76 | } 77 | 78 | attemptToInterpretUrl(str: string): { docId?: string; keyPath?: string[] } { 79 | if (str.length > 2000 || str.includes("\n")) return {} 80 | 81 | try { 82 | return interpretHypermergeUri(vscode.Uri.parse(str)) || {} 83 | } catch (e) { 84 | return {} 85 | } 86 | } 87 | 88 | public getChildren( 89 | element?: HypermergeMetadataKey, 90 | ): HypermergeMetadataKey[] | Thenable { 91 | // Make sure we're in a valid hypermerge document. 92 | if (!this.activeDocumentUri) { 93 | return ["no active hypermerge doc"] 94 | } 95 | const details = interpretHypermergeUri(this.activeDocumentUri) 96 | if (!details) { 97 | return ["bad URI"] 98 | } 99 | 100 | // Create an array of results. 101 | const { docUrl } = details 102 | if (!docUrl) { throw new Error("invalid doc URL") } 103 | 104 | if (element === "clocks") { 105 | return new Promise(resolve => { 106 | this.hypermergeWrapper.repo.meta(docUrl, meta => { 107 | const clock = meta && meta.type === "Document" ? meta.clock : {} 108 | resolve( 109 | Object.entries(clock).map( 110 | ([key, value]) => `[${key.slice(0, 5)}]: ${value}`, 111 | ), 112 | ) 113 | }) 114 | }) 115 | } 116 | 117 | return ["actor", "clocks"] 118 | } 119 | 120 | public getParent( 121 | element: HypermergeMetadataKey, 122 | ): HypermergeMetadataKey | null { 123 | // there isn't necessarily a parent for a particular node in our system.. 124 | // or at least not the way i'm currently modeling it 125 | // XX: the node key should arguably be a path of some kind? 126 | return null 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | "use strict" 2 | import * as vscode from "vscode" 3 | import DebugManager from "./DebugManager" 4 | import HypermergeFS from "./HypermergeFS" 5 | import HypercoreFS from "./HypercoreFS" 6 | import HypermergeExplorer from "./HypermergeExplorer" 7 | import { HypermergeWrapper } from "./HypermergeWrapper" 8 | import HypermergeUriHandler from "./HypermergeUriHandler" 9 | import HypermergeDocumentLinkProvider from "./DocumentLinkProvider" 10 | import DiagnosticCollector from "./DiagnosticCollector" 11 | 12 | export function activate(context: vscode.ExtensionContext) { 13 | const output = vscode.window.createOutputChannel("Hypermerge") 14 | const debugManager = new DebugManager(output) 15 | 16 | output.appendLine("HypermergeFS activated") 17 | 18 | const hypermergeWrapper = new HypermergeWrapper() 19 | 20 | context.subscriptions.push( 21 | output, 22 | debugManager, 23 | 24 | vscode.workspace.registerFileSystemProvider( 25 | "hypermerge", 26 | new HypermergeFS(hypermergeWrapper), 27 | { 28 | isCaseSensitive: true, 29 | }, 30 | ), 31 | 32 | vscode.workspace.registerFileSystemProvider( 33 | "hypercore", 34 | new HypercoreFS(hypermergeWrapper), 35 | { 36 | isCaseSensitive: true, 37 | isReadonly: true, 38 | }, 39 | ), 40 | 41 | vscode.window.onDidChangeActiveTextEditor(editor => { 42 | const isHypermerge = editor && editor.document.uri.scheme === "hypermerge" 43 | 44 | vscode.commands.executeCommand("setContext", "isHypermerge", isHypermerge) 45 | }), 46 | 47 | vscode.workspace.onDidOpenTextDocument(document => { 48 | if (document.uri.scheme === "hypermerge") { 49 | try { 50 | JSON.parse(document.getText()) 51 | ;(vscode.languages as any).setTextDocumentLanguage(document, "json") 52 | } catch (e) { 53 | // not JSON, which is fine 54 | // really, we should do something cheaper than parse the whole file here 55 | } 56 | } 57 | }), 58 | 59 | vscode.languages.registerDocumentLinkProvider( 60 | { scheme: "*" }, 61 | new HypermergeDocumentLinkProvider(), 62 | ), 63 | 64 | vscode.workspace.onDidOpenTextDocument(document => { 65 | if (document.uri.scheme === "hypermerge") { 66 | if (JSON.parse(document.getText())) { 67 | ;(vscode.languages as any).setTextDocumentLanguage(document, "json") 68 | } 69 | } 70 | }), 71 | 72 | vscode.window.registerUriHandler(new HypermergeUriHandler(output)), 73 | 74 | new HypermergeExplorer(context, hypermergeWrapper), 75 | ) 76 | 77 | // self-registers 78 | new DiagnosticCollector(context, hypermergeWrapper) 79 | 80 | return { 81 | repo: hypermergeWrapper.repo, 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strictNullChecks": true, 4 | "module": "commonjs", 5 | "target": "es6", 6 | "outDir": "out", 7 | "lib": [ 8 | "es6", 9 | "es2017.object" 10 | ], 11 | "sourceMap": true, 12 | "rootDir": ".", 13 | "esModuleInterop": true, 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | ".vscode-test" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@hyperswarm/dht@^3.0.0": 6 | version "3.0.0" 7 | resolved "https://registry.yarnpkg.com/@hyperswarm/dht/-/dht-3.0.0.tgz#2f18494dbda02c0eaa8721fb91c623033b129f8d" 8 | integrity sha512-x3fwXtCkyjfevSjNkS2uanEZxGpJ3pcHPHXJN1JuIhQEdRj3L2CYFAGttkWOoT6Mtz19YXvLaf7wI4w6C/68Lg== 9 | dependencies: 10 | "@hyperswarm/hypersign" "^2.0.0" 11 | dht-rpc "^4.1.6" 12 | end-of-stream "^1.4.1" 13 | hashlru "^2.3.0" 14 | ipv4-peers "^2.0.0" 15 | protocol-buffers-encodings "^1.1.0" 16 | record-cache "^1.1.0" 17 | sodium-universal "^2.0.0" 18 | 19 | "@hyperswarm/discovery@^1.1.0", "@hyperswarm/discovery@^1.6.0": 20 | version "1.7.0" 21 | resolved "https://registry.yarnpkg.com/@hyperswarm/discovery/-/discovery-1.7.0.tgz#72492f040a7b1caa1e212070229755b972b92bc0" 22 | integrity sha512-eXMOh+Sb7P+SdfoZxLOeRiy5SlJHOODLrfQIePfrV+mUp6LRfaG07R9osjeXq2tA7LEKATJK9TXFB56erYA1zw== 23 | dependencies: 24 | "@hyperswarm/dht" "^3.0.0" 25 | multicast-dns "^7.2.0" 26 | 27 | "@hyperswarm/hypersign@^2.0.0": 28 | version "2.0.0" 29 | resolved "https://registry.yarnpkg.com/@hyperswarm/hypersign/-/hypersign-2.0.0.tgz#86f1927eb19926d9db4ca4b0f3bbb3f99976ee54" 30 | integrity sha512-CWDNRAF/5aL7ocZkr/I8y2HWCB1RX3fvvObQn1ExAZ3ha7grApzaSrEt0Q3bqzQXeSEXNerx6dquXhAVOOZXFA== 31 | dependencies: 32 | sodium-universal "^2.0.0" 33 | 34 | "@hyperswarm/network@1.1.0": 35 | version "1.1.0" 36 | resolved "https://registry.yarnpkg.com/@hyperswarm/network/-/network-1.1.0.tgz#e190a6c3eb71fd225bbaa085dd6bdaf6553fe104" 37 | integrity sha512-sKmHjRLz0mnWMz+jLClQ1hpWZomfTUGhJazQKHteU9U5gxinrt5O9GtmhNzBttvtm1xsCyVxtUnLfWreVFAy8g== 38 | dependencies: 39 | "@hyperswarm/discovery" "^1.6.0" 40 | nanoresource "^1.0.0" 41 | utp-native "^2.1.3" 42 | 43 | "@types/better-sqlite3@^5.4.0": 44 | version "5.4.0" 45 | resolved "https://registry.yarnpkg.com/@types/better-sqlite3/-/better-sqlite3-5.4.0.tgz#ab7336ccc2e31bd88247016c675cfcb01df99787" 46 | integrity sha512-nzm7lJ7l3jBmGUbtkL8cdOMhPkN6Pw2IM+b0V7iIKba+YKiLrjkIy7vVLsBIVnd7+lgzBzrHsXZxCaFTcmw5Ow== 47 | dependencies: 48 | "@types/integer" "*" 49 | 50 | "@types/color-name@^1.1.1": 51 | version "1.1.1" 52 | resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" 53 | integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== 54 | 55 | "@types/integer@*": 56 | version "1.0.0" 57 | resolved "https://registry.yarnpkg.com/@types/integer/-/integer-1.0.0.tgz#f5b313876012fad0afeb5318f03cb871064eb33e" 58 | integrity sha512-3viiRKLoSP2Qr78nMoQjkDc0fan4BgmpOyV1+1gKjE8wWXo3QQ78WItO6f9WuBf3qe3ymDYhM65oqHTOZ0rFxw== 59 | 60 | "@types/node@^10.2.0": 61 | version "10.17.27" 62 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.27.tgz#391cb391c75646c8ad2a7b6ed3bbcee52d1bdf19" 63 | integrity sha512-J0oqm9ZfAXaPdwNXMMgAhylw5fhmXkToJd06vuDUSAgEDZ/n/69/69UmyBZbc+zT34UnShuDSBqvim3SPnozJg== 64 | 65 | "@types/pretty-bytes@^5.1.0": 66 | version "5.1.0" 67 | resolved "https://registry.yarnpkg.com/@types/pretty-bytes/-/pretty-bytes-5.1.0.tgz#1df59db5c7def05dbbb0df2ad80b46863d9fafda" 68 | integrity sha512-rc7x/HkZyguytBsCUVvcdARplUf0DsrRXqv3yO0v0CIgXuuwNlgYZRfYGCFHxr1CTnKHjCIJ13tB9t49ZixOIw== 69 | 70 | "@types/vscode@^1.46.0": 71 | version "1.46.0" 72 | resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.46.0.tgz#53f2075986e901ed25cd1ec5f3ffa5db84a111b3" 73 | integrity sha512-8m9wPEB2mcRqTWNKs9A9Eqs8DrQZt0qNFO8GkxBOnyW6xR//3s77SoMgb/nY1ctzACsZXwZj3YRTDsn4bAoaUw== 74 | 75 | abbrev@1: 76 | version "1.1.1" 77 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 78 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 79 | 80 | abstract-extension@^3.0.1: 81 | version "3.1.0" 82 | resolved "https://registry.yarnpkg.com/abstract-extension/-/abstract-extension-3.1.0.tgz#104da6e40765216d60688e31ee17fed6f4ed2196" 83 | integrity sha512-IhhwBFoP2l4xm0gp/YGzOfkie28OCT0X3OG4k9Zari/cM92QUU1tluUIBdhVrGXF8KrFGd8x9snuz152j6yi6A== 84 | dependencies: 85 | codecs "^2.0.0" 86 | 87 | ajv@^6.5.5: 88 | version "6.12.2" 89 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" 90 | integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== 91 | dependencies: 92 | fast-deep-equal "^3.1.1" 93 | fast-json-stable-stringify "^2.0.0" 94 | json-schema-traverse "^0.4.1" 95 | uri-js "^4.2.2" 96 | 97 | ansi-regex@^2.0.0: 98 | version "2.1.1" 99 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 100 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 101 | 102 | ansi-regex@^3.0.0: 103 | version "3.0.0" 104 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 105 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 106 | 107 | ansi-regex@^4.1.0: 108 | version "4.1.0" 109 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 110 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 111 | 112 | ansi-regex@^5.0.0: 113 | version "5.0.0" 114 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 115 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 116 | 117 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 118 | version "3.2.1" 119 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 120 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 121 | dependencies: 122 | color-convert "^1.9.0" 123 | 124 | ansi-styles@^4.0.0: 125 | version "4.2.1" 126 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" 127 | integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== 128 | dependencies: 129 | "@types/color-name" "^1.1.1" 130 | color-convert "^2.0.1" 131 | 132 | aproba@^1.0.3: 133 | version "1.2.0" 134 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 135 | integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== 136 | 137 | arch@^2.1.0: 138 | version "2.1.1" 139 | resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" 140 | integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== 141 | 142 | are-we-there-yet@~1.1.2: 143 | version "1.1.5" 144 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" 145 | integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== 146 | dependencies: 147 | delegates "^1.0.0" 148 | readable-stream "^2.0.6" 149 | 150 | asn1@~0.2.3: 151 | version "0.2.4" 152 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 153 | integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== 154 | dependencies: 155 | safer-buffer "~2.1.0" 156 | 157 | assert-plus@1.0.0, assert-plus@^1.0.0: 158 | version "1.0.0" 159 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 160 | integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= 161 | 162 | async-limiter@~1.0.0: 163 | version "1.0.0" 164 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" 165 | integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== 166 | 167 | asynckit@^0.4.0: 168 | version "0.4.0" 169 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 170 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 171 | 172 | atomic-batcher@^1.0.2: 173 | version "1.0.2" 174 | resolved "https://registry.yarnpkg.com/atomic-batcher/-/atomic-batcher-1.0.2.tgz#d16901d10ccec59516c197b9ccd8930689b813b4" 175 | integrity sha1-0WkB0QzOxZUWwZe5zNiTBom4E7Q= 176 | 177 | automerge@^0.9.1: 178 | version "0.9.2" 179 | resolved "https://registry.yarnpkg.com/automerge/-/automerge-0.9.2.tgz#adf82e6423c1fffc69caa0409badd9828c6c46ef" 180 | integrity sha512-tgwGwsyDdQmKEfnXAXsY/roUgxVtgqg06jOQn3VWPrmT2L25TW1sJ6aG/CKDNOrRvoOviE9izbixsk/5vCiyjA== 181 | dependencies: 182 | immutable "^3.8.2" 183 | transit-immutable-js "^0.7.0" 184 | transit-js "^0.8.861" 185 | uuid "3.1.0" 186 | 187 | "automerge@github:automerge/automerge#opaque-strings": 188 | version "0.12.2-beta.0" 189 | resolved "https://codeload.github.com/automerge/automerge/tar.gz/340ca073b716f28426175e221766352e52d84daf" 190 | dependencies: 191 | immutable "^3.8.2" 192 | transit-immutable-js "^0.7.0" 193 | transit-js "^0.8.861" 194 | uuid "3.3.2" 195 | 196 | aws-sign2@~0.7.0: 197 | version "0.7.0" 198 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 199 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= 200 | 201 | aws4@^1.8.0: 202 | version "1.10.0" 203 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" 204 | integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== 205 | 206 | balanced-match@^1.0.0: 207 | version "1.0.0" 208 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 209 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 210 | 211 | base-x@^3.0.2: 212 | version "3.0.5" 213 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.5.tgz#d3ada59afed05b921ab581ec3112e6444ba0795a" 214 | integrity sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA== 215 | dependencies: 216 | safe-buffer "^5.0.1" 217 | 218 | bcrypt-pbkdf@^1.0.0: 219 | version "1.0.2" 220 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" 221 | integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= 222 | dependencies: 223 | tweetnacl "^0.14.3" 224 | 225 | better-sqlite3@^5.4.3: 226 | version "5.4.3" 227 | resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-5.4.3.tgz#2cb843ce14c56de9e9c0ca6b89844b7d4b5794b8" 228 | integrity sha512-fPp+8f363qQIhuhLyjI4bu657J/FfMtgiiHKfaTsj3RWDkHlWC1yT7c6kHZDnBxzQVoAINuzg553qKmZ4F1rEw== 229 | dependencies: 230 | integer "^2.1.0" 231 | tar "^4.4.10" 232 | 233 | bitfield-rle@^2.2.1: 234 | version "2.2.1" 235 | resolved "https://registry.yarnpkg.com/bitfield-rle/-/bitfield-rle-2.2.1.tgz#07c910f7e650c005c46d18ee5ca6e62c4baf8310" 236 | integrity sha512-wrDhHe7LUkqaytxgbsFXoemzHRv6e8FrVNWWsQCgUfmuVYW6ke44hoGc9VdpjgfIsJ/ejmCFA8wDtDqACNAvyw== 237 | dependencies: 238 | buffer-alloc-unsafe "^1.1.0" 239 | varint "^4.0.0" 240 | 241 | blake2b-wasm@^1.1.0: 242 | version "1.1.7" 243 | resolved "https://registry.yarnpkg.com/blake2b-wasm/-/blake2b-wasm-1.1.7.tgz#e4d075da10068e5d4c3ec1fb9accc4d186c55d81" 244 | integrity sha512-oFIHvXhlz/DUgF0kq5B1CqxIDjIJwh9iDeUUGQUcvgiGz7Wdw03McEO7CfLBy7QKGdsydcMCgO9jFNBAFCtFcA== 245 | dependencies: 246 | nanoassert "^1.0.0" 247 | 248 | blake2b@^2.1.1: 249 | version "2.1.3" 250 | resolved "https://registry.yarnpkg.com/blake2b/-/blake2b-2.1.3.tgz#f5388be424768e7c6327025dad0c3c6d83351bca" 251 | integrity sha512-pkDss4xFVbMb4270aCyGD3qLv92314Et+FsKzilCLxDz5DuZ2/1g3w4nmBbu6nKApPspnjG7JcwTjGZnduB1yg== 252 | dependencies: 253 | blake2b-wasm "^1.1.0" 254 | nanoassert "^1.0.0" 255 | 256 | brace-expansion@^1.1.7: 257 | version "1.1.11" 258 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 259 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 260 | dependencies: 261 | balanced-match "^1.0.0" 262 | concat-map "0.0.1" 263 | 264 | bs58@^4.0.1: 265 | version "4.0.1" 266 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" 267 | integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= 268 | dependencies: 269 | base-x "^3.0.2" 270 | 271 | buffer-alloc-unsafe@^1.1.0: 272 | version "1.1.0" 273 | resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" 274 | integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== 275 | 276 | buffer-alloc@^1.1.0: 277 | version "1.2.0" 278 | resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" 279 | integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== 280 | dependencies: 281 | buffer-alloc-unsafe "^1.1.0" 282 | buffer-fill "^1.0.0" 283 | 284 | buffer-fill@^1.0.0: 285 | version "1.0.0" 286 | resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" 287 | integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= 288 | 289 | buffer-from@^1.0.0, buffer-from@^1.1.0: 290 | version "1.1.1" 291 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 292 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 293 | 294 | bulk-write-stream@^1.1.3: 295 | version "1.1.4" 296 | resolved "https://registry.yarnpkg.com/bulk-write-stream/-/bulk-write-stream-1.1.4.tgz#04b4bdaad61f5a813d8323547383020efffa7d7e" 297 | integrity sha512-GtKwd/4etuk1hNeprXoESBO1RSeRYJMXKf+O0qHmWdUomLT8ysNEfX/4bZFXr3BK6eukpHiEnhY2uMtEHDM2ng== 298 | dependencies: 299 | buffer-from "^1.0.0" 300 | inherits "^2.0.1" 301 | readable-stream "^2.1.4" 302 | 303 | camelcase@^5.0.0: 304 | version "5.3.1" 305 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 306 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 307 | 308 | caseless@~0.12.0: 309 | version "0.12.0" 310 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 311 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= 312 | 313 | chalk@^2.0.1, chalk@^2.4.2: 314 | version "2.4.2" 315 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 316 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 317 | dependencies: 318 | ansi-styles "^3.2.1" 319 | escape-string-regexp "^1.0.5" 320 | supports-color "^5.3.0" 321 | 322 | chownr@^1.1.1: 323 | version "1.1.4" 324 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" 325 | integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== 326 | 327 | cli-cursor@^2.1.0: 328 | version "2.1.0" 329 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" 330 | integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= 331 | dependencies: 332 | restore-cursor "^2.0.0" 333 | 334 | cli-spinners@^2.0.0: 335 | version "2.3.0" 336 | resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.3.0.tgz#0632239a4b5aa4c958610142c34bb7a651fc8df5" 337 | integrity sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w== 338 | 339 | clipboardy@^1.2.3: 340 | version "1.2.3" 341 | resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.3.tgz#0526361bf78724c1f20be248d428e365433c07ef" 342 | integrity sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA== 343 | dependencies: 344 | arch "^2.1.0" 345 | execa "^0.8.0" 346 | 347 | cliui@^5.0.0: 348 | version "5.0.0" 349 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" 350 | integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== 351 | dependencies: 352 | string-width "^3.1.0" 353 | strip-ansi "^5.2.0" 354 | wrap-ansi "^5.1.0" 355 | 356 | cliui@^6.0.0: 357 | version "6.0.0" 358 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" 359 | integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== 360 | dependencies: 361 | string-width "^4.2.0" 362 | strip-ansi "^6.0.0" 363 | wrap-ansi "^6.2.0" 364 | 365 | clone@^1.0.2: 366 | version "1.0.4" 367 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" 368 | integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= 369 | 370 | clone@^2.1.2: 371 | version "2.1.2" 372 | resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" 373 | integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= 374 | 375 | code-point-at@^1.0.0: 376 | version "1.1.0" 377 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 378 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 379 | 380 | codecs@^2.0.0: 381 | version "2.1.0" 382 | resolved "https://registry.yarnpkg.com/codecs/-/codecs-2.1.0.tgz#ea8878bbb0156ce977ffe275370b3851ef1181d6" 383 | integrity sha512-nSWYToViFEpZXOxhtMQ6IDs76TN9xKIkHOu1KCr/iFiBcgzKuY1AFPZktuXN8r82FbZ/TXP9fwITszLgcp3eQg== 384 | 385 | color-convert@^1.9.0: 386 | version "1.9.3" 387 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 388 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 389 | dependencies: 390 | color-name "1.1.3" 391 | 392 | color-convert@^2.0.1: 393 | version "2.0.1" 394 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 395 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 396 | dependencies: 397 | color-name "~1.1.4" 398 | 399 | color-name@1.1.3: 400 | version "1.1.3" 401 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 402 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 403 | 404 | color-name@~1.1.4: 405 | version "1.1.4" 406 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 407 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 408 | 409 | colors@^1.3.3: 410 | version "1.4.0" 411 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" 412 | integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== 413 | 414 | combined-stream@^1.0.6, combined-stream@~1.0.6: 415 | version "1.0.8" 416 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 417 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 418 | dependencies: 419 | delayed-stream "~1.0.0" 420 | 421 | concat-map@0.0.1: 422 | version "0.0.1" 423 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 424 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 425 | 426 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 427 | version "1.1.0" 428 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 429 | integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= 430 | 431 | copyfiles@^2.1.1: 432 | version "2.3.0" 433 | resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.3.0.tgz#1c26ebbe3d46bba2d309a3fd8e3aaccf53af8c76" 434 | integrity sha512-73v7KFuDFJ/ofkQjZBMjMBFWGgkS76DzXvBMUh7djsMOE5EELWtAO/hRB6Wr5Vj5Zg+YozvoHemv0vnXpqxmOQ== 435 | dependencies: 436 | glob "^7.0.5" 437 | minimatch "^3.0.3" 438 | mkdirp "^1.0.4" 439 | noms "0.0.0" 440 | through2 "^2.0.1" 441 | yargs "^15.3.1" 442 | 443 | core-util-is@1.0.2, core-util-is@~1.0.0: 444 | version "1.0.2" 445 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 446 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 447 | 448 | count-trailing-zeros@^1.0.1: 449 | version "1.0.1" 450 | resolved "https://registry.yarnpkg.com/count-trailing-zeros/-/count-trailing-zeros-1.0.1.tgz#aba6c5833be410d45b1eca3e6d583844ce682c77" 451 | integrity sha1-q6bFgzvkENRbHso+bVg4RM5oLHc= 452 | 453 | cross-spawn@^5.0.1: 454 | version "5.1.0" 455 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 456 | integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= 457 | dependencies: 458 | lru-cache "^4.0.1" 459 | shebang-command "^1.2.0" 460 | which "^1.2.9" 461 | 462 | dashdash@^1.12.0: 463 | version "1.14.1" 464 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 465 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= 466 | dependencies: 467 | assert-plus "^1.0.0" 468 | 469 | debug@^2.5.1: 470 | version "2.6.9" 471 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 472 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 473 | dependencies: 474 | ms "2.0.0" 475 | 476 | debug@^4.1.1: 477 | version "4.1.1" 478 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 479 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 480 | dependencies: 481 | ms "^2.1.1" 482 | 483 | decamelize@^1.2.0: 484 | version "1.2.0" 485 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 486 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 487 | 488 | defaults@^1.0.3: 489 | version "1.0.3" 490 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" 491 | integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= 492 | dependencies: 493 | clone "^1.0.2" 494 | 495 | delayed-stream@~1.0.0: 496 | version "1.0.0" 497 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 498 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 499 | 500 | delegates@^1.0.0: 501 | version "1.0.0" 502 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 503 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= 504 | 505 | detect-libc@^1.0.3: 506 | version "1.0.3" 507 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 508 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= 509 | 510 | dht-rpc@^4.1.6: 511 | version "4.1.7" 512 | resolved "https://registry.yarnpkg.com/dht-rpc/-/dht-rpc-4.1.7.tgz#68e11f40b7b2b3fd63604b6316533a0e7e988257" 513 | integrity sha512-XXSqvWXp80EpT24f0nJvwsvgXW2T1F/Upa2X7Wd9KZPO2BY5N2EmckynnwKYkQwuOwhilzDbjR1RUvSQ2tu0Hw== 514 | dependencies: 515 | codecs "^2.0.0" 516 | ipv4-peers "^2.0.0" 517 | k-bucket "^5.0.0" 518 | protocol-buffers-encodings "^1.1.0" 519 | sodium-universal "^2.0.0" 520 | stream-collector "^1.0.1" 521 | time-ordered-set "^1.0.1" 522 | xor-distance "^2.0.0" 523 | 524 | dns-packet@^4.0.0: 525 | version "4.2.0" 526 | resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-4.2.0.tgz#3fd6f5ff5a4ec3194ed0b15312693ffe8776b343" 527 | integrity sha512-bn1AKpfkFbm0MIioOMHZ5qJzl2uypdBwI4nYNsqvhjsegBhcKJUlCrMPWLx6JEezRjxZmxhtIz/FkBEur2l8Cw== 528 | dependencies: 529 | ip "^1.1.5" 530 | safe-buffer "^5.1.1" 531 | 532 | ecc-jsbn@~0.1.1: 533 | version "0.1.2" 534 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" 535 | integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= 536 | dependencies: 537 | jsbn "~0.1.0" 538 | safer-buffer "^2.1.0" 539 | 540 | electron-rebuild@^1.8.6: 541 | version "1.11.0" 542 | resolved "https://registry.yarnpkg.com/electron-rebuild/-/electron-rebuild-1.11.0.tgz#e384773a9ad30fe0a6a5bbb326b779d51f668b6a" 543 | integrity sha512-cn6AqZBQBVtaEyj5jZW1/LOezZZ22PA1HvhEP7asvYPJ8PDF4i4UFt9be4i9T7xJKiSiomXvY5Fd+dSq3FXZxA== 544 | dependencies: 545 | colors "^1.3.3" 546 | debug "^4.1.1" 547 | detect-libc "^1.0.3" 548 | fs-extra "^8.1.0" 549 | node-abi "^2.11.0" 550 | node-gyp "^6.0.1" 551 | ora "^3.4.0" 552 | spawn-rx "^3.0.0" 553 | yargs "^14.2.0" 554 | 555 | emoji-regex@^7.0.1: 556 | version "7.0.3" 557 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 558 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 559 | 560 | emoji-regex@^8.0.0: 561 | version "8.0.0" 562 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 563 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 564 | 565 | end-of-stream@^1.1.0, end-of-stream@^1.4.1: 566 | version "1.4.4" 567 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 568 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 569 | dependencies: 570 | once "^1.4.0" 571 | 572 | env-paths@^2.2.0: 573 | version "2.2.0" 574 | resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" 575 | integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== 576 | 577 | escape-string-regexp@^1.0.5: 578 | version "1.0.5" 579 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 580 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 581 | 582 | execa@^0.8.0: 583 | version "0.8.0" 584 | resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" 585 | integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= 586 | dependencies: 587 | cross-spawn "^5.0.1" 588 | get-stream "^3.0.0" 589 | is-stream "^1.1.0" 590 | npm-run-path "^2.0.0" 591 | p-finally "^1.0.0" 592 | signal-exit "^3.0.0" 593 | strip-eof "^1.0.0" 594 | 595 | extend@~3.0.2: 596 | version "3.0.2" 597 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 598 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 599 | 600 | extsprintf@1.3.0: 601 | version "1.3.0" 602 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 603 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= 604 | 605 | extsprintf@^1.2.0: 606 | version "1.4.0" 607 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 608 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= 609 | 610 | fast-bitfield@^1.2.2: 611 | version "1.2.2" 612 | resolved "https://registry.yarnpkg.com/fast-bitfield/-/fast-bitfield-1.2.2.tgz#7f08cdb46a6384b887a64127b56aa4d59bc8fa25" 613 | integrity sha512-t8HYqkuE3YEqNcyWlAfh55479aTxO+GpYwvQvJppYqyBfSmRdNIhzY2m09FKN/MENTzq4wH6heHOIvsPyMAwvQ== 614 | dependencies: 615 | count-trailing-zeros "^1.0.1" 616 | 617 | fast-deep-equal@^3.1.1: 618 | version "3.1.3" 619 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 620 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 621 | 622 | fast-fifo@^1.0.0: 623 | version "1.0.0" 624 | resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.0.0.tgz#9bc72e6860347bb045a876d1c5c0af11e9b984e7" 625 | integrity sha512-4VEXmjxLj7sbs8J//cn2qhRap50dGzF5n8fjay8mau+Jn4hxSeR3xPFwxMaQq/pDaq7+KQk0PAbC2+nWDkJrmQ== 626 | 627 | fast-json-stable-stringify@^2.0.0: 628 | version "2.1.0" 629 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 630 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 631 | 632 | fd-lock@^1.0.2: 633 | version "1.0.2" 634 | resolved "https://registry.yarnpkg.com/fd-lock/-/fd-lock-1.0.2.tgz#fb68e9f40830f96a098e090b79ab6ee9363ea89d" 635 | integrity sha512-8O4zSv6rlNNghVfzVkj/p7LUIeBm7Xxk6QnhfmR1WJm/W4kwS8IyShy4X1peRnFUYZUYLlcwEMKXF8QWxJCMvg== 636 | dependencies: 637 | napi-macros "^1.8.2" 638 | node-gyp-build "^3.8.0" 639 | 640 | find-up@^3.0.0: 641 | version "3.0.0" 642 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" 643 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== 644 | dependencies: 645 | locate-path "^3.0.0" 646 | 647 | find-up@^4.1.0: 648 | version "4.1.0" 649 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" 650 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== 651 | dependencies: 652 | locate-path "^5.0.0" 653 | path-exists "^4.0.0" 654 | 655 | flat-tree@^1.3.0, flat-tree@^1.6.0: 656 | version "1.6.0" 657 | resolved "https://registry.yarnpkg.com/flat-tree/-/flat-tree-1.6.0.tgz#fca30cddb9006fb656eb5ebc79aeb274e7fde9ed" 658 | integrity sha1-/KMM3bkAb7ZW6168ea6ydOf96e0= 659 | 660 | forever-agent@~0.6.1: 661 | version "0.6.1" 662 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 663 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= 664 | 665 | form-data@~2.3.2: 666 | version "2.3.3" 667 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 668 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 669 | dependencies: 670 | asynckit "^0.4.0" 671 | combined-stream "^1.0.6" 672 | mime-types "^2.1.12" 673 | 674 | from2@^2.3.0: 675 | version "2.3.0" 676 | resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" 677 | integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= 678 | dependencies: 679 | inherits "^2.0.1" 680 | readable-stream "^2.0.0" 681 | 682 | fs-extra@^8.1.0: 683 | version "8.1.0" 684 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" 685 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== 686 | dependencies: 687 | graceful-fs "^4.2.0" 688 | jsonfile "^4.0.0" 689 | universalify "^0.1.0" 690 | 691 | fs-minipass@^1.2.5: 692 | version "1.2.7" 693 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" 694 | integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== 695 | dependencies: 696 | minipass "^2.6.0" 697 | 698 | fs.realpath@^1.0.0: 699 | version "1.0.0" 700 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 701 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 702 | 703 | gauge@~2.7.3: 704 | version "2.7.4" 705 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 706 | integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= 707 | dependencies: 708 | aproba "^1.0.3" 709 | console-control-strings "^1.0.0" 710 | has-unicode "^2.0.0" 711 | object-assign "^4.1.0" 712 | signal-exit "^3.0.0" 713 | string-width "^1.0.1" 714 | strip-ansi "^3.0.1" 715 | wide-align "^1.1.0" 716 | 717 | get-caller-file@^2.0.1: 718 | version "2.0.5" 719 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 720 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 721 | 722 | get-stream@^3.0.0: 723 | version "3.0.0" 724 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 725 | integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= 726 | 727 | getpass@^0.1.1: 728 | version "0.1.7" 729 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 730 | integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= 731 | dependencies: 732 | assert-plus "^1.0.0" 733 | 734 | glob@^7.0.5, glob@^7.1.3, glob@^7.1.4: 735 | version "7.1.6" 736 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 737 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 738 | dependencies: 739 | fs.realpath "^1.0.0" 740 | inflight "^1.0.4" 741 | inherits "2" 742 | minimatch "^3.0.4" 743 | once "^1.3.0" 744 | path-is-absolute "^1.0.0" 745 | 746 | graceful-fs@^4.1.11, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: 747 | version "4.2.4" 748 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" 749 | integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== 750 | 751 | har-schema@^2.0.0: 752 | version "2.0.0" 753 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 754 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= 755 | 756 | har-validator@~5.1.3: 757 | version "5.1.3" 758 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" 759 | integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== 760 | dependencies: 761 | ajv "^6.5.5" 762 | har-schema "^2.0.0" 763 | 764 | has-flag@^3.0.0: 765 | version "3.0.0" 766 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 767 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 768 | 769 | has-unicode@^2.0.0: 770 | version "2.0.1" 771 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 772 | integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= 773 | 774 | hashlru@^2.3.0: 775 | version "2.3.0" 776 | resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.3.0.tgz#5dc15928b3f6961a2056416bb3a4910216fdfb51" 777 | integrity sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A== 778 | 779 | hmac-blake2b@^0.2.0: 780 | version "0.2.0" 781 | resolved "https://registry.yarnpkg.com/hmac-blake2b/-/hmac-blake2b-0.2.0.tgz#f8c71699dc834ce8066a512ba0592eda572bff4c" 782 | integrity sha512-cJpnWOYMtaLr+3O32OII7DSTmQh+BKoeLXw49UAIc2QU68UwD2iBjItwxRVHmu1GBTuHeqME+rq7GpW2rBncCQ== 783 | dependencies: 784 | nanoassert "^1.1.0" 785 | sodium-universal "^2.0.0" 786 | 787 | http-signature@~1.2.0: 788 | version "1.2.0" 789 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 790 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= 791 | dependencies: 792 | assert-plus "^1.0.0" 793 | jsprim "^1.2.2" 794 | sshpk "^1.7.0" 795 | 796 | hypercore-cache@^1.0.1: 797 | version "1.0.2" 798 | resolved "https://registry.yarnpkg.com/hypercore-cache/-/hypercore-cache-1.0.2.tgz#f170a5fda597437533e1563f39dd60dbbd56056d" 799 | integrity sha512-AJ/q7y6EOrXnOH/4+DVcfDygsh1ZXMRGvNc67GBNqwCt22oSCOWhRI6EJ+3HEJciM9M2oSm1WX3qg6kgRhT/Gw== 800 | 801 | hypercore-crypto@^1.0.0: 802 | version "1.0.0" 803 | resolved "https://registry.yarnpkg.com/hypercore-crypto/-/hypercore-crypto-1.0.0.tgz#90dfd2c77364483d24af204b9a99136cb6320de6" 804 | integrity sha512-xFwOnNlOt8L+SovC7dTNchKaNYJb5l8rKZZwpWQnCme1r7CU4Hlhp1RDqPES6b0OpS7DkTo9iU0GltQGkpsjMw== 805 | dependencies: 806 | buffer-alloc-unsafe "^1.1.0" 807 | buffer-from "^1.1.0" 808 | sodium-universal "^2.0.0" 809 | uint64be "^2.0.2" 810 | 811 | hypercore-protocol@^7.6.0, hypercore-protocol@^7.9.0: 812 | version "7.10.0" 813 | resolved "https://registry.yarnpkg.com/hypercore-protocol/-/hypercore-protocol-7.10.0.tgz#34858414aae5cd8dfbf1c3bb77cc723a67e4d3f1" 814 | integrity sha512-9p+Mm8yTp8pW3EURSSQYSqEcDOWW1Fyg/Pqfxr1WYnWAvotuqPq2lIBSIuUOb6AIvHISuCKRqLxSLfJkvIWZ7g== 815 | dependencies: 816 | abstract-extension "^3.0.1" 817 | debug "^4.1.1" 818 | hypercore-crypto "^1.0.0" 819 | inspect-custom-symbol "^1.1.0" 820 | nanoguard "^1.2.1" 821 | pretty-hash "^1.0.1" 822 | simple-hypercore-protocol "^1.4.0" 823 | streamx "^2.1.0" 824 | timeout-refresh "^1.0.0" 825 | 826 | hypercore@^8.2.5: 827 | version "8.14.0" 828 | resolved "https://registry.yarnpkg.com/hypercore/-/hypercore-8.14.0.tgz#4d084370e21d7ded7ba5f488a1a012aa52ba28c2" 829 | integrity sha512-UIW0qSjBzQL4Z9tN97kBxM85JJsQL9osA6FWD9BYB/UKPD+umGgrocaN3kM9l3g2yKe/ziFU0DP5ys+qgqYIdQ== 830 | dependencies: 831 | abstract-extension "^3.0.1" 832 | atomic-batcher "^1.0.2" 833 | bitfield-rle "^2.2.1" 834 | bulk-write-stream "^1.1.3" 835 | codecs "^2.0.0" 836 | fast-bitfield "^1.2.2" 837 | flat-tree "^1.6.0" 838 | from2 "^2.3.0" 839 | hypercore-cache "^1.0.1" 840 | hypercore-crypto "^1.0.0" 841 | hypercore-protocol "^7.9.0" 842 | inherits "^2.0.3" 843 | inspect-custom-symbol "^1.1.0" 844 | last-one-wins "^1.0.4" 845 | memory-pager "^1.0.2" 846 | merkle-tree-stream "^3.0.3" 847 | nanoguard "^1.2.0" 848 | nanoresource "^1.3.0" 849 | pretty-hash "^1.0.1" 850 | random-access-file "^2.1.0" 851 | sodium-universal "^2.0.0" 852 | sparse-bitfield "^3.0.0" 853 | timeout-refresh "^1.0.1" 854 | uint64be "^2.0.1" 855 | unordered-array-remove "^1.0.2" 856 | unordered-set "^2.0.0" 857 | optionalDependencies: 858 | fd-lock "^1.0.2" 859 | 860 | "hypermerge@github:automerge/hypermerge": 861 | version "2.0.0-beta.25" 862 | resolved "https://codeload.github.com/automerge/hypermerge/tar.gz/95b41a0b2ebf0044b91553d5fdc3f6bc3cc62f9d" 863 | dependencies: 864 | automerge "github:automerge/automerge#opaque-strings" 865 | better-sqlite3 "^5.4.3" 866 | bs58 "^4.0.1" 867 | copyfiles "^2.1.1" 868 | debug "^4.1.1" 869 | hypercore "^8.2.5" 870 | hypercore-crypto "^1.0.0" 871 | hypercore-protocol "^7.6.0" 872 | js-sha1 "^0.6.0" 873 | mime-types "^2.1.24" 874 | noise-peer "^1.1.0" 875 | proper-lockfile "^4.1.1" 876 | pump "^3.0.0" 877 | random-access-file "^2.1.3" 878 | random-access-memory "^3.0.0" 879 | simple-message-channels "^1.2.1" 880 | sodium-native "^2.4.6" 881 | streamx "^2.5.0" 882 | uuid "^3.3.3" 883 | 884 | hyperswarm@^2.2.0: 885 | version "2.2.0" 886 | resolved "https://registry.yarnpkg.com/hyperswarm/-/hyperswarm-2.2.0.tgz#c5fb47aa6ce94740141a853a2609383026b99685" 887 | integrity sha512-Kzp28Qxwzmzob+JadDoMR1geigquCJHtB30tfVmM6tAm4+HSqa8tIlrR3llsiFfD2kzOmB5IHcP0/vTUiBnP7w== 888 | dependencies: 889 | "@hyperswarm/discovery" "^1.1.0" 890 | "@hyperswarm/network" "1.1.0" 891 | shuffled-priority-queue "^2.1.0" 892 | utp-native "^2.1.3" 893 | 894 | immutable@^3.8.2: 895 | version "3.8.2" 896 | resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" 897 | integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= 898 | 899 | inflight@^1.0.4: 900 | version "1.0.6" 901 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 902 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 903 | dependencies: 904 | once "^1.3.0" 905 | wrappy "1" 906 | 907 | inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: 908 | version "2.0.4" 909 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 910 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 911 | 912 | ini@^1.3.5: 913 | version "1.3.5" 914 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 915 | integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== 916 | 917 | inspect-custom-symbol@^1.1.0: 918 | version "1.1.1" 919 | resolved "https://registry.yarnpkg.com/inspect-custom-symbol/-/inspect-custom-symbol-1.1.1.tgz#18dae2ed4537f3d8e1708626d3756c10d7edf782" 920 | integrity sha512-GOucsp9EcdlLdhPUyOTvQDnbFJtp2WBWZV1Jqe+mVnkJQBL3w96+fB84C+JL+EKXOspMdB0eMDQPDp5w9fkfZA== 921 | 922 | integer@^2.1.0: 923 | version "2.1.0" 924 | resolved "https://registry.yarnpkg.com/integer/-/integer-2.1.0.tgz#29134ea2f7ba3362ed4dbe6bcca992b1f18ff276" 925 | integrity sha512-vBtiSgrEiNocWvvZX1RVfeOKa2mCHLZQ2p9nkQkQZ/BvEiY+6CcUz0eyjvIiewjJoeNidzg2I+tpPJvpyspL1w== 926 | 927 | ip@^1.1.5: 928 | version "1.1.5" 929 | resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" 930 | integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= 931 | 932 | ipv4-peers@^2.0.0: 933 | version "2.0.0" 934 | resolved "https://registry.yarnpkg.com/ipv4-peers/-/ipv4-peers-2.0.0.tgz#56db3a04c1bbde4b9035d19757821d7b66b3fbb7" 935 | integrity sha512-6ZMWB3JnCWT0gISUkzChcUEkJS6+LpGRU3h10f9Mfc0usVmyIcbcTN9+QPMg29gLOY8WtaKFbM5ME8qNySoh8g== 936 | 937 | is-fullwidth-code-point@^1.0.0: 938 | version "1.0.0" 939 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 940 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 941 | dependencies: 942 | number-is-nan "^1.0.0" 943 | 944 | is-fullwidth-code-point@^2.0.0: 945 | version "2.0.0" 946 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 947 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 948 | 949 | is-fullwidth-code-point@^3.0.0: 950 | version "3.0.0" 951 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 952 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 953 | 954 | is-options@^1.0.1: 955 | version "1.0.1" 956 | resolved "https://registry.yarnpkg.com/is-options/-/is-options-1.0.1.tgz#25b13036030fafca858918124c24048f788be04f" 957 | integrity sha512-2Xj8sA0zDrAcaoWfBiNmc6VPWAgKDpim0T3J9Djq7vbm1UjwbUWzeuLu/FwC46g3cBbAn0E5R0xwVtOobM6Xxg== 958 | 959 | is-stream@^1.1.0: 960 | version "1.1.0" 961 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 962 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= 963 | 964 | is-typedarray@~1.0.0: 965 | version "1.0.0" 966 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 967 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 968 | 969 | isarray@0.0.1: 970 | version "0.0.1" 971 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 972 | integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= 973 | 974 | isarray@~1.0.0: 975 | version "1.0.0" 976 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 977 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 978 | 979 | isexe@^2.0.0: 980 | version "2.0.0" 981 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 982 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 983 | 984 | isstream@~0.1.2: 985 | version "0.1.2" 986 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 987 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= 988 | 989 | js-sha1@^0.6.0: 990 | version "0.6.0" 991 | resolved "https://registry.yarnpkg.com/js-sha1/-/js-sha1-0.6.0.tgz#adbee10f0e8e18aa07cdea807cf08e9183dbc7f9" 992 | integrity sha512-01gwBFreYydzmU9BmZxpVk6svJJHrVxEN3IOiGl6VO93bVKYETJ0sIth6DASI6mIFdt7NmfX9UiByRzsYHGU9w== 993 | 994 | jsbn@~0.1.0: 995 | version "0.1.1" 996 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 997 | integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= 998 | 999 | json-schema-traverse@^0.4.1: 1000 | version "0.4.1" 1001 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 1002 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 1003 | 1004 | json-schema@0.2.3: 1005 | version "0.2.3" 1006 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 1007 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= 1008 | 1009 | json-stringify-safe@~5.0.1: 1010 | version "5.0.1" 1011 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 1012 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 1013 | 1014 | jsonc-parser@^2.0.2: 1015 | version "2.0.2" 1016 | resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.2.tgz#42fcf56d70852a043fadafde51ddb4a85649978d" 1017 | integrity sha512-TSU435K5tEKh3g7bam1AFf+uZrISheoDsLlpmAo6wWZYqjsnd09lHYK1Qo+moK4Ikifev1Gdpa69g4NELKnCrQ== 1018 | 1019 | jsonfile@^4.0.0: 1020 | version "4.0.0" 1021 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 1022 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 1023 | optionalDependencies: 1024 | graceful-fs "^4.1.6" 1025 | 1026 | jsprim@^1.2.2: 1027 | version "1.4.1" 1028 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 1029 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= 1030 | dependencies: 1031 | assert-plus "1.0.0" 1032 | extsprintf "1.3.0" 1033 | json-schema "0.2.3" 1034 | verror "1.10.0" 1035 | 1036 | k-bucket@^5.0.0: 1037 | version "5.0.0" 1038 | resolved "https://registry.yarnpkg.com/k-bucket/-/k-bucket-5.0.0.tgz#ef7a401fcd4c37cd31dceaa6ae4440ca91055e01" 1039 | integrity sha512-r/q+wV/Kde62/tk+rqyttEJn6h0jR7x+incdMVSYTqK73zVxVrzJa70kJL49cIKen8XjIgUZKSvk8ktnrQbK4w== 1040 | dependencies: 1041 | randombytes "^2.0.3" 1042 | 1043 | last-one-wins@^1.0.4: 1044 | version "1.0.4" 1045 | resolved "https://registry.yarnpkg.com/last-one-wins/-/last-one-wins-1.0.4.tgz#c1bfd0cbcb46790ec9156b8d1aee8fcb86cda22a" 1046 | integrity sha1-wb/Qy8tGeQ7JFWuNGu6Py4bNoio= 1047 | 1048 | locate-path@^3.0.0: 1049 | version "3.0.0" 1050 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" 1051 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== 1052 | dependencies: 1053 | p-locate "^3.0.0" 1054 | path-exists "^3.0.0" 1055 | 1056 | locate-path@^5.0.0: 1057 | version "5.0.0" 1058 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" 1059 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== 1060 | dependencies: 1061 | p-locate "^4.1.0" 1062 | 1063 | lodash.assign@^4.2.0: 1064 | version "4.2.0" 1065 | resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" 1066 | integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= 1067 | 1068 | log-symbols@^2.2.0: 1069 | version "2.2.0" 1070 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" 1071 | integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== 1072 | dependencies: 1073 | chalk "^2.0.1" 1074 | 1075 | lru-cache@^4.0.1: 1076 | version "4.1.5" 1077 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" 1078 | integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== 1079 | dependencies: 1080 | pseudomap "^1.0.2" 1081 | yallist "^2.1.2" 1082 | 1083 | memory-pager@^1.0.2: 1084 | version "1.5.0" 1085 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 1086 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== 1087 | 1088 | merkle-tree-stream@^3.0.3: 1089 | version "3.0.3" 1090 | resolved "https://registry.yarnpkg.com/merkle-tree-stream/-/merkle-tree-stream-3.0.3.tgz#f8a064760d37e7978ad5f9f6d3c119a494f57081" 1091 | integrity sha1-+KBkdg0355eK1fn208EZpJT1cIE= 1092 | dependencies: 1093 | flat-tree "^1.3.0" 1094 | readable-stream "^2.0.5" 1095 | 1096 | mime-db@1.44.0: 1097 | version "1.44.0" 1098 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" 1099 | integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== 1100 | 1101 | mime-types@^2.1.12, mime-types@^2.1.24, mime-types@~2.1.19: 1102 | version "2.1.27" 1103 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" 1104 | integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== 1105 | dependencies: 1106 | mime-db "1.44.0" 1107 | 1108 | mimic-fn@^1.0.0: 1109 | version "1.2.0" 1110 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" 1111 | integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== 1112 | 1113 | minimatch@^3.0.3, minimatch@^3.0.4: 1114 | version "3.0.4" 1115 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1116 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 1117 | dependencies: 1118 | brace-expansion "^1.1.7" 1119 | 1120 | minimist@^1.2.5: 1121 | version "1.2.5" 1122 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 1123 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 1124 | 1125 | minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: 1126 | version "2.9.0" 1127 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" 1128 | integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== 1129 | dependencies: 1130 | safe-buffer "^5.1.2" 1131 | yallist "^3.0.0" 1132 | 1133 | minizlib@^1.2.1: 1134 | version "1.3.3" 1135 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" 1136 | integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== 1137 | dependencies: 1138 | minipass "^2.9.0" 1139 | 1140 | mkdirp-classic@^0.5.2: 1141 | version "0.5.3" 1142 | resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" 1143 | integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== 1144 | 1145 | mkdirp@^0.5.0, mkdirp@^0.5.1: 1146 | version "0.5.5" 1147 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 1148 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 1149 | dependencies: 1150 | minimist "^1.2.5" 1151 | 1152 | mkdirp@^1.0.4: 1153 | version "1.0.4" 1154 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 1155 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 1156 | 1157 | ms@2.0.0: 1158 | version "2.0.0" 1159 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1160 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 1161 | 1162 | ms@^2.1.1: 1163 | version "2.1.2" 1164 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1165 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1166 | 1167 | multicast-dns@^7.2.0: 1168 | version "7.2.0" 1169 | resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.0.tgz#7aa49a7efba931a346011aa02e7d1c314a65ac77" 1170 | integrity sha512-Tu2QORGOFANB124NWQ/JTRhMf/ODouVLEuvu5Dz8YWEU55zQgRgFGnBHfIh5PbfNDAuaRl7yLB+pgWhSqVxi2Q== 1171 | dependencies: 1172 | dns-packet "^4.0.0" 1173 | thunky "^1.0.2" 1174 | 1175 | nan@^2.14.0: 1176 | version "2.14.1" 1177 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" 1178 | integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== 1179 | 1180 | nanoassert@^1.0.0, nanoassert@^1.1.0: 1181 | version "1.1.0" 1182 | resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-1.1.0.tgz#4f3152e09540fde28c76f44b19bbcd1d5a42478d" 1183 | integrity sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40= 1184 | 1185 | nanoassert@^2.0.0: 1186 | version "2.0.0" 1187 | resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09" 1188 | integrity sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA== 1189 | 1190 | nanoguard@^1.2.0, nanoguard@^1.2.1: 1191 | version "1.3.0" 1192 | resolved "https://registry.yarnpkg.com/nanoguard/-/nanoguard-1.3.0.tgz#9b38a2a69f30a848f8ed1e4f0dabee8ff506e54c" 1193 | integrity sha512-K/ON5wyflyPyZskdeT3m7Y2gJVkm3QLdKykMCquAbK8A2erstyMpZUc3NG8Nz5jKdfatiYndONrlmLF8+pGl+A== 1194 | 1195 | nanoresource@^1.0.0: 1196 | version "1.2.0" 1197 | resolved "https://registry.yarnpkg.com/nanoresource/-/nanoresource-1.2.0.tgz#59a8bac28a1302179cdce49d95fd3393aa74f5bd" 1198 | integrity sha512-6DJTce5okL9IQlVcswSsrLP4lQER52GkRMHAnkmHQNX1AqpT6VOE8y0MBartHJW3SV0ppC0wy0u4eAK3JARfpA== 1199 | 1200 | nanoresource@^1.3.0: 1201 | version "1.3.0" 1202 | resolved "https://registry.yarnpkg.com/nanoresource/-/nanoresource-1.3.0.tgz#823945d9667ab3e81a8b2591ab8d734552878cd0" 1203 | integrity sha512-OI5dswqipmlYfyL3k/YMm7mbERlh4Bd1KuKdMHpeoVD1iVxqxaTMKleB4qaA2mbQZ6/zMNSxCXv9M9P/YbqTuQ== 1204 | dependencies: 1205 | inherits "^2.0.4" 1206 | 1207 | napi-macros@^1.8.1: 1208 | version "1.8.1" 1209 | resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-1.8.1.tgz#da351d116cd317d85417f7594ce6b206508260eb" 1210 | integrity sha512-lhRfh61ei9CTpDEoaH3+KPS/lrpoKltCKMeqcA1rt/tjUhMICCbnAkcdkZmYs7jpraJ5hizngPIASwjjRsbvUA== 1211 | 1212 | napi-macros@^1.8.2: 1213 | version "1.8.2" 1214 | resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-1.8.2.tgz#299265c1d8aa401351ad0675107d751228c03eda" 1215 | integrity sha512-Tr0DNY4RzTaBG2W2m3l7ZtFuJChTH6VZhXVhkGGjF/4cZTt+i8GcM9ozD+30Lmr4mDoZ5Xx34t2o4GJqYWDGcg== 1216 | 1217 | node-abi@^2.11.0: 1218 | version "2.18.0" 1219 | resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.18.0.tgz#1f5486cfd7d38bd4f5392fa44a4ad4d9a0dffbf4" 1220 | integrity sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw== 1221 | dependencies: 1222 | semver "^5.4.1" 1223 | 1224 | node-gyp-build@^3.5.0: 1225 | version "3.6.0" 1226 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.6.0.tgz#484b229d92e3268bcc3bff6ca333ca15883f23f0" 1227 | integrity sha512-4yfIUBKGAjjsgRI50D1U5RF8zgOn+xfV8qmP9zQ078erdxIX6dOPCRb37Vj0nm1yaONuWAJJcWwSZqrt+Fq/MA== 1228 | 1229 | node-gyp-build@^3.8.0: 1230 | version "3.9.0" 1231 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.9.0.tgz#53a350187dd4d5276750da21605d1cb681d09e25" 1232 | integrity sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A== 1233 | 1234 | node-gyp-build@^4.1.0: 1235 | version "4.2.2" 1236 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.2.tgz#3f44b65adaafd42fb6c3d81afd630e45c847eb66" 1237 | integrity sha512-Lqh7mrByWCM8Cf9UPqpeoVBBo5Ugx+RKu885GAzmLBVYjeywScxHXPGLa4JfYNZmcNGwzR0Glu5/9GaQZMFqyA== 1238 | 1239 | node-gyp@^6.0.1: 1240 | version "6.1.0" 1241 | resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-6.1.0.tgz#64e31c61a4695ad304c1d5b82cf6b7c79cc79f3f" 1242 | integrity sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw== 1243 | dependencies: 1244 | env-paths "^2.2.0" 1245 | glob "^7.1.4" 1246 | graceful-fs "^4.2.2" 1247 | mkdirp "^0.5.1" 1248 | nopt "^4.0.1" 1249 | npmlog "^4.1.2" 1250 | request "^2.88.0" 1251 | rimraf "^2.6.3" 1252 | semver "^5.7.1" 1253 | tar "^4.4.12" 1254 | which "^1.3.1" 1255 | 1256 | noise-peer@^1.1.0: 1257 | version "1.1.0" 1258 | resolved "https://registry.yarnpkg.com/noise-peer/-/noise-peer-1.1.0.tgz#4ef5807a466112e9f89f2f395082ecf9129107dd" 1259 | integrity sha512-dzsc5/WxArnPK46aFx9OstdTDKPr7HkfPKQFsI5hL17hfLgblZsP1sZFxxr9tna1Debq4+HxK/17bXLUow+hxw== 1260 | dependencies: 1261 | readable-stream "^3.0.6" 1262 | secretstream-stream "^1.2.1" 1263 | simple-handshake "^1.2.0" 1264 | sodium-universal "^2.0.0" 1265 | 1266 | noise-protocol@^1.0.0: 1267 | version "1.0.0" 1268 | resolved "https://registry.yarnpkg.com/noise-protocol/-/noise-protocol-1.0.0.tgz#260e0447ddabc6f1d40f4c5829a64aba38c08768" 1269 | integrity sha512-MEseV3jGZGkPPlhJMHrjFHs9XCEcnoYg72hI89GMz/JfDjWEHzhTaTGqHM5gTGtLA9Z04XoGvEI5aCEAqplQrQ== 1270 | dependencies: 1271 | clone "^2.1.2" 1272 | hmac-blake2b "^0.2.0" 1273 | nanoassert "^1.1.0" 1274 | sodium-native "^2.2.1" 1275 | 1276 | noms@0.0.0: 1277 | version "0.0.0" 1278 | resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859" 1279 | integrity sha1-2o69nzr51nYJGbJ9nNyAkqczKFk= 1280 | dependencies: 1281 | inherits "^2.0.1" 1282 | readable-stream "~1.0.31" 1283 | 1284 | nopt@^4.0.1: 1285 | version "4.0.3" 1286 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" 1287 | integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== 1288 | dependencies: 1289 | abbrev "1" 1290 | osenv "^0.1.4" 1291 | 1292 | npm-run-path@^2.0.0: 1293 | version "2.0.2" 1294 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" 1295 | integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= 1296 | dependencies: 1297 | path-key "^2.0.0" 1298 | 1299 | npmlog@^4.1.2: 1300 | version "4.1.2" 1301 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 1302 | integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== 1303 | dependencies: 1304 | are-we-there-yet "~1.1.2" 1305 | console-control-strings "~1.1.0" 1306 | gauge "~2.7.3" 1307 | set-blocking "~2.0.0" 1308 | 1309 | number-is-nan@^1.0.0: 1310 | version "1.0.1" 1311 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 1312 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 1313 | 1314 | oauth-sign@~0.9.0: 1315 | version "0.9.0" 1316 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 1317 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== 1318 | 1319 | object-assign@^4.1.0: 1320 | version "4.1.1" 1321 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1322 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 1323 | 1324 | "odiff@github:inkandswitch/odiff": 1325 | version "1.4.0" 1326 | resolved "https://codeload.github.com/inkandswitch/odiff/tar.gz/4d51dd3214095d85db305fc4d1d0bfba54e6fb0f" 1327 | 1328 | once@^1.3.0, once@^1.3.1, once@^1.4.0: 1329 | version "1.4.0" 1330 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1331 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1332 | dependencies: 1333 | wrappy "1" 1334 | 1335 | onetime@^2.0.0: 1336 | version "2.0.1" 1337 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" 1338 | integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= 1339 | dependencies: 1340 | mimic-fn "^1.0.0" 1341 | 1342 | ora@^3.4.0: 1343 | version "3.4.0" 1344 | resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" 1345 | integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== 1346 | dependencies: 1347 | chalk "^2.4.2" 1348 | cli-cursor "^2.1.0" 1349 | cli-spinners "^2.0.0" 1350 | log-symbols "^2.2.0" 1351 | strip-ansi "^5.2.0" 1352 | wcwidth "^1.0.1" 1353 | 1354 | os-homedir@^1.0.0: 1355 | version "1.0.2" 1356 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1357 | integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= 1358 | 1359 | os-tmpdir@^1.0.0: 1360 | version "1.0.2" 1361 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 1362 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 1363 | 1364 | osenv@^0.1.4: 1365 | version "0.1.5" 1366 | resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 1367 | integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== 1368 | dependencies: 1369 | os-homedir "^1.0.0" 1370 | os-tmpdir "^1.0.0" 1371 | 1372 | p-finally@^1.0.0: 1373 | version "1.0.0" 1374 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" 1375 | integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= 1376 | 1377 | p-limit@^2.0.0, p-limit@^2.2.0: 1378 | version "2.3.0" 1379 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" 1380 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== 1381 | dependencies: 1382 | p-try "^2.0.0" 1383 | 1384 | p-locate@^3.0.0: 1385 | version "3.0.0" 1386 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" 1387 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== 1388 | dependencies: 1389 | p-limit "^2.0.0" 1390 | 1391 | p-locate@^4.1.0: 1392 | version "4.1.0" 1393 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" 1394 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== 1395 | dependencies: 1396 | p-limit "^2.2.0" 1397 | 1398 | p-try@^2.0.0: 1399 | version "2.2.0" 1400 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 1401 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 1402 | 1403 | path-exists@^3.0.0: 1404 | version "3.0.0" 1405 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 1406 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= 1407 | 1408 | path-exists@^4.0.0: 1409 | version "4.0.0" 1410 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1411 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1412 | 1413 | path-is-absolute@^1.0.0: 1414 | version "1.0.1" 1415 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1416 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1417 | 1418 | path-key@^2.0.0: 1419 | version "2.0.1" 1420 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 1421 | integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= 1422 | 1423 | performance-now@^2.1.0: 1424 | version "2.1.0" 1425 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 1426 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= 1427 | 1428 | prettier@^1.16.1: 1429 | version "1.16.1" 1430 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.1.tgz#534c2c9d7853f8845e5e078384e71973bd74089f" 1431 | integrity sha512-XXUITwIkGb3CPJ2hforHah/zTINRyie5006Jd2HKy2qz7snEJXl0KLfsJZW/wst9g6R2rFvqba3VpNYdu1hDcA== 1432 | 1433 | pretty-bytes@^5.1.0: 1434 | version "5.1.0" 1435 | resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.1.0.tgz#6237ecfbdc6525beaef4de722cc60a58ae0e6c6d" 1436 | integrity sha512-wa5+qGVg9Yt7PB6rYm3kXlKzgzgivYTLRandezh43jjRqgyDyP+9YxfJpJiLs9yKD1WeU8/OvtToWpW7255FtA== 1437 | 1438 | pretty-hash@^1.0.1: 1439 | version "1.0.1" 1440 | resolved "https://registry.yarnpkg.com/pretty-hash/-/pretty-hash-1.0.1.tgz#16e0579188def56bdb565892bcd05a5d65324807" 1441 | integrity sha1-FuBXkYje9WvbVliSvNBaXWUySAc= 1442 | 1443 | process-nextick-args@~2.0.0: 1444 | version "2.0.1" 1445 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 1446 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 1447 | 1448 | proper-lockfile@^4.1.1: 1449 | version "4.1.1" 1450 | resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.1.tgz#284cf9db9e30a90e647afad69deb7cb06881262c" 1451 | integrity sha512-1w6rxXodisVpn7QYvLk706mzprPTAPCYAqxMvctmPN3ekuRk/kuGkGc82pangZiAt4R3lwSuUzheTTn0/Yb7Zg== 1452 | dependencies: 1453 | graceful-fs "^4.1.11" 1454 | retry "^0.12.0" 1455 | signal-exit "^3.0.2" 1456 | 1457 | protocol-buffers-encodings@^1.1.0: 1458 | version "1.1.0" 1459 | resolved "https://registry.yarnpkg.com/protocol-buffers-encodings/-/protocol-buffers-encodings-1.1.0.tgz#f3905631106669b85381bad47a336add7d206873" 1460 | integrity sha512-SmjEuAf3hc3h3rWZ6V1YaaQw2MNJWK848gLJgzx/sefOJdNLujKinJVXIS0q2cBQpQn2Q32TinawZyDZPzm4kQ== 1461 | dependencies: 1462 | signed-varint "^2.0.1" 1463 | varint "^5.0.0" 1464 | 1465 | pseudomap@^1.0.2: 1466 | version "1.0.2" 1467 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 1468 | integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= 1469 | 1470 | psl@^1.1.28: 1471 | version "1.8.0" 1472 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" 1473 | integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== 1474 | 1475 | pump@^3.0.0: 1476 | version "3.0.0" 1477 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 1478 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 1479 | dependencies: 1480 | end-of-stream "^1.1.0" 1481 | once "^1.3.1" 1482 | 1483 | punycode@^2.1.0, punycode@^2.1.1: 1484 | version "2.1.1" 1485 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 1486 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1487 | 1488 | qs@~6.5.2: 1489 | version "6.5.2" 1490 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 1491 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 1492 | 1493 | random-access-file@^2.0.1: 1494 | version "2.0.1" 1495 | resolved "https://registry.yarnpkg.com/random-access-file/-/random-access-file-2.0.1.tgz#dc22de79270e9a84cb36a2419b759725930dcaeb" 1496 | integrity sha512-nb4fClpzoUY+v1SHrro+9yykN90eMA1rc+xM39tnZ5R3BgFY+J/NxPZ0KuUpishEsvnwou9Fvm2wa3cjeuG7vg== 1497 | dependencies: 1498 | mkdirp "^0.5.1" 1499 | random-access-storage "^1.1.1" 1500 | 1501 | random-access-file@^2.1.0, random-access-file@^2.1.3: 1502 | version "2.1.4" 1503 | resolved "https://registry.yarnpkg.com/random-access-file/-/random-access-file-2.1.4.tgz#d783e9082d08094c08c6f3dd481f37b2079709dc" 1504 | integrity sha512-WAcBP5iLhg1pbjZA40WyMenjK7c5gJUY6Pi5HJ3fLJCeVFNSZv3juf20yFMKxBdvcX5GKbX/HZSfFzlLBdGTdQ== 1505 | dependencies: 1506 | mkdirp-classic "^0.5.2" 1507 | random-access-storage "^1.1.1" 1508 | 1509 | random-access-memory@^3.0.0: 1510 | version "3.1.1" 1511 | resolved "https://registry.yarnpkg.com/random-access-memory/-/random-access-memory-3.1.1.tgz#cb8516663a8a294b719c8363a6517c1dcb3e8392" 1512 | integrity sha512-Qy1MliJDozZ1A6Hx3UbEnm8PPCfkiG/8CArbnhrxXMx1YRJPWipgPTB9qyhn4Z7WlLvCEqPb6Bd98OayyVuwrA== 1513 | dependencies: 1514 | inherits "^2.0.3" 1515 | is-options "^1.0.1" 1516 | random-access-storage "^1.1.1" 1517 | 1518 | random-access-storage@^1.1.1: 1519 | version "1.4.1" 1520 | resolved "https://registry.yarnpkg.com/random-access-storage/-/random-access-storage-1.4.1.tgz#39a524dd428ade9161ce61a8ae677766e6117ffb" 1521 | integrity sha512-DbCc2TIzOxPaHF6KCbr8zLtiYOJQQQCBHUVNHV/SckUQobCBB2YkDtbLdxGnPwPNpJfEyMWxDAm36A2xkbxxtw== 1522 | dependencies: 1523 | inherits "^2.0.3" 1524 | 1525 | randombytes@^2.0.3: 1526 | version "2.1.0" 1527 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 1528 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 1529 | dependencies: 1530 | safe-buffer "^5.1.0" 1531 | 1532 | readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@~2.3.6: 1533 | version "2.3.7" 1534 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 1535 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 1536 | dependencies: 1537 | core-util-is "~1.0.0" 1538 | inherits "~2.0.3" 1539 | isarray "~1.0.0" 1540 | process-nextick-args "~2.0.0" 1541 | safe-buffer "~5.1.1" 1542 | string_decoder "~1.1.1" 1543 | util-deprecate "~1.0.1" 1544 | 1545 | readable-stream@^3.0.2: 1546 | version "3.0.6" 1547 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a" 1548 | integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg== 1549 | dependencies: 1550 | inherits "^2.0.3" 1551 | string_decoder "^1.1.1" 1552 | util-deprecate "^1.0.1" 1553 | 1554 | readable-stream@^3.0.6: 1555 | version "3.6.0" 1556 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 1557 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 1558 | dependencies: 1559 | inherits "^2.0.3" 1560 | string_decoder "^1.1.1" 1561 | util-deprecate "^1.0.1" 1562 | 1563 | readable-stream@~1.0.31: 1564 | version "1.0.34" 1565 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" 1566 | integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= 1567 | dependencies: 1568 | core-util-is "~1.0.0" 1569 | inherits "~2.0.1" 1570 | isarray "0.0.1" 1571 | string_decoder "~0.10.x" 1572 | 1573 | record-cache@^1.1.0: 1574 | version "1.1.0" 1575 | resolved "https://registry.yarnpkg.com/record-cache/-/record-cache-1.1.0.tgz#f8a467a691a469584b26e88d36b18afdb3932037" 1576 | integrity sha512-u8rbtLEJV7HRacl/ZYwSBFD8NFyB3PfTTfGLP37IW3hftQCwu6z4Q2RLyxo1YJUNRTEzJfpLpGwVuEYdaIkG9Q== 1577 | 1578 | request@^2.88.0: 1579 | version "2.88.2" 1580 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" 1581 | integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== 1582 | dependencies: 1583 | aws-sign2 "~0.7.0" 1584 | aws4 "^1.8.0" 1585 | caseless "~0.12.0" 1586 | combined-stream "~1.0.6" 1587 | extend "~3.0.2" 1588 | forever-agent "~0.6.1" 1589 | form-data "~2.3.2" 1590 | har-validator "~5.1.3" 1591 | http-signature "~1.2.0" 1592 | is-typedarray "~1.0.0" 1593 | isstream "~0.1.2" 1594 | json-stringify-safe "~5.0.1" 1595 | mime-types "~2.1.19" 1596 | oauth-sign "~0.9.0" 1597 | performance-now "^2.1.0" 1598 | qs "~6.5.2" 1599 | safe-buffer "^5.1.2" 1600 | tough-cookie "~2.5.0" 1601 | tunnel-agent "^0.6.0" 1602 | uuid "^3.3.2" 1603 | 1604 | require-directory@^2.1.1: 1605 | version "2.1.1" 1606 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1607 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 1608 | 1609 | require-main-filename@^2.0.0: 1610 | version "2.0.0" 1611 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 1612 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 1613 | 1614 | restore-cursor@^2.0.0: 1615 | version "2.0.0" 1616 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" 1617 | integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= 1618 | dependencies: 1619 | onetime "^2.0.0" 1620 | signal-exit "^3.0.2" 1621 | 1622 | retry@^0.12.0: 1623 | version "0.12.0" 1624 | resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" 1625 | integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= 1626 | 1627 | rimraf@^2.6.3: 1628 | version "2.7.1" 1629 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" 1630 | integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== 1631 | dependencies: 1632 | glob "^7.1.3" 1633 | 1634 | rxjs@^6.3.1: 1635 | version "6.5.5" 1636 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" 1637 | integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== 1638 | dependencies: 1639 | tslib "^1.9.0" 1640 | 1641 | safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: 1642 | version "5.2.1" 1643 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1644 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1645 | 1646 | safe-buffer@^5.1.0, safe-buffer@^5.1.1: 1647 | version "5.2.0" 1648 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 1649 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== 1650 | 1651 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1652 | version "5.1.2" 1653 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1654 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 1655 | 1656 | safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 1657 | version "2.1.2" 1658 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1659 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 1660 | 1661 | secretstream-stream@^1.2.1: 1662 | version "1.2.1" 1663 | resolved "https://registry.yarnpkg.com/secretstream-stream/-/secretstream-stream-1.2.1.tgz#34a5d7111f5c9a4658a0868c3679408690031f94" 1664 | integrity sha512-mAfqXrNMRQZ60xkj3O32buVUVSgg/S2hEeMpDsIN8vZwG1BXOL+Z0NlAyLad4YNkLlEXiiLOzxDNi17rOiSwKg== 1665 | dependencies: 1666 | nanoassert "^1.1.0" 1667 | sodium-native "^2.1.4" 1668 | 1669 | semver@^5.4.1, semver@^5.7.1: 1670 | version "5.7.1" 1671 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 1672 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 1673 | 1674 | set-blocking@^2.0.0, set-blocking@~2.0.0: 1675 | version "2.0.0" 1676 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 1677 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 1678 | 1679 | shebang-command@^1.2.0: 1680 | version "1.2.0" 1681 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 1682 | integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= 1683 | dependencies: 1684 | shebang-regex "^1.0.0" 1685 | 1686 | shebang-regex@^1.0.0: 1687 | version "1.0.0" 1688 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 1689 | integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= 1690 | 1691 | shuffled-priority-queue@^2.1.0: 1692 | version "2.1.0" 1693 | resolved "https://registry.yarnpkg.com/shuffled-priority-queue/-/shuffled-priority-queue-2.1.0.tgz#432bf14dd90f7c4dd1705752d81aadf454fd3af6" 1694 | integrity sha512-xhdh7fHyMsr0m/w2kDfRJuBFRS96b9l8ZPNWGaQ+PMvnUnZ/Eh+gJJ9NsHBd7P9k0399WYlCLzsy18EaMfyadA== 1695 | dependencies: 1696 | unordered-set "^2.0.1" 1697 | 1698 | signal-exit@^3.0.0, signal-exit@^3.0.2: 1699 | version "3.0.3" 1700 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" 1701 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== 1702 | 1703 | signed-varint@^2.0.1: 1704 | version "2.0.1" 1705 | resolved "https://registry.yarnpkg.com/signed-varint/-/signed-varint-2.0.1.tgz#50a9989da7c98c2c61dad119bc97470ef8528129" 1706 | integrity sha1-UKmYnafJjCxh2tEZvJdHDvhSgSk= 1707 | dependencies: 1708 | varint "~5.0.0" 1709 | 1710 | simple-handshake@^1.2.0, simple-handshake@^1.3.1: 1711 | version "1.3.1" 1712 | resolved "https://registry.yarnpkg.com/simple-handshake/-/simple-handshake-1.3.1.tgz#3f3d3ef103cb59e25f85c6b5952a631659e53411" 1713 | integrity sha512-3Q6FjXdVFCa5JiLsWFl9s/Wp9hfBI9OqGfnlA/fUqIgR8M6zykFMxgGmV7M3YFbBkXYXQYayj6D6aFDejQcPjA== 1714 | dependencies: 1715 | nanoassert "^1.1.0" 1716 | noise-protocol "^1.0.0" 1717 | 1718 | simple-hypercore-protocol@^1.4.0: 1719 | version "1.5.0" 1720 | resolved "https://registry.yarnpkg.com/simple-hypercore-protocol/-/simple-hypercore-protocol-1.5.0.tgz#8e03961f015b67e138d42e84ef12d4f20e702d37" 1721 | integrity sha512-HEweK2xilxAZ2RjDg770xDKPbKwvIR9OUTRtFLHsepFYiyfFxAoZkUxFkJQMTav935P8ompf6npnIie+d/8Dsw== 1722 | dependencies: 1723 | protocol-buffers-encodings "^1.1.0" 1724 | simple-handshake "^1.3.1" 1725 | simple-message-channels "^1.2.1" 1726 | sodium-universal "^2.0.0" 1727 | varint "^5.0.0" 1728 | 1729 | simple-message-channels@^1.2.1: 1730 | version "1.2.1" 1731 | resolved "https://registry.yarnpkg.com/simple-message-channels/-/simple-message-channels-1.2.1.tgz#d827d3da0df1f862fd09b748457a01f9a0eb7ac3" 1732 | integrity sha512-knSr69GKW9sCjzpoy817xQelpOASUQ53TXCBcSLDKLE7GTGpUAhZzOZYrdbX2Ig//m+8AIrNp7sM7HDNHBRzXw== 1733 | dependencies: 1734 | varint "^5.0.0" 1735 | 1736 | siphash24@^1.0.1: 1737 | version "1.1.1" 1738 | resolved "https://registry.yarnpkg.com/siphash24/-/siphash24-1.1.1.tgz#94ad021a2b2c62de381b546ee02df0cf778acd50" 1739 | integrity sha512-dKKwjIoTOa587TARYLlBRXq2lkbu5Iz35XrEVWpelhBP1m8r2BGOy1QlaZe84GTFHG/BTucEUd2btnNc8QzIVA== 1740 | dependencies: 1741 | nanoassert "^1.0.0" 1742 | 1743 | sodium-javascript@~0.5.0: 1744 | version "0.5.6" 1745 | resolved "https://registry.yarnpkg.com/sodium-javascript/-/sodium-javascript-0.5.6.tgz#748680f9bf0e33433d78660543afaeeec28ea199" 1746 | integrity sha512-Uk+JpqHEbzsEmiMxwL7TB/ndhMEpc52KdReYXXSIX2oRFPaI7ZDlDImF8KbkFWbYl9BJRtc82AZ/kNf4/0n9KA== 1747 | dependencies: 1748 | blake2b "^2.1.1" 1749 | nanoassert "^1.0.0" 1750 | siphash24 "^1.0.1" 1751 | xsalsa20 "^1.0.0" 1752 | 1753 | sodium-native@^2.0.0, sodium-native@^2.1.4, sodium-native@^2.2.1, sodium-native@^2.4.6: 1754 | version "2.4.9" 1755 | resolved "https://registry.yarnpkg.com/sodium-native/-/sodium-native-2.4.9.tgz#7a7beb997efdbd2c773a385fb959f0cead5f5162" 1756 | integrity sha512-mbkiyA2clyfwAyOFIzMvsV6ny2KrKEIhFVASJxWfsmgfUEymgLIS2MLHHcGIQMkrcKhPErRaMR5Dzv0EEn+BWg== 1757 | dependencies: 1758 | ini "^1.3.5" 1759 | nan "^2.14.0" 1760 | node-gyp-build "^4.1.0" 1761 | 1762 | sodium-universal@^2.0.0: 1763 | version "2.0.0" 1764 | resolved "https://registry.yarnpkg.com/sodium-universal/-/sodium-universal-2.0.0.tgz#cfb4e1a9c4afece4382b2c23c53439b443bd2af3" 1765 | integrity sha512-csdVyakzHJRyCevY4aZC2Eacda8paf+4nmRGF2N7KxCLKY2Ajn72JsExaQlJQ2BiXJncp44p3T+b80cU+2TTsg== 1766 | dependencies: 1767 | sodium-javascript "~0.5.0" 1768 | optionalDependencies: 1769 | sodium-native "^2.0.0" 1770 | 1771 | sparse-bitfield@^3.0.0: 1772 | version "3.0.3" 1773 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 1774 | integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= 1775 | dependencies: 1776 | memory-pager "^1.0.2" 1777 | 1778 | spawn-rx@^3.0.0: 1779 | version "3.0.0" 1780 | resolved "https://registry.yarnpkg.com/spawn-rx/-/spawn-rx-3.0.0.tgz#1d33511e13ec26337da51d78630e08beb57a6767" 1781 | integrity sha512-dw4Ryg/KMNfkKa5ezAR5aZe9wNwPdKlnHEXtHOjVnyEDSPQyOpIPPRtcIiu7127SmtHhaCjw21yC43HliW0iIg== 1782 | dependencies: 1783 | debug "^2.5.1" 1784 | lodash.assign "^4.2.0" 1785 | rxjs "^6.3.1" 1786 | 1787 | sshpk@^1.7.0: 1788 | version "1.16.1" 1789 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" 1790 | integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== 1791 | dependencies: 1792 | asn1 "~0.2.3" 1793 | assert-plus "^1.0.0" 1794 | bcrypt-pbkdf "^1.0.0" 1795 | dashdash "^1.12.0" 1796 | ecc-jsbn "~0.1.1" 1797 | getpass "^0.1.1" 1798 | jsbn "~0.1.0" 1799 | safer-buffer "^2.0.2" 1800 | tweetnacl "~0.14.0" 1801 | 1802 | stream-collector@^1.0.1: 1803 | version "1.0.1" 1804 | resolved "https://registry.yarnpkg.com/stream-collector/-/stream-collector-1.0.1.tgz#4d4e55f171356121b2c5f6559f944705ab28db15" 1805 | integrity sha1-TU5V8XE1YSGyxfZVn5RHBaso2xU= 1806 | dependencies: 1807 | once "^1.3.1" 1808 | 1809 | streamx@^2.1.0, streamx@^2.5.0: 1810 | version "2.6.3" 1811 | resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.6.3.tgz#0331675a9c96211e9cc226b622cf21a0732e83d5" 1812 | integrity sha512-GF1TU5hNN0EabSgEoGGSzxwQ7ah+cp8YC1S8c9j3xizy55DHfu7xh0mbXw2w55EABfx38MNfz8oN3ldw6RxN2Q== 1813 | dependencies: 1814 | fast-fifo "^1.0.0" 1815 | nanoassert "^2.0.0" 1816 | 1817 | string-width@^1.0.1: 1818 | version "1.0.2" 1819 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 1820 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 1821 | dependencies: 1822 | code-point-at "^1.0.0" 1823 | is-fullwidth-code-point "^1.0.0" 1824 | strip-ansi "^3.0.0" 1825 | 1826 | "string-width@^1.0.2 || 2": 1827 | version "2.1.1" 1828 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 1829 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 1830 | dependencies: 1831 | is-fullwidth-code-point "^2.0.0" 1832 | strip-ansi "^4.0.0" 1833 | 1834 | string-width@^3.0.0, string-width@^3.1.0: 1835 | version "3.1.0" 1836 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 1837 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 1838 | dependencies: 1839 | emoji-regex "^7.0.1" 1840 | is-fullwidth-code-point "^2.0.0" 1841 | strip-ansi "^5.1.0" 1842 | 1843 | string-width@^4.1.0, string-width@^4.2.0: 1844 | version "4.2.0" 1845 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" 1846 | integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== 1847 | dependencies: 1848 | emoji-regex "^8.0.0" 1849 | is-fullwidth-code-point "^3.0.0" 1850 | strip-ansi "^6.0.0" 1851 | 1852 | string_decoder@^1.1.1: 1853 | version "1.3.0" 1854 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1855 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1856 | dependencies: 1857 | safe-buffer "~5.2.0" 1858 | 1859 | string_decoder@~0.10.x: 1860 | version "0.10.31" 1861 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 1862 | integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= 1863 | 1864 | string_decoder@~1.1.1: 1865 | version "1.1.1" 1866 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1867 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 1868 | dependencies: 1869 | safe-buffer "~5.1.0" 1870 | 1871 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 1872 | version "3.0.1" 1873 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1874 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 1875 | dependencies: 1876 | ansi-regex "^2.0.0" 1877 | 1878 | strip-ansi@^4.0.0: 1879 | version "4.0.0" 1880 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 1881 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 1882 | dependencies: 1883 | ansi-regex "^3.0.0" 1884 | 1885 | strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: 1886 | version "5.2.0" 1887 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 1888 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 1889 | dependencies: 1890 | ansi-regex "^4.1.0" 1891 | 1892 | strip-ansi@^6.0.0: 1893 | version "6.0.0" 1894 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 1895 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 1896 | dependencies: 1897 | ansi-regex "^5.0.0" 1898 | 1899 | strip-eof@^1.0.0: 1900 | version "1.0.0" 1901 | resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" 1902 | integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= 1903 | 1904 | supports-color@^5.3.0: 1905 | version "5.5.0" 1906 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1907 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1908 | dependencies: 1909 | has-flag "^3.0.0" 1910 | 1911 | tar@^4.4.10, tar@^4.4.12: 1912 | version "4.4.13" 1913 | resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" 1914 | integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== 1915 | dependencies: 1916 | chownr "^1.1.1" 1917 | fs-minipass "^1.2.5" 1918 | minipass "^2.8.6" 1919 | minizlib "^1.2.1" 1920 | mkdirp "^0.5.0" 1921 | safe-buffer "^5.1.2" 1922 | yallist "^3.0.3" 1923 | 1924 | through2@^2.0.1: 1925 | version "2.0.5" 1926 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" 1927 | integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== 1928 | dependencies: 1929 | readable-stream "~2.3.6" 1930 | xtend "~4.0.1" 1931 | 1932 | thunky@^1.0.2: 1933 | version "1.1.0" 1934 | resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" 1935 | integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== 1936 | 1937 | time-ordered-set@^1.0.1: 1938 | version "1.0.2" 1939 | resolved "https://registry.yarnpkg.com/time-ordered-set/-/time-ordered-set-1.0.2.tgz#3bd931fc048234147f8c2b8b1ebbebb0a3ecb96f" 1940 | integrity sha512-vGO99JkxvgX+u+LtOKQEpYf31Kj3i/GNwVstfnh4dyINakMgeZCpew1e3Aj+06hEslhtHEd52g7m5IV+o1K8Mw== 1941 | 1942 | timeout-refresh@^1.0.0, timeout-refresh@^1.0.1: 1943 | version "1.0.2" 1944 | resolved "https://registry.yarnpkg.com/timeout-refresh/-/timeout-refresh-1.0.2.tgz#3fee27c3543f96268816fb68a8cec132be239693" 1945 | integrity sha512-lsO23gD/EeW53AvEoTOleUFqTIapZTu5NPzD6ndUGs0+G1IuN0+hu2kT6I3AmNX2fiOrcC6umtzMEv1XQmajgQ== 1946 | 1947 | tough-cookie@~2.5.0: 1948 | version "2.5.0" 1949 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" 1950 | integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== 1951 | dependencies: 1952 | psl "^1.1.28" 1953 | punycode "^2.1.1" 1954 | 1955 | transit-immutable-js@^0.7.0: 1956 | version "0.7.0" 1957 | resolved "https://registry.yarnpkg.com/transit-immutable-js/-/transit-immutable-js-0.7.0.tgz#993e25089b6311ff402140f556276d6d253005d9" 1958 | integrity sha1-mT4lCJtjEf9AIUD1VidtbSUwBdk= 1959 | 1960 | transit-js@^0.8.861: 1961 | version "0.8.861" 1962 | resolved "https://registry.yarnpkg.com/transit-js/-/transit-js-0.8.861.tgz#829e516b80349a41fff5d59f5e6993b5473f72c9" 1963 | integrity sha512-4O9OrYPZw6C0M5gMTvaeOp+xYz6EF79JsyxIvqXHlt+pisSrioJWFOE80N8aCPoJLcNaXF442RZrVtdmd4wkDQ== 1964 | 1965 | tslib@^1.9.0: 1966 | version "1.13.0" 1967 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" 1968 | integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== 1969 | 1970 | tunnel-agent@^0.6.0: 1971 | version "0.6.0" 1972 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 1973 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 1974 | dependencies: 1975 | safe-buffer "^5.0.1" 1976 | 1977 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 1978 | version "0.14.5" 1979 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 1980 | integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= 1981 | 1982 | typescript@^3.1.4: 1983 | version "3.9.7" 1984 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" 1985 | integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== 1986 | 1987 | uint64be@^2.0.1, uint64be@^2.0.2: 1988 | version "2.0.2" 1989 | resolved "https://registry.yarnpkg.com/uint64be/-/uint64be-2.0.2.tgz#ef4a179752fe8f9ddaa29544ecfc13490031e8e5" 1990 | integrity sha512-9QqdvpGQTXgxthP+lY4e/gIBy+RuqcBaC6JVwT5I3bDLgT/btL6twZMR0pI3/Fgah9G/pdwzIprE5gL6v9UvyQ== 1991 | dependencies: 1992 | buffer-alloc "^1.1.0" 1993 | 1994 | universalify@^0.1.0: 1995 | version "0.1.2" 1996 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" 1997 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 1998 | 1999 | unordered-array-remove@^1.0.2: 2000 | version "1.0.2" 2001 | resolved "https://registry.yarnpkg.com/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz#c546e8f88e317a0cf2644c97ecb57dba66d250ef" 2002 | integrity sha1-xUbo+I4xegzyZEyX7LV9umbSUO8= 2003 | 2004 | unordered-set@^2.0.0, unordered-set@^2.0.1: 2005 | version "2.0.1" 2006 | resolved "https://registry.yarnpkg.com/unordered-set/-/unordered-set-2.0.1.tgz#4cd0fe27b8814bcf5d6073e5f0966ec7a50841e6" 2007 | integrity sha512-eUmNTPzdx+q/WvOHW0bgGYLWvWHNT3PTKEQLg0MAQhc0AHASHVHoP/9YytYd4RBVariqno/mEUhVZN98CmD7bg== 2008 | 2009 | uri-js@^4.2.2: 2010 | version "4.2.2" 2011 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" 2012 | integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== 2013 | dependencies: 2014 | punycode "^2.1.0" 2015 | 2016 | util-deprecate@^1.0.1, util-deprecate@~1.0.1: 2017 | version "1.0.2" 2018 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 2019 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 2020 | 2021 | utp-native@^2.1.3: 2022 | version "2.1.3" 2023 | resolved "https://registry.yarnpkg.com/utp-native/-/utp-native-2.1.3.tgz#139f8724a171091aa3f8be580ccce1174ee252f2" 2024 | integrity sha512-lXjmAJxlaz58GDFlEqKYkNzO5rqttA+/TVHl7UUAs8Saj1QJq/3D4IckuVpsmCsjjZod5N7sE8QMUCYScVHDpg== 2025 | dependencies: 2026 | napi-macros "^1.8.1" 2027 | node-gyp-build "^3.5.0" 2028 | readable-stream "^3.0.2" 2029 | timeout-refresh "^1.0.0" 2030 | unordered-set "^2.0.1" 2031 | 2032 | utp-native@^2.1.4: 2033 | version "2.1.4" 2034 | resolved "https://registry.yarnpkg.com/utp-native/-/utp-native-2.1.4.tgz#fa7063d143c690e65064317fe17f8829dabfa3ce" 2035 | integrity sha512-FYjr3bHBnJpw8yD0CmFCh5USyDgr6VtuncEIun100GqCUdgqnkAx9irSY3tA4UrzRH56qmiocP2fs1QjQ7ZDZA== 2036 | dependencies: 2037 | napi-macros "^1.8.1" 2038 | node-gyp-build "^3.5.0" 2039 | readable-stream "^3.0.2" 2040 | timeout-refresh "^1.0.0" 2041 | unordered-set "^2.0.1" 2042 | 2043 | uuid@3.1.0: 2044 | version "3.1.0" 2045 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" 2046 | integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== 2047 | 2048 | uuid@3.3.2: 2049 | version "3.3.2" 2050 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" 2051 | integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== 2052 | 2053 | uuid@^3.3.2, uuid@^3.3.3: 2054 | version "3.4.0" 2055 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 2056 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 2057 | 2058 | varint@^4.0.0: 2059 | version "4.0.1" 2060 | resolved "https://registry.yarnpkg.com/varint/-/varint-4.0.1.tgz#490829b942d248463b2b35097995c3bf737198e9" 2061 | integrity sha1-SQgpuULSSEY7KzUJeZXDv3NxmOk= 2062 | 2063 | varint@^5.0.0, varint@~5.0.0: 2064 | version "5.0.0" 2065 | resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.0.tgz#d826b89f7490732fabc0c0ed693ed475dcb29ebf" 2066 | integrity sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8= 2067 | 2068 | verror@1.10.0: 2069 | version "1.10.0" 2070 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 2071 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= 2072 | dependencies: 2073 | assert-plus "^1.0.0" 2074 | core-util-is "1.0.2" 2075 | extsprintf "^1.2.0" 2076 | 2077 | wcwidth@^1.0.1: 2078 | version "1.0.1" 2079 | resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" 2080 | integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= 2081 | dependencies: 2082 | defaults "^1.0.3" 2083 | 2084 | which-module@^2.0.0: 2085 | version "2.0.0" 2086 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 2087 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 2088 | 2089 | which@^1.2.9, which@^1.3.1: 2090 | version "1.3.1" 2091 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 2092 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 2093 | dependencies: 2094 | isexe "^2.0.0" 2095 | 2096 | wide-align@^1.1.0: 2097 | version "1.1.3" 2098 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 2099 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 2100 | dependencies: 2101 | string-width "^1.0.2 || 2" 2102 | 2103 | wrap-ansi@^5.1.0: 2104 | version "5.1.0" 2105 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" 2106 | integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== 2107 | dependencies: 2108 | ansi-styles "^3.2.0" 2109 | string-width "^3.0.0" 2110 | strip-ansi "^5.0.0" 2111 | 2112 | wrap-ansi@^6.2.0: 2113 | version "6.2.0" 2114 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" 2115 | integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== 2116 | dependencies: 2117 | ansi-styles "^4.0.0" 2118 | string-width "^4.1.0" 2119 | strip-ansi "^6.0.0" 2120 | 2121 | wrappy@1: 2122 | version "1.0.2" 2123 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 2124 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 2125 | 2126 | ws@^6.1.0: 2127 | version "6.1.2" 2128 | resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" 2129 | integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== 2130 | dependencies: 2131 | async-limiter "~1.0.0" 2132 | 2133 | xor-distance@^2.0.0: 2134 | version "2.0.0" 2135 | resolved "https://registry.yarnpkg.com/xor-distance/-/xor-distance-2.0.0.tgz#cad3920d3a1e3d73eeedc61a554e51972dae0798" 2136 | integrity sha512-AsAqZfPAuWx7qB/0kyRDUEvoU3QKsHWzHU9smFlkaiprEpGfJ/NBbLze2Uq0rdkxCxkNM9uOLvz/KoNBCbZiLQ== 2137 | 2138 | xsalsa20@^1.0.0: 2139 | version "1.1.0" 2140 | resolved "https://registry.yarnpkg.com/xsalsa20/-/xsalsa20-1.1.0.tgz#bee27174af1913aaec0fe677d8ba161ec12bf87d" 2141 | integrity sha512-zd3ytX2cm+tcSndRU+krm0eL4TMMpZE7evs5hLRAoOy6gviqLfe3qOlkjF3i5SeAkQUCeJk0lJZrEU56kHRfWw== 2142 | 2143 | xtend@~4.0.1: 2144 | version "4.0.2" 2145 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 2146 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 2147 | 2148 | y18n@^4.0.0: 2149 | version "4.0.0" 2150 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 2151 | integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 2152 | 2153 | yallist@^2.1.2: 2154 | version "2.1.2" 2155 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 2156 | integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= 2157 | 2158 | yallist@^3.0.0, yallist@^3.0.3: 2159 | version "3.1.1" 2160 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" 2161 | integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== 2162 | 2163 | yargs-parser@^15.0.1: 2164 | version "15.0.1" 2165 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3" 2166 | integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw== 2167 | dependencies: 2168 | camelcase "^5.0.0" 2169 | decamelize "^1.2.0" 2170 | 2171 | yargs-parser@^18.1.1: 2172 | version "18.1.3" 2173 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" 2174 | integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== 2175 | dependencies: 2176 | camelcase "^5.0.0" 2177 | decamelize "^1.2.0" 2178 | 2179 | yargs@^14.2.0: 2180 | version "14.2.3" 2181 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" 2182 | integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== 2183 | dependencies: 2184 | cliui "^5.0.0" 2185 | decamelize "^1.2.0" 2186 | find-up "^3.0.0" 2187 | get-caller-file "^2.0.1" 2188 | require-directory "^2.1.1" 2189 | require-main-filename "^2.0.0" 2190 | set-blocking "^2.0.0" 2191 | string-width "^3.0.0" 2192 | which-module "^2.0.0" 2193 | y18n "^4.0.0" 2194 | yargs-parser "^15.0.1" 2195 | 2196 | yargs@^15.3.1: 2197 | version "15.3.1" 2198 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" 2199 | integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== 2200 | dependencies: 2201 | cliui "^6.0.0" 2202 | decamelize "^1.2.0" 2203 | find-up "^4.1.0" 2204 | get-caller-file "^2.0.1" 2205 | require-directory "^2.1.1" 2206 | require-main-filename "^2.0.0" 2207 | set-blocking "^2.0.0" 2208 | string-width "^4.2.0" 2209 | which-module "^2.0.0" 2210 | y18n "^4.0.0" 2211 | yargs-parser "^18.1.1" 2212 | --------------------------------------------------------------------------------