Migrates to new visualization framework.

This commit is contained in:
hediet
2020-08-13 21:55:02 +02:00
parent c56f21d8ab
commit f09e345908
56 changed files with 5965 additions and 17011 deletions

2
.vscode/launch.json vendored
View File

@@ -62,7 +62,7 @@
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/extension",
"${workspaceFolder}/demos/php"
"${workspaceFolder}/demos/js"
],
"env": {
"HOT_RELOAD": "",

View File

@@ -7,5 +7,6 @@
"plantuml.exportOutDir": "docs/exported",
"typescript.updateImportsOnFileMove.enabled": "prompt",
"mochaExplorer.files": "./data-extraction/test/**/*.test.ts",
"mochaExplorer.require": ["ts-node/register", "source-map-support/register"]
"mochaExplorer.require": ["ts-node/register", "source-map-support/register"],
"tasksStatusbar.taskLabelFilter": "dev"
}

View File

@@ -4,16 +4,39 @@ import {
ExtractionCollector,
DataExtractorContext,
} from "../DataExtractorApi";
import { CommonDataTypes } from "../../../CommonDataTypes";
// This class is self contained and can be injected into both nodejs and browser environments.
export class TypeScriptAstDataExtractor
implements DataExtractor<CommonDataTypes.Ast> {
type AstType = {
kind: {
tree: true;
ast: true;
text: true;
};
root: TreeNode;
text: string;
};
type TreeNode = {
children: TreeNode[];
items: TreeNodeItem[];
segment?: string;
isMarked?: boolean;
span: {
start: number;
length: number;
};
};
type TreeNodeItem = {
text: string;
emphasis?: "style1" | "style2" | "style3";
};
export class TypeScriptAstDataExtractor implements DataExtractor<AstType> {
readonly id = "typescript-ast";
getExtractions(
data: unknown,
collector: ExtractionCollector<CommonDataTypes.Ast>,
collector: ExtractionCollector<AstType>,
{ evalFn }: DataExtractorContext
): void {
if (!data) {
@@ -68,7 +91,7 @@ export class TypeScriptAstDataExtractor
memberName: string,
marked: Set<ts.Node>,
emphasizedValueFn: (node: ts.Node) => string | undefined
): CommonDataTypes.Ast["root"] {
): TreeNode {
const name = tsApi.SyntaxKind[node.kind];
const children = getChildren(node)
.map((childNode, idx) => {
@@ -105,16 +128,18 @@ export class TypeScriptAstDataExtractor
}
return {
name: name,
id: memberName,
items: [
{ text: memberName, emphasis: "style1" },
{ text: name },
],
children: children,
data: {
span: {
length: node.end - node.pos,
position: node.pos,
start: node.pos,
},
emphasizedValue: emphasizedValueFn(node),
//emphasizedValue: emphasizedValueFn(node),
isMarked: marked.has(node),
value,
//value,
};
}

View File

@@ -2,7 +2,7 @@
# yarn lockfile v1
"@hediet/live-debug@^0.5.1", "@hediet/live-debug@^0.5.2":
"@hediet/live-debug@^0.5.1":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@hediet/live-debug/-/live-debug-0.5.2.tgz#f2ee0034f014836bfd68e26c35a168ab42b15486"
integrity sha512-HBqVbyFez1oQlIPO9dzkFi7/9Gvt6ZpssgURzYaVFREl9Oq03nPd6V7Ay4bW03xFHPo3YT2Yff9mFmGQUX7JEg==
@@ -13,30 +13,21 @@
stacktracey "^1.2.112"
ws "^7.0.0"
"@hediet/node-reload@0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@hediet/node-reload/-/node-reload-0.7.0.tgz#ec50160ce26203079f18e7024cd58025fa79652a"
integrity sha512-gWFbq2tOThSV9GT+pFx1JJzFuOV7l40IsseOFHMJGyvLmmAdgbJPV3OZuV9gcsXIGocOtbfEyky9S4tQELLLxA==
"@hediet/node-reload@0.7.3":
version "0.7.3"
resolved "https://registry.yarnpkg.com/@hediet/node-reload/-/node-reload-0.7.3.tgz#305d68f54185200b018b14f257037ab8d8ca9857"
integrity sha512-icOyfDpArfvqmw0VLf2CoGR/jCSuWk3fScJGFuXQHpb0c9yNoGTiuG3Q8L2iJIuDzCjRu47DR2T+yCvZsY/f+w==
dependencies:
"@hediet/live-debug" "^0.5.1"
"@hediet/std" "^0.6.0"
"@hediet/typed-json-rpc" "^0.7.6"
"@types/node" "^12.0.7"
"@types/stack-trace" "^0.0.29"
chalk "^2.4.2"
chokidar "^3.0.1"
stack-trace "^0.0.10"
ws "^7.0.0"
"@hediet/std@^0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@hediet/std/-/std-0.4.0.tgz#95dfd6e9d62f8bf9d91f3925d37b7b359b2af047"
integrity sha512-2kw4vSOprLchTjhcg8qQo6fdbBxJicSUrzZXgL0KzgMv18hjVmpm57NPLCPfI6115kAaMIWvMnlHFLYbx7poQQ==
dependencies:
"@types/chai" "^4.1.7"
"@types/sinon" "^7.0.10"
chai "^4.2.0"
sinon "^7.2.7"
"@hediet/std@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@hediet/std/-/std-0.6.0.tgz#f7d2ffc1180ecef6ff272d0d6780f0c0d9337e4e"
@@ -109,6 +100,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c"
integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==
"@types/node@^13.7.4":
version "13.13.15"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.15.tgz#fe1cc3aa465a3ea6858b793fd380b66c39919766"
integrity sha512-kwbcs0jySLxzLsa2nWUAGOd/s21WU1jebrEdtzhsj1D4Yps1EOuyI1Qcu+FD56dL7NRNIJtDDjcqIG22NwkgLw==
"@types/node@^8.0.7":
version "8.10.51"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627"
@@ -132,6 +128,13 @@
"@types/events" "*"
"@types/node" "*"
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
anymatch@^3.0.1:
version "3.0.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.0.3.tgz#2fb624fe0e84bccab00afee3d0006ed310f22f09"
@@ -186,6 +189,15 @@ chai@^4.2.0:
pathval "^1.1.0"
type-detect "^4.0.5"
chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
@@ -206,6 +218,18 @@ chokidar@^3.0.1:
optionalDependencies:
fsevents "^2.0.6"
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies:
color-name "1.1.3"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
data-uri-to-buffer@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.1.tgz#ca8f56fe38b1fd329473e9d1b4a9afcd8ce1c045"
@@ -225,6 +249,11 @@ diff@^3.5.0:
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@@ -404,7 +433,7 @@ stacktracey@^1.2.112:
as-table "^1.0.36"
get-source "^1.0.34"
supports-color@^5.5.0:
supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
@@ -423,10 +452,10 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
typescript@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
typescript@^3.8.2:
version "3.9.7"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==
ws@^7.0.0:
version "7.1.1"

View File

@@ -9,7 +9,7 @@ Like the VS Code's watch view, but with custom visualizations.
## Supported Languages
See [demos](./demos/) for demos. These languages and debuggers are verified to work with this extension:
See [demos](../demos/) for demos. These languages and debuggers are verified to work with this extension:
- JavaScript/TypeScript/... using `node`/`node2`/`extensionHost` or `chrome` debug adapter: [⭐ Full Support](../demos/js)
- Go using `go` (Delve) debug adapter: [✅ Rudimentary Support](../demos/golang)

File diff suppressed because it is too large Load Diff

View File

@@ -3,16 +3,13 @@
"workspaces": [
"./data-extraction",
"./extension",
"./webview",
"./visualization",
"./visualization-playground"
"./webview"
],
"scripts": {
"build": "yarn build-data-extraction && yarn build-extension && yarn build-visualization && yarn build-ui",
"build": "yarn build-data-extraction && yarn build-ui && yarn build-extension",
"build-data-extraction": "yarn workspace @hediet/debug-visualizer-data-extraction build",
"build-extension": "yarn workspace debug-visualizer build",
"build-visualization": "yarn workspace @hediet/visualization build",
"build-ui": "yarn workspace debug-visualizer-webview build"
"build-ui": "yarn workspace debug-visualizer-webview build",
"build-extension": "yarn workspace debug-visualizer build"
},
"devDependencies": {
"prettier": "^1.19.1"

View File

@@ -1,52 +0,0 @@
{
"name": "visualization-playground",
"version": "0.0.1",
"license": "GPL-3.0",
"scripts": {
"dev": "webpack-dev-server --hot --port 8090",
"dev-fast": "webpack-dev-server --hot --port 8090 --fast",
"build": "webpack",
"pub": "gh-pages -d dist"
},
"dependencies": {
"@blueprintjs/core": "^3.23.1",
"@hediet/std": "^0.6.0",
"blueprintjs": "^0.0.8",
"classnames": "^2.2.6",
"mobx": "^5.15.4",
"mobx-react": "^6.1.8",
"monaco-editor": "^0.20.0",
"popper.js": "^1.16.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-measure": "^2.3.0",
"@hediet/debug-visualizer-data-extraction": "*",
"react-autosize-textarea": "^7.0.0"
},
"devDependencies": {
"gh-pages": "^2.2.0",
"@types/html-webpack-plugin": "^3.2.2",
"@types/react-measure": "^2.0.6",
"@types/webpack": "^4.41.6",
"@types/classnames": "^2.2.9",
"@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.4.2",
"file-loader": "^5.1.0",
"fork-ts-checker-webpack-plugin": "^4.0.4",
"html-webpack-plugin": "^3.2.0",
"monaco-editor-webpack-plugin": "^1.9.0",
"node-sass": "^4.13.1",
"raw-loader": "^4.0.0",
"sass": "^1.25.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"ts-loader": "^6.2.1",
"ts-node": "^8.6.2",
"typescript": "^3.8.2",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
}
}

View File

@@ -1,45 +0,0 @@
import * as React from "react";
import { Button, Spinner } from "@blueprintjs/core";
import { observable, action } from "mobx";
import { observer } from "mobx-react";
import { Model } from "../model/Model";
import classnames = require("classnames");
import { knownVisualizations } from "@hediet/visualization";
import { CommonDataType } from "@hediet/debug-visualizer-data-extraction";
import { LightExpressionInput } from "./LightExpressionInput";
@observer
export class GUI extends React.Component<{ model: Model }> {
render() {
const m = this.props.model;
return (
<div
className="component-GUI"
style={{ display: "flex", flexDirection: "column" }}
>
<div className="part-header">
<LightExpressionInput model={m.jsonExpression} />
</div>
<div
className="part-visualization"
style={{ minHeight: 0, flex: 1 }}
>
{this.renderVisualization()}
</div>
</div>
);
}
renderVisualization() {
const m = this.props.model;
if (!m.visualizations) {
return <div>No/Invalid Data</div>;
}
if (!m.visualizations.visualization) {
return <div>Data cannot be visualized</div>;
}
return m.visualizations.visualization.render();
}
}

View File

@@ -1,76 +0,0 @@
import * as React from "react";
import { observer } from "mobx-react";
import { observable, action } from "mobx";
import TextareaAutosize from "react-autosize-textarea";
export class ExpressionModel {
@observable
private _value: string;
constructor(initialValue: string) {
this._value = initialValue;
}
public get value(): string {
return this._value;
}
public setValue(newValue: string): void {
this._value = newValue;
}
}
@observer
export class LightExpressionInput extends React.Component<{
model: ExpressionModel;
}> {
@observable localText: string | undefined = undefined;
get text(): string {
if (this.localText !== undefined) {
return this.localText;
}
return this.props.model.value;
}
render() {
return (
<div>
<TextareaAutosize
value={this.text}
spellCheck={false}
onChange={e => (this.localText = e.currentTarget.value)}
onKeyDown={e => {
if (e.keyCode == 9 || e.which == 9) {
// enable tab
const target = e.currentTarget;
e.preventDefault();
var s = target.selectionStart;
target.value =
target.value.substring(
0,
target.selectionStart
) +
"\t" +
target.value.substring(target.selectionEnd);
target.selectionEnd = s + 1;
}
}}
style={{
width: "100%",
resize: "none",
}}
onBlur={this.handleBlur}
/>
</div>
);
}
@action.bound
private handleBlur() {
if (this.localText !== undefined) {
this.props.model.setValue(this.localText);
}
this.localText = undefined;
}
}

View File

@@ -1,35 +0,0 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import "./style.scss";
import { Model } from "./model/Model";
import Components = require("./components/GUI");
const model = new Model();
if (model.theme === "light") {
require("./vscode-light.scss");
} else {
require("./vscode-dark.scss");
}
function render(target: HTMLDivElement) {
const c = require("./components/GUI") as typeof Components;
ReactDOM.render(<c.GUI model={model} />, target);
}
const target = document.createElement("div");
target.className = "target";
document.body.appendChild(target);
render(target);
declare var module: {
hot?: { accept: (componentName: string, callback: () => void) => void };
};
declare var require: (name: string) => any;
if (module.hot) {
module.hot.accept("./components/GUI", () => {
render(target);
});
}

View File

@@ -1,95 +0,0 @@
import { observable, action, computed, when } from "mobx";
import {
Visualization,
VisualizationId,
knownVisualizations,
} from "@hediet/visualization";
import { Disposable } from "@hediet/std/disposable";
import { ExpressionModel } from "../components/LightExpressionInput";
import { ExtractedData } from "@hediet/debug-visualizer-data-extraction";
import { QueryController } from "./QueryController";
export class Model {
public readonly dispose = Disposable.fn();
@observable
public theme: "dark" | "light" = "light";
@observable private preferredVisualizationId:
| VisualizationId
| undefined = undefined;
@action
public setPreferredVisualizationId(id: VisualizationId) {
this.preferredVisualizationId = id;
}
public jsonExpression = new ExpressionModel(
JSON.stringify(
{
kind: { graph: true },
nodes: [
{ id: "1", label: "1" },
{ id: "2", label: "2" },
],
edges: [
{
from: "1",
to: "2",
},
],
},
undefined,
4
)
);
get state():
| { kind: "data"; data: ExtractedData }
| { kind: "parseError" } {
const json = this.jsonExpression.value;
let data: ExtractedData;
try {
data = JSON.parse(json);
} catch (e) {
return {
kind: "parseError",
};
}
return {
kind: "data",
data,
};
}
@computed get visualizations():
| {
visualization: Visualization | undefined;
allVisualizations: Visualization[];
}
| undefined {
if (this.state.kind === "data") {
const vis = knownVisualizations.getBestVisualization(
this.state.data,
this.preferredVisualizationId
);
return vis;
} else {
return undefined;
}
}
private readonly q = new QueryController(this);
constructor() {
const url = new URL(window.location.href);
const theme = url.searchParams.get("theme");
if (theme && theme === "dark") {
this.theme = "dark";
} else {
this.theme = "light";
}
}
}

View File

@@ -1,18 +0,0 @@
import * as monaco from "monaco-editor";
import { Model } from "./Model";
import { Disposable } from "@hediet/std/disposable";
import { autorun } from "mobx";
export class MonacoBridge {
public readonly dispose = Disposable.fn();
constructor(private readonly model: Model) {
this.dispose.track({
dispose: autorun(() => {
monaco.editor.setTheme(
model.theme === "light" ? "vs-light" : "vs-dark"
);
}),
});
}
}

View File

@@ -1,26 +0,0 @@
import { Model } from "./Model";
import { autorun } from "mobx";
export class QueryController {
constructor(private readonly model: Model) {
this.loadFromQuery();
autorun(() => {
this.updateQuery();
});
}
loadFromQuery() {
const url = new URL(window.location.href);
const val = url.searchParams.get("value");
if (val) {
this.model.jsonExpression.setValue(val);
}
}
updateQuery() {
const url = new URL(window.location.href);
url.searchParams.set("value", this.model.jsonExpression.value);
history.replaceState(null, document.title, url.toString());
}
}

View File

@@ -1,71 +0,0 @@
@import "~normalize.css";
@import "~@blueprintjs/core/lib/css/blueprint.css";
@import "~@blueprintjs/icons/lib/css/blueprint-icons.css";
@import "~@hediet/visualization/style.scss";
html,
body,
.target {
height: 100%;
}
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
margin: 0px;
padding: 0px;
border: 0px;
margin: 0;
padding: 0;
background-color: var(--vscode-editor-background);
}
.bp3-input,
.bp3-button {
border-radius: 0;
}
.bp3-icon {
svg {
color: lighten(black, 20);
width: 14px;
}
}
.component-GUI {
height: 100%;
& > .part-Header {
//padding: 6px 20px 6px 0;
//background-color: var(--vscode-sideBar-background);
// border-top: solid 1px var(--vscode-button-background);
// rgba(128, 128, 128, 0.15)
}
}
.component-monaco-editor {
width: 100%;
min-width: 0;
box-sizing: border-box;
display: flex;
padding: 2px;
border: 0.5px solid gray;
.part-editor {
min-width: 0;
min-height: 0;
flex: 1;
.current-line {
border: none !important;
}
.selectionHighlight {
background: transparent !important;
}
}
}
.bp3-transition-container {
z-index: 100000;
}

View File

@@ -1,288 +0,0 @@
:root {
--background-color: #263238;
--color: #eeffff;
--font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", HelveticaNeue-Light, Ubuntu, "Droid Sans", sans-serif;
--font-size: 13px;
--font-weight: normal;
--link-active-color: #eeffff;
--link-color: #80cbc4;
--vscode-activityBar-background: #192227;
--vscode-activityBar-border: rgba(0, 0, 0, 0.38);
--vscode-activityBar-dropBackground: rgba(255, 255, 255, 0.12);
--vscode-activityBar-foreground: #eeffff;
--vscode-activityBar-inactiveForeground: rgba(238, 255, 255, 0.6);
--vscode-activityBarBadge-background: #80cbc4;
--vscode-activityBarBadge-foreground: #000000;
--vscode-badge-background: rgba(0, 0, 0, 0.19);
--vscode-badge-foreground: #546e7a;
--vscode-breadcrumb-activeSelectionForeground: #80cbc4;
--vscode-breadcrumb-background: #263238;
--vscode-breadcrumb-focusForeground: #eeffff;
--vscode-breadcrumb-foreground: #5f7a87;
--vscode-breadcrumbPicker-background: #192227;
--vscode-button-background: rgba(128, 203, 196, 0.13);
--vscode-button-foreground: #ffffff;
--vscode-button-hoverBackground: rgba(175, 222, 218, 0.13);
--vscode-debugExceptionWidget-background: #420b0d;
--vscode-debugExceptionWidget-border: #a31515;
--vscode-debugToolBar-background: #263238;
--vscode-descriptionForeground: rgba(204, 204, 204, 0.7);
--vscode-diffEditor-insertedTextBackground: rgba(195, 232, 141, 0.08);
--vscode-diffEditor-removedTextBackground: rgba(255, 83, 112, 0.13);
--vscode-dropdown-background: #263238;
--vscode-dropdown-border: rgba(255, 255, 255, 0.06);
--vscode-dropdown-foreground: #f0f0f0;
--vscode-editor-background: #263238;
--vscode-editor-findMatchBackground: #515c6a;
--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);
--vscode-editor-findRangeHighlightBackground: rgba(58, 61, 65, 0.4);
--vscode-editor-focusedStackFrameHighlightBackground: rgba(122, 189, 122, 0.3);
--vscode-editor-font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", HelveticaNeue-Light, Ubuntu, "Droid Sans", sans-serif;
--vscode-editor-font-size: 13px;
--vscode-editor-font-weight: normal;
--vscode-editor-foreground: #eeffff;
--vscode-editor-hoverHighlightBackground: rgba(38, 79, 120, 0.25);
--vscode-editor-inactiveSelectionBackground: rgba(128, 203, 196, 0.06);
--vscode-editor-lineHighlightBackground: rgba(0, 0, 0, 0.31);
--vscode-editor-lineHighlightBorder: #282828;
--vscode-editor-rangeHighlightBackground: rgba(255, 255, 255, 0.04);
--vscode-editor-selectionBackground: rgba(128, 203, 196, 0.13);
--vscode-editor-selectionHighlightBackground: rgba(255, 204, 0, 0.13);
--vscode-editor-snippetFinalTabstopHighlightBorder: #525252;
--vscode-editor-snippetTabstopHighlightBackground: rgba(124, 124, 124, 0.3);
--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 0, 0.2);
--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.72);
--vscode-editor-wordHighlightStrongBackground: rgba(0, 73, 114, 0.72);
--vscode-editorActiveLineNumber-foreground: #c6c6c6;
--vscode-editorBracketMatch-background: #263238;
--vscode-editorBracketMatch-border: rgba(255, 204, 0, 0.31);
--vscode-editorCodeLens-foreground: #999999;
--vscode-editorCursor-foreground: #ffcc00;
--vscode-editorError-foreground: rgba(255, 83, 112, 0.44);
--vscode-editorGroup-border: rgba(0, 0, 0, 0.19);
--vscode-editorGroup-dropBackground: rgba(83, 89, 93, 0.5);
--vscode-editorGroupHeader-noTabsBackground: #263238;
--vscode-editorGroupHeader-tabsBackground: #263238;
--vscode-editorGutter-addedBackground: rgba(195, 232, 141, 0.38);
--vscode-editorGutter-background: #263238;
--vscode-editorGutter-commentRangeForeground: #c5c5c5;
--vscode-editorGutter-deletedBackground: rgba(255, 83, 112, 0.38);
--vscode-editorGutter-modifiedBackground: rgba(130, 170, 255, 0.38);
--vscode-editorHint-foreground: rgba(238, 238, 238, 0.7);
--vscode-editorHoverWidget-background: #263238;
--vscode-editorHoverWidget-border: rgba(255, 255, 255, 0.06);
--vscode-editorIndentGuide-activeBackground: #37474f;
--vscode-editorIndentGuide-background: rgba(55, 71, 79, 0.44);
--vscode-editorInfo-foreground: #008000;
--vscode-editorLineNumber-activeForeground: #5f7a87;
--vscode-editorLineNumber-foreground: #37474f;
--vscode-editorLink-activeForeground: #eeffff;
--vscode-editorMarkerNavigation-background: rgba(238, 255, 255, 0.02);
--vscode-editorMarkerNavigationError-background: rgba(255, 83, 112, 0.44);
--vscode-editorMarkerNavigationInfo-background: #008000;
--vscode-editorMarkerNavigationWarning-background: rgba(195, 232, 141, 0.44);
--vscode-editorOverviewRuler-addedForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-border: #263238;
--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;
--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);
--vscode-editorOverviewRuler-currentContentForeground: rgba(64, 200, 174, 0.5);
--vscode-editorOverviewRuler-deletedForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);
--vscode-editorOverviewRuler-findMatchForeground: rgba(246, 185, 77, 0.7);
--vscode-editorOverviewRuler-incomingContentForeground: rgba(64, 166, 255, 0.5);
--vscode-editorOverviewRuler-infoForeground: rgba(18, 18, 136, 0.7);
--vscode-editorOverviewRuler-modifiedForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(160, 160, 160, 0.8);
--vscode-editorOverviewRuler-warningForeground: rgba(18, 136, 18, 0.7);
--vscode-editorOverviewRuler-wordHighlightForeground: rgba(160, 160, 160, 0.8);
--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(192, 160, 192, 0.8);
--vscode-editorPane-background: #263238;
--vscode-editorRuler-foreground: #37474f;
--vscode-editorSuggestWidget-background: #263238;
--vscode-editorSuggestWidget-border: rgba(255, 255, 255, 0.06);
--vscode-editorSuggestWidget-foreground: #eeffff;
--vscode-editorSuggestWidget-highlightForeground: #80cbc4;
--vscode-editorSuggestWidget-selectedBackground: rgba(0, 0, 0, 0.31);
--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.67);
--vscode-editorWarning-foreground: rgba(195, 232, 141, 0.44);
--vscode-editorWhitespace-foreground: rgba(238, 255, 255, 0.25);
--vscode-editorWidget-background: #192227;
--vscode-editorWidget-border: #ff0000;
--vscode-editorWidget-resizeBorder: #80cbc4;
--vscode-errorForeground: #f48771;
--vscode-extensionButton-prominentBackground: rgba(195, 232, 141, 0.56);
--vscode-extensionButton-prominentForeground: #ffffff;
--vscode-extensionButton-prominentHoverBackground: #c3e88d;
--vscode-focusBorder: rgba(255, 255, 255, 0);
--vscode-foreground: #cccccc;
--vscode-gitDecoration-addedResourceForeground: #81b88b;
--vscode-gitDecoration-conflictingResourceForeground: rgba(255, 203, 107, 0.56);
--vscode-gitDecoration-deletedResourceForeground: rgba(255, 83, 112, 0.56);
--vscode-gitDecoration-ignoredResourceForeground: rgba(95, 122, 135, 0.56);
--vscode-gitDecoration-modifiedResourceForeground: rgba(130, 170, 255, 0.56);
--vscode-gitDecoration-submoduleResourceForeground: #8db9e2;
--vscode-gitDecoration-untrackedResourceForeground: rgba(195, 232, 141, 0.56);
--vscode-gitlens-gutterBackgroundColor: rgba(255, 255, 255, 0.07);
--vscode-gitlens-gutterForegroundColor: #bebebe;
--vscode-gitlens-gutterUncommittedForegroundColor: rgba(0, 188, 242, 0.6);
--vscode-gitlens-lineHighlightBackgroundColor: rgba(0, 188, 242, 0.2);
--vscode-gitlens-lineHighlightOverviewRulerColor: rgba(0, 188, 242, 0.6);
--vscode-gitlens-trailingLineBackgroundColor: rgba(0, 0, 0, 0);
--vscode-gitlens-trailingLineForegroundColor: rgba(153, 153, 153, 0.35);
--vscode-input-background: #303c41;
--vscode-input-border: rgba(255, 255, 255, 0.06);
--vscode-input-foreground: #eeffff;
--vscode-input-placeholderForeground: rgba(238, 255, 255, 0.38);
--vscode-inputOption-activeBorder: #007acc;
--vscode-inputValidation-errorBackground: #5a1d1d;
--vscode-inputValidation-errorBorder: rgba(255, 83, 112, 0.31);
--vscode-inputValidation-infoBackground: #063b49;
--vscode-inputValidation-infoBorder: rgba(130, 170, 255, 0.31);
--vscode-inputValidation-warningBackground: #352a05;
--vscode-inputValidation-warningBorder: rgba(255, 203, 107, 0.31);
--vscode-list-activeSelectionBackground: #192227;
--vscode-list-activeSelectionForeground: #80cbc4;
--vscode-list-dropBackground: rgba(238, 255, 255, 0.13);
--vscode-list-errorForeground: #f88070;
--vscode-list-focusBackground: rgba(238, 255, 255, 0.13);
--vscode-list-focusForeground: #eeffff;
--vscode-list-highlightForeground: #80cbc4;
--vscode-list-hoverBackground: #192227;
--vscode-list-hoverForeground: #ffffff;
--vscode-list-inactiveFocusBackground: #313135;
--vscode-list-inactiveSelectionBackground: rgba(0, 0, 0, 0.19);
--vscode-list-inactiveSelectionForeground: #80cbc4;
--vscode-list-invalidItemForeground: #b89500;
--vscode-list-warningForeground: #4d9e4d;
--vscode-menu-background: #263238;
--vscode-menu-foreground: #eeffff;
--vscode-menu-selectionBackground: rgba(0, 0, 0, 0.31);
--vscode-menu-selectionBorder: rgba(0, 0, 0, 0.19);
--vscode-menu-selectionForeground: #80cbc4;
--vscode-menu-separatorBackground: #eeffff;
--vscode-menubar-selectionBackground: rgba(0, 0, 0, 0.19);
--vscode-menubar-selectionBorder: rgba(0, 0, 0, 0.19);
--vscode-menubar-selectionForeground: #80cbc4;
--vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);
--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);
--vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);
--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);
--vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);
--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);
--vscode-notificationCenterHeader-background: #314149;
--vscode-notificationLink-foreground: #80cbc4;
--vscode-notifications-background: #263238;
--vscode-notifications-border: #314149;
--vscode-notifications-foreground: #eeffff;
--vscode-panel-background: #192227;
--vscode-panel-border: rgba(0, 0, 0, 0.38);
--vscode-panel-dropBackground: #eeffff;
--vscode-panelTitle-activeBorder: #80cbc4;
--vscode-panelTitle-activeForeground: #ffffff;
--vscode-panelTitle-inactiveForeground: #eeffff;
--vscode-peekView-border: rgba(0, 0, 0, 0.19);
--vscode-peekViewEditor-background: rgba(238, 255, 255, 0.02);
--vscode-peekViewEditor-matchHighlightBackground: rgba(128, 203, 196, 0.13);
--vscode-peekViewEditorGutter-background: rgba(238, 255, 255, 0.02);
--vscode-peekViewResult-background: rgba(238, 255, 255, 0.02);
--vscode-peekViewResult-fileForeground: #ffffff;
--vscode-peekViewResult-lineForeground: #bbbbbb;
--vscode-peekViewResult-matchHighlightBackground: rgba(128, 203, 196, 0.13);
--vscode-peekViewResult-selectionBackground: rgba(95, 122, 135, 0.44);
--vscode-peekViewResult-selectionForeground: #ffffff;
--vscode-peekViewTitle-background: rgba(238, 255, 255, 0.02);
--vscode-peekViewTitleDescription-foreground: rgba(238, 255, 255, 0.38);
--vscode-peekViewTitleLabel-foreground: #ffffff;
--vscode-pickerGroup-border: #3f3f46;
--vscode-pickerGroup-foreground: #80cbc4;
--vscode-progressBar-background: #80cbc4;
--vscode-scrollbar-shadow: rgba(38, 50, 56, 0);
--vscode-scrollbarSlider-activeBackground: #80cbc4;
--vscode-scrollbarSlider-background: rgba(238, 255, 255, 0.13);
--vscode-scrollbarSlider-hoverBackground: rgba(238, 255, 255, 0.06);
--vscode-selection-background: #eeffff;
--vscode-settings-checkboxBackground: #192227;
--vscode-settings-checkboxBorder: rgba(255, 255, 255, 0.06);
--vscode-settings-checkboxForeground: #eeffff;
--vscode-settings-dropdownBackground: #192227;
--vscode-settings-dropdownBorder: rgba(255, 255, 255, 0.06);
--vscode-settings-dropdownForeground: #eeffff;
--vscode-settings-dropdownListBorder: #ff0000;
--vscode-settings-headerForeground: #80cbc4;
--vscode-settings-modifiedItemIndicator: #80cbc4;
--vscode-settings-numberInputBackground: #192227;
--vscode-settings-numberInputBorder: rgba(255, 255, 255, 0.06);
--vscode-settings-numberInputForeground: #eeffff;
--vscode-settings-textInputBackground: #192227;
--vscode-settings-textInputBorder: rgba(255, 255, 255, 0.06);
--vscode-settings-textInputForeground: #eeffff;
--vscode-sideBar-background: #192227;
--vscode-sideBar-border: rgba(0, 0, 0, 0.38);
--vscode-sideBar-dropBackground: rgba(255, 255, 255, 0.12);
--vscode-sideBar-foreground: #5f7a87;
--vscode-sideBarSectionHeader-background: #192227;
--vscode-sideBarSectionHeader-border: rgba(0, 0, 0, 0.38);
--vscode-sideBarSectionHeader-foreground: #5f7a87;
--vscode-sideBarTitle-foreground: #eeffff;
--vscode-statusBar-background: #192227;
--vscode-statusBar-border: rgba(0, 0, 0, 0.38);
--vscode-statusBar-debuggingBackground: #c792ea;
--vscode-statusBar-debuggingBorder: rgba(0, 0, 0, 0.38);
--vscode-statusBar-debuggingForeground: #ffffff;
--vscode-statusBar-foreground: #546e7a;
--vscode-statusBar-noFolderBackground: #263238;
--vscode-statusBar-noFolderBorder: rgba(0, 0, 0, 0.38);
--vscode-statusBar-noFolderForeground: #546e7a;
--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);
--vscode-statusBarItem-hoverBackground: rgba(84, 110, 122, 0.13);
--vscode-statusBarItem-prominentBackground: #388a34;
--vscode-statusBarItem-prominentHoverBackground: #369432;
--vscode-tab-activeBackground: #263238;
--vscode-tab-activeBorder: #80cbc4;
--vscode-tab-activeForeground: #ffffff;
--vscode-tab-activeModifiedBorder: #5f7a87;
--vscode-tab-border: #263238;
--vscode-tab-inactiveBackground: #263238;
--vscode-tab-inactiveForeground: #5f7a87;
--vscode-tab-inactiveModifiedBorder: rgba(95, 122, 135, 0.5);
--vscode-tab-unfocusedActiveBorder: #546e7a;
--vscode-tab-unfocusedActiveForeground: #eeffff;
--vscode-tab-unfocusedActiveModifiedBorder: rgba(95, 122, 135, 0.5);
--vscode-tab-unfocusedInactiveForeground: rgba(95, 122, 135, 0.5);
--vscode-tab-unfocusedInactiveModifiedBorder: rgba(95, 122, 135, 0.25);
--vscode-terminal-ansiBlack: #000000;
--vscode-terminal-ansiBlue: #82aaff;
--vscode-terminal-ansiBrightBlack: #546e7a;
--vscode-terminal-ansiBrightBlue: #82aaff;
--vscode-terminal-ansiBrightCyan: #89ddff;
--vscode-terminal-ansiBrightGreen: #c3e88d;
--vscode-terminal-ansiBrightMagenta: #c792ea;
--vscode-terminal-ansiBrightRed: #ff5370;
--vscode-terminal-ansiBrightWhite: #ffffff;
--vscode-terminal-ansiBrightYellow: #ffcb6b;
--vscode-terminal-ansiCyan: #89ddff;
--vscode-terminal-ansiGreen: #c3e88d;
--vscode-terminal-ansiMagenta: #c792ea;
--vscode-terminal-ansiRed: #ff5370;
--vscode-terminal-ansiWhite: #ffffff;
--vscode-terminal-ansiYellow: #ffcb6b;
--vscode-terminal-background: #192227;
--vscode-terminal-border: rgba(0, 0, 0, 0.38);
--vscode-terminal-foreground: #cccccc;
--vscode-terminal-selectionBackground: rgba(255, 255, 255, 0.25);
--vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);
--vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);
--vscode-textCodeBlock-background: rgba(10, 10, 10, 0.4);
--vscode-textLink-activeForeground: #eeffff;
--vscode-textLink-foreground: #80cbc4;
--vscode-textPreformat-foreground: #d7ba7d;
--vscode-textSeparator-foreground: rgba(255, 255, 255, 0.18);
--vscode-titleBar-activeBackground: #192227;
--vscode-titleBar-activeForeground: #eeffff;
--vscode-titleBar-border: rgba(0, 0, 0, 0.38);
--vscode-titleBar-inactiveBackground: #192227;
--vscode-titleBar-inactiveForeground: #5f7a87;
--vscode-widget-shadow: rgba(0, 0, 0, 0.19);
}

