@pb33f/cowboy-components 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/model-renderer/rendered-node.css.d.ts +2 -0
  2. package/dist/components/model-renderer/rendered-node.css.js +96 -0
  3. package/dist/components/model-renderer/rendered-node.d.ts +8 -0
  4. package/dist/components/model-renderer/rendered-node.js +117 -0
  5. package/dist/components/model-renderer/rendered-property.css.d.ts +2 -0
  6. package/dist/components/model-renderer/rendered-property.css.js +118 -0
  7. package/dist/components/model-renderer/rendered-property.d.ts +14 -0
  8. package/dist/components/model-renderer/rendered-property.js +204 -0
  9. package/dist/components/model-tree/tree-item.d.ts +10 -0
  10. package/dist/components/model-tree/tree-item.js +37 -0
  11. package/dist/components/model-tree/tree.css.d.ts +2 -0
  12. package/dist/components/model-tree/tree.css.js +20 -0
  13. package/dist/components/model-tree/tree.d.ts +16 -0
  14. package/dist/components/model-tree/tree.js +103 -0
  15. package/dist/components/the-doctor/the-doctor.d.ts +2 -1
  16. package/dist/components/the-doctor/the-doctor.js +32 -13
  17. package/dist/components/visualizer/explorer.d.ts +52 -0
  18. package/dist/components/visualizer/explorer.js +296 -0
  19. package/dist/components/visualizer/node.d.ts +11 -0
  20. package/dist/components/visualizer/node.js +27 -0
  21. package/dist/components/visualizer/operation.css.d.ts +2 -0
  22. package/dist/components/visualizer/operation.css.js +53 -0
  23. package/dist/components/visualizer/operation.d.ts +12 -0
  24. package/dist/components/visualizer/operation.js +52 -0
  25. package/dist/components/visualizer/visualizer.css.d.ts +2 -0
  26. package/dist/components/visualizer/visualizer.css.js +157 -0
  27. package/dist/components/visualizer/visualizer.d.ts +60 -0
  28. package/dist/components/visualizer/visualizer.js +137 -0
  29. package/dist/cowboy-components.d.ts +1 -0
  30. package/dist/cowboy-components.js +2 -0
  31. package/dist/cowboy-components.umd.cjs +948 -322
  32. package/dist/css/pb33f-theme.css +1 -1
  33. package/dist/events/doctor.d.ts +5 -0
  34. package/dist/events/doctor.js +2 -0
  35. package/dist/model/graph.d.ts +6 -0
  36. package/dist/model/graph.js +1 -0
  37. package/dist/services/model-service.d.ts +5 -0
  38. package/dist/services/model-service.js +30 -0
  39. package/dist/style.css +1 -1
  40. package/package.json +6 -3
