Cleanup sprotty live beans view

This commit is contained in:
Kris De Volder
2019-08-27 13:05:44 -07:00
parent c49a9f0c83
commit 9708319ea7
18 changed files with 4807 additions and 33830 deletions

View File

@@ -1,8 +1,5 @@
package org.springframework.ide.vscode.commons.sprotty.autoconf;
import org.eclipse.sprotty.IPopupModelFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.ide.vscode.commons.sprotty.scan.DiagramWebsocketServer;
@@ -11,10 +8,4 @@ import org.springframework.ide.vscode.commons.sprotty.scan.DiagramWebsocketServe
@ComponentScan(basePackageClasses = DiagramWebsocketServer.class)
public class SprottyAutoConf {
@Bean
@ConditionalOnMissingBean(IPopupModelFactory.class)
public IPopupModelFactory popupModelFactory() {
return new IPopupModelFactory.NullImpl();
}
}

View File

@@ -0,0 +1,82 @@
package org.springframework.ide.vscode.commons.sprotty.scan;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import org.eclipse.sprotty.Action;
import org.eclipse.sprotty.ActionMessage;
import org.eclipse.sprotty.DefaultDiagramServer;
import org.eclipse.sprotty.IDiagramServer;
import org.eclipse.sprotty.ILayoutEngine;
import org.eclipse.sprotty.RequestModelAction;
import org.eclipse.sprotty.SGraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@Component
public class DefaultDiagramServerManager implements DiagramServerManager {
public static final SGraph EMPTY_GRAPH = new SGraph(((Consumer<SGraph>) (SGraph it) -> {
it.setType("NONE");
it.setId("EMPTY");
}));
private static final Logger log = LoggerFactory.getLogger(DefaultDiagramServerManager.class);
private Cache<String, IDiagramServer> servers = CacheBuilder.newBuilder().build();
@Autowired
private DiagramGenerator diagramGenerator;
@Autowired
private ILayoutEngine layoutEngine;
private Consumer<ActionMessage> remoteEndpoint;
private IDiagramServer getDiagramServer(String clientId) {
try {
return servers.get(clientId, () -> {
DefaultDiagramServer diagramServer = new DefaultDiagramServer(clientId);
diagramServer.setRemoteEndpoint(this::sendMessageToRemoteEndpoint);
diagramServer.setLayoutEngine(layoutEngine);
return diagramServer;
});
} catch (ExecutionException e) {
throw ExceptionUtil.unchecked(e);
}
}
public void setRemoteEndpoint(Consumer<ActionMessage> remoteEndpoint) {
Assert.isNull(this.remoteEndpoint, "Can only be set once!");
this.remoteEndpoint = remoteEndpoint;
}
private void sendMessageToRemoteEndpoint(ActionMessage message) {
if (remoteEndpoint != null) {
remoteEndpoint.accept(message);
}
}
public void sendMessageToServer(ActionMessage message) {
RequestModelAction modelRequest = null;
Action action = message.getAction();
if (action instanceof RequestModelAction) {
modelRequest = (RequestModelAction) action;
}
String clientId = message.getClientId();
IDiagramServer server = getDiagramServer(clientId);
if (server != null) {
if (modelRequest!=null) {
server.setModel(diagramGenerator.generateModel(clientId, modelRequest));
}
server.accept(message);
}
}
}

View File

@@ -0,0 +1,8 @@
package org.springframework.ide.vscode.commons.sprotty.scan;
import org.eclipse.sprotty.RequestModelAction;
import org.eclipse.sprotty.SModelRoot;
public interface DiagramGenerator {
SModelRoot generateModel(String clientId, RequestModelAction modelRequest);
}

View File