View File

@@ -1,307 +0,0 @@
:root {
--vscode-activityBar-background: #2c2c2c;
--vscode-activityBar-dropBackground: rgba(255, 255, 255, 0.12);
--vscode-activityBar-foreground: #ffffff;
--vscode-activityBar-inactiveForeground: rgba(255, 255, 255, 0.6);
--vscode-activityBarBadge-background: #007acc;
--vscode-activityBarBadge-foreground: #ffffff;
--vscode-badge-background: #c4c4c4;
--vscode-badge-foreground: #333333;
--vscode-breadcrumb-activeSelectionForeground: #4e4e4e;
--vscode-breadcrumb-background: #ffffff;
--vscode-breadcrumb-focusForeground: #4e4e4e;
--vscode-breadcrumb-foreground: rgba(97, 97, 97, 0.8);
--vscode-breadcrumbPicker-background: #f3f3f3;
--vscode-button-background: #007acc;
--vscode-button-foreground: #ffffff;
--vscode-button-hoverBackground: #0062a3;
--vscode-debugExceptionWidget-background: #f1dfde;
--vscode-debugExceptionWidget-border: #a31515;
--vscode-debugToolBar-background: #f3f3f3;
--vscode-descriptionForeground: #717171;
--vscode-diffEditor-insertedTextBackground: rgba(155, 185, 85, 0.2);
--vscode-diffEditor-removedTextBackground: rgba(255, 0, 0, 0.2);
--vscode-dropdown-background: #ffffff;
--vscode-dropdown-border: #cecece;
--vscode-editor-background: #ffffff;
--vscode-editor-findMatchBackground: #a8ac94;
--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);
--vscode-editor-findRangeHighlightBackground: rgba(180, 180, 180, 0.3);
--vscode-editor-focusedStackFrameHighlightBackground: rgba(
206,
231,
206,
0.45
);
--vscode-editor-font-family: Consolas, "Courier New", monospace;
--vscode-editor-font-size: 14;
--vscode-editor-font-weight: normal;
--vscode-editor-foreground: #000000;
--vscode-editor-hoverHighlightBackground: rgba(173, 214, 255, 0.15);
--vscode-editor-inactiveSelectionBackground: #e5ebf1;
--vscode-editor-lineHighlightBorder: #eeeeee;
--vscode-editor-rangeHighlightBackground: rgba(253, 255, 0, 0.2);
--vscode-editor-selectionBackground: #add6ff;
--vscode-editor-selectionHighlightBackground: rgba(173, 214, 255, 0.5);
--vscode-editor-snippetFinalTabstopHighlightBorder: rgba(10, 50, 100, 0.5);
--vscode-editor-snippetTabstopHighlightBackground: rgba(10, 50, 100, 0.2);
--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 102, 0.45);
--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.25);
--vscode-editor-wordHighlightStrongBackground: rgba(14, 99, 156, 0.25);
--vscode-editorActiveLineNumber-foreground: #0b216f;
--vscode-editorBracketMatch-background: rgba(0, 100, 0, 0.1);
--vscode-editorBracketMatch-border: #b9b9b9;
--vscode-editorCodeLens-foreground: #999999;
--vscode-editorCursor-foreground: #000000;
--vscode-editorError-foreground: #e51400;
--vscode-editorGroup-border: #e7e7e7;
--vscode-editorGroup-dropBackground: rgba(38, 119, 203, 0.18);
--vscode-editorGroupHeader-noTabsBackground: #ffffff;
--vscode-editorGroupHeader-tabsBackground: #f3f3f3;
--vscode-editorGutter-addedBackground: #81b88b;
--vscode-editorGutter-background: #ffffff;
--vscode-editorGutter-commentRangeForeground: #c5c5c5;
--vscode-editorGutter-deletedBackground: #ca4b51;
--vscode-editorGutter-modifiedBackground: #66afe0;
--vscode-editorHint-foreground: #6c6c6c;
--vscode-editorHoverWidget-background: #f3f3f3;
--vscode-editorHoverWidget-border: #c8c8c8;
--vscode-editorHoverWidget-statusBarBackground: #e7e7e7;
--vscode-editorIndentGuide-activeBackground: #939393;
--vscode-editorIndentGuide-background: #d3d3d3;
--vscode-editorInfo-foreground: #008000;
--vscode-editorLineNumber-activeForeground: #0b216f;
--vscode-editorLineNumber-foreground: #237893;
--vscode-editorLink-activeForeground: #0000ff;
--vscode-editorMarkerNavigation-background: #ffffff;
--vscode-editorMarkerNavigationError-background: #e51400;
--vscode-editorMarkerNavigationInfo-background: #008000;
--vscode-editorMarkerNavigationWarning-background: #e9a700;
--vscode-editorOverviewRuler-addedForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-border: rgba(127, 127, 127, 0.3);
--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;
--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);
--vscode-editorOverviewRuler-currentContentForeground: rgba(
64,
200,
174,
0.5
);
--vscode-editorOverviewRuler-deletedForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);
--vscode-editorOverviewRuler-findMatchForeground: rgba(209, 134, 22, 0.49);
--vscode-editorOverviewRuler-incomingContentForeground: rgba(
64,
166,
255,
0.5
);
--vscode-editorOverviewRuler-infoForeground: #008000;
--vscode-editorOverviewRuler-modifiedForeground: rgba(0, 122, 204, 0.6);
--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(
0,
122,
204,
0.6
);
--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(
160,
160,
160,
0.8
);
--vscode-editorOverviewRuler-warningForeground: #e9a700;
--vscode-editorOverviewRuler-wordHighlightForeground: rgba(
160,
160,
160,
0.8
);
--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(
192,
160,
192,
0.8
);
--vscode-editorPane-background: #ffffff;
--vscode-editorRuler-foreground: #d3d3d3;
--vscode-editorSuggestWidget-background: #f3f3f3;
--vscode-editorSuggestWidget-border: #c8c8c8;
--vscode-editorSuggestWidget-foreground: #000000;
--vscode-editorSuggestWidget-highlightForeground: #0066bf;
--vscode-editorSuggestWidget-selectedBackground: #d6ebff;
--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.47);
--vscode-editorWarning-foreground: #e9a700;
--vscode-editorWhitespace-foreground: rgba(51, 51, 51, 0.2);
--vscode-editorWidget-background: #f3f3f3;
--vscode-editorWidget-border: #c8c8c8;
--vscode-errorForeground: #a1260d;
--vscode-extensionBadge-remoteBackground: #007acc;
--vscode-extensionBadge-remoteForeground: #ffffff;
--vscode-extensionButton-prominentBackground: #327e36;
--vscode-extensionButton-prominentForeground: #ffffff;
--vscode-extensionButton-prominentHoverBackground: #28632b;
--vscode-focusBorder: rgba(0, 122, 204, 0.4);
--vscode-font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC",
"Segoe UI", "Ubuntu", "Droid Sans", ans-serif;
--vscode-font-size: 13px;
--vscode-font-weight: normal;
--vscode-foreground: #616161;
--vscode-gitDecoration-addedResourceForeground: #587c0c;
--vscode-gitDecoration-conflictingResourceForeground: #6c6cc4;
--vscode-gitDecoration-deletedResourceForeground: #ad0707;
--vscode-gitDecoration-ignoredResourceForeground: #8e8e90;
--vscode-gitDecoration-modifiedResourceForeground: #895503;
--vscode-gitDecoration-submoduleResourceForeground: #1258a7;
--vscode-gitDecoration-untrackedResourceForeground: #007100;
--vscode-gitlens-gutterBackgroundColor: rgba(0, 0, 0, 0.05);
--vscode-gitlens-gutterForegroundColor: #747474;
--vscode-gitlens-gutterUncommittedForegroundColor: rgba(0, 188, 242, 0.6);
--vscode-gitlens-lineHighlightBackgroundColor: rgba(0, 188, 242, 0.2);
--vscode-gitlens-lineHighlightOverviewRulerColor: rgba(0, 188, 242, 0.6);
--vscode-gitlens-trailingLineBackgroundColor: rgba(0, 0, 0, 0);
--vscode-gitlens-trailingLineForegroundColor: rgba(153, 153, 153, 0.35);
--vscode-input-background: #ffffff;
--vscode-input-foreground: #616161;
--vscode-input-placeholderForeground: #767676;
--vscode-inputOption-activeBorder: #007acc;
--vscode-inputValidation-errorBackground: #f2dede;
--vscode-inputValidation-errorBorder: #be1100;
--vscode-inputValidation-infoBackground: #d6ecf2;
--vscode-inputValidation-infoBorder: #007acc;
--vscode-inputValidation-warningBackground: #f6f5d2;
--vscode-inputValidation-warningBorder: #b89500;
--vscode-list-activeSelectionBackground: #0074e8;
--vscode-list-activeSelectionForeground: #ffffff;
--vscode-list-dropBackground: #d6ebff;
--vscode-list-errorForeground: #b01011;
--vscode-list-focusBackground: #d6ebff;
--vscode-list-highlightForeground: #0066bf;
--vscode-list-hoverBackground: #e8e8e8;
--vscode-list-inactiveSelectionBackground: #e4e6f1;
--vscode-list-invalidItemForeground: #b89500;
--vscode-list-warningForeground: #855f00;
--vscode-listFilterWidget-background: #efc1ad;
--vscode-listFilterWidget-noMatchesOutline: #be1100;
--vscode-listFilterWidget-outline: rgba(0, 0, 0, 0);
--vscode-menu-background: #ffffff;
--vscode-menu-foreground: #616161;
--vscode-menu-selectionBackground: #0074e8;
--vscode-menu-selectionForeground: #ffffff;
--vscode-menu-separatorBackground: #888888;
--vscode-menubar-selectionBackground: rgba(0, 0, 0, 0.1);
--vscode-menubar-selectionForeground: #333333;
--vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);
--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);
--vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);
--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);
--vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);
--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);
--vscode-notificationCenterHeader-background: #e7e7e7;
--vscode-notificationLink-foreground: #006ab1;
--vscode-notifications-background: #f3f3f3;
--vscode-notifications-border: #e7e7e7;
--vscode-panel-background: #ffffff;
--vscode-panel-border: rgba(128, 128, 128, 0.35);
--vscode-panel-dropBackground: rgba(38, 119, 203, 0.18);
--vscode-panelInput-border: #dddddd;
--vscode-panelTitle-activeBorder: rgba(128, 128, 128, 0.35);
--vscode-panelTitle-activeForeground: #424242;
--vscode-panelTitle-inactiveForeground: rgba(66, 66, 66, 0.75);
--vscode-peekView-border: #007acc;
--vscode-peekViewEditor-background: #f2f8fc;
--vscode-peekViewEditor-matchHighlightBackground: rgba(245, 216, 2, 0.87);
--vscode-peekViewEditorGutter-background: #f2f8fc;
--vscode-peekViewResult-background: #f3f3f3;
--vscode-peekViewResult-fileForeground: #1e1e1e;
--vscode-peekViewResult-lineForeground: #646465;
--vscode-peekViewResult-matchHighlightBackground: rgba(234, 92, 0, 0.3);
--vscode-peekViewResult-selectionBackground: rgba(51, 153, 255, 0.2);
--vscode-peekViewResult-selectionForeground: #6c6c6c;
--vscode-peekViewTitle-background: #ffffff;
--vscode-peekViewTitleDescription-foreground: rgba(108, 108, 108, 0.7);
--vscode-peekViewTitleLabel-foreground: #333333;
--vscode-pickerGroup-border: #cccedb;
--vscode-pickerGroup-foreground: #0066bf;
--vscode-progressBar-background: #0e70c0;
--vscode-quickInput-background: #f3f3f3;
--vscode-scrollbar-shadow: #dddddd;
--vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, 0.6);
--vscode-scrollbarSlider-background: rgba(100, 100, 100, 0.4);
--vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7);
--vscode-settings-checkboxBackground: #ffffff;
--vscode-settings-checkboxBorder: #cecece;
--vscode-settings-dropdownBackground: #ffffff;
--vscode-settings-dropdownBorder: #cecece;
--vscode-settings-dropdownListBorder: #c8c8c8;
--vscode-settings-headerForeground: #444444;
--vscode-settings-modifiedItemIndicator: #66afe0;
--vscode-settings-numberInputBackground: #ffffff;
--vscode-settings-numberInputBorder: #cecece;
--vscode-settings-numberInputForeground: #616161;
--vscode-settings-textInputBackground: #ffffff;
--vscode-settings-textInputBorder: #cecece;
--vscode-settings-textInputForeground: #616161;
--vscode-sideBar-background: #f3f3f3;
--vscode-sideBar-dropBackground: rgba(0, 0, 0, 0.1);
--vscode-sideBarSectionHeader-background: rgba(128, 128, 128, 0.2);
--vscode-sideBarTitle-foreground: #6f6f6f;
--vscode-statusBar-background: #007acc;
--vscode-statusBar-debuggingBackground: #cc6633;
--vscode-statusBar-debuggingForeground: #ffffff;
--vscode-statusBar-foreground: #ffffff;
--vscode-statusBar-noFolderBackground: #68217a;
--vscode-statusBar-noFolderForeground: #ffffff;
--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);
--vscode-statusBarItem-hoverBackground: rgba(255, 255, 255, 0.12);
--vscode-statusBarItem-prominentBackground: rgba(0, 0, 0, 0.5);
--vscode-statusBarItem-prominentForeground: #ffffff;
--vscode-statusBarItem-prominentHoverBackground: rgba(0, 0, 0, 0.3);
--vscode-statusBarItem-remoteBackground: #16825d;
--vscode-statusBarItem-remoteForeground: #ffffff;
--vscode-tab-activeBackground: #ffffff;
--vscode-tab-activeForeground: #333333;
--vscode-tab-activeModifiedBorder: #33aaee;
--vscode-tab-border: #f3f3f3;
--vscode-tab-inactiveBackground: #ececec;
--vscode-tab-inactiveForeground: rgba(51, 51, 51, 0.7);
--vscode-tab-inactiveModifiedBorder: rgba(51, 170, 238, 0.5);
--vscode-tab-unfocusedActiveBackground: #ffffff;
--vscode-tab-unfocusedActiveForeground: rgba(51, 51, 51, 0.7);
--vscode-tab-unfocusedActiveModifiedBorder: rgba(51, 170, 238, 0.7);
--vscode-tab-unfocusedInactiveForeground: rgba(51, 51, 51, 0.35);
--vscode-tab-unfocusedInactiveModifiedBorder: rgba(51, 170, 238, 0.25);
--vscode-terminal-ansiBlack: #000000;
--vscode-terminal-ansiBlue: #0451a5;
--vscode-terminal-ansiBrightBlack: #666666;
--vscode-terminal-ansiBrightBlue: #0451a5;
--vscode-terminal-ansiBrightCyan: #0598bc;
--vscode-terminal-ansiBrightGreen: #14ce14;
--vscode-terminal-ansiBrightMagenta: #bc05bc;
--vscode-terminal-ansiBrightRed: #cd3131;
--vscode-terminal-ansiBrightWhite: #a5a5a5;
--vscode-terminal-ansiBrightYellow: #b5ba00;
--vscode-terminal-ansiCyan: #0598bc;
--vscode-terminal-ansiGreen: #00bc00;
--vscode-terminal-ansiMagenta: #bc05bc;
--vscode-terminal-ansiRed: #cd3131;
--vscode-terminal-ansiWhite: #555555;
--vscode-terminal-ansiYellow: #949800;
--vscode-terminal-background: #ffffff;
--vscode-terminal-border: rgba(128, 128, 128, 0.35);
--vscode-terminal-foreground: #333333;
--vscode-terminal-selectionBackground: rgba(0, 0, 0, 0.25);
--vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);
--vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);
--vscode-textCodeBlock-background: rgba(220, 220, 220, 0.4);
--vscode-textLink-activeForeground: #006ab1;
--vscode-textLink-foreground: #006ab1;
--vscode-textPreformat-foreground: #a31515;
--vscode-textSeparator-foreground: rgba(0, 0, 0, 0.18);
--vscode-titleBar-activeBackground: #dddddd;
--vscode-titleBar-activeForeground: #333333;
--vscode-titleBar-inactiveBackground: rgba(221, 221, 221, 0.6);
--vscode-titleBar-inactiveForeground: rgba(51, 51, 51, 0.6);
--vscode-tree-indentGuidesStroke: #a9a9a9;
--vscode-widget-shadow: #a8a8a8;
}