@@ -0,0 +1,103 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import '@shoelace-style/shoelace/dist/components/tree/tree.js';
8
+ import '@shoelace-style/shoelace/dist/components/tree-item/tree-item.js';
9
+ import { customElement, property } from "lit/decorators.js";
10
+ import { html, LitElement } from "lit";
11
+ import treeCss from "./tree.css.js";
12
+ import { ModelTreeNodeClicked } from "../../events/doctor";
13
+ let ModelTree = class ModelTree extends LitElement {
14
+ nodeClicked(nodeHashId) {
15
+ this.dispatchEvent(new CustomEvent(ModelTreeNodeClicked, {
16
+ bubbles: true,
17
+ composed: true,
18
+ detail: {
19
+ nodeHashId: nodeHashId
20
+ }
21
+ }));
22
+ }
23
+ explorerClicked(nodeHashId) {
24
+ const treeItems = this.renderRoot.querySelectorAll(`sl-tree-item`);
25
+ let selected = null;
26
+ for (let i = 0; i < treeItems.length; i++) {
27
+ const item = treeItems[i];
28
+ item.selected = item.id === `model-${nodeHashId}`;
29
+ item.expanded = true;
30
+ if (item.selected) {
31
+ selected = item;
32
+ }
33
+ }
34
+ if (selected) {
35
+ requestAnimationFrame(() => {
36
+ selected?.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" });
37
+ });
38
+ }
39
+ }
40
+ collapse(evt, node) {
41
+ evt.stopPropagation();
42
+ node.treeExpanded = false;
43
+ }
44
+ expanded(evt, node) {
45
+ evt.stopPropagation();
46
+ node.treeExpanded = true;
47
+ }
48
+ buildTree(node, depth) {
49
+ let results = [];
50
+ if (node.nodes && node.nodes.length > 0) {
51
+ for (let i = 0; i < node.nodes.length; i++) {
52
+ depth++;
53
+ results.push(this.buildTree(node.nodes[i], depth));
54
+ }
55
+ }
56
+ let expanded = node.treeExpanded;
57
+ if (depth < 2) {
58
+ expanded = true;
59
+ }
60
+ return html `
61
+ <sl-tree-item id="model-${node.idHash}" ?expanded="${expanded}"
62
+ @sl-expand="${(evt) => {
63
+ this.expanded(evt, node);
64
+ }}"
65
+ @sl-collapse="${(evt) => {
66
+ this.collapse(evt, node);
67
+ }}">
68
+ <sl-icon name="plus-square" slot="expand-icon"></sl-icon>
69
+ <sl-icon name="dash-square" slot="collapse-icon"></sl-icon>
70
+ <span >${node.label}</span>
71
+ ${results}
72
+ </sl-tree-item>
73
+ `;
74
+ }
75
+ nodesSelected(treeItems) {
76
+ for (let i = 0; i < treeItems.length; i++) {
77
+ this.nodeClicked(treeItems[i].id);
78
+ }
79
+ }
80
+ render() {
81
+ if (!this.node) {
82
+ return html ``;
83
+ }
84
+ return html `
85
+ <sl-tree @sl-selection-change="${(evt) => {
86
+ {
87
+ const selected = evt.detail.selection;
88
+ this.nodesSelected(selected);
89
+ }
90
+ }}">
91
+ ${this.buildTree(this.node, 0)}
92
+ </sl-tree>
93
+ `;
94
+ }
95
+ };
96
+ ModelTree.styles = [treeCss];
97
+ __decorate([
98
+ property()
99
+ ], ModelTree.prototype, "node", void 0);
100
+ ModelTree = __decorate([
101
+ customElement("pb33f-model-tree")
102
+ ], ModelTree);
103
+ export { ModelTree };
@@ -7,7 +7,7 @@ import '@shoelace-style/shoelace/dist/components/dialog/dialog.js';
7
7
  import '@shoelace-style/shoelace/dist/components/alert/alert.js';
8
8
  import '@shoelace-style/shoelace/dist/components/badge/badge.js';
9
9
  import { LitElement } from "lit";
10
- import { AddToastEvent, EditorUpdatedEvent, ProblemRuleFilterChangedEvent, RulesetSavedEvent, RuleClickedEvent } from "../../events/doctor.js";
10
+ import { AddToastEvent, EditorUpdatedEvent, ProblemRuleFilterChangedEvent, RulesetSavedEvent, RuleClickedEvent, NodeClickedEvent } from "../../events/doctor.js";
11
11
  import { ProblemDrawerEvent } from "../problem-list/details-drawer.js";
12
12
  import { SlDialog, SlIcon, SlRadioGroup, SlTab, SlTabGroup } from "@shoelace-style/shoelace";
13
13
  import { AttentionBox } from "../attention-box/attention-box.js";