@@ -11,6 +11,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.protocol.STS4LanguageClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
@@ -54,10 +55,8 @@ public class DiagramWebsocketServer implements WebSocketConfigurer, Initializing
ActionMessage actionMessage = gson.fromJson(jsonMessage, ActionMessage.class);
diagramServers.sendMessageToServer(actionMessage);
});
server.doOnInitialized(() -> {
diagramServers.setRemoteEndpoint(message -> {
sendMessage((JsonObject)gson.toJsonTree(message));
});
diagramServers.setRemoteEndpoint(message -> {
sendMessage((JsonObject)gson.toJsonTree(message));
});
}
@@ -127,7 +126,10 @@ public class DiagramWebsocketServer implements WebSocketConfigurer, Initializing
}
private void sendMessage(JsonObject msg) {
server.getClient().sprottyMessage(msg);
STS4LanguageClient client = server.getClient();
if (client!=null) {
client.sprottyMessage(msg);
}
synchronized (ws_sessions) {
for (WebSocketSession ws : ws_sessions) {
try {

View File

@@ -3,15 +3,12 @@ package org.springframework.ide.vscode.boot.app.diagram;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import org.eclipse.sprotty.ActionMessage;
import org.eclipse.sprotty.DefaultDiagramServer;
import org.eclipse.sprotty.Dimension;
import org.eclipse.sprotty.IDiagramServer;
import org.eclipse.sprotty.ILayoutEngine;
import org.eclipse.sprotty.Point;
import org.eclipse.sprotty.RequestModelAction;
import org.eclipse.sprotty.SCompartment;
import org.eclipse.sprotty.SEdge;
import org.eclipse.sprotty.SGraph;
@@ -21,88 +18,42 @@ import org.eclipse.sprotty.SNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider;
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBean;
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBeansModel;
import org.springframework.ide.vscode.commons.sprotty.scan.DiagramServerManager;
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
import org.springframework.ide.vscode.commons.sprotty.scan.DiagramGenerator;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@Component
public class LiveBeansDiagramServerManager implements DiagramServerManager {
public class LiveBeanDiagramGenerator implements DiagramGenerator {
public static final SGraph EMPTY_GRAPH = new SGraph(((Consumer<SGraph>) (SGraph it) -> {
it.setType("NONE");
it.setId("EMPTY");
}));
private static final Logger log = LoggerFactory.getLogger(LiveBeansDiagramServerManager.class);
private Cache<String, IDiagramServer> servers = CacheBuilder.newBuilder().build();
@Autowired
private RunningAppProvider runningAppProvider;
private static final Logger log = LoggerFactory.getLogger(LiveBeanDiagramGenerator.class);
@Autowired
private ILayoutEngine layoutEngine;
RunningAppProvider runningAppProvider;
@Autowired
private ApplicationContext appContext;
private Consumer<ActionMessage> remoteEndpoint;
private IDiagramServer getDiagramServer(String clientId) {
try {
return servers.get(clientId, () -> {
DefaultDiagramServer diagramServer = new DefaultDiagramServer(clientId);
diagramServer.setRemoteEndpoint(this::sendMessageToRemoteEndpoint);
diagramServer.setLayoutEngine(layoutEngine);
diagramServer.setModel(generateModel(clientId));
return diagramServer;
});
} catch (ExecutionException e) {
throw ExceptionUtil.unchecked(e);
public SGraph generateModel(String clientId, RequestModelAction modelRequest) {
String processStr = modelRequest.getOptions().get("target");
if (processStr.startsWith("process-")) {
processStr = processStr.substring("process-".length());
}
}
public void setRemoteEndpoint(Consumer<ActionMessage> remoteEndpoint) {
Assert.isNull(this.remoteEndpoint, "Can only be set once!");
this.remoteEndpoint = remoteEndpoint;
}
private void sendMessageToRemoteEndpoint(ActionMessage message) {
if (remoteEndpoint != null) {
remoteEndpoint.accept(message);
}
}
public void sendMessageToServer(ActionMessage message) {
IDiagramServer server = getDiagramServer(message.getClientId());
if (server != null) {
server.accept(message);
}
}
private SGraph generateModel(String clientId) {
int process = Integer.parseInt(processStr);
try {
Collection<SpringBootApp> apps = runningAppProvider.getAllRunningSpringApps();
if (!apps.isEmpty()) {
String indexStr = clientId.substring(clientId.lastIndexOf('-') + 1);
int index = Integer.valueOf(indexStr);
for (SpringBootApp springBootApp : apps) {
if (--index == 0) {
return toSprottyGraph(springBootApp);
}
int index = 0;
for (SpringBootApp app : apps) {
if (++index == process) {
return toSprottyGraph(app);
}
}
} catch (Exception e) {
log.error("{}", e);
log.error("", e);
}
return EMPTY_GRAPH;
}
@@ -164,4 +115,5 @@ public class LiveBeansDiagramServerManager implements DiagramServerManager {
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,46 +0,0 @@
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
.sprotty-node {
fill: #aae;
stroke: #66b;
stroke-width: 3;
}
.sprotty-text {
font-size: 16pt;
text-anchor: middle;
}
.sprotty-edge {
fill: none;
stroke: #488;
stroke-width: 2;
}
.sprotty-node.selected {
stroke: #dd8;
stroke-width: 6;
}
.sprotty-missing {
stroke-width: 1;
stroke: #f00;
fill: #f00;
font-family: SansSerif;
font-size: 14pt;
text-anchor: middle;
}

View File

@@ -1,38 +0,0 @@
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
.copyright {
margin-top: 10px;
text-align: right;
font-size: 10px;
color: #888;
}
.help {
margin-top: 24px;
text-align: right;
font-size: 16px;
color: #888;
}
svg {
margin-top: 15px;
width: 100%;
height: 500px;
border-style: solid;
border-width: 1px;
border-color: #bbb;
}

View File

@@ -11,7 +11,7 @@
</head>
<body>
<div class="container">
<div class="row" id="sprotty-app" data-app="circlegraph">
<div class="row" id="sprotty-app" client-id="livebeans" target="process-1">
<div class="col-md-10">
<h1>sprotty Circles Example</h1>
<p>
@@ -25,7 +25,7 @@
</div>
<div class="row">
<div class="col-md-12">
<div id="spring-boot" class="sprotty"/>
<div id="livebeans" class="sprotty"/>
</div>
<div class="copyright">
&copy; 2017 <a href="http://typefox.io">TypeFox GmbH</a>.

View File

@@ -0,0 +1,4 @@
node_modules
bundle.js
bundle.js.map
/lib

View File

@@ -1,5 +1,14 @@
set -ev
# For vscode webview
rm -rf ../../vscode-extensions/vscode-spring-boot/media/*
mkdir -p ../../vscode-extensions/vscode-spring-boot/media
cp bundle.js* ../../vscode-extensions/vscode-spring-boot/media
cp -R css ../../vscode-extensions/vscode-spring-boot/media
cp -R lib ../../vscode-extensions/vscode-spring-boot/media
# For webserver embedded in language server
rm -fr ../../headless-services/spring-boot-language-server/src/main/resources/static/bundle*
rm -fr ../../headless-services/spring-boot-language-server/src/main/resources/static/css
cp bundle.js* ../../headless-services/spring-boot-language-server/src/main/resources/static
cp -R css ../../headless-services/spring-boot-language-server/src/main/resources/static
cp -R lib ../../headless-services/spring-boot-language-server/src/main/resources/static

File diff suppressed because it is too large Load Diff

View File

@@ -19,9 +19,4 @@ console.log("Loaded reflect-metadata");
import runStandalone from "./standalone";
const appDiv = document.getElementById('sprotty-app')
if(appDiv) {
const clientId = appDiv.getAttribute('client-id');
console.log('app.ts : ' + clientId);
runStandalone(clientId || 'spring-boot');
}
runStandalone();

View File

@@ -18,87 +18,26 @@
declare const acquireVsCodeApi: any;
import {
TYPES, IActionDispatcher, SModelElementSchema, SEdgeSchema, SNodeSchema, SGraphSchema,
ModelSource, LocalModelSource, WebSocketDiagramServer, RequestModelAction
TYPES, IActionDispatcher,
ModelSource, WebSocketDiagramServer, RequestModelAction
} from "sprotty";
import createContainer, {TransportMedium} from "./di.config";
import * as SockJS from "sockjs-client";
import {VSCodeWebViewDiagramServer} from "./model";
export default function runStandalone(clientId: string) {
export default function runStandalone() {
const clientId = getOptionFromDom('client-id') || 'sprotty-client';
const container = createContainer(TransportMedium.LSP, clientId);
const dispatcher = container.get<IActionDispatcher>(TYPES.IActionDispatcher);
// Initialize gmodel
const node0 = {
id: 'node0', type: 'node:bean', position: {x: 100, y: 100}, size: {width: 80, height: 80},
layout: 'vbox',
children: [
{
id: 'node0_header',
type: 'compartment',
layout: 'hbox',
children: [
{
id: 'bean-name',
type: 'node:label',
text: 'SpringBootApplication'
}
]
}
]
};
// const children_for_node = [];
const graph: SGraphSchema = {id: 'graph', type: 'graph', children: [node0]};
let count = 2;
function addNode(): SModelElementSchema[] {
const newNode: SNodeSchema = {
id: 'node' + count,
type: 'node:bean',
position: {
x: Math.random() * 1024,
y: Math.random() * 768
},
size: {
width: 80,
height: 80
}
};
const newEdge: SEdgeSchema = {
id: 'edge' + count,
type: 'edge:straight',
sourceId: 'node0',
targetId: 'node' + count++
};
return [newNode, newEdge];
}
for (let i = 0; i < 10; ++i) {
const newElements = addNode();
for (const e of newElements) {
graph.children.splice(0, 0, e);
}
}
// Run
const modelSource = container.get<ModelSource>(TYPES.ModelSource);
console.log('Model source: ' + modelSource);
if (modelSource instanceof LocalModelSource) {
(<LocalModelSource>modelSource).setModel(graph);
}
if (modelSource instanceof WebSocketDiagramServer) {
const ws = new SockJS('http://localhost:8080/websocket');
modelSource.clientId = 'spring-boot';
modelSource.listen(ws);
ws.addEventListener('open', () => {
dispatcher.dispatch(new RequestModelAction());
dispatcher.dispatch(requestModelAction());
});
ws.addEventListener('error', (event) => {
console.error(`WebSocket Error: ${event}`)
@@ -106,16 +45,29 @@ export default function runStandalone(clientId: string) {
}
if (modelSource instanceof VSCodeWebViewDiagramServer) {
console.log('Listen and acquire VSCode API with client-id = ' + clientId);
modelSource.listen(acquireVsCodeApi());
dispatcher.dispatch(new RequestModelAction());
dispatcher.dispatch(requestModelAction());
}
console.log('Before requesting model');
// Button features
document.getElementById('refresh')!.addEventListener('click', () => {
dispatcher.dispatch(new RequestModelAction());
dispatcher.dispatch(requestModelAction());
});
function getOptionFromDom(att: string) : string | null {
const appDiv = document.getElementById('sprotty-app');
if (appDiv) {
return appDiv.getAttribute(att);
}
return null;
}
function getTarget() : string {
return getOptionFromDom('target') || 'target-missing';
}
function requestModelAction() : RequestModelAction {
return new RequestModelAction({ 'target' : getTarget()});
}
}

View File

@@ -1 +0,0 @@
*.js

View File

@@ -14,7 +14,7 @@ export async function activate(context: vscode.ExtensionContext, client: Languag
'process-3',
]).then(pick => {
console.log('Pick is: ' + pick);
LiveBeansView.createOrShow(context.extensionPath, client, pick);
LiveBeansView.createOrShow(context.extensionPath, client, pick, pick);
})
@@ -27,8 +27,9 @@ export async function activate(context: vscode.ExtensionContext, client: Languag
* Manages cat coding webview panels
*/
class LiveBeansView {
/**
* Track the currently panel. Only allow a single panel to exist at a time.
* Track panels that currently exist. Indexed by process id.
*/
public static currentPanels: Map<string, LiveBeansView> = new Map();
@@ -39,8 +40,9 @@ class LiveBeansView {
private _disposables: vscode.Disposable[] = [];
private clientId: string;
private processId: string;
public static createOrShow(extensionPath: string, client: LanguageClient, clientId: string) {
public static createOrShow(extensionPath: string, client: LanguageClient, clientId: string, processId: string) {
const column = vscode.window.activeTextEditor
? vscode.window.activeTextEditor.viewColumn
: undefined;
@@ -65,7 +67,7 @@ class LiveBeansView {
}
);
LiveBeansView.currentPanels.set(clientId, new LiveBeansView(panel, extensionPath, clientId));
LiveBeansView.currentPanels.set(clientId, new LiveBeansView(panel, extensionPath, clientId, processId));
console.log('Created webview panel!');
const bridge: LSWebViewToLSPBridge = new LSWebViewToLSPBridge(panel, client);
@@ -76,8 +78,9 @@ class LiveBeansView {
// LiveBeansView.currentPanels.set() = new LiveBeansView(panel, extensionPath);
// }
private constructor(panel: vscode.WebviewPanel, extensionPath: string, clientId: string) {
private constructor(panel: vscode.WebviewPanel, extensionPath: string, clientId: string, processId: string) {
this.clientId = clientId;
this.processId = processId;
this._panel = panel;
this._extensionPath = extensionPath;
@@ -113,12 +116,6 @@ class LiveBeansView {
);
}
public doRefactor() {
// Send a message to the webview webview.
// You can send any JSON serializable data.
this._panel.webview.postMessage({ command: 'refactor' });
}
public dispose() {
LiveBeansView.currentPanels.delete(this.clientId);
@@ -134,7 +131,7 @@ class LiveBeansView {
}
private _update() {
this._panel.webview.html = this._getHtmlForWebview(/*cats[catName]*/);
this._panel.webview.html = this._getHtmlForWebview();
}
mediaUrl(...pathsegments: string[]) {
@@ -149,15 +146,12 @@ class LiveBeansView {
return scriptPathOnDisk.with({ scheme: 'vscode-resource' });
}
private _getHtmlForWebview(/*catGif: string*/) {
private _getHtmlForWebview() {
// And the uri we use to load this script in the webview
const scriptUri = this.mediaUrl('bundle.js');
const cssUri = this.mediaUrl('css', 'page.css');
// Use a nonce to whitelist which scripts can be run
const nonce = getNonce();
return `<!DOCTYPE html>
<html>
<head>
@@ -171,7 +165,7 @@ class LiveBeansView {
</head>
<body>
<div class="container">
<div class="row" id="sprotty-app" client-id="${this.clientId}">
<div class="row" id="sprotty-app" client-id="${this.clientId}" target="${this.processId}">
<div class="col-md-10">
<h1>sprotty Circles Example</h1>
<p>
@@ -198,15 +192,6 @@ class LiveBeansView {
}
}
function getNonce() {
let text = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
const SOCKET_MESSAGE_BUFFER = 4000;
const END_MESSAGE = '@end';

View File

@@ -1,6 +1,6 @@
{
"name": "vscode-spring-boot",
"version": "1.10.0",
"version": "1.11.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -19,11 +19,26 @@
"integrity": "sha512-6VnPe6TkVYr9UCOOlVVEAxhC+mEVt4Hevzc4eoDvUKFxexOD8MY38z6VNpa+lyhdvF6p5+Its/zfCPhdQlbhrQ=="
},
"@types/node": {
"version": "9.6.41",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.41.tgz",
"integrity": "sha512-sPZWEbFMz6qAy9SLY7jh5cgepmsiwqUUHjvEm8lpU6kug2hmmcyuTnwhoGw/GWpI5Npue4EqvsiQQI0eWjW/ZA==",
"version": "9.6.51",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.51.tgz",
"integrity": "sha512-5lhC7QM2J3b/+epdwaNfRuG2peN4c9EX+mkd27+SqLKhJSdswHTZvc4aZLBZChi+Wo32+E1DeMZs0fSpu/uBXQ==",
"dev": true
},
"@types/sockjs-client": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/sockjs-client/-/sockjs-client-1.1.1.tgz",
"integrity": "sha512-DaTdN4kfPNxu0otmQlxhmYeCjtY8cHmJsU6LqiFOrhytIkx8Txq06PwAWYzha7nMkEyju44a3NDpqCKiHn/NZQ==",
"dev": true
},
"@types/ws": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.3.tgz",
"integrity": "sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"agent-base": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
@@ -327,6 +342,14 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"eventsource": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
"integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
"requires": {
"original": "^1.0.0"
}
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -351,6 +374,14 @@
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
"dev": true
},
"faye-websocket": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
"integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
"requires": {
"websocket-driver": ">=0.5.1"
}
},
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
@@ -454,6 +485,11 @@
"readable-stream": "^3.0.6"
}
},
"http-parser-js": {
"version": "0.4.10",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz",
"integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q="
},
"http-proxy-agent": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
@@ -498,8 +534,7 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"is-typedarray": {
"version": "1.0.0",
@@ -537,6 +572,11 @@
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
"dev": true
},
"json3": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
"integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA=="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -702,6 +742,14 @@
"wrappy": "1"
}
},
"original": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
"integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
"requires": {
"url-parse": "^1.4.3"
}
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
@@ -796,8 +844,7 @@
"querystringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
"dev": true
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
},
"read": {
"version": "1.0.7",
@@ -850,14 +897,12 @@
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
@@ -870,6 +915,34 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
},
"sockjs-client": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz",
"integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==",
"requires": {
"debug": "^3.2.5",
"eventsource": "^1.0.7",
"faye-websocket": "~0.11.1",
"inherits": "^2.0.3",
"json3": "^3.3.2",
"url-parse": "^1.4.3"
},
"dependencies": {
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -1030,7 +1103,6 @@
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -1149,6 +1221,21 @@
"underscore": "^1.8.3"
}
},
"websocket-driver": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz",
"integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
"requires": {
"http-parser-js": ">=0.4.0 <0.4.11",
"safe-buffer": ">=5.1.0",
"websocket-extensions": ">=0.1.1"
}
},
"websocket-extensions": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg=="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",