View File

@@ -1,16 +0,0 @@
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"strict": true,
"outDir": "dist",
"skipLibCheck": true,
"rootDir": "./src",
"resolveJsonModule": true,
"newLine": "LF",
"sourceMap": true,
"jsx": "react",
"experimentalDecorators": true
},
"include": ["src/**/*"]
}

View File

@@ -1,2 +0,0 @@
require("ts-node").register();
module.exports = require("./webpack.config.ts");

View File

@@ -1,95 +0,0 @@
import * as webpack from "webpack";
import path = require("path");
import HtmlWebpackPlugin = require("html-webpack-plugin");
import MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
import ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
import { CleanWebpackPlugin } from "clean-webpack-plugin";
import { EnabledVisualizers } from "@hediet/visualization";
const r = (file: string) => path.resolve(__dirname, file);
const mode = process.argv.some(v => v === "--fast") ? "fast" : "default";
const enabledVisualizers: EnabledVisualizers =
mode === "fast"
? {
VisJsGraphVisualizer: true,
TreeVisualizer: false,
GraphvizGraphVisualizer: false,
SvgVisualizer: false,
GraphvizDotVisualizer: false,
TextVisualizer: false,
PlotlyVisualizer: false,
GridVisualizer: false,
MonacoTextVisualizer: false,
AstVisualizer: false,
}
: {
VisJsGraphVisualizer: true,
TreeVisualizer: true,
GraphvizGraphVisualizer: true,
SvgVisualizer: true,
GraphvizDotVisualizer: true,
TextVisualizer: true,
PlotlyVisualizer: true,
GridVisualizer: true,
MonacoTextVisualizer: true,
AstVisualizer: true,
};
const stringifiedEnabledVisualizers: Record<string, string> = {};
for (const [key, val] of Object.entries(enabledVisualizers)) {
stringifiedEnabledVisualizers[key] = JSON.stringify(val);
}
module.exports = {
entry: [r("src/index.tsx")],
output: {
path: r("dist"),
filename: "[name].js",
chunkFilename: "[name]-[hash].js",
},
resolve: {
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
},
devtool: "source-map",
module: {
rules: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.scss$/, loader: "style-loader!css-loader!sass-loader" },
{
test: /\.(jpe?g|png|gif|eot|ttf|svg|woff|woff2|md)$/i,
loader: "file-loader",
},
{
test: /\.tsx?$/,
loader: "ts-loader",
options: { transpileOnly: true },
},
],
},
node: {
fs: "empty",
},
plugins: (() => {
const plugins: any[] = [
new HtmlWebpackPlugin({
title: "Debug Visualizer",
}),
new ForkTsCheckerWebpackPlugin(),
new CleanWebpackPlugin(),
new webpack.DefinePlugin({
ENABLED_VISUALIZERS: stringifiedEnabledVisualizers,
}),
];
plugins.push(
new MonacoWebpackPlugin({
// Add more languages here once webworker issues are solved.
languages: ["typescript"],
})
);
return plugins;
})(),
} as webpack.Configuration;