@@ -87,6 +87,7 @@ export declare class TheDoctor extends LitElement {
87
87
  private selectedEditorTab;
88
88
  private sidebarClosed;
89
89
  constructor(doctorEndpoint?: string);
90
+ modelTreeNodeClicked(evt: CustomEvent<NodeClickedEvent>): void;
90
91
  exportRuleset(): void;
91
92
  addToastEvent(event: CustomEvent<AddToastEvent>): void;
92
93
  sendToast(toast: Toast): void;
@@ -38,6 +38,7 @@ import dialogCss from "../../css/dialog.css.js";
38
38
  import buttonCss from "../../css/button.css.js";
39
39
  import radioGroupsCss from "../../css/radiogroups.css.js";
40
40
  import { MarkerSeverity } from "monaco-editor";
41
+ import { ModelService } from "../../services/model-service";
41
42
  export const DoctorDocumentBag = "pb33f-doctor-editor";
42
43
  export const HowToFixBag = "pb33f-doctor-howtofix";
43
44
  export const FunctionDocumentationBag = "pb33f-doctor-funcdocs";
@@ -112,6 +113,8 @@ let TheDoctor = class TheDoctor extends LitElement {
112
113
  this.addEventListener(RuleClicked, this.ruleClicked);
113
114
  // @ts-ignore
114
115
  this.addEventListener(BuiltInRulesetChanged, this.builtInRulesetSelected);
116
+ // @ts-ignore
117
+ //this.addEventListener(ModelTreeNodeClicked, this.modelTreeNodeClicked)
115
118
  // hijack navigation buttons.
116
119
  window.addEventListener('popstate', (e) => {
117
120
  const state = e.state;
@@ -128,6 +131,10 @@ let TheDoctor = class TheDoctor extends LitElement {
128
131
  });
129
132
  //history.pushState({view: ActiveView.Overview}, "", ActiveView.Overview);
130
133
  }
134
+ modelTreeNodeClicked(evt) {
135
+ // TODO: this is a placeholder for now
136
+ console.log(evt);
137
+ }
131
138
  exportRuleset() {
132
139
  this.exportRulesetDialog.show();
133
140
  }
@@ -283,6 +290,13 @@ let TheDoctor = class TheDoctor extends LitElement {
283
290
  });
284
291
  }
285
292
  }
