@gregoriusrippenstein/node-red-contrib-introspection 0.9.2 → 0.9.4

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.
package/README.md CHANGED
@@ -94,7 +94,7 @@ Also this is an experimental feature liable to be [enhanced](https://discourse.n
94
94
 
95
95
  This now has a [treeList](https://nodered.org/docs/api/ui/treeList/) of nodes and how often they received a message. Clicking on the node in the list will highlight the node, double-click will open the nodes edit panel.
96
96
 
97
- *UPDATE2*:
97
+ *UPDATE TWO*:
98
98
 
99
99
  It is now possible to send all messages to the debug panel. By toggling the 'msg to debug' checkbox, *all messages* will be sent to the Node-RED debug panel. This can be toggled on and off independently of the message tracing. That is, as long as message tracing is activated. It is therefore possible (as shown in the animation above) to active message tracing, then activate msg to debug to have msg appear in the debug panel and then deactive the msg to debug. The message tracing continues unabated.
100
100
 
@@ -104,6 +104,12 @@ This makes it possible to trace messages, if something critical happens, to acti
104
104
 
105
105
  Also this feature causes **no extra overhead** on the backend server if it is *not in use* - the hooks for capturing the data are removed if this feature is deactivated.
106
106
 
107
+ *UPDATE THREE*:
108
+
109
+ Tracing and debug-message tracing are now separate operations and neither works on *all* nodes by default. To use either feature, a selection of nodes must now be made beforehand (in the flow editor window) and then tracing activated. If you really want to trace **all** nodes, then select none in the editor (deselect all nodes) and check the corresponding "All?" checkbox - there is one for debug messages and one for message tracing.
110
+
111
+ Tracing or debugging **all** nodes is **no longer** the default action.
112
+
107
113
  ## Palette Nodes
108
114
 
109
115
  ### Sink & Seeker
@@ -1,10 +1,13 @@
1
- module.exports = function(RED) {
1
+ module.exports = function (RED) {
2
2
  let UglifyJS = require('uglify-js');
3
3
  let CleanCSS = require('clean-css');
4
4
 
5
- const OnReceiveHookName = "onReceive.introspectionMsgTracer"
5
+ const OnReceiveTracingHookName = "onReceive.introspectionMsgTracer"
6
+ const OnReceiveDebugHookName = "onReceive.introspectionMsgDebug"
7
+
6
8
  const OnPreuninstallHookName = "preUninstall.introspectionMsgTracer"
7
- const debugLength = RED.settings.debugMaxLength || 1000
9
+
10
+ const debugLength = RED.settings.debugMaxLength || 1000
8
11
 
9
12
  function msgTracerOnReceiveHook(evnt) {
10
13
  try {
@@ -18,8 +21,6 @@ module.exports = function(RED) {
18
21
  nodeid: evnt.destination.id
19
22
  })
20
23
  )
21
-
22
- return nde
23
24
  } catch (ex) {
24
25
  console.error(ex)
25
26
  }
@@ -27,38 +28,41 @@ module.exports = function(RED) {
27
28
 
28
29
  function msgTracerOnReceiveHookWithDebug(evnt) {
29
30
  try {
30
- let nde = msgTracerOnReceiveHook(evnt)
31
+ let nde = RED.nodes.getNode(evnt.destination.id)
32
+
33
+ // don't publish debug messages for junctions because they
34
+ // cause errors in handleDebugMessages in the client.
35
+ if (nde.type == "junction") { return }
31
36
 
32
37
  // taken from the [debug node](https://github.com/node-red/node-red/blob/2854351909dee9f92597faba3f37239134294eec/packages/node_modules/%40node-red/nodes/core/common/21-debug.js#L227)
33
- let msg = {
34
- id: nde.id,
35
- z: nde.z,
36
- _alias: nde._alias,
37
- path: nde._flow.path,
38
- name: nde.name,
39
- topic: evnt.msg.topic,
38
+ let msg = {
39
+ id: nde.id,
40
+ z: nde.z,
41
+ _alias: nde._alias,
42
+ path: nde._flow.path,
43
+ name: nde.name,
44
+ topic: evnt.msg.topic,
40
45
  msg: evnt.msg
41
46
  }
42
47
 
43
48
  msg = RED.util.encodeObject(msg, { maxLength: debugLength });
44
- RED.comms.publish("debug",msg);
45
-
49
+ RED.comms.publish("debug", msg);
46
50
  } catch (ex) {
47
51
  console.error(ex)
48
52
  }
49
53
  }
50
54
 
51
55
  function ClientCodeFunctionality(config) {
52
- RED.nodes.createNode(this,config);
56
+ RED.nodes.createNode(this, config);
53
57
 
54
58
  var node = this;
55
59
  var cfg = config;
56
60
 
57
- node.on('close', function() {
61
+ node.on('close', function () {
58
62
  node.status({});
59
63
  });
60
64
 
61
- node.on("input", function(msg, send, done) {
65
+ node.on("input", function (msg, send, done) {
62
66
  // msg object may cause problem if there are circular references, so
63
67
  // do a pre-stringify before erroring out.
64
68
  try {
@@ -83,20 +87,32 @@ module.exports = function(RED) {
83
87
  RED.nodes.registerType("ClientCode", ClientCodeFunctionality);
84
88
 
85
89
  /**
86
- * These are the two endpoints for the message tracer functionality.
90
+ * These are the four endpoints for the message tracer functionality.
87
91
  * Rather badly placed in the ClientCode node code but the author
88
92
  * didn't find a better place. The world is confusing, why should
89
93
  * this codebase be any different.
90
94
  */
91
- RED.httpAdmin.post("/MsgTracer/msgtracing/on",
92
- RED.auth.needsPermission("ClientCode.write"),
95
+ RED.httpAdmin.post("/MsgTracer/debug/on",
96
+ RED.auth.needsPermission("MsgTracer.write"),
93
97
  (req, res) => {
94
98
  try {
95
- RED.hooks.remove(OnReceiveHookName)
96
- if ( req.body.withDebug ) {
97
- RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHookWithDebug)
98
- } else {
99
- RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHook)
99
+
100
+ /*
101
+ * If selected nodes is empty by allIsOn is on, then trace all messages.
102
+ * If node selection is non-empty, then trace those nodes.
103
+ */
104
+ if (req.body.nodesSelected.length == 0 && req.body.allIsOn) {
105
+ RED.hooks.remove(OnReceiveDebugHookName)
106
+ RED.hooks.add(OnReceiveDebugHookName, msgTracerOnReceiveHookWithDebug)
107
+ } else if (req.body.nodesSelected.length > 0) {
108
+ RED.hooks.remove(OnReceiveDebugHookName)
109
+
110
+ let nodesToBeTraced = [...req.body.nodesSelected]
111
+ RED.hooks.add(OnReceiveDebugHookName, (evnt) => {
112
+ if (nodesToBeTraced.indexOf(evnt.destination.id) > -1) {
113
+ msgTracerOnReceiveHookWithDebug(evnt)
114
+ }
115
+ })
100
116
  }
101
117
 
102
118
  // add hook on uninstall package so that the hook for the
@@ -104,24 +120,62 @@ module.exports = function(RED) {
104
120
  RED.hooks.remove(OnPreuninstallHookName)
105
121
  RED.hooks.add(OnPreuninstallHookName, (evnt) => {
106
122
  if (evnt.module == "@gregoriusrippenstein/node-red-contrib-introspection") {
107
- RED.hooks.remove(OnReceiveHookName)
123
+ RED.hooks.remove(OnReceiveTracingHookName)
124
+ RED.hooks.remove(OnReceiveDebugHookName)
108
125
  RED.hooks.remove(OnPreuninstallHookName)
109
126
  }
110
127
  })
111
128
 
112
129
  res.sendStatus(200);
113
- } catch (err) {
130
+ } catch (ex) {
114
131
  res.sendStatus(500);
115
132
  }
116
133
  });
117
134
 
118
- RED.httpAdmin.post("/MsgTracer/msgtracing/off",
119
- RED.auth.needsPermission("ClientCode.write"),
135
+ RED.httpAdmin.post("/MsgTracer/debug/off",
136
+ RED.auth.needsPermission("MsgTracer.write"),
120
137
  (req, res) => {
121
138
  try {
139
+ RED.hooks.remove(OnReceiveDebugHookName)
140
+ res.sendStatus(200);
141
+ } catch (err) {
142
+ res.sendStatus(500);
143
+ }
144
+ });
145
+
146
+ RED.httpAdmin.post("/MsgTracer/msgtracing/on",
147
+ RED.auth.needsPermission("MsgTracer.write"),
148
+ (req, res) => {
149
+ try {
150
+
151
+ /*
152
+ * If selected nodes is empty by allIsOn is on, then trace all messages.
153
+ * If node selection is non-empty, then trace those nodes.
154
+ */
155
+ if (req.body.nodesSelected.length == 0 && req.body.allIsOn) {
156
+ RED.hooks.remove(OnReceiveTracingHookName)
157
+ RED.hooks.add(OnReceiveTracingHookName, msgTracerOnReceiveHook)
158
+ } else if (req.body.nodesSelected.length > 0) {
159
+ RED.hooks.remove(OnReceiveTracingHookName)
160
+
161
+ let nodesToBeTraced = [...req.body.nodesSelected]
162
+ RED.hooks.add(OnReceiveTracingHookName, (evnt) => {
163
+ if (nodesToBeTraced.indexOf(evnt.destination.id) > -1) {
164
+ msgTracerOnReceiveHook(evnt)
165
+ }
166
+ })
167
+ }
122
168
 
123
- RED.hooks.remove(OnReceiveHookName)
169
+ // add hook on uninstall package so that the hook for the
170
+ // message tracer is removed on uninstall of this package.
124
171
  RED.hooks.remove(OnPreuninstallHookName)
172
+ RED.hooks.add(OnPreuninstallHookName, (evnt) => {
173
+ if (evnt.module == "@gregoriusrippenstein/node-red-contrib-introspection") {
174
+ RED.hooks.remove(OnReceiveTracingHookName)
175
+ RED.hooks.remove(OnReceiveDebugHookName)
176
+ RED.hooks.remove(OnPreuninstallHookName)
177
+ }
178
+ })
125
179
 
126
180
  res.sendStatus(200);
127
181
  } catch (err) {
@@ -129,19 +183,34 @@ module.exports = function(RED) {
129
183
  }
130
184
  });
131
185
 
186
+ RED.httpAdmin.post("/MsgTracer/msgtracing/off",
187
+ RED.auth.needsPermission("MsgTracer.write"),
188
+ (req, res) => {
189
+ try {
190
+ RED.hooks.remove(OnReceiveTracingHookName)
191
+ res.sendStatus(200);
192
+ } catch (err) {
193
+ res.sendStatus(500);
194
+ }
195
+ });
196
+
197
+
198
+ /*
199
+ * Back to the client code http endpoints.
200
+ */
132
201
  RED.httpAdmin.post("/ClientCode/:id",
133
202
  RED.auth.needsPermission("ClientCode.write"),
134
- (req,res) => {
203
+ (req, res) => {
135
204
  var node = RED.nodes.getNode(req.params.id);
136
205
  if (node != null) {
137
206
  try {
138
- if (req.body && node.type == "ClientCode" ) {
207
+ if (req.body && node.type == "ClientCode") {
139
208
  node.send(req.body);
140
209
  res.sendStatus(200);
141
210
  } else {
142
211
  res.sendStatus(404);
143
212
  }
144
- } catch(err) {
213
+ } catch (err) {
145
214
  res.sendStatus(500);
146
215
  }
147
216
  } else {
@@ -173,12 +242,12 @@ module.exports = function(RED) {
173
242
  RED.auth.needsPermission("ClientCode.write"),
174
243
  (req, res) => {
175
244
  try {
176
- if (req.body ) {
177
- req.body.nodes.forEach( n => {
245
+ if (req.body) {
246
+ req.body.nodes.forEach(n => {
178
247
 
179
- if (n.format == "css" && !/[@]obfuscate-ignore/.test(n.template) ) {
248
+ if (n.format == "css" && !/[@]obfuscate-ignore/.test(n.template)) {
180
249
  let output = new CleanCSS(req.body.csscfg).minify(n.template);
181
- if ( output.styles && (output.errors || []).length == 0 ) {
250
+ if (output.styles && (output.errors || []).length == 0) {
182
251
  n.template = output.styles
183
252
  } else {
184
253
  n._error = output.errors
@@ -202,13 +271,13 @@ module.exports = function(RED) {
202
271
  }
203
272
  }
204
273
 
205
- if (n.format == "javascript" && !/[@]obfuscate-ignore/.test(n.template)) {
274
+ if (n.format == "javascript" && !/[@]obfuscate-ignore/.test(n.template)) {
206
275
  /* this handles PkgFile nodes and template nodes */
207
276
  let result = UglifyJS.minify(n.template, req.body.jscfg)
208
277
 
209
- if ( result.code && !result.error) {
278
+ if (result.code && !result.error) {
210
279
  n.template = result.code
211
- } else {
280
+ } else {
212
281
  n._error = result.error
213
282
  n._code = result.code
214
283
  }
@@ -218,13 +287,13 @@ module.exports = function(RED) {
218
287
  let result = UglifyJS.minify(n.func, req.body.jscfg)
219
288
 
220
289
  if (result.code && !result.error) {
221
- n.func = result.code
290
+ n.func = result.code
222
291
  } else {
223
292
  n._error = result.error
224
293
  n._code = result.code
225
294
  }
226
295
  }
227
-
296
+
228
297
  })
229
298
  res.status(200).send(req.body.nodes);
230
299
  } else {
@@ -234,6 +303,4 @@ module.exports = function(RED) {
234
303
  res.sendStatus(500);
235
304
  }
236
305
  });
237
-
238
-
239
306
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gregoriusrippenstein/node-red-contrib-introspection",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "dependencies": {
5
5
  "got": "^13",
6
6
  "uglify-js": "^3.17.4",
@@ -4,7 +4,7 @@
4
4
 
5
5
  let obfuscateHelpers={getFlowDataFromCurrentWorkspace:e=>{var e=e||RED.workspaces.active(),t=RED.nodes.groups(e),e=(t=(t=t.concat(RED.nodes.junctions(e))).concat(RED.nodes.filterNodes({z:e})),RED.nodes.eachConfig(function(e){e.z===RED.workspaces.active()&&!1===e._def.hasUsers&&t.push(e)}),RED.nodes.workspace(e)||RED.nodes.subflow(e));return t.unshift(e),RED.nodes.createExportableNodeSet(t)},openImportDialog:e=>{RED.clipboard.import();let t=e;setTimeout(()=>{$("#red-ui-clipboard-dialog-import-text").val(JSON.stringify(t)).trigger("paste")},300)}};function obfuscatieCurrentFlow(l){let p=obfuscateHelpers.getFlowDataFromCurrentWorkspace(),f=(l.remove_groups&&(p=p.filter(e=>"group"!=e.type)).forEach(e=>{delete e.g}),{}),t={},d={},c={},s=[],h={},r={};if(p.forEach(e=>{"subflow"==(f[e.id]=e).type&&(r[e.id]=e),"junction"==e.type&&(t[e.id]=e),"link out"==e.type&&(c[e.id]=e),"link in"==e.type&&(d[e.id]=e),"link call"==e.type&&s.push(e.id),"catch"==e.type&&(h[e.id]=(e.wires||[])[0]||[])}),l.remove_junctions&&(Object.keys(t).forEach(n=>{let s=t[n];r[s.z]||p.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r=t.wires[e].indexOf(n);-1<r&&(t.wires[e].splice(r,1),t.wires[e].push(...s.wires[0]))}})}),p=p.filter(e=>!("junction"==e.type&&!r[e.z]))),l.remove_linkout_nodes||l.remove_linkcall_nodes){let r=[],n=[],i=[],a=(l.remove_linkout_nodes&&!l.copy_linkin_nodes&&Object.keys(c).forEach(n=>{var e=c[n];let s=e.links||[];s.reduce((e,t)=>e&&(!!d[t]||l.ignore_off_flow_links),!0)&&"return"!=e.mode&&(r.push(n),p.forEach(r=>{for(let t=0;t<(r.wires||[]).length;t++){var e=r.wires[t].indexOf(n);-1<e&&(r.wires[t].splice(e,1),s.forEach(e=>{d[e]&&r.wires[t].push(...d[e].wires[0])}))}}))}),(s,e)=>{if(!e)return!1;let t=[],o=[],r=[];function u(e){if(r.indexOf(e.id)<0)switch(r.push(e.id),t.push(e),e.type){case"link out":if("return"!=e.mode)throw"not handable";break;case"link call":throw"unhandled";default:RED.nodes.getNodeLinks(e).forEach(function(e){u(e.target)})}}try{RED.nodes.getNodeLinks(e).forEach(function(e){u(e.target),o.push(e.target.id)});if(Object.keys(h).forEach(e=>{((t,e)=>{try{return e.map(e=>e.id).forEach(e=>{if(t.includes(e))throw"yes"}),!1}catch(e){return!0}})(h[e],t)&&t.push(f[e])}),0==t.length)return!1;let r={};var i=t[0];let n={x:s.x-i.x,y:s.y-i.y};var a=t.map(e=>{var t=structuredClone(f[e.id]);return t||console.log("WARNING: nodeid not found",[e.id,f[e.id]]),t.id=RED.nodes.id(),t.x+=n.x,t.y+=n.y,r[e.id]=t});return a.forEach(e=>{"catch"==e.type&&Array.isArray(e.scope)&&(e.scope=e.scope.map(e=>{var t=r[e];return t&&t.id||e})),e.wires&&(e.wires=e.wires.map(e=>e.map(e=>{var t=r[e];return t&&"link out"==t.type?[...s.wires[0],(t||{}).id||e]:(t||{}).id||e}).flat()))}),{nodes:a.filter(e=>"link out"!=e.type),entryNodes:o.map(e=>r[e])}}catch(e){return!1}});l.remove_linkout_nodes&&l.copy_linkin_nodes&&Object.keys(c).forEach(s=>{let o=c[s],u=o.links||[];if("return"!=o.mode){let t=u.map(e=>{var t=d[e],t=a(o,t);return t?[e,t]:[void 0,void 0]});t.reduce((e,t)=>e&&(!!t[0]||l.ignore_off_flow_links),!0)&&(r.push(s),p.forEach(n=>{for(let r=0;r<(n.wires||[]).length;r++){var e=n.wires[r].indexOf(s);-1<e&&(n.wires[r].splice(e,1),(t=u.map(e=>{var t=d[e],t=a(o,t);return t?[e,t]:[void 0,void 0]})).forEach(([,e])=>{var t;e&&(t=e.entryNodes.map(e=>e.id),n.wires[r].push(...t),i.push(...e.nodes))}))}}))}}),l.remove_linkcall_nodes&&s.forEach(s=>{var e=f[s],t=d[e.links[0]];let o=a(e,t);t&&o&&(n.push(e.id),p.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r,n=t.wires[e].indexOf(s);-1<n&&(r=o.entryNodes.map(e=>e.id),t.wires[e].splice(n,1),t.wires[e].push(...r),i.push(...o.nodes))}}))}),(p=p.filter(e=>r.indexOf(e.id)<0&&n.indexOf(e.id)<0)).push(...i)}if((p=l.remove_debugs?p.filter(e=>"debug"!=e.type&&"comment"!=e.type):p).forEach(e=>{l.name&&(e.name=RED.nodes.id()),l.shrink_node&&(e.l=!1),l.info&&(e.info="",delete e.outputLabels,delete e.inputLabels),l.add_license&&(l.append_license?e.info=(e.info||"")+"\n---\n\n"+l.license_text:e.info=l.license_text),l.position&&(e.x=150,e.y=150),l.remove_icons&&delete e.icon}),l.replace_switch){let n=(t,r)=>{for(let e=0;e<r.rules.length;e++){var n=r.rules[e];if("nnull"==n.t)t.push("if ( _propValue != null ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("null"==n.t)t.push("if ( _propValue == null ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("eq"==n.t&&"str"==n.vt){s=n.v;s=btoa(encodeURIComponent(s).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}));t.push("if ( _propValue === Buffer.from('"+s+"', 'base64').toString('utf-8') ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }")}else if("gt"==n.t&&"num"==n.vt)t.push("if ( _propValue > "+n.v+" ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("eq"==n.t&&"num"==n.vt)t.push("if ( _propValue == "+n.v+" ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("empty"==n.t)t.push('let p = _propValue ; if ( (Array.isArray(p) && p.length == 0) || ((typeof p === "object") && p != null && Object.keys(p).length == 0) || ((typeof p === "string") && p.length == 0) ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }');else if("nempty"==n.t)t.push('let p = _propValue ; if ( (Array.isArray(p) && p.length > 0) || ((typeof p === "object") && p != null && Object.keys(p).length > 0) || ((typeof p === "string") && p.length > 0) ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }');else{if("else"!=n.t)throw"unhandled";t.push("_returnValue.push(msg)","return node.send(_returnValue)")}}var s};p=p.map(t=>{if("switch"!=t.type)return t;var e={id:t.id,name:t.name,type:"function",x:t.x,y:t.y,func:"",outputs:t.outputs,timeout:"",noerr:0,initialize:"",finalize:"",libs:[{var:"process",module:"process"},{var:"jsonata",module:"jsonata"}],wires:t.wires};t.hasOwnProperty("z")&&(e.z=t.z),t.hasOwnProperty("l")&&(e.l=t.l);try{var r=[];if(t.checkAll)throw"unhandled";if("msg"==t.propertyType)r.push("((msg,node) => {","let _propValue = undefined","try { _propValue = RED.util.getMessageProperty(msg, '"+t.property+"') } catch (ex) {}","let _returnValue = []"),n(r,t),r.push("})(msg,node);");else{if("jsonata"!=t.propertyType)throw"unhandled";r.push("jsonata('"+t.property+"').evaluate(msg).then(_propValue => {","let _returnValue = []"),n(r,t),r.push("})")}return e.func=r.join("\n"),e}catch(e){return t}})}if(l.replace_change){let s=e=>btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}));p=p.map(t=>{if("change"!=t.type)return t;var e={id:t.id,name:t.name,type:"function",x:t.x,y:t.y,func:"",outputs:1,timeout:"",noerr:0,initialize:"",finalize:"",libs:[{var:"process",module:"process"},{var:"jsonata",module:"jsonata"}],wires:t.wires};t.hasOwnProperty("z")&&(e.z=t.z),t.hasOwnProperty("l")&&(e.l=t.l);try{var r=["(async (msg,node) => {","let __s = RED.util.setMessageProperty","let __g = RED.util.getMessageProperty"];for(let e=0;e<t.rules.length;e++){var n=t.rules[e];if("set"==n.t){if(n.dc)throw"unhandled";if("msg"==n.pt&&"str"==n.tot)r.push("__s(msg,'"+n.p+"', Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8') )");else if("msg"==n.pt&&"bool"==n.tot)r.push("__s(msg,'"+n.p+"', "+n.to+")");else if("msg"==n.pt&&"num"==n.tot)r.push("__s(msg,'"+n.p+"', Number(Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8')))");else if("msg"==n.pt&&"json"==n.tot)r.push("__s(msg,'"+n.p+"', JSON.parse(Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8')))");else if("msg"==n.pt&&"msg"==n.tot)r.push("try { __s(msg,'"+n.p+"', __g(msg, '"+n.to+"')) } catch (ex) {}");else if("msg"==n.pt&&"env"==n.tot)r.push("__s(msg,'"+n.p+"', process.env['"+n.to+"'])");else{if("msg"!=n.pt||"jsonata"!=n.tot||!n.to.startsWith("/* @obfuscate-safe */"))throw"unhandlable";r.push("__s(msg,'"+n.p+"', await jsonata(Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8')).evaluate(msg) )")}}else{if("delete"!=n.t||"msg"!=n.pt)throw"unhandlable";r.push("delete msg."+n.p)}}return r.push("node.send(msg) })(msg,node);"),e.func=r.join("\n"),e}catch(e){return console.log(e),t}})}if(l.javascript){let r={},t=[];p.forEach(e=>{"javascript"!=(r[e.id]=e).format&&"function"!=e.type&&"css"!=e.format&&"json"!=e.format||t.push(e)});var e={parse:{bare_returns:!0,expression:!1},compress:{},mangle:{reserved:["$","export","require"]},output:null,sourceMap:null,nameCache:null,toplevel:!1,warnings:!1},o={compatibility:"*",level:2};$.ajax({url:"ClientCode/"+RED.nodes.id()+"/ugify",type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodes:t,jscfg:e,csscfg:o}),success:function(e){e.forEach(e=>{var t=r[e.id];e._error&&console.log("ERROR NODE",e),"function"==t.type?t.func=e.func:"javascript"!=t.format&&"css"!=t.format&&"json"!=t.format||(t.template=e.template)}),obfuscateHelpers.openImportDialog(p)},error:function(e,t,r){RED.notify("ClientCode Communcation Failure: "+n.id+": "+t,{type:"error",timeout:3e3})}})}else obfuscateHelpers.openImportDialog(p)}
6
6
 
7
- function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"success",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){const t=new Set;var n=[],i=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{(!t.has(e)||"link out"==e.type&&"link"==e.mode&&0==e.links.reduce((e,t)=>e||!!RED.nodes.node(t),!1))&&n.push(e)}),[]),r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},i.push(r[e.id])}),i}
7
+ function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"success",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){let t=new Set;var n=[],i=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{(!t.has(e)||"link out"==e.type&&"link"==e.mode&&0==e.links.reduce((e,t)=>e||!!RED.nodes.node(t),!1))&&n.push(e)}),[]),r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},i.push(r[e.id])}),i}
8
8
 
9
9
  function nr_intro_generate_svg_4_0(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_1(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_0(r,t){return e=>{try{handleSvgObject($($("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function handleSvgObject(a,e,t){var n=a.clone(),r=(n.find("foreignObject").remove(),n.find("svg.__screenshot").remove(),'width="'+a.attr("width")+'" height="'+a.attr("height")+'"'),s=RED.settings.version.split("."),i=parseInt(s[0]),s=parseInt(s[1]);if(3<=i&&1<=s){var o=$($($(a).children("g")[0]).children("g")[0]).children("g"),l={x:8e3,y:8e3,w:-1,h:-1};for(let t=1;t<o.length;t++){var g=o[t].getBBox();0==g.width&&0==g.height||(l.x=Math.min(g.x,l.x),l.y=Math.min(g.y,l.y),l.w=Math.max(g.width,l.w),l.h=Math.max(g.height,l.h))}r+=` viewBox='${l.x} ${l.y} ${l.w} ${l.h}'`}function c(t,e){for(var n=0;n<t.length;n++){var s=t.item(n),i=e[n];["stroke-width","fill-opacity","stroke-opacity","opacity","stroke-dasharray"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))}),["fill","stroke"].forEach(function(t){var e,n,r=(e=$(i).attr(t)||$(i).css(t))&&null!==e&&"none"!=e?(n=e.match(/^#(.)(.)(.)$/))?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:(n=e.match(/^#......$/))?e:null===(n=e.match(/^rgb\(([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?(r=e.match(/^rgba\(([0-9]+),\s+([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?{clr:"#"+("0"+parseInt(r[1],10).toString(16)).slice(-2)+("0"+parseInt(r[2],10).toString(16)).slice(-2)+("0"+parseInt(r[3],10).toString(16)).slice(-2),opa:r[4]}:(console.log("Screenshot node: returned unknown color: "+e),e):"#"+("0"+parseInt(n[1],10).toString(16)).slice(-2)+("0"+parseInt(n[2],10).toString(16)).slice(-2)+("0"+parseInt(n[3],10).toString(16)).slice(-2):"none";"object"==typeof r?(s.setAttribute(t+"-opacity",r.opa),s.setAttribute(t,r.clr)):s.setAttribute(t,r)}),$(i).hasClass("hide")&&("g"==s.tagName&&s.setAttribute("opacity","0"),s.setAttribute("visibility","hidden"))}}var i='<?xml version="1.0" standalone="no"?>\r\n<svg '+r+' pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" class="__screenshot" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n',s=n.html(),h=(new DOMParser).parseFromString(i+s+"\r\n</svg>","image/svg+xml"),v=t=>t,f=(t.rmidsandclasses&&(v=e=>(["g","rect","line","path","circle","image","text"].forEach(t=>{$(e.getElementsByTagName(t)).each((t,e)=>{e.setAttribute("class",""),e.setAttribute("id","")})}),e)),["g","rect","line","path","circle","image"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t))}),["text"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t));for(var e=h.getElementsByTagName(t),n=a.find(t),r=0;r<e.length;r++){var s=e.item(r),i=n[r];["font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","text-anchor","dominant-baseline"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))})}}),h.getElementsByTagName("image")),w={},m=(n,r,s)=>{var i=n.getAttribute("xlink:href")||n.getAttribute("href"),a=i.substr(-4,4).toLowerCase(),o={".jpg":"jpeg",jpeg:"jpeg",".png":"png",".svg":"svg+xml"};if(w[i])return n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+w[i]),s(r-1);switch(a){case".jpg":case"jpeg":case".png":var l=new XMLHttpRequest;l.open("GET",i,!0),l.responseType="arraybuffer";l.onload=function(t){var e=l.response;e&&(e=(t=>{for(var e="",n=new Uint8Array(t),r=n.byteLength,s=0;s<r;s++)e+=String.fromCharCode(n[s]);return window.btoa(e)})(e),w[i]=e,n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+e)),s(r-1)},l.send(null);break;case".svg":$.get(i,function(t){var e=new XMLSerializer,e=btoa(e.serializeToString(t));w[i]=e,n.setAttribute("xlink:href","data:image/svg+xml;base64,"+e),s(r-1)})}},d=t=>{t<0?e((new XMLSerializer).serializeToString(v(h))):m(f.item(t),t,d)};0<f.length?m(f.item(f.length-1),f.length-1,d):e((new XMLSerializer).serializeToString(v(h)))}function generatorFunctionForVersion(t,e){var n,r=t.settings.version.split("."),s=r[0],r=r[1];if("3"==s){if("0"==r)return nr_intro_generate_svg_3_0(t,e);if("1"==r)return nr_intro_generate_svg_3_1(t,e)}return"4"==s&&"0"==r?nr_intro_generate_svg_4_0(t,e):(n=t,t=>{var e="Node-RED version ("+n.settings.version+") not supported";n.notify(e,{type:"error"}),t&&t('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+e+"</text></svg>")})}function addPanZoom(){var t=d3.select("#node-input-screenshot-svgcontainer svg"),e=(t.html("<g>"+t.html()+"</g>"),setTimeout(()=>{var t=$("#node-input-screenshot-svgcontainer svg"),e=$(t).attr("viewBox").split(" ");t.animate({height:parseInt(e[3]),width:parseInt(e[2])},800,"swing")},100),t.select("g")),n=d3.behavior.zoom().scaleExtent([.1,200]).on("zoom",function(t){e.attr({transform:"translate("+n.translate()+") scale("+n.scale()+")"})});t.call(n)}
10
10
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  function setupTreelistAllLinksForLinkIn(e){e=collectAllLinksNodes(e);if(0==e.length){RED.notify("No links found",{type:"error",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e,"editor-tab-description")),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectAllLinksNodes(t){let n=[];RED.nodes.eachNode(e=>{"link call"!=e.type&&"link out"!=e.type||-1<e.links.indexOf(t)&&n.push(e)});var i=[],r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n,o=t.label,o=("function"==typeof o?o.call(e):o)||"";if(0===(n=e.type).indexOf("subflow:"))return}t&&o||(o=e.type),r[e.id]={node:e,label:o,sublabel:n,selected:!1,checkbox:!1},i.push(r[e.id])}),i}function collectNodeStats(){let t={},n=[],o={workspaces:0,junctions:0,subflows:0,configs:0,groups:0,wires:0,nodes:0},i=(RED.nodes.eachConfig(e=>{o.configs+=1}),RED.nodes.eachLink(e=>{o.wires+=1}),RED.nodes.eachJunction(e=>{o.junctions+=1}),RED.nodes.eachGroup(e=>{o.groups+=1}),RED.nodes.eachWorkspace(e=>{o.workspaces+=1}),RED.nodes.eachSubflow(e=>{o.subflows+=1}),RED.nodes.eachNode(e=>{o.nodes+=1,t[e.type]=(t[e.type]||0)+1}),Object.keys(t).forEach(e=>{n.push({label:e,sublabel:t[e],selected:!1,checkbox:!1})}),[]),r=0;return Object.keys(o).forEach(e=>{r+=o[e],i.push({label:e,sublabel:o[e],selected:!1,checkbox:!1})}),[{label:"__ TOTALS",sublabel:r,selected:!1,checkbox:!1,children:i}].concat(n.sort((e,t)=>e.label>t.label))}function setupTreeListForNodeStats(){var e=collectNodeStats();try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){}).on("treelistconfirm",function(e,t){}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e)}
16
16
 
17
- function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw(),$("#node-input-msgtracer-toggle").is(":checked")||($(".red-ui-debug-msg").css("background-color",""),$(".red-ui-debug-msg-node-"+t.node.id).css("background-color","red")))}).on("treelistconfirm",function(e,t){var r;t.node&&(r=t.node.id,setTimeout(()=>{var e=RED.nodes.node(r);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),r==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var r=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),r.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)||-1<e.node.id.toLowerCase().indexOf(t)}),r.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}function toggleMsgTracingInBackend(e){let t=$("#node-input-msgtracer-toggle").is(":checked"),r=$("#node-input-msgtracer-msgtodebug").is(":checked");$.ajax({url:"MsgTracer/msgtracing/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({withDebug:r}),success:function(e){RED.notify("Message tracing is <b>"+(t?"on":"off")+"</b> and msg to debug is <b>"+(r?"on":"off")+"</b>",{type:"success",timeout:3e3})},error:function(e,t,r){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})}function handleMsgTracerToggles(e){$("#node-input-msgtracer-toggle").is(":checked")&&setupTreeMsgTracerlist(),toggleMsgTracingInBackend(e)}
17
+ function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw(),$("#node-input-msgtracer-toggle").is(":checked")||($(".red-ui-debug-msg").css("background-color",""),$(".red-ui-debug-msg-node-"+t.node.id).css("background-color","red")))}).on("treelistconfirm",function(e,t){var o;t.node&&(o=t.node.id,setTimeout(()=>{var e=RED.nodes.node(o);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),o==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var o=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),o.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)||-1<e.node.id.toLowerCase().indexOf(t)}),o.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}function toggleDebugTracingInBackend(e){let t=$("#node-input-msgtracer-msgtodebug").is(":checked");var o=$("#node-input-msgtracer-msgtodebug-all").is(":checked");RED.view.selection().nodes||o||!t?(t||$("#node-input-msgtracer-msgtodebug-all").prop("checked",!1),$.ajax({url:"MsgTracer/debug/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodesSelected:(RED.view.selection().nodes||[]).map(e=>e.id),allIsOn:o}),success:function(e){RED.notify("Message debugging is <b>"+(t?"on":"off")+"</b>",{type:"success",timeout:3e3})},error:function(e,t,o){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})):($("#node-input-msgtracer-msgtodebug").prop("checked",!1),RED.notify("Debug Messages not toggled, either no selection or all is off",{type:"error",timeout:3e3}))}function toggleMsgTracingInBackend(e){let t=$("#node-input-msgtracer-toggle").is(":checked");var o=$("#node-input-msgtracer-toggle-all").is(":checked");RED.view.selection().nodes||o||!t?(t||$("#node-input-msgtracer-toggle-all").prop("checked",!1),t&&setupTreeMsgTracerlist(),$.ajax({url:"MsgTracer/msgtracing/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodesSelected:(RED.view.selection().nodes||[]).map(e=>e.id),allIsOn:o}),success:function(e){RED.notify("Message tracing is <b>"+(t?"on":"off")+"</b>",{type:"success",timeout:3e3})},error:function(e,t,o){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})):($("#node-input-msgtracer-toggle").prop("checked",!1),RED.notify("Message tracing not toggled, either no node selection or all is off",{type:"error",timeout:3e3}))}
18
18
 
19
19
  // Add your plugin as a new tabsheet in the right sidebar AFTER the flow editor is completely started
20
20
  var initialiseConfigNodeOnce = () => {
@@ -257,8 +257,8 @@
257
257
  $("#node-input-msgtracer-trace-treelist").treeList('data', [])
258
258
  })
259
259
 
260
- $('#node-input-msgtracer-msgtodebug').on("change", toggleMsgTracingInBackend)
261
- $('#node-input-msgtracer-toggle').on("change", handleMsgTracerToggles)
260
+ $('#node-input-msgtracer-msgtodebug').on("change", toggleDebugTracingInBackend)
261
+ $('#node-input-msgtracer-toggle').on("change", toggleMsgTracingInBackend)
262
262
 
263
263
  RED.actions.add( "introspection:show-link-call-links", highlightAllLinkCalls)
264
264
 
@@ -366,53 +366,69 @@
366
366
  class="red-ui-button"><i class="fa fa-cc"></i> Undocumented</button>
367
367
  <button id="node-input-linkin-nodes-find-btn"
368
368
  class="red-ui-button"><i class="fa fa-link"></i> Link Ins</button>
369
+ <button id="node-input-linkcalls-find-btn"
370
+ class="red-ui-button"><i class="fa fa-link"></i> Link Calls</button>
371
+ <button id="node-input-orphan-clear-workspace-btn"
372
+ class="red-ui-button">Clear dots</button>
369
373
  <button id="node-input-statistics-btn"
370
374
  class="red-ui-button"><i class="fa fa-pie-chart"></i> Stats</button>
371
375
  </div>
372
376
 
373
377
  <div class="form-row"
374
- style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px;">
378
+ style="margin-left: 10px; position: relative; min-height: 200px; height: 430px; margin-right: 15px;">
375
379
  <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
376
380
  <input type="text" id="node-input-orphan-target-filter" style="display: none;">
377
381
  </div>
378
382
  <div id="node-input-orphan-target-container-div"></div>
379
383
  </div>
380
384
 
381
- <div class="form-row" style="margin-left: 10px; margin-top: 40px">
382
- <button id="node-input-linkcalls-find-btn"
383
- class="red-ui-button"><i class="fa fa-link"></i> Link Calls</button>
384
- <button id="node-input-orphan-clear-workspace-btn"
385
- class="red-ui-button">Clear dots</button>
386
- </div>
385
+ <!-- message tracing stuff -->
387
386
 
388
387
  <div class="form-row" style="margin-left: 10px; margin-top: 40px">
389
388
  <label for="node-input-msgtracer-toggle" class="w-25">
390
- <i class="fa fa-stethoscope"></i>
391
- <span>Trace Messages?</span>
389
+ <i class="fa fa-stethoscope"></i>
390
+ <span>Trace selected nodes?</span>
392
391
  </label>
393
392
  <input type="checkbox" id="node-input-msgtracer-toggle"
394
- style="display:inline-block; width:15px; vertical-align:baseline;">
393
+ style="display:inline-block; width:15px; vertical-align:baseline;">
395
394
 
396
- <label for="node-input-msgtracer-msgtodebug" class="w-25">
397
- <i class="fa fa-bug"></i>
398
- <span>Msg to Debug?</span>
395
+ <label for="node-input-msgtracer-toggle-all" class="w-25">
396
+ <i class="fa fa-warning"></i>
397
+ <span>All nodes?</span>
399
398
  </label>
400
- <input type="checkbox" id="node-input-msgtracer-msgtodebug"
401
- style="display:inline-block; width:15px; vertical-align:baseline;">
399
+ <input type="checkbox" id="node-input-msgtracer-toggle-all"
400
+ style="display:inline-block; width:15px; vertical-align:baseline;">
402
401
 
403
402
  <button id="node-input-msgtrace-clear-trace-btn" style="margin-left: 10px;"
404
403
  class="red-ui-button">Clear Trace</button>
405
- <button id="node-input-msgtrace-clear-debug-btn" style="margin-left: 10px;"
406
- class="red-ui-button">Clear Debug</button>
407
404
  </div>
408
405
 
409
406
  <div class="form-row"
410
- style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px;">
407
+ style="margin-left: 10px; position: relative; min-height: 200px; height: 430px; margin-right: 15px;">
411
408
  <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
412
409
  <input type="text" id="node-input-msgtracer-trace-treelist-filter" style="display: none;">
413
410
  </div>
414
411
  <div id="node-input-msgtracer-trace-treelist"></div>
415
412
  </div>
413
+
414
+ <div class="form-row" style="margin-left: 10px; margin-top: 40px;">
415
+ <label for="node-input-msgtracer-msgtodebug" class="w-25">
416
+ <i class="fa fa-bug"></i>
417
+ <span>Msgs from selected nodes to Debug?</span>
418
+ </label>
419
+ <input type="checkbox" id="node-input-msgtracer-msgtodebug"
420
+ style="display:inline-block; width:15px; vertical-align:baseline;">
421
+
422
+ <label for="node-input-msgtracer-msgtodebug-all" class="w-25">
423
+ <i class="fa fa-warning"></i>
424
+ <span>All nodes?</span>
425
+ </label>
426
+ <input type="checkbox" id="node-input-msgtracer-msgtodebug-all"
427
+ style="display:inline-block; width:15px; vertical-align:baseline;">
428
+
429
+ <button id="node-input-msgtrace-clear-debug-btn" style="margin-left: 10px;"
430
+ class="red-ui-button">Clear Debug</button>
431
+ </div>
416
432
  </div>
417
433
 
418
434
  <!-- Obfuscation Tab in Sidebar -->