File diff suppressed because it is too large Load Diff

View File

@@ -1,57 +0,0 @@
{
"name": "@hediet/visualization",
"version": "0.0.1",
"license": "GPL-3.0",
"scripts": {
"dev": "tsc --watch",
"build": "tsc"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"dependencies": {
"@hediet/std": "^0.6.0",
"classnames": "^2.2.6",
"mobx": "^5.15.4",
"mobx-react": "^6.1.8",
"monaco-editor": "^0.20.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-measure": "^2.3.0",
"react-svg-pan-zoom": "^3.8.0",
"viz.js": "^2.1.2",
"line-column": "^1.0.2",
"vis-network": "^7.3.6",
"vis-data": "^6.4.1",
"react-plotly.js": "^2.4.0",
"plotly.js": "^1.52.2"
},
"devDependencies": {
"@types/plotly.js": "1.44.28",
"@types/react-plotly.js": "^2.2.4",
"@types/html-webpack-plugin": "^3.2.2",
"@types/react-measure": "^2.0.6",
"@types/react-svg-pan-zoom": "^3.3.0",
"@types/webpack": "^4.41.6",
"@types/classnames": "^2.2.9",
"@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5",
"@types/line-column": "^1.0.0",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.4.2",
"file-loader": "^5.1.0",
"fork-ts-checker-webpack-plugin": "^4.0.4",
"html-webpack-plugin": "^3.2.0",
"monaco-editor-webpack-plugin": "^1.9.0",
"node-sass": "^4.13.1",
"raw-loader": "^4.0.0",
"sass": "^1.25.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"ts-loader": "^6.2.1",
"ts-node": "^8.6.2",
"typescript": "^3.8.2",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
}
}

View File

@@ -1,12 +0,0 @@
export interface EnabledVisualizers {
VisJsGraphVisualizer: boolean;
TreeVisualizer: boolean;
GraphvizGraphVisualizer: boolean;
SvgVisualizer: boolean;
GraphvizDotVisualizer: boolean;
TextVisualizer: boolean;
PlotlyVisualizer: boolean;
GridVisualizer: boolean;
MonacoTextVisualizer: boolean;
AstVisualizer: boolean;
}

View File

@@ -1,30 +0,0 @@
import * as React from "react";
import { observable, runInAction } from "mobx";
import { observer } from "mobx-react";
export function makeLazyLoadable<TProps>(
selector: () => Promise<React.ComponentClass<TProps>>
): React.ComponentClass<TProps> {
@observer
class MyComponent extends React.Component<TProps> {
@observable
component: React.ComponentClass<TProps> | undefined;
async componentDidMount() {
const result = await selector();
runInAction("Set Lazily Loaded Component", () => {
this.component = result;
});
}
render() {
if (!this.component) {
return <div>Loading...</div>;
}
const C = this.component;
return <C {...this.props} />;
}
}
return MyComponent;
}

View File

@@ -1,71 +0,0 @@
import { ExtractedData } from "@hediet/debug-visualizer-data-extraction";
export interface VisualizationId extends String {
__brand: "VisualizationId";
}
export function asVisualizationId(id: string): VisualizationId {
return (id as unknown) as VisualizationId;
}
export interface Visualization {
readonly name: string;
readonly id: VisualizationId;
readonly priority: number;
render(): React.ReactElement;
}
export interface VisualizationCollector {
addVisualization(visualization: Visualization): void;
}
export abstract class Visualizer {
abstract visualize(
data: ExtractedData,
collector: VisualizationCollector
): void;
getVisualizationsArray(data: ExtractedData): Visualization[] {
const result = new Array<Visualization>();
this.visualize(data, {
addVisualization(visualization) {
result.push(visualization);
},
});
return result;
}
getBestVisualization(
data: ExtractedData,
preferredVisualization: VisualizationId | undefined
): {
visualization: Visualization | undefined;
allVisualizations: Visualization[];
} {
const allVisualizations = this.getVisualizationsArray(data);
allVisualizations.sort((a, b) => b.priority - a.priority);
let visualization: Visualization | undefined = allVisualizations[0];
if (preferredVisualization) {
const preferred = allVisualizations.find(
vis => vis.id === preferredVisualization
);
if (preferred) {
visualization = preferred;
}
}
return { visualization, allVisualizations };
}
}
export class ComposedVisualizer extends Visualizer {
constructor(private readonly composedProviders: ReadonlyArray<Visualizer>) {
super();
}
visualize(data: ExtractedData, collector: VisualizationCollector): void {
for (const c of this.composedProviders) {
c.visualize(data, collector);
}
}
}

View File

@@ -1,7 +0,0 @@
import * as React from "react";
export class VisualizerView extends React.Component {
render(): React.ReactNode {
return null;
}
}

View File

@@ -1,4 +0,0 @@
export * from "./visualizers";
export * from "./Visualizer";
export * from "./VisualizerView";
export * from "./EnabledVisualizers";

View File

@@ -1,22 +0,0 @@
declare module "viz.js" {
const x: any;
export default x;
}
declare module "viz.js/full.render.js" {
export const render: any;
export const Module: any;
}
declare module "line-column" {
export = function(
text: string
): {
fromIndex(
idx: number
): {
line: number;
col: number;
};
} {};
}

View File

@@ -1,256 +0,0 @@
function sqr(a: number) {
return a * a;
}
export type PointLike =
| Point
| { x?: number; y: number }
| { x: number; y?: number };
export function point(data: PointLike) {
if (data instanceof Point) {
return data;
}
return new Point(data.x || 0, data.y || 0);
}
export class Point {
public static readonly Zero = new Point(0, 0);
constructor(public readonly x: number, public readonly y: number) {}
public mapXY(fn: (arg: number) => number): Point {
return new Point(fn(this.x), fn(this.y));
}
public distance(other: PointLike = Point.Zero): number {
const d = this.sub(other);
return Math.sqrt(sqr(d.x) + sqr(d.y));
}
public sub(other: PointLike): Point {
const o = point(other);
return new Point(this.x - o.x, this.y - o.y);
}
public add(other: PointLike): Point {
const o = point(other);
return new Point(this.x + o.x, this.y + o.y);
}
public mul(scalar: number): Point {
return new Point(this.x * scalar, this.y * scalar);
}
public div(scalar: number): Point {
return new Point(this.x / scalar, this.y / scalar);
}
public equals(other: PointLike) {
const o = point(other);
return this.x === o.x && this.y === o.y;
}
public angle(): number {
const angle = Math.atan2(this.x, this.y);
return angle;
}
public getPointCloserTo(dest: PointLike, dist: number): Point {
if (this.equals(dest)) return this;
const angle = point(dest)
.sub(this)
.angle();
const result = new Point(
this.x + Math.sin(angle) * dist,
this.y + Math.cos(angle) * dist
);
return result;
}
public toJson(): { x: number; y: number } {
return { x: this.x, y: this.y };
}
}
function turn(p1: Point, p2: Point, p3: Point): number {
const A = (p3.y - p1.y) * (p2.x - p1.x);
const B = (p2.y - p1.y) * (p3.x - p1.x);
return A > B + Number.MIN_VALUE ? 1 : A + Number.MIN_VALUE < B ? -1 : 0;
}
export function isIntersect(
aStart: Point,
aEnd: Point,
bStart: Point,
bEnd: Point
): boolean {
return (
turn(aStart, bStart, bEnd) != turn(aEnd, bStart, bEnd) &&
turn(aStart, aEnd, bStart) != turn(aStart, aEnd, bEnd)
);
}
/**
* Liang-Barsky function by Daniel White
*
* @link http://www.skytopia.com/project/articles/compsci/clipping.html
*
* @param {number} x0
* @param {number} y0
* @param {number} x1
* @param {number} y1
* @param {array<number>} bbox
* @return {array<array<number>>|null}
*/
function liangBarsky(
x0: number,
y0: number,
x1: number,
y1: number,
bbox: [number, number, number, number]
): [[number, number], [number, number]] | null {
let [xmin, xmax, ymin, ymax] = bbox;
let t0 = 0,
t1 = 1;
let dx = x1 - x0,
dy = y1 - y0;
let p = 0,
q = 0,
r = 0;
for (let edge: 0 | 1 | 2 | 3 = 0; edge < 4; edge++) {
// Traverse through left, right, bottom, top edges.
if (edge === 0) {
p = -dx;
q = -(xmin - x0);
} else if (edge === 1) {
p = dx;
q = xmax - x0;
} else if (edge === 2) {
p = -dy;
q = -(ymin - y0);
} else if (edge === 3) {
p = dy;
q = ymax - y0;
}
r = q / p;
if (p === 0 && q < 0) return null; // Don't draw line at all. (parallel line outside)
if (p < 0) {
if (r > t1) return null;
// Don't draw line at all.
else if (r > t0) t0 = r; // Line is clipped!
} else if (p > 0) {
if (r < t0) return null;
// Don't draw line at all.
else if (r < t1) t1 = r; // Line is clipped!
}
}
return [[x0 + t0 * dx, y0 + t0 * dy], [x0 + t1 * dx, y0 + t1 * dy]];
}
export function intersectRectWithLine(
start: Point,
end: Point,
rect: Rectangle
): { first: Point; second: Point } | undefined {
const r = liangBarsky(start.x, start.y, end.x, end.y, [
rect.topLeft.x,
rect.bottomRight.x,
rect.topLeft.y,
rect.bottomRight.y,
]);
if (!r) {
return undefined;
}
return {
first: new Point(r[0][0], r[0][1]),
second: new Point(r[1][0], r[1][1]),
};
}
// first zoom then translate
export function scale(
clientOffset: Point,
clientSize: Point,
viewSize: Point
): { clientZoom: number; clientOffset: Point } {
const clientRatio = clientSize.x / clientSize.y;
const viewRatio = viewSize.x / viewSize.y;
let zoom = 1;
if (clientRatio < viewRatio) zoom = viewSize.y / clientSize.y;
else zoom = viewSize.x / clientSize.x;
const clientMid = clientOffset.mul(zoom).add(clientSize.mul(zoom / 2));
const viewMid = viewSize.div(2);
const clientOffset2 = viewMid.sub(clientMid);
return { clientOffset: clientOffset2, clientZoom: zoom };
}
export class Rectangle {
public static ofSize(position: PointLike, size: PointLike): Rectangle {
const pos = point(position);
return new Rectangle(pos, pos.add(size));
}
public static spanning(first: Point, ...rest: Point[]): Rectangle {
let min = first.toJson();
let max = first.toJson();
for (const p of rest) {
min.x = Math.min(min.x, p.x);
min.y = Math.min(min.y, p.y);
max.x = Math.max(max.x, p.x);
max.y = Math.max(max.y, p.y);
}
return new Rectangle(point(min), point(max));
}
constructor(
public readonly topLeft: Point,
public readonly bottomRight: Point
) {}
get center(): Point {
return this.bottomRight.add(this.topLeft).div(2);
}
get size(): Point {
return this.bottomRight.sub(this.topLeft);
}
get topRight(): Point {
return new Point(this.bottomRight.x, this.topLeft.y);
}
get bottomLeft(): Point {
return new Point(this.topLeft.x, this.bottomRight.y);
}
public intersects(selectionRect: Rectangle): boolean {
return !(
selectionRect.topLeft.x > this.bottomRight.x ||
selectionRect.bottomRight.x < this.topLeft.x ||
selectionRect.topLeft.y > this.bottomRight.y ||
selectionRect.bottomRight.y < this.topLeft.y
);
}
equals(other: Rectangle) {
return (
this.topLeft.equals(other.topLeft) &&
this.bottomRight.equals(other.bottomRight)
);
}
}

View File

@@ -1,90 +0,0 @@
import { Point, Rectangle } from "./Point";
import * as React from "react";
import { Properties } from "csstype";
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
export function omit<T, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {
const newObj: Omit<T, K> = {} as any;
for (const [key, val] of Object.entries(obj)) {
if (!keys.includes(key as K)) {
(newObj as any)[key] = val;
}
}
return newObj;
}
export interface SvgAttributes<T> extends React.DOMAttributes<T> {
stroke?: string;
className?: string;
style?: Properties;
pointerEvents?: "none" | "auto" | "initial";
}
export function SvgText(
props: {
position: Point;
children: any;
childRef?: React.Ref<SVGTextElement>;
textAnchor?: "middle" | "end" | "start";
dominantBaseline?: "central" | "middle";
} & SvgAttributes<SVGTextElement>
) {
return (
<text
x={props.position.x}
y={props.position.y}
ref={props.childRef}
{...omit(props, ["position", "childRef"])}
/>
);
}
export function SvgCircle(
props: {
center: Point;
radius: number;
childRef?: React.Ref<SVGCircleElement>;
} & SvgAttributes<SVGCircleElement>
) {
return (
<circle
cx={props.center.x}
cy={props.center.y}
r={props.radius}
ref={props.childRef}
{...omit(props, ["center", "radius", "childRef"])}
/>
);
}
export function SvgLine(
props: { start: Point; end: Point } & SvgAttributes<SVGLineElement>
) {
return (
<line
x1={props.start.x}
y1={props.start.y}
x2={props.end.x}
y2={props.end.y}
{...omit(props, ["end", "start"])}
/>
);
}
export function SvgRect(
props: { rectangle: Rectangle; fill?: string } & SvgAttributes<
SVGRectElement
>
) {
const r = props.rectangle;
return (
<rect
x={r.topLeft.x}
y={r.topLeft.y}
width={r.size.x}
height={r.size.y}
{...omit(props, ["rectangle"])}
/>
);
}

View File

@@ -1,255 +0,0 @@
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../Visualizer";
import {
ExtractedData,
isCommonDataType,
CommonDataTypes,
} from "@hediet/debug-visualizer-data-extraction";
import { createTreeViewModelFromTreeNodeData } from "./TreeVisualizer/TreeVisualizer";
import { TreeWithPathView, TreeViewModel } from "./TreeVisualizer/Views";
import * as React from "react";
import { observer, disposeOnUnmount } from "mobx-react";
import { observable, autorun, trace, computed } from "mobx";
import * as monaco from "monaco-editor";
import { getLanguageId } from "./text-visualizers/MonacoTextVisualizer";
import LineColumn from "line-column";
export class AstVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { ast: true })) {
collector.addVisualization({
id: asVisualizationId("ast"),
name: "AST",
priority: 110,
render() {
const m = createTreeViewModelFromTreeNodeData(data.root);
const l = LineColumn(data.text);
function translatePosition(pos: number): monaco.IPosition {
const r = l.fromIndex(pos);
return {
column: r.col,
lineNumber: r.line,
};
}
const nodeInfoToRange = (info: NodeInfo): monaco.IRange => {
const start = translatePosition(info.position);
const end = translatePosition(
info.position + info.length
);
const range = monaco.Range.fromPositions(start, end);
return range;
};
return (
<AstTree
model={m}
data={data}
nodeInfoToRange={nodeInfoToRange}
/>
);
},
});
}
}
}
interface NodeInfo {
position: number;
length: number;
}
@observer
export class AstTree extends React.Component<{
model: TreeViewModel<NodeInfo>;
data: CommonDataTypes.Ast;
nodeInfoToRange: (info: NodeInfo) => monaco.IRange;
}> {
render() {
const model = this.props.model;
const data = this.props.data;
let languageId = "text";
if (data.fileName) {
languageId = getLanguageId(data.fileName);
}
return (
<div className="component-AstTree">
<div className="part-tree2">
<TreeWithPathView model={model} />
</div>
<div className="part-editor">
<MonacoEditor
nodeInfoToRange={this.props.nodeInfoToRange}
model={model}
languageId={languageId}
text={data.text}
/>
</div>
</div>
);
}
}
@observer
export class MonacoEditor extends React.Component<{
text: string;
languageId: string;
model: TreeViewModel<NodeInfo>;
nodeInfoToRange: (info: NodeInfo) => monaco.IRange;
}> {
@observable private editor: monaco.editor.IStandaloneCodeEditor | undefined;
private modelNotObservable:
| monaco.editor.ITextModel
| undefined = undefined;
@observable private model: monaco.editor.ITextModel | undefined = undefined;
private markedDecorations: string[] = [];
private selectedDecorations: string[] = [];
componentWillUnmount() {
if (this.editor) {
this.editor.dispose();
}
}
@computed.struct
private get markedRanges(): monaco.IRange[] {
if (!this.editor || !this.model) {
return [];
}
const editorModel = this.model;
const ranges = this.props.model.marked.map(s =>
this.props.nodeInfoToRange(s.data)
);
return ranges;
}
@disposeOnUnmount
private _updateMarkedDecorations = autorun(
() => {
if (!this.editor) {
return;
}
const ranges = this.markedRanges;
this.markedDecorations = this.editor.deltaDecorations(
this.markedDecorations,
ranges.map(range => ({
range,
options: { className: "marked" },
}))
);
if (ranges.length > 0) {
this.editor.revealRange(
ranges[0],
monaco.editor.ScrollType.Smooth
);
}
},
{ name: "updateMarkedDecorations" }
);
@computed.struct
private get selected(): monaco.IRange | undefined {
if (this.editor && this.model) {
const selected = this.props.model.selected;
if (selected) {
const range = this.props.nodeInfoToRange(selected.data);
return range;
}
}
return undefined;
}
@disposeOnUnmount
private _updateSelectedDecoration = autorun(
() => {
console.log("_updateSelectedDecoration");
if (!this.editor) {
return;
}
const range = this.selected;
if (range) {
this.selectedDecorations = this.editor.deltaDecorations(
this.selectedDecorations,
[
{
range,
options: { className: "selected" },
},
]
);
this.editor.revealRange(range, monaco.editor.ScrollType.Smooth);
} else {
this.selectedDecorations = this.editor.deltaDecorations(
this.selectedDecorations,
[]
);
}
},
{ name: "updateDecorations" }
);
private test = (() => {
console.log("test created");
})();
@computed.struct
private get modelData(): { text: string; languageId: string } {
const { text, languageId } = this.props;
return { text, languageId };
}
@disposeOnUnmount
private _updateText = autorun(
() => {
console.log("_updateText rerun");
if (this.editor) {
const model = monaco.editor.createModel(
this.modelData.text,
this.modelData.languageId,
undefined
);
this.editor.setModel(model);
if (this.modelNotObservable) {
this.modelNotObservable.dispose();
}
this.modelNotObservable = model;
this.model = model;
}
},
{ name: "Update Model" }
);
private readonly setEditorDiv = (editorDiv: HTMLDivElement) => {
if (!editorDiv) {
return;
}
this.editor = monaco.editor.create(editorDiv, {
model: null,
automaticLayout: true,
scrollBeyondLastLine: false,
minimap: { enabled: false },
fixedOverflowWidgets: true,
readOnly: true,
lineDecorationsWidth: 0,
lineNumbersMinChars: 4,
glyphMargin: false,
smoothScrolling: true,
});
};
render() {
return (
<div className="component-monaco-editor">
<div className="part-editor" ref={this.setEditorDiv} />
</div>
);
}
}

