@gregoriusrippenstein/node-red-contrib-introspection 0.6.8 → 0.6.10

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
@@ -63,6 +63,8 @@ Clicking on the green dot will take the user to the corresponding link-in node w
63
63
 
64
64
  The green dot on the link-in node brings the clickee back to the original link-call node (i.e. the first green dot clicked). Also, to remove the green dots, switch between flow tabs. It can be tried out in the [crash-test dummy Node-RED](https://cdn.flowhub.org/?fhid=c520d9da20ad7f1d&t=0&sb=Introspection).
65
65
 
66
+ This functionality can also be bound to a key-shortcut in the settings by using the `Show Link Call Links` action.
67
+
66
68
  The Undocumented button will highlight all nodes that *have* documentation with a yellow dot (think sun) and list all those node that don't have any documentation.
67
69
 
68
70
  ### Obfuscate
@@ -79,7 +79,7 @@ module.exports = function(RED) {
79
79
  if (req.body ) {
80
80
  req.body.nodes.forEach( n => {
81
81
 
82
- if ( n.format == "css") {
82
+ if (n.format == "css" && !/[@]obfuscate-ignore/.test(n.template) ) {
83
83
  let output = new CleanCSS(req.body.csscfg).minify(n.template);
84
84
  if ( output.styles && (output.errors || []).length == 0 ) {
85
85
  n.template = output.styles
@@ -89,7 +89,7 @@ module.exports = function(RED) {
89
89
  }
90
90
  }
91
91
 
92
- if (n.format == "json") {
92
+ if (n.format == "json" && !/[@]obfuscate-ignore/.test(n.template)) {
93
93
  let result = {}
94
94
  try {
95
95
  result.code = JSON.stringify(JSON.parse(n.template))
@@ -105,7 +105,7 @@ module.exports = function(RED) {
105
105
  }
106
106
  }
107
107
 
108
- if ( n.format == "javascript") {
108
+ if (n.format == "javascript" && !/[@]obfuscate-ignore/.test(n.template)) {
109
109
  /* this handles PkgFile nodes and template nodes */
110
110
  let result = UglifyJS.minify(n.template, req.body.jscfg)
111
111
 
@@ -117,7 +117,7 @@ module.exports = function(RED) {
117
117
  }
118
118
  }
119
119
 
120
- if (n.type == "function") {
120
+ if (n.type == "function" && !/[@]obfuscate-ignore/.test(n.func)) {
121
121
  let result = UglifyJS.minify(n.func, req.body.jscfg)
122
122
 
123
123
  if (result.code && !result.error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gregoriusrippenstein/node-red-contrib-introspection",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "dependencies": {
5
5
  "got": "^13",
6
6
  "uglify-js": "^3.17.4",
@@ -16,7 +16,7 @@
16
16
  ],
17
17
 
18
18
  "homepage": "https://github.com/gorenje/node-red-contrib-introspection#readme",
19
- "license": "SEE LICENSE IN https://github.com/gorenje/node-red-contrib-introspection/blob/main/LICENSE",
19
+ "license": "Don't do Evil.",
20
20
  "author": "Gerrit Riessen <nodered@spreads-the.love> (https://spread-the.love)",
21
21
  "engines": {
22
22
  "node": ">=8"
@@ -2,7 +2,7 @@
2
2
  (function() {
3
3
  var globalRefToSvgData;
4
4
 
5
- let obfuscateHelpers={getFlowDataFromCurrentWorkspace:e=>{var e=e||RED.workspaces.active(),r=RED.nodes.groups(e),e=(r=(r=r.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&&r.push(e)}),RED.nodes.workspace(e)||RED.nodes.subflow(e));return r.unshift(e),RED.nodes.createExportableNodeSet(r)},openImportDialog:e=>{RED.clipboard.import();let r=e;setTimeout(()=>{$("#red-ui-clipboard-dialog-import-text").val(JSON.stringify(r)).trigger("paste")},300)}};function obfuscatieCurrentFlow(r){let l=obfuscateHelpers.getFlowDataFromCurrentWorkspace(),u=(r.remove_groups&&(l=l.filter(e=>"group"!=e.type)).forEach(e=>{delete e.g}),{}),t={},p={},c={},o=[],d={},i={};if(l.forEach(e=>{"subflow"==(u[e.id]=e).type&&(i[e.id]=e),"junction"==e.type&&(t[e.id]=e),"link out"==e.type&&(c[e.id]=e),"link in"==e.type&&(p[e.id]=e),"link call"==e.type&&o.push(e.id),"catch"==e.type&&(d[e.id]=(e.wires||[])[0]||[])}),r.remove_junctions&&(Object.keys(t).forEach(s=>{let o=t[s];i[o.z]||l.forEach(r=>{for(let e=0;e<(r.wires||[]).length;e++){var t=r.wires[e].indexOf(s);-1<t&&(r.wires[e].splice(t,1),r.wires[e].push(...o.wires[0]))}})}),l=l.filter(e=>!("junction"==e.type&&!i[e.z]))),r.remove_linkout_nodes||r.remove_linkcall_nodes){let s=[],t=[],i=[],a=(r.remove_linkout_nodes&&!r.copy_linkin_nodes&&Object.keys(c).forEach(o=>{var e=c[o],r=e.links||[];r.reduce((e,r)=>e&&!!p[r],!0)&&"return"!=e.mode&&(s.push(o),r.forEach(s=>{l.forEach(r=>{for(let e=0;e<(r.wires||[]).length;e++){var t=r.wires[e].indexOf(o);-1<t&&(r.wires[e].splice(t,1),r.wires[e].push(...p[s].wires[0]))}})}))}),(o,e)=>{if(!e)return!1;let r=[],n=[],t=[];function i(e){if(t.indexOf(e.id)<0)if(t.push(e.id),r.push(e),"link out"===e.type){if("return"!=e.mode)throw"not handable"}else RED.nodes.getNodeLinks(e).forEach(function(e){i(e.target)})}try{RED.nodes.getNodeLinks(e).forEach(function(e){i(e.target),n.push(e.target.id)});if(Object.keys(d).forEach(e=>{((r,e)=>{try{return e.map(e=>e.id).forEach(e=>{if(r.includes(e))throw"yes"}),!1}catch(e){return!0}})(d[e],r)&&r.push(u[e])}),0==r.length)return!1;let t={};var a=r[0];let s={x:o.x-a.x,y:o.y-a.y};var l=r.map(e=>{var r=structuredClone(u[e.id]);return r||console.log("WARNING: nodeid not found",[e.id,u[e.id]]),r.id=RED.nodes.id(),r.x+=s.x,r.y+=s.y,t[e.id]=r});return l.forEach(e=>{"catch"==e.type&&Array.isArray(e.scope)&&(e.scope=e.scope.map(e=>{var r=t[e];return r&&r.id||e})),e.wires&&(e.wires=e.wires.map(e=>e.map(e=>{var r=t[e];return r&&"link out"==r.type?[...o.wires[0],(r||{}).id||e]:(r||{}).id||e}).flat()))}),{nodes:l.filter(e=>"link out"!=e.type),entryNodes:n.map(e=>t[e])}}catch(e){return console.log(e),!1}});r.remove_linkout_nodes&&r.copy_linkin_nodes&&Object.keys(c).forEach(n=>{let t=c[n];var e=t.links||[];"return"!=t.mode&&(e=e.map(e=>{var r=p[e],r=a(t,r);if(r)return[e,r]})).reduce((e,r)=>e&&!!r,!0)&&(s.push(n),e.forEach(([,o])=>{l.forEach(r=>{for(let e=0;e<(r.wires||[]).length;e++){var t,s=r.wires[e].indexOf(n);-1<s&&(t=o.entryNodes.map(e=>e.id),r.wires[e].splice(s,1),r.wires[e].push(...t),i.push(...o.nodes))}})}))}),r.remove_linkcall_nodes&&o.forEach(o=>{var e=u[o],r=p[e.links[0]];let n=a(e,r);r&&n&&(t.push(e.id),l.forEach(r=>{for(let e=0;e<(r.wires||[]).length;e++){var t,s=r.wires[e].indexOf(o);-1<s&&(t=n.entryNodes.map(e=>e.id),r.wires[e].splice(s,1),r.wires[e].push(...t),i.push(...n.nodes))}}))}),(l=l.filter(e=>s.indexOf(e.id)<0&&t.indexOf(e.id)<0)).push(...i)}if((l=r.remove_debugs?l.filter(e=>"debug"!=e.type&&"comment"!=e.type):l).forEach(e=>{r.name&&(e.name=RED.nodes.id()),r.shrink_node&&(e.l=!1),r.info&&(e.info="",delete e.outputLabels,delete e.inputLabels),r.position&&(e.x=150,e.y=150),r.remove_icons&&delete e.icon}),r.replace_switch&&(l=l.map(r=>{if("switch"!=r.type)return r;var e={id:r.id,name:r.name,type:"function",x:r.x,y:r.y,func:"",outputs:r.outputs,noerr:0,initialize:"",finalize:"",libs:[{var:"process",module:"process"}],wires:r.wires};r.hasOwnProperty("z")&&(e.z=r.z),r.hasOwnProperty("l")&&(e.l=r.l);try{var t=[];if("msg"!=r.propertyType||r.checkAll)throw"unhandled";t.push("let _propValue = RED.util.getMessageProperty(msg, '"+r.property+"')","let _returnValue = []");for(let e=0;e<r.rules.length;e++){var s=r.rules[e];if("nnull"==s.t)t.push("if ( _propValue != null ) { _returnValue.push(msg) ; return _returnValue } else { _returnValue.push(undefined) }");else{if("else"!=s.t)throw"unhandled";t.push("_returnValue.push(msg)","return _returnValue")}}return e.func=t.join(";\n"),e}catch(e){return r}})),r.replace_change&&(l=l.map(r=>{if("change"!=r.type)return r;var e={id:r.id,name:r.name,type:"function",x:r.x,y:r.y,func:"",outputs:1,noerr:0,initialize:"",finalize:"",libs:[{var:"process",module:"process"}],wires:r.wires};r.hasOwnProperty("z")&&(e.z=r.z),r.hasOwnProperty("l")&&(e.l=r.l);try{var t=[];for(let e=0;e<r.rules.length;e++){var s=r.rules[e];if("set"==s.t){if(s.dc)throw"unhandled";if("msg"==s.pt&&"str"==s.tot)t.push("RED.util.setMessageProperty(msg,'"+s.p+"', '"+s.to+"')");else if("msg"==s.pt&&"bool"==s.tot)t.push("RED.util.setMessageProperty(msg,'"+s.p+"', "+s.to+")");else if("msg"==s.pt&&"num"==s.tot)t.push("RED.util.setMessageProperty(msg,'"+s.p+"', Number('"+s.to+"'))");else if("msg"==s.pt&&"json"==s.tot)t.push("RED.util.setMessageProperty(msg,'"+s.p+"', JSON.parse('"+s.to+"'))");else if("msg"==s.pt&&"msg"==s.tot)t.push("try { RED.util.setMessageProperty(msg,'"+s.p+"', RED.util.getMessageProperty(msg, '"+s.to+"')) } catch (ex) {}");else{if("msg"!=s.pt||"env"!=s.tot)throw"unhandlable";t.push("RED.util.setMessageProperty(msg,'"+s.p+"', process.env['"+s.to+"'])")}}else{if("delete"!=s.t||"msg"!=s.pt)throw"unhandlable";t.push("delete msg."+s.p)}}return t.push("return msg"),e.func=t.join(";\n"),e}catch(e){return r}})),r.javascript){let t={},r=[];l.forEach(e=>{"javascript"!=(t[e.id]=e).format&&"function"!=e.type&&"css"!=e.format&&"json"!=e.format||r.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},s={compatibility:"*",level:2};$.ajax({url:"ClientCode/"+RED.nodes.id()+"/ugify",type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodes:r,jscfg:e,csscfg:s}),success:function(e){e.forEach(e=>{var r=t[e.id];e._error&&console.log("ERROR NODE",e),"function"==r.type?r.func=e.func:"javascript"!=r.format&&"css"!=r.format&&"json"!=r.format||(r.template=e.template)}),obfuscateHelpers.openImportDialog(l)},error:function(e,r,t){RED.notify("ClientCode Communcation Failure: "+n.id+": "+r,{type:"error",timeout:3e3})}})}else obfuscateHelpers.openImportDialog(l)}
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(t){let a=obfuscateHelpers.getFlowDataFromCurrentWorkspace(),l=(t.remove_groups&&(a=a.filter(e=>"group"!=e.type)).forEach(e=>{delete e.g}),{}),r={},p={},f={},o=[],d={},u={};if(a.forEach(e=>{"subflow"==(l[e.id]=e).type&&(u[e.id]=e),"junction"==e.type&&(r[e.id]=e),"link out"==e.type&&(f[e.id]=e),"link in"==e.type&&(p[e.id]=e),"link call"==e.type&&o.push(e.id),"catch"==e.type&&(d[e.id]=(e.wires||[])[0]||[])}),t.remove_junctions&&(Object.keys(r).forEach(s=>{let n=r[s];u[n.z]||a.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r=t.wires[e].indexOf(s);-1<r&&(t.wires[e].splice(r,1),t.wires[e].push(...n.wires[0]))}})}),a=a.filter(e=>!("junction"==e.type&&!u[e.z]))),t.remove_linkout_nodes||t.remove_linkcall_nodes){let s=[],r=[],u=[],i=(t.remove_linkout_nodes&&!t.copy_linkin_nodes&&Object.keys(f).forEach(n=>{var e=f[n],t=e.links||[];t.reduce((e,t)=>e&&!!p[t],!0)&&"return"!=e.mode&&(s.push(n),t.forEach(s=>{a.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(...p[s].wires[0]))}})}))}),(n,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(d).forEach(e=>{((t,e)=>{try{return e.map(e=>e.id).forEach(e=>{if(t.includes(e))throw"yes"}),!1}catch(e){return!0}})(d[e],t)&&t.push(l[e])}),0==t.length)return!1;let r={};var i=t[0];let s={x:n.x-i.x,y:n.y-i.y};var a=t.map(e=>{var t=structuredClone(l[e.id]);return t||console.log("WARNING: nodeid not found",[e.id,l[e.id]]),t.id=RED.nodes.id(),t.x+=s.x,t.y+=s.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?[...n.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}});t.remove_linkout_nodes&&t.copy_linkin_nodes&&Object.keys(f).forEach(o=>{let r=f[o];var e=r.links||[];"return"!=r.mode&&(e=e.map(e=>{var t=p[e],t=i(r,t);if(t)return[e,t]})).reduce((e,t)=>e&&!!t,!0)&&(s.push(o),e.forEach(([,n])=>{a.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r,s=t.wires[e].indexOf(o);-1<s&&(r=n.entryNodes.map(e=>e.id),t.wires[e].splice(s,1),t.wires[e].push(...r),u.push(...n.nodes))}})}))}),t.remove_linkcall_nodes&&o.forEach(n=>{var e=l[n],t=p[e.links[0]];let o=i(e,t);t&&o&&(r.push(e.id),a.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r,s=t.wires[e].indexOf(n);-1<s&&(r=o.entryNodes.map(e=>e.id),t.wires[e].splice(s,1),t.wires[e].push(...r),u.push(...o.nodes))}}))}),(a=a.filter(e=>s.indexOf(e.id)<0&&r.indexOf(e.id)<0)).push(...u)}if((a=t.remove_debugs?a.filter(e=>"debug"!=e.type&&"comment"!=e.type):a).forEach(e=>{t.name&&(e.name=RED.nodes.id()),t.shrink_node&&(e.l=!1),t.info&&(e.info="",delete e.outputLabels,delete e.inputLabels),t.add_license&&(e.info=t.license_text),t.position&&(e.x=150,e.y=150),t.remove_icons&&delete e.icon}),t.replace_switch){let s=(t,r)=>{for(let e=0;e<r.rules.length;e++){var s=r.rules[e];if("nnull"==s.t)t.push("if ( _propValue != null ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("null"==s.t)t.push("if ( _propValue == null ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("eq"==s.t&&"str"==s.vt){n=s.v;n=btoa(encodeURIComponent(n).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}));t.push("if ( _propValue === Buffer.from('"+n+"', 'base64').toString('utf-8') ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }")}else if("gt"==s.t&&"num"==s.vt)t.push("if ( _propValue > "+s.v+" ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("eq"==s.t&&"num"==s.vt)t.push("if ( _propValue == "+s.v+" ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("empty"==s.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"==s.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"!=s.t)throw"unhandled";t.push("_returnValue.push(msg)","return node.send(_returnValue)")}}var n};a=a.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 = []"),s(r,t),r.push("})(msg,node);");else{if("jsonata"!=t.propertyType)throw"unhandled";r.push("jsonata('"+t.property+"').evaluate(msg).then(_propValue => {","let _returnValue = []"),s(r,t),r.push("})")}return e.func=r.join("\n"),e}catch(e){return t}})}if(t.replace_change){let n=e=>btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}));a=a.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 s=t.rules[e];if("set"==s.t){if(s.dc)throw"unhandled";if("msg"==s.pt&&"str"==s.tot)r.push("__s(msg,'"+s.p+"', Buffer.from('"+n(s.to)+"', 'base64').toString('utf-8') )");else if("msg"==s.pt&&"bool"==s.tot)r.push("__s(msg,'"+s.p+"', "+s.to+")");else if("msg"==s.pt&&"num"==s.tot)r.push("__s(msg,'"+s.p+"', Number(Buffer.from('"+n(s.to)+"', 'base64').toString('utf-8')))");else if("msg"==s.pt&&"json"==s.tot)r.push("__s(msg,'"+s.p+"', JSON.parse(Buffer.from('"+n(s.to)+"', 'base64').toString('utf-8')))");else if("msg"==s.pt&&"msg"==s.tot)r.push("try { __s(msg,'"+s.p+"', __g(msg, '"+s.to+"')) } catch (ex) {}");else if("msg"==s.pt&&"env"==s.tot)r.push("__s(msg,'"+s.p+"', process.env['"+s.to+"'])");else{if("msg"!=s.pt||"jsonata"!=s.tot||!s.to.startsWith("/* @obfuscate-safe */"))throw"unhandlable";r.push("__s(msg,'"+s.p+"', await jsonata(Buffer.from('"+n(s.to)+"', 'base64').toString('utf-8')).evaluate(msg) )")}}else{if("delete"!=s.t||"msg"!=s.pt)throw"unhandlable";r.push("delete msg."+s.p)}}return r.push("node.send(msg) })(msg,node);"),e.func=r.join("\n"),e}catch(e){return console.log(e),t}})}if(t.javascript){let r={},t=[];a.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},s={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:s}),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(a)},error:function(e,t,r){RED.notify("ClientCode Communcation Failure: "+n.id+": "+t,{type:"error",timeout:3e3})}})}else obfuscateHelpers.openImportDialog(a)}
6
6
 