293
+ // update visualization
294
+ // TODO: this is a placeholder for now
295
+ // ModelService.createGraph(value).then((result) => {
296
+ // this.vis
297
+ //
298
+ //
299
+ // })
286
300
  }).catch((e) => {
287
301
  console.error("statistics service is down", e);
288
302
  this.platformUnavailable(e);
@@ -307,6 +321,8 @@ let TheDoctor = class TheDoctor extends LitElement {
307
321
  }
308
322
  platformUnavailable(error) {
309
323
  if (!this.unavailable) {
324
+ this.loadingOverlay.hide();
325
+ this.activitySpinner.hide();
310
326
  this.errorBanner.errorTitle = "The doctor is out.";
311
327
  if (!error) {
312
328
  this.errorBanner.errorMessage = "The clinic is <strong>closed!</strong> " +
@@ -373,6 +389,7 @@ let TheDoctor = class TheDoctor extends LitElement {
373
389
  LintingService.doctorEndpoint = this.doctorEndpoint;
374
390
  FeedbackService.doctorEndpoint = this.doctorEndpoint;
375
391
  RulesetService.doctorEndpoint = this.doctorEndpoint;
392
+ ModelService.doctorEndpoint = this.doctorEndpoint;
376
393
  this.docBag = this.bagManager.getBag(DoctorDocumentBag);
377
394
  if (this.docBag) {
378
395
  const doc = this.docBag.get(DefaultDocument);
@@ -461,6 +478,7 @@ let TheDoctor = class TheDoctor extends LitElement {
461
478
  this.sessionRulesetMapBag = this.bagManager.getBag(SessionRulesetMapBag);
462
479
  // fire off all network requests, then configure the ruleset management.
463
480
  Promise.all(promises).then(() => {
481
+ this.loadingOverlay.hide();
464
482
  // configure rule management
465
483
  this.manageRuleset.defaultRuleset = this.defaultRuleset;
466
484
  this.manageRuleset.owaspRuleset = this.OWASPRuleset;
@@ -473,17 +491,18 @@ let TheDoctor = class TheDoctor extends LitElement {
473
491
  else {
474
492
  this.manageRuleset.rulesetConfig = { ruleMapping: new Map(), allRulesSwitch: true };
475
493
  }
476
- this.manageRuleset.buildRulesets();
477
- if (this.CustomRuleset && this.CustomRuleset.rules.size > 0) {
478
- this.manageRuleset.customRuleset = this.CustomRuleset;
479
- }
480
- // do nothing with this for now. we just need to make sure the default ruleset
481
- // has a session.
482
- this.fetchSessionRulesetAsYaml().then((result) => {
483
- this.loadingOverlay.hide();
484
- this.rulesetEditor?.setValue(result, true);
485
- this.fetchRulesetMap();
486
- });
494
+ setTimeout(() => {
495
+ this.manageRuleset.buildRulesets();
496
+ if (this.CustomRuleset && this.CustomRuleset.rules.size > 0) {
497
+ this.manageRuleset.customRuleset = this.CustomRuleset;
498
+ }
499
+ this.fetchSessionRulesetAsYaml().then((result) => {
500
+ this.rulesetEditor?.setValue(result, true);
501
+ this.fetchRulesetMap();
502
+ }).catch((e) => {
503
+ this.platformUnavailable(e);
504
+ });
505
+ }, 50);
487
506
  });
488
507
  // refresh state for how to fix.
489
508
  this.fetchDocs();
@@ -537,12 +556,12 @@ let TheDoctor = class TheDoctor extends LitElement {
537
556
  }
538
557
  }
539
558
  async fetchSessionRulesetAsYaml() {
540
- return new Promise(async (resolve) => {
559
+ return new Promise(async (resolve, reject) => {
541
560
  RulesetService.getSessionRulesetAsYAML().then((result) => {
542
561
  resolve(result);
543
562
  }).catch((e) => {
544
563
  console.error("cannot fetch session ruleset: ", e.title);
545
- resolve("");
564
+ reject(e);
546
565
  });
547
566
  });
548
567
  }
@@ -0,0 +1,52 @@
1
+ import { LitElement } from "lit";
2
+ import { Direction, Edge, Node } from "./visualizer";
3
+ import { NodeComponent } from "./node";
4
+ export declare class ExplorerComponent extends LitElement {
5
+ static styles: import("lit").CSSResult[];
6
+ svgItem: SVGSVGElement;
7
+ svgGroup: SVGSVGElement;
8
+ ready: boolean;
9
+ elk: any;
10
+ graph: any;
11
+ nodes: Node[];
12
+ models: Node[];
13
+ edges: Edge[];
14
+ direction: Direction;
15
+ nodeComponents: NodeComponent[];
16
+ scale: number;
17
+ private grabbed;
18
+ nodeMap: Map<string, Node>;
19
+ private startX;
20
+ private startY;
21
+ private translateX;
22
+ private translateY;
23
+ constructor();
24
+ mouseMove(evt: MouseEvent): void;
25
+ mouseDown(evt: MouseEvent): void;
26
+ mouseUp(): void;
27
+ onWheel(evt: MouseEvent): void;
28
+ buildLayout(): void;
29
+ buildGraph(): any;
30
+ readyGo(): void;
31
+ reset(): void;
32
+ zoomIn(): void;
33
+ zoomOut(): void;
34
+ generateOptions(): {
35
+ 'spacing.nodeNodeBetweenLayers': number;
36
+ 'spacing.nodeNode': number;
37
+ 'elk.nodeLabels.placement': string;
38
+ 'elk.algorithm': string;
39
+ 'elk.direction': Direction;
40
+ 'org.eclipse.elk.edgeRouting': string;
41
+ 'elk.layered.unnecessaryBendpoints': string;
42
+ 'elk.layered.spacing.edgeNodeBetweenLayers': number;
43
+ 'org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment': string;
44
+ 'org.eclipse.elk.layered.cycleBreaking.strategy': string;
45
+ 'nodePlacement.strategy': string;
46
+ 'org.eclipse.elk.spacing.edgeLabel': string;
47
+ 'org.eclipse.elk.spacing.edgeNode': string;
48
+ 'org.eclipse.elk.layered.edgeLabels.sideSelection': string;
49
+ 'org.eclipse.elk.spacing.portPort': string;
50
+ };
51
+ render(): import("lit-html").TemplateResult<1> | import("lit-html").TemplateResult<2>;
52
+ }
@@ -0,0 +1,296 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { customElement, query, state } from "lit/decorators.js";
8
+ import { html, LitElement, svg } from "lit";
9
+ import visualizerCss from "./visualizer.css";
10
+ import { Direction } from "./visualizer";
11
+ import { NodeComponent } from "./node";
12
+ import { OperationGraphNode } from "./operation";
13
+ import { curveBundle, line } from "d3-shape";
14
+ import ELK from "elkjs/lib/elk.bundled";
15
+ let ExplorerComponent = class ExplorerComponent extends LitElement {
16
+ constructor() {
17
+ super();
18
+ this.nodeComponents = [];
19
+ this.scale = 1;
20
+ this.translateX = 0;
21
+ this.translateY = 0;
22
+ this.elk = new ELK();
23
+ this.ready = false;
24
+ this.direction = Direction.RIGHT;
25
+ this.nodeMap = new Map();
26
+ const targets = new Map();
27
+ }
28
+ mouseMove(evt) {
29
+ if (this.grabbed) {
30
+ this.translateX = evt.clientX - this.startX;
31
+ this.translateY = evt.clientY - this.startY;
32
+ this.svgGroup.style.transform = `scale(${this.scale}) translate(${this.translateX / this.scale}px, ${this.translateY / this.scale}px)`;
33
+ }
34
+ }
35
+ mouseDown(evt) {
36
+ this.grabbed = true;
37
+ this.startX = evt.clientX - this.translateX;
38
+ this.startY = evt.clientY - this.translateY;
39
+ }
40
+ mouseUp() {
41
+ this.grabbed = false;
42
+ }
43
+ onWheel(evt) {
44
+ evt.preventDefault();
45
+ //@ts-ignore
46
+ const delta = evt.deltaY || evt.deltaX;
47
+ const scaleStep = Math.abs(delta) < 50
48
+ ? 0.05 // touchpad pitch
49
+ : 0.25; // mouse wheel
50
+ const scaleDelta = delta < 0 ? scaleStep : -scaleStep;
51
+ const nextScale = this.scale + scaleDelta; // 'scale' is prev scale
52
+ // calc fixedPoint
53
+ const fixedPoint = { x: evt.clientX, y: evt.clientY };
54
+ this.scale = nextScale;
55
+ if (nextScale < 0.25) {
56
+ this.scale = 0.25;
57
+ return;
58
+ }
59
+ // if (nextScale > 5) {
60
+ // this.scale = 5;
61
+ // return
62
+ // }
63
+ const mouseX = evt.clientX;
64
+ const mouseY = evt.clientY;
65
+ const svgRect = this.svgItem.getBoundingClientRect();
66
+ const offsetX = mouseX - svgRect.left;
67
+ const offsetY = mouseY - svgRect.top;
68
+ this.svgGroup.style.transformOrigin = `${offsetX}px ${offsetY}px`;
69
+ this.svgGroup.style.transform = `scale(${nextScale}) translate(${this.translateX / this.scale}px, ${this.translateY / this.scale}px)`;
70
+ }
71
+ buildLayout() {
72
+ this.elk.layout(this.graph, {
73
+ layoutOptions: {
74
+ 'algorithm': 'layered'
75
+ },
76
+ logging: true,
77
+ measureExecutionTime: true
78
+ }).then(this.readyGo.bind(this));
79
+ }
80
+ buildGraph() {
81
+ const graph = {
82
+ id: "root",
83
+ layoutOptions: this.generateOptions(),
84
+ children: this.nodes,
85
+ edges: this.edges
86
+ };
87
+ this.graph = graph;
88
+ // build node map
89
+ this.nodeMap.clear();
90
+ this.nodes.forEach((node) => {
91
+ this.nodeMap.set(node.nodePath, node);
92
+ });
93
+ this.buildLayout();
94
+ return graph;
95
+ }
96
+ readyGo() {
97
+ this.ready = true;
98
+ this.requestUpdate();
99
+ }
100
+ reset() {
101
+ this.scale = 1;
102
+ this.translateX = 0;
103
+ this.translateY = 0;
104
+ this.svgGroup.style.transform = `scale(${this.scale}) translate(${this.translateX}px, ${this.translateY}px)`;
105
+ }
106
+ zoomIn() {
107
+ const nextScale = this.scale + 0.25; // 'scale' is prev scale
108
+ this.scale = nextScale;
109
+ this.svgGroup.style.transform = `scale(${nextScale}) translate(${this.translateX / this.scale}px, ${this.translateY / this.scale}px)`;
110
+ }
111
+ zoomOut() {
112
+ const nextScale = this.scale - 0.25; // 'scale' is prev scale
113
+ this.scale = nextScale;
114
+ this.svgGroup.style.transform = `scale(${nextScale}) translate(${this.translateX / this.scale}px, ${this.translateY / this.scale}px)`;
115
+ }
116
+ generateOptions() {
117
+ return {
118
+ 'spacing.nodeNodeBetweenLayers': 40,
119
+ 'spacing.nodeNode': 40,
120
+ 'elk.nodeLabels.placement': 'INSIDE V_CENTER H_RIGHT',
121
+ 'elk.algorithm': 'org.eclipse.elk.layered',
122
+ 'elk.direction': this.direction,
123
+ 'org.eclipse.elk.edgeRouting': 'ORTHOGONAL',
124
+ 'elk.layered.unnecessaryBendpoints': 'true',
125
+ 'elk.layered.spacing.edgeNodeBetweenLayers': 30,
126
+ 'org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment': 'BALANCED',
127
+ 'org.eclipse.elk.layered.cycleBreaking.strategy': 'DEPTH_FIRST',
128
+ 'nodePlacement.strategy': 'BRANDES_KOEPF',
129
+ 'org.eclipse.elk.spacing.edgeLabel': '0',
130
+ 'org.eclipse.elk.spacing.edgeNode': '24',
131
+ 'org.eclipse.elk.layered.edgeLabels.sideSelection': 'ALWAYS_UP',
132
+ 'org.eclipse.elk.spacing.portPort': '10',
133
+ };
134
+ }
135
+ render() {
136
+ if (!this.ready) {
137
+ return html ``;
138
+ }
139
+ const nodes = this.graph.children?.map((child) => {
140
+ const nc = new NodeComponent();
141
+ nc.id = child.idHash;
142
+ if (child.x && child.y) {
143
+ nc.x = child.x;
144
+ nc.y = child.y;
145
+ }
146
+ nc.width = child.width;
147
+ nc.height = child.height;
148
+ // if (child.expanded) {
149
+ // nc.visible = child.expanded;
150
+ // } else {
151
+ //debugger
152
+ let expanded = false;
153
+ // check if any of the edges have a target of this node, and then check
154
+ // if any of the source nodes are expanded
155
+ this.edges?.forEach((edge) => {
156
+ if (edge.targets.includes(child.id)) {
157
+ edge.sources.forEach((source) => {
158
+ const node = this.nodes.find((n) => n.id === source);
159
+ if (node?.expanded) {
160
+ expanded = true;
161
+ }
162
+ });
163
+ }
164
+ });
165
+ nc.visible = expanded;
166
+ // }
167
+ const op = new OperationGraphNode();
168
+ op.height = child.height - 2;
169
+ op.width = child.width - 2;
170
+ op.id = child.idHash;
171
+ op.label = child.label;
172
+ if (child.active) {
173
+ op.active = child.active;
174
+ nc.active = child.active;
175
+ }
176
+ nc.body = op;
177
+ this.nodeComponents.push(nc);
178
+ return nc.render();
179
+ });
180
+ const edges = this.graph.edges?.map((edge) => {
181
+ let x = 0;
182
+ const sections = edge.sections?.map((section) => {
183
+ // check if any of the targets for the edge are visible, if not, don't render the edge
184
+ let visible = false;
185
+ edge.targets.forEach((target) => {
186
+ const node = this.nodes.find((n) => n.id === target);
187
+ if (node?.expanded) {
188
+ visible = true;
189
+ }
190
+ this.nodeComponents.forEach((nc) => {
191
+ if (nc.visible && nc.id === target) {
192
+ console.log(nc.id);
193
+ visible = true;
194
+ }
195
+ });
196
+ });
197
+ // if (!visible) {
198
+ // return svg``
199
+ // }
200
+ const points = section ? [section.startPoint, ...(section.bendPoints || []), section.endPoint] : [];
201
+ let pathFn = line().x((d) => d.x).y((d) => d.y);
202
+ pathFn = pathFn.curve(curveBundle.beta(1));
203
+ const lines = svg `
204
+ <path id="edge-${edge.id}-${x}"
205
+ d="${pathFn(points)}"
206
+ class="edge ${edge.ref.length > 0 ? 'ref' : ''} ${edge.poly && edge.poly != '' ? edge.poly : ''}"
207
+ marker-end="url(#${edge.ref.length > 0 ? edge.poly ? 'arrow-poly' : 'arrow-ref' : 'arrow'})"/>`;
208
+ x++;
209
+ return lines;
210
+ });
211
+ return sections;
212
+ });
213
+ let base = 600;
214
+ let offset = 0;
215
+ this.graph.children.forEach(() => {
216
+ base += 5;
217
+ offset += 20;
218
+ });
219
+ if (offset > 900) {
220
+ offset = 900;
221
+ }
222
+ return svg `
223
+ <svg width="100%" height="100%" viewBox="${offset} 80 ${base} ${base}"
224
+ @wheel="${this.onWheel}"
225
+ @mousedown="${this.mouseDown}"
226
+ @mouseup="${this.mouseUp}"
227
+ @mousemove="${this.mouseMove}"
228
+ @mouseout="${this.mouseUp}"
229
+ >
230
+ <defs>
231
+ <filter id="glow">
232
+ <!-- First, apply a Gaussian blur -->
233
+ <feGaussianBlur stdDeviation="4.5" result="coloredBlur"/>
234
+ <!-- Then, apply a merge filter to add the blur effect back with the original graphic -->
235
+ <feMerge>
236
+ <feMergeNode in="coloredBlur"/>
237
+ <feMergeNode in="SourceGraphic"/>
238
+ </feMerge>
239
+ </filter>
240
+ <marker
241
+ id="arrow"
242
+ viewBox="0 0 12 12"
243
+ refX="8"
244
+ refY="5"
245
+ markerWidth="5"
246
+ markerHeight="5"
247
+ fill="var(--secondary-color)"
248
+ orient="auto-start-reverse">
249
+ <path d="M 0 0 L 10 5 L 0 10 z" class="glow"/>
250
+ </marker>
251
+ <marker
252
+ id="arrow-ref"
253
+ viewBox="0 0 12 12"
254
+ refX="8"
255
+ refY="5"
256
+ markerWidth="5"
257
+ markerHeight="5"
258
+ fill="var(--terminal-text)"
259
+ orient="auto-start-reverse">
260
+ <path d="M 0 0 L 10 5 L 0 10 z" class="glow"/>
261
+ </marker>
262
+ <marker
263
+ id="arrow-poly"
264
+ viewBox="0 0 12 12"
265
+ refX="8"
266
+ refY="5"
267
+ markerWidth="5"
268
+ markerHeight="5"
269
+ fill="var(--terminal-yellow)"
270
+ orient="auto-start-reverse">
271
+ <path d="M 0 0 L 10 5 L 0 10 z" class="glow"/>
272
+ </marker>
273
+
274
+ </defs>
275
+ <g id="#svgGroup">
276
+ ${nodes}
277
+ ${edges}
278
+ </g>
279
+ </svg>
280
+ `;
281
+ }
282
+ };
283
+ ExplorerComponent.styles = [visualizerCss];
284
+ __decorate([
285
+ query('svg')
286
+ ], ExplorerComponent.prototype, "svgItem", void 0);
287
+ __decorate([
288
+ query('svg > g')
289
+ ], ExplorerComponent.prototype, "svgGroup", void 0);
290
+ __decorate([
291
+ state()
292
+ ], ExplorerComponent.prototype, "ready", void 0);
293
+ ExplorerComponent = __decorate([
294
+ customElement('pb33f-explorer')
295
+ ], ExplorerComponent);
296
+ export { ExplorerComponent };
@@ -0,0 +1,11 @@
1
+ export declare class NodeComponent {
2
+ id: string;
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ body: any;
8
+ visible: boolean;
9
+ active: boolean | undefined;
10
+ render(): import("lit-html").TemplateResult<2>;
11
+ }
@@ -0,0 +1,27 @@
1
+ import { svg } from "lit";
2
+ export class NodeComponent {
3
+ render() {
4
+ // if (!this.visible) {
5
+ // return svg``;
6
+ // }
7
+ let body = "";
8
+ if (this.body) {
9
+ body = this.body;
10
+ }
11
+ else {
12
+ body = "Object Node";
13
+ }
14
+ // <!--<text x="${this.x + 6}" y="${this.y + 26}" class="text">${body}</text> -->
15
+ return svg `
16
+ <rect id="node-${this.id}" x="${this.x}" y="${this.y}" width="${this.width}" height="${this.height}" class="node"/>
17
+
18
+ <foreignObject x="${this.x}" y="${this.y}" width="${this.width}" height="${this.height + 20}" class="fo">
19
+ <div xmlns="http://www.w3.org/1999/xhtml" class="node-body" style="height: ${this.height}px; width: ${this.width}px;">
20
+ ${body}
21
+ </div>
22
+ </foreignObject>
23
+
24
+
25
+ `;
26
+ }
27
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("lit").CSSResult;
2
+ export default _default;
@@ -0,0 +1,53 @@
1
+ import { css } from 'lit';
2
+ export default css `
3
+
4
+ .operation-node {
5
+ border: 1px solid var(--primary-color);
6
+ }
7
+
8
+ .operation-node:hover {
9
+ cursor: pointer;
10
+ border: 1px solid var(--secondary-color);
11
+ }
12
+
13
+ .operation-node:active {
14
+ cursor: pointer;
15
+ border: 1px solid var(--warn-color);
16
+ }
17
+
18
+ .active {
19
+ border: 2px solid var(--error-color);
20
+ animation: pulse-animation 2.5s infinite
21
+ }
22
+
23
+ .operation-node.active:hover {
24
+ cursor: pointer;
25
+ border: 2px solid var(--error-color);
26
+ }
27
+
28
+ @keyframes pulse-animation {
29
+ 0% {
30
+ box-shadow: 0 0 0 0 var(--error-color);
31
+ }
32
+ 100% {
33
+ box-shadow: 0 0 30px 30px rgb(0, 0, 0, 0);
34
+ }
35
+ }
36
+
37
+ @keyframes dashdraw {
38
+ 0% {
39
+ stroke-dashoffset: 10;
40
+ }
41
+ }
42
+
43
+ .active-icon {
44
+ position: absolute;
45
+ right: calc(50% - 10px);
46
+ bottom: -8px;
47
+ font-size: 1.5rem;
48
+ color: var(--error-color);
49
+ }
50
+
51
+
52
+
53
+ `;