View File

@@ -1,399 +0,0 @@
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../Visualizer";
import {
ExtractedData,
isCommonDataType,
CommonDataTypes,
} from "@hediet/debug-visualizer-data-extraction";
import * as React from "react";
import { observer } from "mobx-react";
import { computed, action, observable } from "mobx";
import { Icon } from "@blueprintjs/core";
export class GridVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { array: true })) {
collector.addVisualization({
id: asVisualizationId("grid"),
name: "Grid",
priority: 90,
render: () => <DecoratedGridComponent data={data} />,
});
}
}
}
export class DecoratedGridComponent extends React.Component<{
data: CommonDataTypes.Grid;
}> {
render() {
const d = this.props.data;
const map = new Set<string>();
function getUniqueId(tag: string): string {
let n = 0;
while (true) {
const id = tag + (n === 0 ? "" : `-${n}`);
if (!map.has(id)) {
map.add(id);
return id;
}
n++;
}
}
const rows: GridComponent["props"]["rows"] = [];
rows.push();
let rowIdx = 0;
let columnCount = 0;
for (const row of d.rows) {
columnCount = Math.max(columnCount, row.columns.length);
rows.push({
columns: row.columns.map((c, colIdx) => ({
content: (
<Cell>
{c.content !== undefined ? c.content : c.tag || ""}
</Cell>
),
id:
c.tag !== undefined
? getUniqueId(c.tag)
: `${rowIdx}-${colIdx}`,
color: c.color,
kind: "data",
})),
});
rowIdx++;
}
rows.unshift({
columns: [...new Array(columnCount)].map((v, idx) => ({
id: `column-header-${idx}`,
content: <Cell>{idx}</Cell>,
kind: "header",
})),
});
if (d.markers) {
for (const m of d.markers) {
rows.push({
columns: [],
});
const r = rows[rows.length - 1];
for (let i = 0; i < m.column; i++) {
r.columns.push({
content: "",
kind: "empty",
id: `marker-spacer-${i}`,
});
}
r.columns.push({
id: m.id,
kind: "empty",
content: (
<Cell>
<Icon
icon="arrow-up"
color="var(--vscode-editor-foreground)"
/>
{m.label || m.id}
</Cell>
),
});
}
}
return (
<div
style={{
height: "100%",
justifyContent: "center",
alignItems: "center",
padding: 10,
display: "flex",
}}
>
<GridComponent rows={rows} markers={[]} />
</div>
);
}
}
function Cell(props: { children: React.ReactNode }) {
return (
<div
style={{
padding: 10,
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
{props.children}
</div>
);
}
interface CellData {
content: React.ReactNode;
id: string;
color?: string;
kind: "data" | "header" | "empty";
}
@observer
class GridComponent extends React.Component<{
rows: {
columns: CellData[];
}[];
markers: {
id: string;
row: number;
column: number;
rows?: number;
columns?: number;
label?: string;
color?: string;
}[];
}> {
private readonly cells = new Map<string, CellInfo>();
@computed get cellsGrid(): { maxWidth: number; grid: CellInfo[][] } {
const unusedIds = new Set(this.cells.keys());
const rows = this.props.rows;
const grid = new Array<Array<CellInfo>>();
let maxWidth = 0;
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
const row = rows[rowIdx];
maxWidth = Math.max(maxWidth, row.columns.length);
const cellRow = new Array<CellInfo>();
grid.push(cellRow);
for (let colIdx = 0; colIdx < row.columns.length; colIdx++) {
const col = row.columns[colIdx];
const key = col.id;
unusedIds.delete(key);
let c = this.cells.get(key);
if (!c) {
// New cell
c = new CellInfo(col);
this.cells.set(key, c);
} else {
c.updateCellData(col);
}
cellRow.push(c);
}
}
for (const id in unusedIds.values()) {
this.cells.delete(id);
}
return { maxWidth, grid };
}
@computed
private get layout(): {
cells: {
cell: CellInfo;
top: number;
left: number;
width: number;
height: number;
}[];
width: number;
height: number;
} {
const { maxWidth, grid } = this.cellsGrid;
const maxWidths = new Array<number>();
for (let colIdx = 0; colIdx < maxWidth; colIdx++) {
let maxWidth = 30;
for (const row of grid) {
const col = row[colIdx];
if (col) {
maxWidth = Math.max(maxWidth, col.contentWidth || 0);
}
}
maxWidths.push(maxWidth);
}
const result = new Array<{
cell: CellInfo;
top: number;
left: number;
width: number;
height: number;
}>();
let width = 0;
let height = 0;
let top = 0;
let left = 0;
for (const row of grid) {
let maxHeight = 0;
for (const col of row) {
maxHeight = Math.max(maxHeight, col.contentHeight || 0);
}
for (let colIdx = 0; colIdx < row.length; colIdx++) {
const maxWidth = maxWidths[colIdx];
const col = row[colIdx];
result.push({
cell: col,
top,
left,
height: maxHeight,
width: maxWidth,
});
height = Math.max(height, top + maxHeight);
width = Math.max(width, left + maxWidth);
col.lastTop = col.top;
col.lastLeft = col.left;
col.top = top;
col.left = left;
col.lastContentArea = col.contentArea;
col.contentArea = maxHeight * maxWidth;
left += maxWidth;
}
left = 0;
top += maxHeight;
}
result.sort((a, b) => a.cell.id.localeCompare(b.cell.id));
return { cells: result, height, width };
}
render() {
const l = this.layout;
return (
<div
className="component-Grid"
style={{
position: "relative",
height: l.height,
width: l.width,
}}
>
{l.cells.map(i => (
<div
key={i.cell.id}
style={{
position: "absolute",
top: i.top,
left: i.left,
height: i.height,
width: i.width,
zIndex: i.cell.distance,
transition:
i.cell.lastContentArea !== 0 ? "all 1s" : "",
}}
>
<div
className={`part-${i.cell.kind}`}
style={
{
empty: {},
data: {
display: "flex",
overflow: "hidden",
justifyContent: "center",
margin: 2,
},
header: {
overflow: "hidden",
display: "flex",
justifyContent: "center",
margin: 2,
},
}[i.cell.kind]
}
>
<div
ref={i.cell.handleRef}
style={{
width: "fit-content",
height: "fit-content",
}}
>
{i.cell.content}
</div>
</div>
</div>
))}
</div>
);
}
componentDidMount() {
this.updateContentSize();
}
componentDidUpdate() {
this.updateContentSize();
}
@action
updateContentSize() {
for (const c of this.cells.values()) {
if (c.ref) {
const r = c.ref.getBoundingClientRect();
c.contentHeight = r.height + 6;
c.contentWidth = r.width + 4;
}
}
}
}
class CellInfo {
@observable public contentWidth: number | undefined = undefined;
@observable public contentHeight: number | undefined = undefined;
public contentArea = 0;
public lastContentArea = 0;
public lastTop = 0;
public top = 0;
public lastLeft = 0;
public left = 0;
public get distance(): number {
return Math.floor(
Math.pow(this.top - this.lastTop, 2) +
Math.pow(this.left - this.lastLeft, 2)
);
}
content!: React.ReactNode;
ref: HTMLDivElement | null = null;
public readonly id: string;
public readonly kind: CellData["kind"];
constructor(cellData: CellData) {
this.id = cellData.id;
this.kind = cellData.kind;
this.updateCellData(cellData);
}
public updateCellData(cellData: CellData) {
this.content = cellData.content;
}
public readonly handleRef = (ref: HTMLDivElement | null) => {
this.ref = ref;
};
}

View File

@@ -1,113 +0,0 @@
import Measure, { ContentRect } from "react-measure";
import { observer } from "mobx-react";
import * as React from "react";
import { observable, action } from "mobx";
import { Tool, ReactSVGPanZoom, Value } from "react-svg-pan-zoom";
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
export class SvgVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { svg: true })) {
collector.addVisualization({
id: asVisualizationId("svg"),
name: "Svg",
priority: 100,
render() {
return <SvgViewer svgContent={data.text} />;
},
});
}
}
}
function widthOrDefault(r: ContentRect): number {
if (r.bounds && r.bounds.width) {
return r.bounds.width;
}
return 1;
}
function heightOrDefault(r: ContentRect): number {
console.log(r);
if (r.bounds && r.bounds.height) {
return r.bounds.height;
}
return 1;
}
@observer
export class SvgViewer extends React.Component<{
svgContent: string;
svgRef?: (element: SVGSVGElement | null) => void;
}> {
@observable tool: Tool = "pan";
@action.bound
private setTool(tool: Tool): void {
this.tool = tool;
}
private setRef(element: ReactSVGPanZoom | null) {
if (this.props.svgRef) {
if (!element) {
this.props.svgRef(null);
return;
}
const svg = (element as any).ViewerDOM as SVGSVGElement;
this.props.svgRef(svg);
}
}
@observable value: Value | {} = {};
render() {
let { svgContent } = this.props;
let width: number = 0;
let height: number = 0;
svgContent = svgContent.replace(
/viewBox="[0-9\.]+ [0-9\.]+ ([0-9\.]+) ([0-9\.]+)"/,
(r, w, h) => {
width = parseFloat(w);
height = parseFloat(h);
return "";
}
);
const tool = this.tool;
const val = this.value;
return (
<Measure bounds>
{({ measureRef, contentRect }) => (
<div ref={measureRef} className="svgViewer">
<ReactSVGPanZoom
width={widthOrDefault(contentRect)}
height={heightOrDefault(contentRect)}
tool={tool}
value={val as any}
onChangeValue={v => (this.value = v)}
onChangeTool={this.setTool}
ref={e => this.setRef(e)}
>
<svg width={width} height={height}>
<g
dangerouslySetInnerHTML={{
__html: svgContent,
}}
/>
</svg>
</ReactSVGPanZoom>
</div>
)}
</Measure>
);
}
}

