debugging_environment.xml 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. <?xml version="1.0" ?>
  2. <diagram name="DebuggingEnvironment" author="Simon Van Mierlo">
  3. <description>
  4. Debugging environment for Dynamic Structure DEVS in HTML + JS (d3/w2ui).
  5. </description>
  6. <inport name="ui_input"/>
  7. <inport name="simulation_input"/>
  8. <outport name="output"/>
  9. <class name="MainApp" default="True">
  10. <relationships>
  11. <association name="toolbar" class="DebuggingToolbar" min="1" max="1" />
  12. <association name="visualizer" class="Visualizer" min="1" max="1" />
  13. </relationships>
  14. <method name="MainApp">
  15. <body>
  16. <![CDATA[
  17. ]]>
  18. </body>
  19. </method>
  20. <scxml initial="creating_toolbar">
  21. <state id="creating_toolbar">
  22. <onentry>
  23. <raise event="create_instance" scope="cd">
  24. <parameter expr="'toolbar'" />
  25. <parameter expr="'DebuggingToolbar'" />
  26. </raise>
  27. </onentry>
  28. <transition target="../creating_visualizer" event="instance_created">
  29. <parameter name="association_name" type="string"/>
  30. <raise event="start_instance" scope="cd">
  31. <parameter expr="association_name"/>
  32. </raise>
  33. </transition>
  34. </state>
  35. <state id="creating_visualizer">
  36. <onentry>
  37. <raise event="create_instance" scope="cd">
  38. <parameter expr="'visualizer'" />
  39. <parameter expr="'Visualizer'" />
  40. </raise>
  41. </onentry>
  42. <transition target="../running" event="instance_created">
  43. <parameter name="association_name" type="string"/>
  44. <raise event="start_instance" scope="cd">
  45. <parameter expr="association_name"/>
  46. </raise>
  47. </transition>
  48. </state>
  49. <state id="running" />
  50. </scxml>
  51. </class>
  52. <class name="DebuggingToolbar">
  53. <relationships>
  54. <association name="parent" class="MainApp" min="1" max="1" />
  55. <association name="buttons" class="Button" />
  56. </relationships>
  57. <method name="DebuggingToolbar">
  58. <body>
  59. <![CDATA[
  60. this.parameters = {};
  61. this.buttons = {};
  62. this.curr_parameter = null;
  63. this.button_counter = 0;
  64. this.buttons_to_create = [{parent: this, description: 'Simulate', icon: 'simulate', command: 'simulate'},
  65. {parent: this, description: 'Realtime Simulate', icon: 'simulatert', command: 'realtime', parameter_needed: 'realtime_scale'},
  66. {parent: this, description: 'Realtime Scale', html: 'input size="1" value="1.0" style="border: 1px solid silver"', default: 1.0, parameter: 'realtime_scale'},
  67. {parent: this, description: 'Pause', icon: 'pause', command: 'pause'},
  68. {parent: this, description: 'Big Step', icon: 'bigstep', command: 'big_step'},
  69. {parent: this, description: 'Small Step', icon: 'smallstep', command: 'small_step'},
  70. {parent: this, description: 'Reset', icon: 'reset', command: 'reset'},
  71. {parent: this, description: 'Add Breakpoint', icon: 'breakpoint', action: function() {breakpoint_dialog.dialog( "open" );}}];
  72. this.tb = ui.create_toolbar('DebuggingToolbar');
  73. ]]>
  74. </body>
  75. </method>
  76. <scxml initial="initializing">
  77. <state id="initializing" initial="check">
  78. <state id="check">
  79. <transition target="../creating_button" cond="this.buttons_to_create.length &gt; 0">
  80. <script>
  81. if ('parameter' in this.buttons_to_create[0]) {
  82. this.curr_parameter = this.buttons_to_create[0]['parameter']
  83. }
  84. </script>
  85. <raise event="create_instance" scope="cd">
  86. <parameter expr="'buttons'" />
  87. <parameter expr="'Button'" />
  88. <parameter expr="'button' + this.button_counter" />
  89. <parameter expr="this.tb" />
  90. <parameter expr="this.buttons_to_create.shift()" />
  91. </raise>
  92. </transition>
  93. <transition target="../running" cond="this.buttons_to_create.length == 0" />
  94. </state>
  95. <state id="creating_button">
  96. <transition target="../check" event="instance_created">
  97. <parameter name="association_name" type="string"/>
  98. <raise event="start_instance" scope="cd">
  99. <parameter expr="association_name"/>
  100. </raise>
  101. <script>
  102. if (this.curr_parameter) {
  103. this.parameters[this.curr_parameter] = association_name;
  104. this.curr_parameter = null;
  105. }
  106. this.buttons['button' + this.button_counter] = association_name;
  107. this.button_counter += 1;
  108. </script>
  109. </transition>
  110. </state>
  111. <state id="running">
  112. <transition target="../getting_parameter" event="get_parameter">
  113. <parameter name="the_parameter" />
  114. <parameter name="respond_id" />
  115. <raise event="get_parameter" target="this.parameters[the_parameter]" />
  116. <script>
  117. this.respond_id = respond_id;
  118. </script>
  119. </transition>
  120. </state>
  121. <state id="getting_parameter">
  122. <transition target="../running" event="parameter_reply">
  123. <parameter name="parameter_value" />
  124. <raise event="parameter_reply" target="this.buttons[this.respond_id]">
  125. <parameter expr="parameter_value" />
  126. </raise>
  127. </transition>
  128. </state>
  129. </state>
  130. </scxml>
  131. </class>
  132. <class name="Button">
  133. <inport name="button_ui_input" />
  134. <relationships>
  135. <association name="parent" class="DebuggingToolbar" min="1" max="1" />
  136. </relationships>
  137. <method name="Button">
  138. <parameter name="button_id" />
  139. <parameter name="toolbar" />
  140. <parameter name="parameters" />
  141. <body>
  142. <![CDATA[
  143. this.button_id = button_id;
  144. this.toolbar = toolbar;
  145. this.action = null;
  146. this.command = null;
  147. if ('parameter_needed' in parameters) {
  148. this.parameter_needed = parameters['parameter_needed'];
  149. } else {
  150. this.parameter_needed = null;
  151. }
  152. if ('html' in parameters) {
  153. var the_html = parameters['html']
  154. the_html += ' id="' + this.button_id + '_input" onchange="ui.parameter_changed(\'' + button_id + '\');"'
  155. this.btn = ui.create_tb_element(this.button_id, '<' + the_html + ' />', parameters['default'], this.toolbar, this.controller, this.inports['button_ui_input']);
  156. } else if ('action' in parameters) {
  157. this.action = parameters['action'];
  158. this.btn = ui.create_button(this.button_id, parameters['description'], parameters['icon'], this.toolbar, this.controller, this.inports['button_ui_input']);
  159. } else {
  160. this.command = parameters['command'];
  161. this.btn = ui.create_button(this.button_id, parameters['description'], parameters['icon'], this.toolbar, this.controller, this.inports['button_ui_input']);
  162. }
  163. ]]>
  164. </body>
  165. </method>
  166. <scxml initial="listening">
  167. <state id="listening">
  168. <transition target="." event="mouse_press" port="button_ui_input" cond="this.action">
  169. <script>
  170. this.action();
  171. </script>
  172. </transition>
  173. <transition target="." event="mouse_press" port="button_ui_input" cond="this.parameter_needed == null &amp;&amp; this.command">
  174. <raise event="debugging_command" port="output">
  175. <parameter expr="this.command" />
  176. </raise>
  177. </transition>
  178. <transition target="../getting_parameter" event="mouse_press" port="button_ui_input" cond="this.parameter_needed != null &amp;&amp; this.command">
  179. <raise event="get_parameter" target="'parent'">
  180. <parameter expr="this.parameter_needed" />
  181. <parameter expr="this.button_id" />
  182. </raise>
  183. </transition>
  184. <transition target="." event="get_parameter">
  185. <raise event="parameter_reply" target="'parent'">
  186. <parameter expr="this.btn.value" />
  187. </raise>
  188. </transition>
  189. </state>
  190. <state id="getting_parameter">
  191. <transition target="../listening" event="parameter_reply">
  192. <parameter name="the_parameter" />
  193. <script>
  194. var the_parameters = {};
  195. the_parameters[this.parameter_needed] = the_parameter;
  196. </script>
  197. <raise event="debugging_command" port="output">
  198. <parameter expr="this.command" />
  199. <parameter expr="the_parameters" />
  200. </raise>
  201. </transition>
  202. </state>
  203. </scxml>
  204. </class>
  205. <class name="Visualizer">
  206. <relationships>
  207. <association name="parent" class="MainApp" min="1" max="1" />
  208. </relationships>
  209. <method name="Visualizer">
  210. <body>
  211. the_controller = this.controller;
  212. this.simulation_info = d3.select("body").append("div")
  213. .attr("class", "simulationInfo")
  214. .style("margin", "5px")
  215. .style("display", "block");
  216. this.simulation_time = this.simulation_info.append("span")
  217. .append("text")
  218. .text("SIMULATION TIME: (not started)")
  219. .style("float", "left");
  220. this.simulation_steps = this.simulation_info.append("span")
  221. .style("margin", "5px")
  222. .style("float", "left")
  223. .attr("class", "invisibleInfo")
  224. .attr("id", "smallStepInfo");
  225. this.simulation_steps.selectAll("div").data([0,1,2,3,4,5,6,7])
  226. .enter()
  227. .append("div")
  228. .attr("id", function(d) {return "smallStepInfo_" + d})
  229. .attr("class", "smallStepInfo inactive")
  230. .style("transform", function(d) {return "translate(" + d * 5 + "px, -4px) rotate(45deg)"});
  231. d3.select("body").append("br");
  232. this.breakpoint_info = d3.select("body").append("div")
  233. .attr("class", "breakpointInfo")
  234. .style("margin", "5px")
  235. .style("display", "block");
  236. this.breakpoint_text = this.breakpoint_info.append("span")
  237. .append("text")
  238. .text("BREAKPOINTS: ")
  239. .style("float", "left");
  240. this.breakpoint_infos = this.breakpoint_info.append("span")
  241. .style("margin", "5px")
  242. .style("float", "left")
  243. .attr("id", "breakpointInfos");
  244. this.breakpoints = [];
  245. this.data = [];
  246. this.port_connections = [];
  247. this.loc_to_item = {};
  248. event_to_inject = undefined;
  249. god_event_to_process = undefined;
  250. // TODO: this is domain-specific!
  251. this.particle_id_to_item = {};
  252. var margin = {top: 50, right: 0, bottom: 0, left: 0},
  253. width = 960 - margin.right - margin.left,
  254. height = 1024 - margin.top - margin.bottom;
  255. this.node_id = 0;
  256. this.tree = d3.layout.tree()
  257. .size([width, height]);
  258. this.diagonal = d3.svg.diagonal();
  259. this.port_connection_diagonal = d3.svg.diagonal().projection(function(d) {return [d.x, d.y]});
  260. this.parent_svg = d3.select("body").append("svg")
  261. .attr("width", width + margin.right + margin.left)
  262. .attr("height", height + margin.top + margin.bottom);
  263. var defs = this.parent_svg.append('svg:defs')
  264. var markers = [{name: 'arrow', path: 'M2,2 L2,11 L10,6 L2,2', fill: "red"},
  265. {name: 'arrow_green', path: 'M2,2 L2,11 L10,6 L2,2', fill: "green"}];
  266. var marker = defs.selectAll('marker')
  267. .data(markers)
  268. .enter()
  269. .append('svg:marker')
  270. .attr('id', function(d){ return 'marker_' + d.name})
  271. .attr('markerHeight', 13)
  272. .attr('markerWidth', 13)
  273. .attr('markerUnits', 'strokeWidth')
  274. .attr('orient', 'auto')
  275. .attr('refX', 2)
  276. .attr('refY', 6)
  277. .append('svg:path')
  278. .attr('d', function(d){ return d.path })
  279. .attr('fill', function(d){ return d.fill });
  280. this.svg = this.parent_svg.append("g")
  281. .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  282. function godEvent() {
  283. god_event_to_process = {'model': $('#currLoc').text(), 'attribute': $('#godEventName').val(), 'value': eval($('#godEventValue').val())};
  284. the_controller.addInput(new Event("process_god_event", "ui_input", [god_event_to_process]), 0.0);
  285. dialog.dialog("close");
  286. }
  287. dialog = $( "#godEventPopup" ).dialog({
  288. autoOpen: false,
  289. height: 200,
  290. width: 325,
  291. modal: true,
  292. buttons: {
  293. "Submit": godEvent,
  294. Cancel: function() {
  295. dialog.dialog( "close" );
  296. }
  297. },
  298. close: function() {
  299. form[ 0 ].reset();
  300. }
  301. }).css("font-size", "14px");;
  302. form = dialog.find( "form" ).on( "submit", function( event ) {
  303. event.preventDefault();
  304. godEvent();
  305. });
  306. function injectEvent() {
  307. event_to_inject = {'port': $('#currLoc').text(), 'event': eval($('#injectEvent').val()), 'time': eval($('#injectTime').val())};
  308. the_controller.addInput(new Event("inject_event", "ui_input", [event_to_inject]), 0.0);
  309. inject_dialog.dialog("close");
  310. }
  311. inject_dialog = $( "#injectEventPopup" ).dialog({
  312. autoOpen: false,
  313. height: 200,
  314. width: 325,
  315. modal: true,
  316. buttons: {
  317. "Submit": injectEvent,
  318. Cancel: function() {
  319. inject_dialog.dialog( "close" );
  320. }
  321. },
  322. close: function() {
  323. inject_form[ 0 ].reset();
  324. }
  325. }).css("font-size", "14px");
  326. inject_form = inject_dialog.find( "form" ).on( "submit", function( event ) {
  327. event.preventDefault();
  328. injectEvent();
  329. });
  330. function addBreakpoint() {
  331. breakpoint_to_add = [$('#breakpointName').val(), $('#breakpointFunction').val(), $('#breakpointEnabled').is(":checked"), $('#breakpointDisableOnTrigger').is(":checked")];
  332. the_controller.addInput(new Event("add_breakpoint", "ui_input", [breakpoint_to_add]), 0.0);
  333. breakpoint_dialog.dialog("close");
  334. }
  335. breakpoint_dialog = $( "#breakpointPopup" ).dialog({
  336. autoOpen: false,
  337. height: 400,
  338. width: 600,
  339. modal: true,
  340. buttons: {
  341. "Submit": addBreakpoint,
  342. Cancel: function() {
  343. breakpoint_dialog.dialog( "close" );
  344. }
  345. },
  346. close: function() {
  347. breakpoint_form[ 0 ].reset();
  348. }
  349. }).css("font-size", "14px");
  350. breakpoint_form = breakpoint_dialog.find( "form" ).on( "submit", function( event ) {
  351. event.preventDefault();
  352. addBreakpoint();
  353. });
  354. </body>
  355. </method>
  356. <method name="update_vis">
  357. <parameter name="structural_changes" />
  358. <body>
  359. d3.select("#smallStepInfo_7").classed("inactive", false);
  360. var created_models = [],
  361. created_ports = [],
  362. connected_ports = [],
  363. deleted_models = [],
  364. deleted_ports = [],
  365. disconnected_ports = [];
  366. if ('CREATED_MODELS' in structural_changes) {
  367. created_models = structural_changes['CREATED_MODELS'];
  368. }
  369. if ('CREATED_PORTS' in structural_changes) {
  370. created_ports = structural_changes['CREATED_PORTS'];
  371. }
  372. if ('CONNECTED_PORTS' in structural_changes) {
  373. connected_ports = structural_changes['CONNECTED_PORTS'];
  374. }
  375. if ('DELETED_MODELS' in structural_changes) {
  376. deleted_models = structural_changes['DELETED_MODELS'];
  377. }
  378. if ('DELETED_PORTS' in structural_changes) {
  379. deleted_ports = structural_changes['DELETED_PORTS'];
  380. }
  381. if ('DISCONNECTED_PORTS' in structural_changes) {
  382. disconnected_ports = structural_changes['DISCONNECTED_PORTS'];
  383. }
  384. // sort according to their depth (amounts of dots in their name)
  385. created_models.sort(function(a, b) {
  386. return (a.match(/./g) || []).length - (b.match(/./g) || []).length
  387. })
  388. data = this.data;
  389. var node_id = this.node_id;
  390. var loc_to_item = this.loc_to_item;
  391. created_models.forEach(function(item) {
  392. splitted_path = item.split('.');
  393. element_to_insert = data;
  394. while (splitted_path.length > 1) {
  395. curr_name = splitted_path.shift();
  396. element_to_insert = element_to_insert.find(function(el) {return el['name'] == curr_name}).children;
  397. }
  398. var node = {'name': splitted_path[0], 'children': [], 'ports': [], 'loc': item, 'id': node_id++}
  399. element_to_insert.push(node);
  400. loc_to_item[item] = node;
  401. });
  402. created_ports.forEach(function(item) {
  403. splitted_path = item[0].split('.');
  404. curr_array = data;
  405. while (splitted_path.length > 2) {
  406. curr_name = splitted_path.shift();
  407. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  408. }
  409. ports = curr_array.find(function(el) {return el['name'] == splitted_path[0]})['ports'];
  410. var node = {'name': splitted_path[1], 'is_input': item[1], 'loc': item[0], 'id': node_id++};
  411. ports.push(node);
  412. loc_to_item[item[0]] = node;
  413. });
  414. this.node_id = node_id;
  415. port_connections = this.port_connections
  416. connected_ports.forEach(function(item) {
  417. splitted_path_src = item[0].split('.');
  418. curr_array = data;
  419. while (splitted_path_src.length > 2) {
  420. curr_name = splitted_path_src.shift();
  421. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  422. }
  423. src_parent = curr_array.find(function(el) {return el['name'] == splitted_path_src[0]});
  424. src = src_parent['ports'].find(function(el) {return el['name'] == splitted_path_src[1]});
  425. splitted_path_dst = item[1].split('.');
  426. curr_array = data;
  427. while (splitted_path_dst.length > 2) {
  428. curr_name = splitted_path_dst.shift();
  429. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  430. }
  431. dst_parent = curr_array.find(function(el) {return el['name'] == splitted_path_dst[0]});
  432. dst = dst_parent['ports'].find(function(el) {return el['name'] == splitted_path_dst[1]});
  433. port_connections.push({'source': src, 'target': dst});
  434. });
  435. disconnected_ports.forEach(function(item) {
  436. port_connections = port_connections.filter(function(el) {return el.source.loc != item[0] || el.target.loc != item[1];});
  437. });
  438. this.port_connections = port_connections
  439. deleted_ports.forEach(function(item) {
  440. splitted_path = item.split('.');
  441. curr_array = data;
  442. while (splitted_path.length > 2) {
  443. curr_name = splitted_path.shift();
  444. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  445. }
  446. parent = curr_array.find(function(el) {return el['name'] == splitted_path[0]});
  447. parent['ports'] = parent['ports'].filter(function(el) {return el['name'] != splitted_path[1]});
  448. });
  449. deleted_models.forEach(function(item) {
  450. splitted_path = item.split('.');
  451. curr_array = data;
  452. while (splitted_path.length > 2) {
  453. curr_name = splitted_path.shift();
  454. curr_array = element_to_insert.find(function(el) {return el['name'] == curr_name}).children;
  455. }
  456. parent = curr_array.find(function(el) {return el['name'] == splitted_path[0]});
  457. parent['children'] = parent['children'].filter(function(el) {return el['name'] != splitted_path[1]});
  458. });
  459. this.data = data;
  460. var nodes = this.tree.nodes(this.data[0]),
  461. links = this.tree.links(nodes);
  462. nodes.forEach(function(d, i) {
  463. d.y = d.depth * 100 + i * 40
  464. d.ports.forEach(function(p, i) {p.dx = 13, p.dy = 18; p.x = (d.x - 40) + i * p.dx; p.y = d.y + p.dy;});
  465. });
  466. // Declare the nodes...
  467. var node = this.svg.selectAll("g.node")
  468. .data(nodes, function(d) { return d.id; });
  469. // Enter the nodes.
  470. var nodeEnter = node.enter().append("g")
  471. .attr("class", "node")
  472. .attr("id", function(d) {return 'instance_' + d.id;})
  473. .attr("transform", function(d) {
  474. return "translate(" + d.x + "," + d.y + ")";
  475. });
  476. nodeEnter.append("rect")
  477. .attr("width", 120)
  478. .attr("height", 25)
  479. .attr("transform", "translate(-60, 0)")
  480. .on("click", function(d) {
  481. console.log(JSON.stringify(d.state, null, 2));
  482. })
  483. .on("mouseover", function(d) {
  484. var node = d3.select("#instance_" + d.id)
  485. var stateInfo = node.selectAll(".stateInfo")
  486. .data(function(n) {if (n.state) {return [n.state]} else {return []}}, function(d) {return d.id});
  487. var stateInfoEnter = stateInfo.enter().append("text")
  488. .attr("transform", "translate(-60, 60)")
  489. .attr("id", this.node_id++)
  490. .attr("class", "stateInfo");
  491. var stateInfoText = stateInfo.selectAll("tspan")
  492. .data(function(d) {return JSON.stringify(d, null, 2).split("\n")});
  493. var stateInfoTextEnter = stateInfoText.enter().append("tspan")
  494. .attr("x", "0.0")
  495. .attr("dy", "1.4em")
  496. .attr("xml:space", "preserve")
  497. .text(function(d) {return d});
  498. })
  499. .on("mouseout", function(d) {
  500. var node = d3.select("#instance_" + d.id)
  501. var stateInfo = node.selectAll(".stateInfo");
  502. stateInfo.selectAll("tspan").data([]).exit().remove();
  503. })
  504. .on("contextmenu", function (d, i) {
  505. $( "#currLoc" ).html(d.loc);
  506. d3.event.preventDefault();
  507. if (!d.children) {
  508. dialog.dialog( "open" );
  509. }
  510. });
  511. nodeEnter.append("text")
  512. .attr("y", 12)
  513. .attr("dy", ".35em")
  514. .attr("text-anchor", "middle")
  515. .text(function(d) { return d.name; })
  516. .style("fill-opacity", 1);
  517. nodeEnter.append("text")
  518. .attr("class", "timeNext")
  519. .attr("y", -10)
  520. .attr("x", 30)
  521. .attr("dy", ".35em")
  522. .attr("text-anchor", "middle")
  523. .text("TN: --")
  524. .style("fill-opacity", 1);
  525. port = node.selectAll("g.port")
  526. .data(function(n) {return n.ports}, function(d) { return d.id; })
  527. portEnter = port.enter().append("g")
  528. .attr("class", "port invisible")
  529. .attr("id", function(d) {return 'port_' + d.id;})
  530. .on("mouseover", function(d) {
  531. d3.selectAll(".source_" + d.id).classed("invisibleLink", false)
  532. .classed("input", false);
  533. d3.selectAll(".target_" + d.id).classed("invisibleLink", false)
  534. .classed("input", true);
  535. port_connections.forEach(function(port_connection) {
  536. if (port_connection.source.id == d.id) {
  537. d3.select('#port_' + port_connection.target.id).attr("class", "port visible");
  538. } else if (port_connection.target.id == d.id) {
  539. d3.select('#port_' + port_connection.source.id).attr("class", "port visible");
  540. }
  541. });
  542. d3.select(this).attr("class", "port visible");
  543. })
  544. .on("mouseout", function(d) {
  545. d3.selectAll(".source_" + d.id).classed("invisibleLink", true);
  546. d3.selectAll(".target_" + d.id).classed("invisibleLink", true);
  547. d3.selectAll(".port").attr("class", "port invisible");
  548. })
  549. .on("click", function (d, i) {
  550. $('#currLoc').html(d.loc);
  551. d3.event.preventDefault();
  552. if (d.is_input) {
  553. inject_dialog.dialog( "open" );
  554. }
  555. });
  556. portEnter.append("rect")
  557. .attr("width", 10)
  558. .attr("height", 10)
  559. .style("fill", function(d) {return d.is_input ? "green" : "purple";})
  560. .attr("transform", "rotate(45)");
  561. portEnter.append("text")
  562. .attr("dy", ".35em")
  563. .attr("text-anchor", "left")
  564. .text(function(d) {return d.name;})
  565. .attr("transform", "translate(0, 20) rotate(30)");
  566. port.attr("transform", function(d, i) {return "translate(" + (-40 + i * d.dx) + ", " + d.dy + ")"});
  567. // Declare the links...
  568. var link = this.svg.selectAll("path.link")
  569. .data(links);
  570. // Enter the links.
  571. link.enter().insert("path", "g")
  572. .attr("class", "link")
  573. .attr("d", this.diagonal);
  574. // Declare port connections...
  575. var port_connection = this.svg.selectAll("path.portConnection")
  576. .data(port_connections);
  577. // Enter port connections.
  578. port_connection.enter().insert("path", "g")
  579. .attr("class", "invisibleLink portConnection");
  580. // Update the nodes.
  581. node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
  582. node.classed("coupled", function(d) {return d.children});
  583. // Transition links to their new position.
  584. link.attr("d", this.diagonal);
  585. // Transition links to their new position.
  586. port_connection.attr("d", function(d) {
  587. var dx = d.target.x - d.source.x,
  588. dy = d.target.y - d.source.y,
  589. dr = Math.sqrt(dx * dx + dy * dy)/4,
  590. mx = d.source.x + dx/2,
  591. my = d.source.y + dy/2 + 30;
  592. return [
  593. "M",d.source.x,d.source.y+5,
  594. "T",mx,my,
  595. "T",d.target.x,d.target.y+5
  596. ].join(" ");
  597. })
  598. .attr("class", function(d) {return "invisibleLink portConnection source_" + d.source.id + " target_" + d.target.id});
  599. // Remove nodes and links.
  600. node.exit().remove();
  601. link.exit().remove();
  602. port.exit().remove();
  603. port_connection.exit().remove();
  604. </body>
  605. </method>
  606. <method name="visualize_initial_state">
  607. <parameter name="initial_states" />
  608. <body>
  609. d3.select("#smallStepInfo").classed("invisibleInfo", true);
  610. d3.selectAll("g.node").attr("class", "node")
  611. .classed("coupled", function(d) {return d.children});
  612. d3.selectAll("circle.inmessage").data([]).exit().remove();
  613. d3.selectAll("circle.outmessage").data([]).exit().remove();
  614. d3.selectAll(".portConnection").classed("invisibleLink", true);
  615. d3.selectAll(".port").classed("visible", false);
  616. d3.selectAll(".port").classed("invisible", true);
  617. d3.selectAll(".stateInfo").data([]).exit().remove();
  618. for (var loc in initial_states) {
  619. var item = this.loc_to_item[loc];
  620. d3.select("#instance_" + item.id + " .timeNext").text("TN: " + initial_states[loc][0][0] + "/" + initial_states[loc][0][1])
  621. item.state = initial_states[loc][1];
  622. if (item.state.particle_id) {
  623. this.particle_id_to_item[item.state.particle_id] = item; // TODO: this is somewhat ugly, we're making a lot of assumptions here and it's no longer domain-independent!
  624. }
  625. }
  626. </body>
  627. </method>
  628. <method name="visualize_new_state">
  629. <parameter name="new_states" />
  630. <parameter name="new_tn" />
  631. <body>
  632. d3.select("#smallStepInfo").classed("invisibleInfo", true);
  633. d3.selectAll("g.node").attr("class", "node")
  634. .classed("coupled", function(d) {return d.children});
  635. d3.selectAll("circle.inmessage").data([]).exit().remove();
  636. d3.selectAll("circle.outmessage").data([]).exit().remove();
  637. d3.selectAll(".portConnection").classed("invisibleLink", true);
  638. d3.selectAll(".port").classed("visible", false);
  639. d3.selectAll(".port").classed("invisible", true);
  640. d3.selectAll(".stateInfo").data([]).exit().remove();
  641. for (var loc in new_tn) {
  642. var item = this.loc_to_item[loc];
  643. d3.select("#instance_" + item.id + " .timeNext").text("TN: " + new_tn[loc][0] + "/" + new_tn[loc][1])
  644. item.state = new_states[loc];
  645. if (item.state.particle_id != undefined) {
  646. this.particle_id_to_item[item.state.particle_id] = item; // TODO: this is somewhat ugly, we're making a lot of assumptions here and it's no longer domain-independent!
  647. }
  648. }
  649. </body>
  650. </method>
  651. <method name="visualize_imminents">
  652. <parameter name="imminents" />
  653. <body>
  654. d3.selectAll(".portConnection").classed("invisibleLink", true);
  655. d3.selectAll(".port").classed("visible", false);
  656. d3.selectAll(".port").classed("invisible", true);
  657. d3.selectAll("circle.inmessage").data([]).exit().remove();
  658. d3.selectAll("circle.outmessage").data([]).exit().remove();
  659. if (this.transitioning_nodes) {
  660. this.transitioning_nodes.forEach(function(n) {n.attr("class", "node")
  661. .classed("coupled", function(d) {return d.children});});
  662. }
  663. d3.select("#smallStepInfo").classed("invisibleInfo", false);
  664. d3.selectAll(".smallStepInfo").classed("inactive", true);
  665. d3.select("#smallStepInfo_0").classed("inactive", false);
  666. var loc_to_item = this.loc_to_item;
  667. this.imminents = imminents;
  668. imminents.forEach(function(imminent) {
  669. d3.select("#instance_" + loc_to_item[imminent].id).classed("imminent", true);
  670. })
  671. </body>
  672. </method>
  673. <method name="visualize_selected_imminent">
  674. <parameter name="selected_imminent" />
  675. <body>
  676. d3.select("#smallStepInfo_1").classed("inactive", false);
  677. var loc_to_item = this.loc_to_item;
  678. this.imminents.forEach(function(imminent) {
  679. if (!(imminent == selected_imminent)) {
  680. d3.select("#instance_" + loc_to_item[imminent].id).classed("imminent", false);
  681. }
  682. })
  683. </body>
  684. </method>
  685. <method name="visualize_messages">
  686. <parameter name="bag" />
  687. <parameter name="msg_type" />
  688. <body>
  689. var total_msgs = [];
  690. for (var key in bag) {
  691. var msgs = bag[key];
  692. var port = this.loc_to_item[key];
  693. if (port != undefined) {
  694. msgs[0].port = port;
  695. Array.prototype.push.apply(total_msgs, msgs);
  696. }
  697. }
  698. var msgs_vis = this.svg.selectAll("circle." + msg_type)
  699. .data(total_msgs);
  700. var msg_enter = msgs_vis.enter().append("circle")
  701. .attr("class", msg_type)
  702. .attr("id", function(m) {return "msg_" + m.port.id;})
  703. .attr("r", 5)
  704. .attr("transform", function(m) {return "translate(" + m.port.x + "," + (m.port.y + 22) + ")"})
  705. .on("click", function(d) {console.log(d[0])});
  706. </body>
  707. </method>
  708. <method name="visualize_inbags">
  709. <parameter name="inbags" />
  710. <body>
  711. d3.select("#smallStepInfo_3").classed("inactive", false);
  712. function transition(circle, path, source_port_vis, target_port_vis) {
  713. circle.transition()
  714. .duration(3000)
  715. .attrTween("transform", translateAlong(path.node()))
  716. .each("end", function() {
  717. path.classed("invisibleLink", true);
  718. source_port_vis.classed("invisible", true);
  719. target_port_vis.classed("invisible", true);
  720. source_port_vis.classed("visible", false);
  721. target_port_vis.classed("visible", false);
  722. circle.attr("class", "inmessage");
  723. });
  724. }
  725. // Returns an attrTween for translating along the specified path element.
  726. function translateAlong(path) {
  727. var l = path.getTotalLength();
  728. return function(d, i, a) {
  729. return function(t) {
  730. var p = path.getPointAtLength(t * l);
  731. return "translate(" + p.x + "," + (p.y + 17) + ")";
  732. };
  733. };
  734. }
  735. var outports_visited = []
  736. for (var key in inbags) {
  737. if (inbags[key].length == 2) {
  738. var msgs = inbags[key][1];
  739. var inport = this.loc_to_item[key];
  740. if (inport != undefined) {
  741. var circle = undefined;
  742. var outport_id = this.loc_to_item[inbags[key][0]].id;
  743. if (outports_visited.indexOf(outport_id) > -1) {
  744. circle = d3.select('#msg_' + outport_id);
  745. var parent = d3.select(circle.node().parentNode);
  746. circle = parent.append("circle")
  747. .attr("class", "outmessage")
  748. .attr("id", circle.id + outports_visited.indexOf(outport_id))
  749. .attr("r", 5)
  750. .attr("transform", circle.transform)
  751. .on("click", (function(msgs) {return function(d) {console.log(msgs[0])}})(msgs));
  752. } else {
  753. circle = d3.select('#msg_' + outport_id);
  754. circle.on("click", (function(msgs) {return function(d) {console.log(msgs[0])}})(msgs));
  755. }
  756. var path = d3.select(".source_" + outport_id + ".target_" + inport.id);
  757. var source_port_vis = d3.select("#port_" + outport_id)
  758. var target_port_vis = d3.select("#port_" + inport.id)
  759. source_port_vis.classed("invisible", false);
  760. target_port_vis.classed("invisible", false);
  761. source_port_vis.classed("visible", true);
  762. target_port_vis.classed("visible", true);
  763. path.classed("invisibleLink", false);
  764. transition(circle, path, source_port_vis, target_port_vis);
  765. outports_visited.push(outport_id);
  766. }
  767. } else {
  768. var msgs = inbags[key][0];
  769. var inport = this.loc_to_item[key];
  770. this.svg.append("circle")
  771. .attr("class", "inmessage")
  772. .attr("id", "msg_" + inport.id)
  773. .attr("r", 5)
  774. .attr("transform", "translate(" + inport.x + "," + (inport.y + 22) + ")")
  775. .on("click", (function(msgs) {return function(d) {console.log(msgs[0])}})(msgs));
  776. }
  777. }
  778. </body>
  779. </method>
  780. <method name="visualize_transitioning">
  781. <parameter name="transitioning" />
  782. <body>
  783. var transitioning_nodes = [];
  784. var loc_to_item = this.loc_to_item;
  785. Object.keys(transitioning).forEach(function(key) {
  786. transitioning_nodes.push(d3.select("#instance_" + loc_to_item[key].id).classed(transitioning[key], true));
  787. });
  788. this.transitioning_nodes = transitioning_nodes;
  789. </body>
  790. </method>
  791. <method name="handle_internal_state_change">
  792. <parameter name="new_internal_states" />
  793. <body>
  794. d3.select("#smallStepInfo_5").classed("inactive", false);
  795. for (var loc in new_internal_states) {
  796. var item = this.loc_to_item[loc];
  797. item.state = new_internal_states[loc];
  798. }
  799. if (this.transitioning_nodes) {
  800. this.transitioning_nodes.forEach(function(n) {n.attr("class", "node")
  801. .classed("coupled", function(d) {return d.children});});
  802. }
  803. var node = this.svg.selectAll("g.node");
  804. var stateInfo = node.selectAll("g.state");
  805. stateInfo.text(function(d) {return JSON.stringify(d);});
  806. </body>
  807. </method>
  808. <method name="visualize_new_tn">
  809. <parameter name="new_tn" />
  810. <body>
  811. d3.select("#smallStepInfo_6").classed("inactive", false);
  812. for (var loc in new_tn) {
  813. var item = this.loc_to_item[loc];
  814. d3.select("#instance_" + item.id + " .timeNext").text("TN: " + new_tn[loc][0] + "/" + new_tn[loc][1])
  815. }
  816. </body>
  817. </method>
  818. <method name="select_instance">
  819. <parameter name="instance_id" />
  820. <body>
  821. d3.selectAll(".stateInfo").data([]).exit().remove();
  822. if (instance_id in this.particle_id_to_item) {
  823. var d = this.particle_id_to_item[instance_id];
  824. var node = d3.select("#instance_" + d.id)
  825. var stateInfo = node.selectAll(".stateInfo")
  826. .data(function(n) {if (n.state) {return [n.state]} else {return []}}, function(d) {return d.id});
  827. var stateInfoEnter = stateInfo.enter().append("text")
  828. .attr("transform", "translate(-60, 60)")
  829. .attr("id", this.node_id++)
  830. .attr("class", "stateInfo");
  831. var stateInfoText = stateInfo.selectAll("tspan")
  832. .data(function(d) {return JSON.stringify(d, null, 2).split("\n")});
  833. var stateInfoTextEnter = stateInfoText.enter().append("tspan")
  834. .attr("x", "0.0")
  835. .attr("dy", "1.4em")
  836. .attr("xml:space", "preserve")
  837. .text(function(d) {return d});
  838. }
  839. </body>
  840. </method>
  841. <method name="visualize_breakpoints">
  842. <body>
  843. for (idx in this.breakpoints) {
  844. var curr_bp = this.breakpoints[idx];
  845. if (curr_bp.triggered) {
  846. this.visualize_messages(curr_bp.outbag, 'outmessage');
  847. for (var key in curr_bp.inbags) {
  848. if (curr_bp.inbags[key].length == 2) {
  849. curr_bp.inbags[key] = [curr_bp.inbags[key][1]];
  850. }
  851. }
  852. this.visualize_messages(curr_bp.inbags, 'inmessage');
  853. this.visualize_transitioning(curr_bp.transitioned);
  854. }
  855. }
  856. var curr_bps = this.breakpoint_infos.selectAll("div").data(this.breakpoints)
  857. curr_bps_enter = curr_bps.enter().append("div")
  858. .attr("id", function(d) {return "breakpoint_" + d.name})
  859. .attr("class", "breakpoint")
  860. .style("transform", function(d, i) {return "translate(" + i * 5 + "px, -8px)"})
  861. .style("float", "left");
  862. curr_bps_enter.append("text")
  863. .text(function(d) {return d.name})
  864. .on("click", function(d) {
  865. d.enabled = !d.enabled;
  866. the_controller.addInput(new Event("toggle_breakpoint", "ui_input", [d.name, d.enabled]), 0.0);
  867. })
  868. .on('mouseover', function() {
  869. d3.event.preventDefault();
  870. });
  871. curr_bps_enter.append("img")
  872. .attr('src', 'img/delete-bp.png')
  873. .style('transform', 'translate(1px, 2px)')
  874. .on("click", function(d) {
  875. the_controller.addInput(new Event("del_breakpoint", "ui_input", [d.name]), 0.0);
  876. });
  877. curr_bps.exit().remove();
  878. curr_bps.style("background-color", function(d) {
  879. if (d.triggered) {
  880. d.triggered = false;
  881. if (d.disable_on_trigger) {
  882. d.enabled = false;
  883. }
  884. return "red";
  885. } else {
  886. return "transparent";
  887. }});
  888. curr_bps.select("text").style("opacity", function(d) {if (d.enabled) return "1"; else return "0.5";});
  889. </body>
  890. </method>
  891. <scxml initial="initializing">
  892. <state id="initializing">
  893. <transition target="../running">
  894. <raise event="reset" port="output" />
  895. </transition>
  896. </state>
  897. <state id="running">
  898. <transition target="." event="all_states_reset" port="simulation_input">
  899. <parameter name="the_parameters" />
  900. <script>
  901. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  902. this.data = [];
  903. this.port_connections = [];
  904. this.update_vis(the_parameters[2]);
  905. this.visualize_initial_state(the_parameters[1]);
  906. this.breakpoints = the_parameters[3];
  907. this.visualize_breakpoints();
  908. </script>
  909. </transition>
  910. <transition target="." event="all_states" port="simulation_input">
  911. <parameter name="the_parameters" />
  912. <script>
  913. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  914. this.update_vis(the_parameters[2]);
  915. this.visualize_initial_state(the_parameters[1]);
  916. this.visualize_breakpoints();
  917. </script>
  918. </transition>
  919. <transition target="." event="new_states" port="simulation_input">
  920. <parameter name="the_parameters" />
  921. <script>
  922. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  923. this.update_vis(the_parameters[3]);
  924. this.visualize_new_state(the_parameters[1], the_parameters[2]);
  925. this.visualize_breakpoints();
  926. </script>
  927. </transition>
  928. <transition target="." event="imminents" port="simulation_input">
  929. <parameter name="the_parameters" />
  930. <script>
  931. this.visualize_breakpoints();
  932. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  933. this.visualize_imminents(the_parameters[1]);
  934. </script>
  935. </transition>
  936. <transition target="." event="selected_imminent" port="simulation_input">
  937. <parameter name="the_parameters" />
  938. <script>
  939. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  940. this.visualize_selected_imminent(the_parameters[1]);
  941. </script>
  942. </transition>
  943. <transition target="." event="outbag" port="simulation_input">
  944. <parameter name="the_parameters" />
  945. <script>
  946. d3.select("#smallStepInfo_2").classed("inactive", false);
  947. d3.selectAll("g.node").classed("imminent", false);
  948. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  949. this.visualize_messages(the_parameters[1], 'outmessage');
  950. </script>
  951. </transition>
  952. <transition target="." event="inbags" port="simulation_input">
  953. <parameter name="the_parameters" />
  954. <script>
  955. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  956. this.visualize_inbags(the_parameters[1]);
  957. </script>
  958. </transition>
  959. <transition target="." event="transitioning" port="simulation_input">
  960. <parameter name="the_parameters" />
  961. <script>
  962. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  963. d3.select("#smallStepInfo_4").classed("inactive", false);
  964. d3.selectAll(".portConnection").classed("invisibleLink", true);
  965. d3.selectAll(".port").classed("visible", false);
  966. d3.selectAll(".port").classed("invisible", true);
  967. d3.selectAll("circle.inmessage").data([]).exit().remove();
  968. d3.selectAll("circle.outmessage").data([]).exit().remove();
  969. this.visualize_transitioning(the_parameters[1]);
  970. </script>
  971. </transition>
  972. <transition target="." event="new_internal_states" port="simulation_input">
  973. <parameter name="the_parameters" />
  974. <script>
  975. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  976. this.handle_internal_state_change(the_parameters[1]);
  977. </script>
  978. </transition>
  979. <transition target="." event="new_tn" port="simulation_input">
  980. <parameter name="the_parameters" />
  981. <script>
  982. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  983. this.visualize_new_tn(the_parameters[1]);
  984. </script>
  985. </transition>
  986. <transition target="." event="structural_changes" port="simulation_input">
  987. <parameter name="the_parameters" />
  988. <script>
  989. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  990. this.update_vis(the_parameters[1]);
  991. </script>
  992. </transition>
  993. <transition target="." event="select_instance" port="ui_input">
  994. <parameter name="the_parameters" />
  995. <script>
  996. this.select_instance(the_parameters);
  997. </script>
  998. </transition>
  999. <transition target="." event="process_god_event" port="ui_input">
  1000. <raise event="god_event" port="output">
  1001. <parameter expr="god_event_to_process" />
  1002. </raise>
  1003. </transition>
  1004. <transition target="." event="god_event_ok" port="simulation_input">
  1005. <parameter name="the_parameters" />
  1006. <script>
  1007. this.handle_internal_state_change(the_parameters[0]);
  1008. </script>
  1009. </transition>
  1010. <transition target="." event="inject_event" port="ui_input">
  1011. <raise event="inject" port="output">
  1012. <parameter expr="event_to_inject" />
  1013. </raise>
  1014. </transition>
  1015. <transition target="." event="inject_ok" port="simulation_input" />
  1016. <transition target="." event="add_breakpoint" port="ui_input">
  1017. <raise event="add_breakpoint" port="output">
  1018. <parameter expr="breakpoint_to_add" />
  1019. </raise>
  1020. <script>
  1021. this.breakpoints.push({'name': breakpoint_to_add[0], 'enabled': breakpoint_to_add[2], 'disable_on_trigger': breakpoint_to_add[3], 'triggered': false});
  1022. this.visualize_breakpoints();
  1023. </script>
  1024. </transition>
  1025. <transition target="." event="toggle_breakpoint" port="ui_input">
  1026. <parameter name="breakpoint_id" />
  1027. <parameter name="enabled" />
  1028. <raise event="toggle_breakpoint" port="output">
  1029. <parameter expr="breakpoint_id" />
  1030. <parameter expr="enabled" />
  1031. </raise>
  1032. <script>
  1033. this.visualize_breakpoints();
  1034. </script>
  1035. </transition>
  1036. <transition target="." event="del_breakpoint" port="ui_input">
  1037. <parameter name="breakpoint_id" />
  1038. <raise event="del_breakpoint" port="output">
  1039. <parameter expr="breakpoint_id" />
  1040. </raise>
  1041. <script>
  1042. this.breakpoints = this.breakpoints.filter(function(bp) {return bp.name != breakpoint_id});
  1043. this.visualize_breakpoints();
  1044. </script>
  1045. </transition>
  1046. <transition target="." event="breakpoint_triggered" port="simulation_input">
  1047. <parameter name="the_parameters" />
  1048. <script>
  1049. for (var idx in this.breakpoints) {
  1050. var curr_bp = this.breakpoints[idx];
  1051. if (curr_bp.name == the_parameters[0]) {
  1052. curr_bp.triggered = true;
  1053. curr_bp.transitioned = the_parameters[1];
  1054. curr_bp.outbag = the_parameters[2];
  1055. curr_bp.inbags = the_parameters[3];
  1056. }
  1057. }
  1058. </script>
  1059. </transition>
  1060. </state>
  1061. </scxml>
  1062. </class>
  1063. </diagram>