7
7
  function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"warning",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)||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
 
@@ -81,9 +81,20 @@
81
81
 
82
82
  replace_switch: $('#node-input-obfuscate-replace-switch').is(":checked"),
83
83
  replace_change: $('#node-input-obfuscate-replace-change').is(":checked"),
84
+
85
+ add_license: $('#node-input-obfuscate-add-license-text').is(":checked"),
86
+ license_text: $('#node-input-obfuscate-license-text').val(),
84
87
  })
85
88
  })
86
89
 
90
+ $('#node-input-obfuscate-add-license-text').on('change', (e) => {
91
+ if ( $('#node-input-obfuscate-add-license-text').is(":checked") ) {
92
+ $('#node-input-obfuscate-add-license-text-row').fadeIn(300)
93
+ } else {
94
+ $('#node-input-obfuscate-add-license-text-row').fadeOut(300)
95
+ }
96
+ })
97
+
87
98
  $('#node-screenshot-capture-btn').on("click", function (e) {
88
99
  if ( e ) { e.preventDefault() }
89
100
 
@@ -160,202 +171,212 @@
160
171
 
161
172
  <!-- The html for the right sidebar plugin screen -->
162
173
  <script type="text/x-red" data-template-name="Screenshot">
174
+ <div class="form-row func-introspection-tabs-row">
175
+ <ul style="min-width: 600px; margin-bottom: 20px;" id="func-introspection-tabs"></ul>
176
+ </div>
163
177
 
164
- <div class="form-row func-introspection-tabs-row">
165
- <ul style="min-width: 600px; margin-bottom: 20px;" id="func-introspection-tabs"></ul>
166
- </div>
167
-
168
- <div id="func-introspection-tabs-content" style="min-height: calc(100% - 95px);">
169
- <div id="func-introspection-tab-screenshot" style="display:none; min-height: calc(100%);">
170
- <div class="form-row">
171
- <div class="col-100">
178
+ <div id="func-introspection-tabs-content" style="min-height: calc(100% - 95px);">
179
+ <div id="func-introspection-tab-screenshot" style="display:none; min-height: calc(100%);">
180
+ <div class="form-row">
181
+ <div class="col-100">
172
182
 
173
- <div class="form-row" style="margin-left: 10px; margin-top: 30px;">
174
- <button type="button" id="node-screenshot-capture-btn"
183
+ <div class="form-row" style="margin-left: 10px; margin-top: 30px;">
184
+ <button type="button" id="node-screenshot-capture-btn"
175
185
  class="red-ui-button red-ui-button-large"><i class="fa fa-camera"></i> Capture</button>
176
-
177
- <button type="button" id="node-screenshot-download-svg" style="margin-left: 30px;"
186
+
187
+ <button type="button" id="node-screenshot-download-svg" style="margin-left: 30px;"
178
188
  class="red-ui-button red-ui-button-large"><i class="fa fa-download"></i> Download</button>
179
- <button type="button" id="node-screenshot-copy-to-clipboard-svg"
180
- class="red-ui-button red-ui-button-large"><i class="fa fa-clipboard"></i> Copy to Clipboard</button>
181
- </div>
189
+ <button type="button" id="node-screenshot-copy-to-clipboard-svg"
190
+ class="red-ui-button red-ui-button-large"><i class="fa fa-clipboard"></i> Copy to Clipboard</button>
191
+ </div>
182
192
 
183
- <div class="form-row" style="min-height: 300px; height: 450px; overflow: hidden; margin-left: 10px; margin-right: 15px; border: 1px rgb(196, 196, 196) solid; border-radius: 5px;">
184
- <div id="node-input-screenshot-svgcontainer"></div>
185
- </div>
193
+ <div class="form-row"
194
+ style="min-height: 300px; height: 450px; overflow: hidden; margin-left: 10px; margin-right: 15px; border: 1px rgb(196, 196, 196) solid; border-radius: 5px;">
195
+ <div id="node-input-screenshot-svgcontainer"></div>
186
196
  </div>
187
197
  </div>
188
198
  </div>
199
+ </div>
189
200
 
190
- <div id="func-introspection-tab-orphans" style="display:none; min-height: calc(100%);">
191
- <div class="form-row">
192
- <div class="col-100">
193
- <div class="form-row node-input-target-row" style="margin-left: 10px; margin-top: 30px">
194
- <button id="node-input-orphan-find-btn"
201
+ <div id="func-introspection-tab-orphans" style="display:none; min-height: calc(100%);">
202
+ <div class="form-row">
203
+ <div class="col-100">
204
+ <div class="form-row node-input-target-row" style="margin-left: 10px; margin-top: 30px">
205
+ <button id="node-input-orphan-find-btn"
195
206
  class="red-ui-button"><i class="fa fa-life-ring"></i> Unconnected</button>
196
- <button id="node-input-documentation-find-btn"
207
+ <button id="node-input-documentation-find-btn"
197
208
  class="red-ui-button"><i class="fa fa-cc"></i> Undocumented</button>
198
- <button id="node-input-linkcalls-find-btn"
209
+ <button id="node-input-linkcalls-find-btn"
199
210
  class="red-ui-button"><i class="fa fa-link"></i> Link Calls</button>
200
- </div>
201
-
202
- <div class="form-row node-input-target-row node-input-target-list-row"
203
- style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px; ">
204
- <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
205
- <input type="text" id="node-input-orphan-target-filter" style="display: none;">
206
- </div>
207
- <div id="node-input-orphan-target-container-div"></div>
208
- </div>
209
211
  </div>
210
- </div>
211
- </div>
212
-
213
- <div id="func-introspection-tab-obfuscation" style="display:none; min-height: calc(100%);">
214
212
 
215
- <div class="form-row">
216
- <div class="col-100">
217
- <div class="form-row node-input-target-row" style="margin-left: 10px; margin-top: 30px">
218
- <button id="node-input-obfuscation-generate-btn"
219
- class="red-ui-button"><i class="fa fa-low-vision"></i> Obfuscate</button>
213
+ <div class="form-row node-input-target-row node-input-target-list-row"
214
+ style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px; ">
215
+ <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
216
+ <input type="text" id="node-input-orphan-target-filter" style="display: none;">
220
217
  </div>
218
+ <div id="node-input-orphan-target-container-div"></div>
221
219
  </div>
222
220
  </div>
221
+ </div>
222
+ </div>
223
+
224
+ <div id="func-introspection-tab-obfuscation" style="display:none; min-height: calc(100%);">
223
225
 
224
- <div class="form-row col-100">
225
- <label for="node-input-obfuscate-name" class="w-30">
226
+ <div class="form-row col-100">
227
+ <label for="node-input-obfuscate-name" class="w-30">
226
228
  <i class="fa fa-tag"></i>
227
229
  <span>Obfuscate Name?</span>
228
230
  </label>
229
- <input type="checkbox" checked=checked id="node-input-obfuscate-name"
231
+ <input type="checkbox" checked=checked id="node-input-obfuscate-name"
230
232
  style="display:inline-block; width:15px; vertical-align:baseline;">
231
- </div>
233
+ </div>
232
234
 
233
- <div class="form-row">
234
- <label for="node-input-obfuscate-position" class="w-30">
235
+ <div class="form-row">
236
+ <label for="node-input-obfuscate-position" class="w-30">
235
237
  <i class="fa fa-map-pin"></i>
236
238
  <span>Obfuscate Position?</span>
237
239
  </label>
238
- <input type="checkbox" checked=checked id="node-input-obfuscate-position"
240
+ <input type="checkbox" checked=checked id="node-input-obfuscate-position"
239
241
  style="display:inline-block; width:15px; vertical-align:baseline;">
240
- </div>
242
+ </div>
241
243
 
242
- <div class="form-row">
243
- <label for="node-input-obfuscate-shrink-size" class="w-30">
244
+ <div class="form-row">
245
+ <label for="node-input-obfuscate-shrink-size" class="w-30">
244
246
  <i class="fa fa-angle-down"></i>
245
- <span>Shrink Node?</span>
247
+ <span>Shrink Nodes?</span>
246
248
  </label>
247
- <input type="checkbox" checked=checked id="node-input-obfuscate-shrink-size"
249
+ <input type="checkbox" checked=checked id="node-input-obfuscate-shrink-size"
248
250
  style="display:inline-block; width:15px; vertical-align:baseline;">
249
- </div>
251
+ </div>
250
252
 
251
- <div class="form-row">
252
- <label for="node-input-obfuscate-javascript" class="w-30">
253
+ <div class="form-row">
254
+ <label for="node-input-obfuscate-javascript" class="w-30">
253
255
  <i class="fa fa-code"></i>
254
256
  <span>Obfuscate Javascript?</span>
255
- </label>
256
- <input type="checkbox" checked=checked id="node-input-obfuscate-javascript"
257
+ </label>
258
+ <input type="checkbox" checked=checked id="node-input-obfuscate-javascript"
257
259
  style="display:inline-block; width:15px; vertical-align:baseline;">
258
- </div>
260
+ </div>
259
261
 
260
- <div class="form-row col-100">
261
- <label for="node-input-obfuscate-remove-icons" class="w-30">
262
+ <div class="form-row col-100">
263
+ <label for="node-input-obfuscate-remove-icons" class="w-30">
262
264
  <i class="fa fa-adjust"></i>
263
265
  <span>Remove Icon?</span>
264
266
  </label>
265
- <input type="checkbox" checked=checked id="node-input-obfuscate-remove-icons"
267
+ <input type="checkbox" checked=checked id="node-input-obfuscate-remove-icons"
266
268
  style="display:inline-block; width:15px; vertical-align:baseline;">
267
- </div>
269
+ </div>
268
270
 
269
- <div class="form-row">
270
- <label for="node-input-obfuscate-info" class="w-30">
271
+ <div class="form-row">
272
+ <label for="node-input-obfuscate-info" class="w-30">
271
273
  <i class="fa fa-info"></i>
272
274
  <span>Remove Info?</span>
273
275
  </label>
274
- <input type="checkbox" checked=checked id="node-input-obfuscate-info"
276
+ <input type="checkbox" checked=checked id="node-input-obfuscate-info"
275
277
  style="display:inline-block; width:15px; vertical-align:baseline;">
276
- </div>
278
+ </div>
277
279
 
278
- <div class="form-row">
279
- <label for="node-input-obfuscate-remove-groups" class="w-30">
280
+ <div class="form-row">
281
+ <label for="node-input-obfuscate-remove-groups" class="w-30">
280
282
  <i class="fa fa-object-group"></i>
281
283
  <span>Remove Groups?</span>
282
284
  </label>
283
- <input type="checkbox" checked=checked id="node-input-obfuscate-remove-groups"
285
+ <input type="checkbox" checked=checked id="node-input-obfuscate-remove-groups"
284
286
  style="display:inline-block; width:15px; vertical-align:baseline;">
285
- </div>
287
+ </div>
286
288
 
287
- <div class="form-row">
288
- <label for="node-input-obfuscate-remove-debugs" class="w-30">
289
+ <div class="form-row">
290
+ <label for="node-input-obfuscate-remove-debugs" class="w-30">
289
291
  <i class="fa fa-bug"></i>
290
292
  <span>Remove comment & debugs?</span>
291
293
  </label>
292
- <input type="checkbox" checked=checked id="node-input-obfuscate-remove-debugs"
294
+ <input type="checkbox" checked=checked id="node-input-obfuscate-remove-debugs"
293
295
  style="display:inline-block; width:15px; vertical-align:baseline;">
294
- </div>
295
-
296
- <div class="form-row">
297
- <label class='w-30'>
298
- <span>Replace Nodes:</span>
299
- </label>
300
- </div>
301
-
302
- <div class="form-row">
303
- <label for="node-input-obfuscate-replace-switch" class="ml-30">
304
- <span>Switch</span>
305
- </label>
306
- <input type="checkbox" checked=checked id="node-input-obfuscate-replace-switch"
307
- style="display:inline-block; width:15px; vertical-align:baseline;">
308
- </div>
296
+ </div>
309
297
 
310
- <div class="form-row">
311
- <label for="node-input-obfuscate-replace-change" class="ml-30">
312
- <span>Change</span>
313
- </label>
314
- <input type="checkbox" checked=checked id="node-input-obfuscate-replace-change"
315
- style="display:inline-block; width:15px; vertical-align:baseline;">
316
- </div>
298
+ <div class="form-row">
299
+ <label for="node-input-obfuscate-remove-junctions" class="w-30">
300
+ <i class="fa fa-sitemap"></i>
301
+ <span>Coalesce Junctions?</span>
302
+ </label>
303
+ <input type="checkbox" checked=checked id="node-input-obfuscate-remove-junctions"
304
+ style="display:inline-block; width:15px; vertical-align:baseline;">
305
+ </div>
317
306
 
318
- <div class="form-row">
319
- <label for="node-input-obfuscate-remove-junctions" class="w-30">
320
- <i class="fa fa-sitemap"></i>
321
- <span>Coalesce Junctions?</span>
322
- </label>
323
- <input type="checkbox" checked=checked id="node-input-obfuscate-remove-junctions"
324
- style="display:inline-block; width:15px; vertical-align:baseline;">
325
- </div>
307
+ <div class="form-row">
308
+ <label for="node-input-obfuscate-remove-linkcall-nodes" class="w-30">
309
+ <i class="fa fa-unlink"></i>
310
+ <span>Coalesce Link Call Nodes?</span>
311
+ </label>
312
+ <input type="checkbox" checked=checked id="node-input-obfuscate-remove-linkcall-nodes" style="display:inline-block; width:15px; vertical-align:baseline;">
313
+ </div>
326
314
 
327
- <div class="form-row">
328
- <label for="node-input-obfuscate-remove-linknodes" class="w-30">
329
- <i class="fa fa-link"></i>
315
+ <div class="form-row">
316
+ <label for="node-input-obfuscate-remove-linknodes" class="w-30">
317
+ <i class="fa fa-unlink"></i>
330
318
  <span>Coalesce Link Out Nodes?</span>
331
- </label>
332
- <input type="checkbox" checked=checked id="node-input-obfuscate-remove-linknodes"
319
+ </label>
320
+ <input type="checkbox" checked=checked id="node-input-obfuscate-remove-linknodes"
333
321
  style="display:inline-block; width:15px; vertical-align:baseline;">
334
- </div>
322
+ </div>
335
323
 
336
- <div class="form-row">
337
- <label for="node-input-obfuscate-copy-linkin-nodes" class="ml-30">
324
+ <div class="form-row">
325
+ <label for="node-input-obfuscate-copy-linkin-nodes" class="ml-30">
338
326
  <span>Copy Link-In Nodes?</span>
339
- </label>
340
- <input type="checkbox" checked=checked id="node-input-obfuscate-copy-linkin-nodes"
341
- style="display:inline-block; width:15px; vertical-align:baseline;">
342
- </div>
327
+ </label>
328
+ <input type="checkbox" checked=checked id="node-input-obfuscate-copy-linkin-nodes" style="display:inline-block; width:15px; vertical-align:baseline;">
329
+ </div>
343
330
 
331
+ <div class="form-row">
332
+ <label class='w-30'>
333
+ <i class="fa fa-refresh"></i>
334
+ <span>Replace Nodes:</span>
335
+ </label>
336
+ </div>
344
337
 
345
- <div class="form-row">
346
- <label for="node-input-obfuscate-remove-linkcall-nodes" class="w-30">
347
- <i class="fa fa-link"></i>
348
- <span>Coalesce Link Call Nodes?</span>
349
- </label>
350
- <input type="checkbox" checked=checked id="node-input-obfuscate-remove-linkcall-nodes"
351
- style="display:inline-block; width:15px; vertical-align:baseline;">
352
- </div>
338
+ <div class="form-row">
339
+ <label for="node-input-obfuscate-replace-switch" class="ml-30">
340
+ <span>Switch</span>
341
+ </label>
342
+ <input type="checkbox" checked=checked id="node-input-obfuscate-replace-switch"
343
+ style="display:inline-block; width:15px; vertical-align:baseline;">
344
+ </div>
353
345
 
346
+ <div class="form-row">
347
+ <label for="node-input-obfuscate-replace-change" class="ml-30">
348
+ <span>Change</span>
349
+ </label>
350
+ <input type="checkbox" checked=checked id="node-input-obfuscate-replace-change"
351
+ style="display:inline-block; width:15px; vertical-align:baseline;">
352
+ </div>
354
353
 
355
- <div class="form-row" style="margin-left: 10px">
356
- <b>Warning</b>: No guarantee is made that the obfuscated flow still works. This has not be
357
- thoroughly tested or promises to fulfil any purpose - good or bad.
354
+ <div class="form-row">
355
+ <label for="node-input-obfuscate-add-license-text" class="w-30">
356
+ <i class="fa fa-gavel"></i>
357
+ <span>Replace info with license?</span>
358
+ </label>
359
+ <input type="checkbox" id="node-input-obfuscate-add-license-text" style="display:inline-block; width:15px; vertical-align:baseline;">
360
+ </div>
361
+
362
+ <div id="node-input-obfuscate-add-license-text-row" class="form-row" style="margin-left: 10px; display: none;">
363
+ <textarea id="node-input-obfuscate-license-text"
364
+ placeholder="License Text"></textarea>
365
+ </div>
366
+
367
+ <div class="form-row">
368
+ <div class="col-100">
369
+ <div class="form-row node-input-target-row" style="margin-left: 10px; margin-top: 30px">
370
+ <button id="node-input-obfuscation-generate-btn"
371
+ class="red-ui-button"><i class="fa fa-low-vision"></i> Obfuscate</button>
372
+ </div>
358
373
  </div>
359
- </div>
374
+ </div>
360
375
 
376
+ <div class="form-row" style="margin-left: 10px">
377
+ <b>Warning</b>: No guarantee is made that the obfuscated flow still works. This has not be
378
+ thoroughly tested. Ensure correctness by completely testing the resultant obfuscated flow.
379
+ No warranty of success is provided, implied or expressed.
380
+ </div>
381
+ </div>
361
382
  </script>