View File

@@ -1,64 +0,0 @@
import {
TreeViewModel,
TreeNodeViewModel,
TreeView,
TreeWithPathView,
} from "./Views";
import {
ExtractedData,
isCommonDataType,
TreeNode,
} from "@hediet/debug-visualizer-data-extraction";
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import * as React from "react";
export class TreeVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { tree: true })) {
collector.addVisualization({
id: asVisualizationId("tree"),
name: "Tree",
priority: 100,
render() {
const m = createTreeViewModelFromTreeNodeData(data.root);
return <TreeWithPathView model={m} />;
},
});
}
}
}
export function createTreeViewModelFromTreeNodeData<TData>(
root: TreeNode<TData>
): TreeViewModel<TData> {
const m = new TreeViewModel<TData>();
m.root = recurse(root, m);
return m;
function recurse(
node: TreeNode<TData>,
viewModel: TreeViewModel<TData>
): TreeNodeViewModel<TData> {
const children: TreeNodeViewModel<TData>[] = node.children.map(c =>
recurse(c, viewModel)
);
const model = new TreeNodeViewModel<TData>(
viewModel,
node.id,
node.name,
node.value,
node.emphasizedValue,
children,
node.data
);
model.isMarked = !!node.isMarked;
for (const c of children) {
c.parent = model;
}
return model;
}
}

View File

@@ -1,530 +0,0 @@
import { observer, disposeOnUnmount } from "mobx-react";
import { observable, autorun, computed, action, runInAction } from "mobx";
import * as React from "react";
import * as classNames from "classnames";
import { Rectangle, Point } from "../../utils/Point";
import { SvgLine } from "../../utils/SvgElements";
// import "./style.scss";
export class TreeViewModel<TData = unknown> {
private started = true;
start() {
this.started = true;
this.updateOffsets();
}
stop() {
this.started = false;
}
private version = 0;
private lastUpdateVersion = -1;
@observable public root: TreeNodeViewModel<TData> | undefined = undefined;
public invalidateOffsets() {
this.version++;
}
@action
public updateOffsets() {
if (!this.started) {
return;
}
if (!this.root) {
return;
}
if (this.lastUpdateVersion === this.version) {
return;
}
this.lastUpdateVersion = this.version;
console.log("update");
this.root.updateOffsets();
}
public get marked(): TreeNodeViewModel<TData>[] {
const result = new Array<TreeNodeViewModel<TData>>();
function recurse(node: TreeNodeViewModel<TData>) {
if (node.isMarked) {
result.push(node);
}
for (const c of node.children) {
recurse(c);
}
}
if (this.root) {
recurse(this.root);
}
return result;
}
@observable selected: TreeNodeViewModel<TData> | undefined = undefined;
@action public select(current: TreeNodeViewModel<TData> | undefined) {
if (this.selected === current) {
return;
}
if (this.selected) {
this.selected.isSelected = false;
}
if (current) {
current.isSelected = true;
}
this.selected = current;
}
@action public toggleSelect(current: TreeNodeViewModel<TData>) {
if (this.selected === current) {
this.select(undefined);
} else {
this.select(current);
}
}
private selectOnHoverEnabled = false;
private selectedBeforeHover:
| TreeNodeViewModel<TData>
| undefined = undefined;
@action public handleHoverEvent(
current: TreeNodeViewModel<TData> | undefined
) {
if (this.selectOnHoverEnabled) {
if (current) {
this.select(current);
} else {
this.select(this.selectedBeforeHover);
}
}
}
setSelectOnHover(enable: boolean) {
if (this.selectOnHoverEnabled === enable) {
return;
}
if (enable) {
this.selectedBeforeHover = this.selected;
} else if (!this.selected) {
this.select(this.selectedBeforeHover);
}
this.selectOnHoverEnabled = enable;
}
}
let i = 0;
export class TreeNodeViewModel<TData = unknown> {
public parent: TreeNodeViewModel<TData> | null = null;
constructor(
public readonly treeViewModel: TreeViewModel<TData>,
public readonly id: string | undefined,
public readonly name: string,
public readonly value: string | undefined,
public readonly emphasizedValue: string | undefined,
public readonly children: TreeNodeViewModel<TData>[],
public readonly data: TData
) {}
@observable expanderOffsetRect: Rectangle | undefined = undefined;
private expanderDiv: HTMLDivElement | null = null;
@action.bound
setExpanderDiv(div: HTMLDivElement | null) {
this.expanderDiv = div;
this.treeViewModel.invalidateOffsets();
}
@observable public expanded: boolean = false;
@observable public isMarked: boolean = false;
@observable public isSelected: boolean = false;
@action
public toggleExpanded() {
this.expanded = !this.expanded;
this.treeViewModel.invalidateOffsets();
}
@computed public get isChildOrThisMarked(): boolean {
if (this.isMarked) return true;
return this.children.some(c => c.isChildOrThisMarked);
}
@computed public get isChildOrThisSelected(): boolean {
if (this.isSelected) return true;
return this.children.some(c => c.isChildOrThisSelected);
}
@computed public get isParentOrThisSelected(): boolean {
if (this.isSelected) return true;
if (this.parent) return this.parent.isParentOrThisSelected;
return false;
}
get path(): string[] {
const result = new Array<string>();
let c: TreeNodeViewModel = this;
while (c.parent) {
result.unshift(c.id || c.name);
c = c.parent;
}
if (result.length === 0) {
result.push("root");
}
return result;
}
updateOffsets() {
for (const c of this.children) {
c.updateOffsets();
}
if (!this.expanderDiv) {
return;
}
const newRect = Rectangle.ofSize(
new Point(this.expanderDiv.offsetLeft, this.expanderDiv.offsetTop),
new Point(
this.expanderDiv.offsetWidth,
this.expanderDiv.offsetHeight
)
);
if (
!this.expanderOffsetRect ||
!newRect.equals(this.expanderOffsetRect)
) {
this.expanderOffsetRect = newRect;
}
}
}
const isValidFunctionName = (function() {
var validName = /^[$A-Z_][0-9A-Z_$]*$/i;
var reserved = {
abstract: true,
boolean: true,
// ...
with: true,
} as any;
return function(s: string) {
// Ensure a valid name and not reserved.
return validName.test(s) && !reserved[s];
};
})();
@observer
export class TreeWithPathView extends React.Component<{
model: TreeViewModel;
}> {
render() {
const model = this.props.model;
return (
<div className="component-TreeWithPathView">
<div className="part-path">
<span>
{model.selected ? (
<span>
{model.selected.path.reduce((acc, v) => {
acc = acc.slice();
function add() {
acc.push(
<span
className="part-path-item"
key={acc.length}
>
{v}
</span>
);
}
if (isValidFunctionName(v)) {
if (acc.length > 0) {
acc.push(
<span key={acc.length}>.</span>
);
}
add();
} else {
acc.push(
<span key={acc.length}>[</span>
);
add();
acc.push(
<span key={acc.length}>]</span>
);
}
return acc;
}, new Array<React.ReactElement>())}
</span>
) : (
"(Nothing Selected)"
)}
</span>
</div>
<div className="part-tree">
<TreeView model={model} />
</div>
</div>
);
}
}
@observer
export class TreeView extends React.Component<{ model: TreeViewModel }> {
componentWillUpdate(newProps: this["props"]) {
newProps.model.stop();
}
componentWillMount() {
this.props.model.stop();
}
componentDidUpdate() {
this.props.model.start();
}
componentDidMount() {
this.props.model.start();
}
render() {
const model = this.props.model;
return (
<div
tabIndex={0}
className="component-TreeView"
onKeyDown={e => {
if (e.keyCode === 18) {
// alt
e.preventDefault();
e.stopPropagation();
model.setSelectOnHover(true);
}
}}
onKeyUp={e => {
if (e.keyCode === 18) {
// alt
e.preventDefault();
e.stopPropagation();
model.setSelectOnHover(false);
}
}}
>
{model.root && (
<>
<svg className="part-svg">
<TreeNodeSvgView model={model.root} />
</svg>
<div className="part-node">
<TreeNodeView model={model.root} />
</div>
</>
)}
</div>
);
}
}
@observer
export class TreeNodeSvgView extends React.Component<{
model: TreeNodeViewModel;
}> {
render() {
const model = this.props.model;
if (
!model.expanderOffsetRect ||
model.children.length === 0 ||
model.expanded
) {
return <g />;
}
function findLastExpanderOffset(
predicate: (v: TreeNodeViewModel) => boolean
): Rectangle | undefined {
const all = model.children
.filter(predicate)
.map(c => c.expanderOffsetRect);
const last = all[all.length - 1];
return last;
}
const lastOffset = findLastExpanderOffset(() => true);
const selectedOffset = findLastExpanderOffset(
v => v.isChildOrThisSelected
);
const markedOffset = findLastExpanderOffset(v => v.isChildOrThisMarked);
if (!lastOffset) {
return <g />;
}
const start = model.expanderOffsetRect.center.add({ y: 10 });
return (
<g className="component-TreeNodeSvgView">
{markedOffset && (
<SvgLine
className="path childOrThisMarked"
start={start}
end={new Point(start.x, markedOffset.center.y)}
/>
)}
{selectedOffset && (
<SvgLine
className="path childOrThisSelected"
start={start}
end={new Point(start.x, selectedOffset.center.y)}
/>
)}
<SvgLine
className="path"
start={start}
end={new Point(start.x, lastOffset.center.y)}
/>
{model.children.map((c, idx) => {
const end = c.expanderOffsetRect!.center.sub({ x: 5 });
return (
<g key={idx}>
{c.isChildOrThisMarked && (
<SvgLine
className={classNames(
"path",
"childOrThisMarked"
)}
start={new Point(start.x, end.y)}
end={end}
/>
)}
<SvgLine
className={classNames(
"path",
c.isChildOrThisSelected &&
"childOrThisSelected"
)}
start={new Point(start.x, end.y)}
end={end}
/>
</g>
);
})}
{model.children.map((c, idx) => (
<TreeNodeSvgView key={idx} model={c} />
))}
</g>
);
}
}
@observer
export class TreeNodeView extends React.Component<{
model: TreeNodeViewModel;
}> {
@action.bound
private clickHandler() {
this.props.model.treeViewModel.toggleSelect(this.props.model);
}
private handleMouseEnterOrLeave(enter: boolean) {
this.props.model.treeViewModel.handleHoverEvent(
enter ? this.props.model : undefined
);
}
@observable
private rootDiv: HTMLElement | null = null;
@action.bound
private setRootDiv(div: HTMLElement | null) {
this.rootDiv = div;
}
@disposeOnUnmount
private readonly _autorun = autorun(() => {
if (this.props.model.isMarked && this.rootDiv) {
this.rootDiv.scrollIntoView();
}
});
public componentDidMount() {
this.props.model.treeViewModel.updateOffsets();
}
public componentDidUpdate() {
this.props.model.treeViewModel.updateOffsets();
}
public render(): JSX.Element {
const model = this.props.model;
const collapsed = model.expanded;
console.log("render");
return (
<div
className={classNames(
"component-TreeNodeView",
model.expanded && "collapsed",
model.isMarked && "selected",
model.isSelected && "hovered",
model.isChildOrThisSelected &&
!model.isSelected &&
"childHovered",
model.isParentOrThisSelected &&
!model.isSelected &&
"parentHovered"
)}
ref={this.setRootDiv}
>
<div
className="part-header"
onMouseOver={e => {
this.handleMouseEnterOrLeave(true);
e.stopPropagation();
}}
onMouseOut={e => {
this.handleMouseEnterOrLeave(false);
e.stopPropagation();
}}
>
<div
ref={model.setExpanderDiv}
onClick={() => model.toggleExpanded()}
className={classNames(
"part-collapser",
model.children.length > 0 &&
"decorator-collapse-icon",
!collapsed && "expanded"
)}
/>
<span className="part-text" onClick={this.clickHandler}>
{model.id && (
<>
<span className="part-id">{model.id}</span>
<span>: </span>
</>
)}
<span className="part-name">{model.name}</span>
{model.value && (
<span className="part-value">{model.value}</span>
)}
{model.emphasizedValue && (
<span className="part-emphasized-value">
{model.emphasizedValue}
</span>
)}
</span>
</div>
{model.children.length > 0 && !model.expanded && (
<div className="part-children">
{model.children.map((c, idx) => (
<TreeNodeView model={c} key={idx} />
))}
</div>
)}
</div>
);
}
}

View File

@@ -1,141 +0,0 @@
.component-TreeView {
overflow: auto;
scroll-behavior: smooth;
height: 100%;
position: relative;
display: grid;
& > .part-svg,
& > .part-node {
height: 100%;
width: 100%;
grid-column: 1;
grid-row: 1;
}
}
.component-TreeNodeSvgView {
.path {
stroke: gray;
stroke-dasharray: 1;
&.childOrThisMarked {
stroke: orange;
stroke-width: 5;
stroke-dasharray: 0;
stroke-linecap: round;
}
&.childOrThisSelected {
stroke: black;
stroke-width: 2;
stroke-dasharray: 0;
}
}
}
.component-TreeNodeView {
font-family: -apple-system, BlinkMacSystemFont, Segoe WPC, Segoe UI,
HelveticaNeue-Light, Ubuntu, Droid Sans, sans-serif;
.part-header {
padding: 2px;
padding-left: 5px;
margin: 0;
display: flex;
align-items: center;
.part-collapser {
width: 10px;
height: 10px;
margin-right: 6px;
}
.part-text {
cursor: pointer;
.part-id {
color: blue;
}
.part-value {
color: darkgreen;
text-decoration: underline;
/*&::before,
&::after {
content: '"';
}*/
padding: 1px 3px;
margin-left: 5px;
}
.part-emphasized-value {
color: darkred;
border: black solid 1px;
padding: 1px 3px;
margin-left: 5px;
}
}
}
.part-children {
margin-left: 0px;
margin-top: 0px;
padding: 5px;
padding-left: 15px;
}
&.selected {
& > .part-header {
font-weight: bold;
}
}
&.hovered {
& > .part-header > span {
font-weight: bold;
}
& > .part-children {
background: transparentize(gray, 0.8);
}
}
}
.component-TreeWithPathView {
display: flex;
flex-direction: column;
height: 100%;
.part-path {
overflow: hidden;
white-space: pre;
padding: 5px 10px;
border-bottom: solid gray 1px;
color: lightgray;
.part-path-item {
color: black;
margin-left: 1px;
margin-right: 1px;
}
}
.part-tree {
overflow: auto;
flex: 1;
}
}
.decorator-collapse-icon {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z'/%3E%3C/svg%3E");
background-position: 50%;
background-position-x: 50%;
background-position-y: center;
background-repeat: no-repeat;
&.expanded {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M11 10.07H5.344L11 4.414v5.656z'/%3E%3C/svg%3E");
}
}

View File

@@ -1,72 +0,0 @@
import { observer, disposeOnUnmount } from "mobx-react";
import * as React from "react";
import { observable, autorun, runInAction } from "mobx";
import { SvgViewer } from "../SvgVisualizer";
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
export class GraphvizDotVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { dotGraph: true })) {
collector.addVisualization({
id: asVisualizationId("graphviz-dot"),
name: "Graphviz (Dot Data)",
priority: 100,
render() {
return <GraphvizDotViewer dotCode={data.text} />;
},
});
}
}
}
class VisLoader {
private result: any | undefined;
async getViz(): Promise<any> {
if (!this.result) {
const Viz = await import("viz.js");
const { Module, render } = await import("viz.js/full.render.js");
const viz = new Viz.default({
Module: () => Module({ TOTAL_MEMORY: 1 << 30 }),
render,
});
this.result = viz;
}
return this.result;
}
}
const vizLoader = new VisLoader();
@observer
export class GraphvizDotViewer extends React.Component<{
dotCode: string;
svgRef?: (element: SVGSVGElement | null) => void;
}> {
@observable private svg: string | null = null;
@disposeOnUnmount
// @ts-ignore
private readonly _updateSvgAutorun = autorun(async () => {
const viz = await vizLoader.getViz();
const svg = await viz.renderString(this.props.dotCode);
runInAction("Update svg", () => (this.svg = svg));
});
render() {
if (!this.svg) {
return <div>Loading...</div>;
}
return <SvgViewer svgRef={this.props.svgRef} svgContent={this.svg} />;
}
}

View File

@@ -1,65 +0,0 @@
import { observer } from "mobx-react";
import * as React from "react";
import { GraphvizDotViewer } from "./GraphvizDotVisualizer";
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
export class GraphvizGraphVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { graph: true })) {
collector.addVisualization({
id: asVisualizationId("graphviz-graph"),
name: "Graphviz",
priority: 100,
render() {
return (
<GraphvizGraphViewer
edges={data.edges}
nodes={data.nodes}
/>
);
},
});
}
}
}
@observer
export class GraphvizGraphViewer extends React.Component<{
nodes: { id: string; label?: string }[];
edges: { from: string; to: string; label?: string }[];
}> {
render() {
const { nodes, edges } = this.props;
const dotContent = `
digraph MyGraph {
${nodes
.map(
n =>
`"${n.id}" [ label = ${JSON.stringify(
n.label !== undefined ? n.label : n.id
)} ];`
)
.join("\n ")}
${edges
.map(
e =>
`"${e.from}" -> "${
e.to
}" [ label = ${JSON.stringify(
e.label !== undefined ? e.label : ""
)} ];`
)
.join("\n")}
}
`;
return <GraphvizDotViewer dotCode={dotContent} />;
}
}

View File

@@ -1,99 +0,0 @@
import { DataSet, Network, Options } from "vis-network";
import { observer } from "mobx-react";
import * as React from "react";
import {
NodeGraphData,
EdgeGraphData,
} from "@hediet/debug-visualizer-data-extraction";
@observer
export class VisJsGraphViewer extends React.Component<{
nodes: NodeGraphData[];
edges: EdgeGraphData[];
}> {
private readonly divRef = React.createRef<HTMLDivElement>();
private readonly nodes = new DataSet<{
id: string;
label?: string;
color?: string;
shape?: string;
}>();
private readonly edges = new DataSet<{
id: string;
from: string;
to: string;
label?: string;
color?: string;
dashes?: boolean;
shape?: boolean;
}>();
render() {
return <div style={{ height: "100%" }} ref={this.divRef} />;
}
synchronizeData() {
const newNodes = new Set<string>();
for (const n of this.props.nodes) {
newNodes.add(n.id);
this.nodes.update({
id: n.id,
label: n.label !== undefined ? n.label : n.id,
color: n.color,
shape: n.shape,
});
}
this.nodes.forEach(item => {
if (!newNodes.has(item.id)) {
this.nodes.remove(item);
}
});
function getIdOfEdge(e: EdgeGraphData): string {
if (e.id) {
return e.id;
}
return e.from + "####" + e.to + "|" + e.label;
}
const newEdges = new Set<string>();
for (const n of this.props.edges) {
const id = getIdOfEdge(n);
newEdges.add(id);
this.edges.update({
id: id,
label: n.label !== undefined ? n.label : "",
from: n.from,
to: n.to,
color: n.color,
dashes: n.dashes,
});
}
this.edges.forEach(item => {
if (!newEdges.has(item.id)) {
this.edges.remove(item);
}
});
}
componentDidUpdate() {
this.synchronizeData();
}
componentDidMount() {
this.synchronizeData();
const data = {
nodes: this.nodes,
edges: this.edges,
};
const options: Options = {
edges: {
arrows: {
to: { enabled: true, scaleFactor: 1, type: "arrow" },
},
},
};
const network = new Network(this.divRef.current!, data, options);
}
}

View File

@@ -1,36 +0,0 @@
import * as React from "react";
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
import { makeLazyLoadable } from "../../LazyLoadable";
// import { DataSet, Network, Options } from "vis-network";
const VisJsGraphViewerLazyLoadable = makeLazyLoadable(
async () => (await import("./VisJsGraphViewer")).VisJsGraphViewer
);
export class VisJsGraphVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { graph: true })) {
collector.addVisualization({
id: asVisualizationId("vis-js-graph"),
name: "vis.js",
priority: 1001,
render() {
return (
<VisJsGraphViewerLazyLoadable
edges={data.edges}
nodes={data.nodes}
/>
);
},
});
}
}
}

View File

@@ -1,33 +0,0 @@
import { ComposedVisualizer, Visualizer } from "../Visualizer";
import { EnabledVisualizers } from "../EnabledVisualizers";
declare const ENABLED_VISUALIZERS: EnabledVisualizers;
function isVisualizer(v: Visualizer | false): v is Visualizer {
return !!v;
}
export const knownVisualizations = new ComposedVisualizer(
[
ENABLED_VISUALIZERS.VisJsGraphVisualizer &&
new (require("./graph-visualizers/VisJsGraphVisualizer") as typeof import("./graph-visualizers/VisJsGraphVisualizer")).VisJsGraphVisualizer(),
ENABLED_VISUALIZERS.TreeVisualizer &&
new (require("./TreeVisualizer/TreeVisualizer") as typeof import("./TreeVisualizer/TreeVisualizer")).TreeVisualizer(),
ENABLED_VISUALIZERS.GraphvizGraphVisualizer &&
new (require("./graph-visualizers/GraphvizGraphVisualizer") as typeof import("./graph-visualizers/GraphvizGraphVisualizer")).GraphvizGraphVisualizer(),
ENABLED_VISUALIZERS.SvgVisualizer &&
new (require("./SvgVisualizer") as typeof import("./SvgVisualizer")).SvgVisualizer(),
ENABLED_VISUALIZERS.GraphvizDotVisualizer &&
new (require("./graph-visualizers/GraphvizDotVisualizer") as typeof import("./graph-visualizers/GraphvizDotVisualizer")).GraphvizDotVisualizer(),
ENABLED_VISUALIZERS.TextVisualizer &&
new (require("./text-visualizers/TextVisualizer") as typeof import("./text-visualizers/TextVisualizer")).TextVisualizer(),
ENABLED_VISUALIZERS.PlotlyVisualizer &&
new (require("./plotly") as typeof import("./plotly")).PlotlyVisualizer(),
ENABLED_VISUALIZERS.GridVisualizer &&
new (require("./GridVisualizer") as typeof import("./GridVisualizer")).GridVisualizer(),
ENABLED_VISUALIZERS.MonacoTextVisualizer &&
new (require("./text-visualizers/MonacoTextVisualizer") as typeof import("./text-visualizers/MonacoTextVisualizer")).MonacoTextVisualizer(),
ENABLED_VISUALIZERS.AstVisualizer &&
new (require("./AstVisualizer") as typeof import("./AstVisualizer")).AstVisualizer(),
].filter(isVisualizer)
);

View File

@@ -1,19 +0,0 @@
import { observer } from "mobx-react";
import * as React from "react";
import Plot from "react-plotly.js";
@observer
export class PlotlyViewer extends React.Component<{
data: Partial<Plotly.Data>[];
}> {
render() {
return (
<Plot
style={{ width: "100%" }}
data={this.props.data}
layout={{}}
config={{ responsive: true }}
/>
);
}
}

View File

@@ -1,30 +0,0 @@
import * as React from "react";
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
import { makeLazyLoadable } from "../../LazyLoadable";
const PlotlyViewerLazyLoadable = makeLazyLoadable(
async () => (await import("./PlotlyViewer")).PlotlyViewer
);
export class PlotlyVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { plotly: true })) {
collector.addVisualization({
id: asVisualizationId("plotly"),
name: "plotly",
priority: 1001,
render() {
return <PlotlyViewerLazyLoadable data={data.data} />;
},
});
}
}
}

View File

@@ -1,74 +0,0 @@
.component-monaco-editor {
min-height: 0;
min-width: 0;
height: 100%;
box-sizing: border-box;
display: flex;
// overflow: hidden;
.part-editor {
min-width: 0;
min-height: 0;
flex: 1;
}
}
.component-AstTree {
height: 100%;
display: flex;
flex-direction: column;
.part-tree2 {
flex: 2;
min-height: 0;
min-width: 0;
}
.part-editor {
flex: 1;
min-height: 0;
min-width: 0;
border-top: solid gray 1px;
.marked {
background: orange;
}
.selected {
background: yellow;
opacity: 0.7;
}
}
/*display: flex;
flex-direction: column;
min-height: 0;
min-width: 0;
.part-tree2 {
flex: 1 0;
}
.part-editor {
min-height: 0;
min-width: 0;
flex: 1;
background: red;
}*/
}
.component-Grid {
.part-data {
border: 1px solid lightgray;
background: #eeeeee;
}
.part-header {
background: transparentize(white, 0.5);
}
.part-empty {
color: var(--vscode-editor-foreground);
}
}

View File

@@ -1,128 +0,0 @@
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
import * as monaco from "monaco-editor";
import * as React from "react";
import { observer, disposeOnUnmount } from "mobx-react";
import { autorun, observable } from "mobx";
export class MonacoTextVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { text: true })) {
collector.addVisualization({
id: asVisualizationId("monaco-text"),
name: "Monaco Editor",
priority: 95,
render() {
let id = "text";
if (data.fileName) {
id = getLanguageId(data.fileName);
}
return <MonacoEditor text={data.text} languageId={id} />;
},
});
}
}
}
export function getLanguageId(fileName: string): string {
const l = monaco.languages.getLanguages();
const result = l.find(l => {
if (l.filenamePatterns) {
for (const p of l.filenamePatterns) {
if (new RegExp(p).test(fileName)) {
return true;
}
}
}
if (l.extensions) {
for (const p of l.extensions) {
if (fileName.endsWith(p)) {
return true;
}
}
}
return false;
});
if (result) {
return result.id;
}
return "text";
}
@observer
export class MonacoEditor extends React.Component<{
text: string;
languageId: string;
}> {
@observable private editor: monaco.editor.IStandaloneCodeEditor | undefined;
componentWillUnmount() {
if (this.editor) {
this.editor.dispose();
}
}
private model: monaco.editor.ITextModel | undefined = undefined;
@disposeOnUnmount
private _updateText = autorun(() => {
if (this.editor) {
const model = monaco.editor.createModel(
this.props.text,
this.props.languageId,
undefined
);
this.editor.setModel(model);
/* this.editor!.updateOptions({ readOnly: false });
setTimeout(() => {
const a = this.editor!.getAction(
"editor.action.formatDocument"
);
a.run().then(() => {
this.editor!.updateOptions({ readOnly: true });
});
}, 200);*/
if (this.model) {
this.model.dispose();
}
this.model = model;
}
});
private readonly setEditorDiv = (editorDiv: HTMLDivElement) => {
if (!editorDiv) {
return;
}
this.editor = monaco.editor.create(editorDiv, {
model: null,
automaticLayout: true,
scrollBeyondLastLine: false,
minimap: { enabled: false },
fixedOverflowWidgets: true,
readOnly: true,
});
};
render() {
return (
<div className="component-monaco-editor">
<div className="part-editor" ref={this.setEditorDiv} />
</div>
);
}
}

View File

@@ -1,29 +0,0 @@
import {
Visualizer,
VisualizationCollector,
asVisualizationId,
} from "../../Visualizer";
import {
ExtractedData,
isCommonDataType,
} from "@hediet/debug-visualizer-data-extraction";
import * as React from "react";
export class TextVisualizer extends Visualizer {
visualize(data: ExtractedData, collector: VisualizationCollector): void {
if (isCommonDataType(data, { text: true })) {
collector.addVisualization({
id: asVisualizationId("text"),
name: "Plain Text",
priority: 90,
render() {
return (
<pre style={{ marginLeft: 20, marginRight: 20 }}>
{data.text}
</pre>
);
},
});
}
}
}

View File

@@ -1,2 +0,0 @@
@import "./src/visualizers/style.scss";
@import "./src/visualizers/TreeVisualizer/style.scss";

View File

@@ -1,19 +0,0 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "es2020",
"moduleResolution": "node",
"strict": true,
"outDir": "dist",
"skipLibCheck": true,
"rootDir": "./src",
"newLine": "LF",
"sourceMap": true,
"jsx": "react",
"experimentalDecorators": true,
"declaration": true,
"declarationMap": true,
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"]
}

View File

@@ -20,7 +20,10 @@
"react-dom": "^16.12.0",
"react-measure": "^2.3.0",
"@hediet/debug-visualizer-data-extraction": "*",
"@knuddels/mobx-logger": "^1.1.1"
"@hediet/visualization-bundle": "^0.1.1",
"@hediet/visualization-core": "^0.1.0",
"@knuddels/mobx-logger": "^1.1.1",
"less-loader": "^6.2.0"
},
"devDependencies": {
"@types/html-webpack-plugin": "^3.2.2",
@@ -35,9 +38,8 @@
"fork-ts-checker-webpack-plugin": "^4.0.4",
"html-webpack-plugin": "^3.2.0",
"monaco-editor-webpack-plugin": "^1.9.0",
"node-sass": "^4.13.1",
"raw-loader": "^4.0.0",
"sass": "^1.25.0",
"raw-loader": "^4.0.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"ts-loader": "^6.2.1",

View File

@@ -3,6 +3,7 @@ import { Model } from "../model/Model";
import { observer } from "mobx-react";
import { NoData } from "./NoData";
import { FormattedMessage } from "debug-visualizer/src/contract";
import { VisualizationView, Theme } from "@hediet/visualization-core";
@observer
export class Visualizer extends React.Component<{ model: Model }> {
@@ -12,11 +13,6 @@ export class Visualizer extends React.Component<{ model: Model }> {
);
}
componentDidCatch() {
this.props.model.setVisualizationError({ kind: {} });
console.log("broken");
}
renderContent(): JSX.Element {
const s = this.props.model.state;
if (s.kind === "loading") {
@@ -38,20 +34,12 @@ export class Visualizer extends React.Component<{ model: Model }> {
if (!vis || !vis.visualization) {
return <NoData>No Visualization Available</NoData>;
}
try {
return vis.visualization.render();
} catch (e) {
console.error(e);
return (
<NoData>
<>
Visualization Error
<pre>{e.message}</pre>
</>
</NoData>
);
}
return (
<VisualizationView
theme={Theme.light}
visualization={vis.visualization}
/>
);
} else {
const nvr: never = s;
return <div />;

View File

@@ -9,11 +9,12 @@ import {
DataExtractorId,
ExtractedData,
} from "@hediet/debug-visualizer-data-extraction";
import "@hediet/visualization-bundle";
import {
Visualization,
globalVisualizationFactory,
VisualizationId,
knownVisualizations,
} from "@hediet/visualization";
Visualization,
} from "@hediet/visualization-core";
import { getApi as getVsCodeApi } from "./VsCodeApi";
import { MonacoBridge } from "./MonacoBridge";
import { Disposable } from "@hediet/std/disposable";
@@ -42,7 +43,7 @@ export class Model {
private serverSecret: string;
@observable expression: string = "";
@observable state:
@observable.ref state:
| DataExtractionState
| { kind: "noExpression" }
| { kind: "visualizationError"; data: ExtractedData } = {
@@ -87,11 +88,14 @@ export class Model {
}
| undefined {
if (this.state.kind === "data") {
const vis = knownVisualizations.getBestVisualization(
const vis = globalVisualizationFactory.getVisualizations(
this.state.result.data,
this.preferredVisualizationId
);
return vis;
return {
visualization: vis.bestVisualization,
allVisualizations: vis.allVisualizations,
};
} else {
return undefined;
}

View File

@@ -1,7 +1,7 @@
@import "~normalize.css";
@import "~@blueprintjs/core/lib/css/blueprint.css";
@import "~@blueprintjs/icons/lib/css/blueprint-icons.css";
@import "~@hediet/visualization/style.scss";
@import "~@hediet/visualization-bundle/style.scss";
html,
body,

View File

@@ -1,2 +0,0 @@
require("ts-node").register();
module.exports = require("./webpack.config.ts");

View File

@@ -4,28 +4,9 @@ import HtmlWebpackPlugin = require("html-webpack-plugin");
import MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
import ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
import { CleanWebpackPlugin } from "clean-webpack-plugin";
import { EnabledVisualizers } from "@hediet/visualization";
const r = (file: string) => path.resolve(__dirname, file);
const enabledVisualizers: EnabledVisualizers = {
VisJsGraphVisualizer: true,
TreeVisualizer: true,
GraphvizGraphVisualizer: true,
SvgVisualizer: true,
GraphvizDotVisualizer: true,
TextVisualizer: true,
PlotlyVisualizer: true,
GridVisualizer: true,
MonacoTextVisualizer: true,
AstVisualizer: true,
};
const stringifiedEnabledVisualizers: Record<string, string> = {};
for (const [key, val] of Object.entries(enabledVisualizers)) {
stringifiedEnabledVisualizers[key] = JSON.stringify(val);
}
module.exports = {
entry: [r("src/index.tsx")],
output: {
@@ -47,6 +28,10 @@ module.exports = {
devtool: "source-map",
module: {
rules: [
{
test: /\.less$/,
loaders: ["style-loader", "css-loader", "less-loader"],
},
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.scss$/, loader: "style-loader!css-loader!sass-loader" },
{
@@ -74,9 +59,6 @@ module.exports = {
// Add more languages here once webworker issues are solved.
languages: ["typescript"],
}),
new webpack.DefinePlugin({
ENABLED_VISUALIZERS: stringifiedEnabledVisualizers,
}),
];
return plugins;

File diff suppressed because it is too large Load Diff

2348
yarn.lock

File diff suppressed because it is too large Load Diff