linny-r 2.0.8 → 2.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +3 -40
  2. package/package.json +6 -2
  3. package/server.js +19 -157
  4. package/static/images/solve-not-same-changed.png +0 -0
  5. package/static/images/solve-not-same-not-changed.png +0 -0
  6. package/static/images/solve-same-changed.png +0 -0
  7. package/static/images/solve-same-not-changed.png +0 -0
  8. package/static/index.html +137 -20
  9. package/static/linny-r.css +260 -23
  10. package/static/scripts/iro.min.js +7 -7
  11. package/static/scripts/linny-r-ctrl.js +126 -85
  12. package/static/scripts/linny-r-gui-actor-manager.js +23 -33
  13. package/static/scripts/linny-r-gui-chart-manager.js +56 -53
  14. package/static/scripts/linny-r-gui-constraint-editor.js +10 -14
  15. package/static/scripts/linny-r-gui-controller.js +644 -260
  16. package/static/scripts/linny-r-gui-dataset-manager.js +64 -66
  17. package/static/scripts/linny-r-gui-documentation-manager.js +11 -17
  18. package/static/scripts/linny-r-gui-equation-manager.js +22 -22
  19. package/static/scripts/linny-r-gui-experiment-manager.js +124 -141
  20. package/static/scripts/linny-r-gui-expression-editor.js +26 -12
  21. package/static/scripts/linny-r-gui-file-manager.js +42 -48
  22. package/static/scripts/linny-r-gui-finder.js +294 -55
  23. package/static/scripts/linny-r-gui-model-autosaver.js +2 -4
  24. package/static/scripts/linny-r-gui-monitor.js +35 -41
  25. package/static/scripts/linny-r-gui-paper.js +42 -70
  26. package/static/scripts/linny-r-gui-power-grid-manager.js +31 -34
  27. package/static/scripts/linny-r-gui-receiver.js +1 -2
  28. package/static/scripts/linny-r-gui-repository-browser.js +44 -46
  29. package/static/scripts/linny-r-gui-scale-unit-manager.js +32 -32
  30. package/static/scripts/linny-r-gui-sensitivity-analysis.js +61 -67
  31. package/static/scripts/linny-r-gui-undo-redo.js +94 -95
  32. package/static/scripts/linny-r-milp.js +20 -24
  33. package/static/scripts/linny-r-model.js +1932 -2274
  34. package/static/scripts/linny-r-utils.js +27 -27
  35. package/static/scripts/linny-r-vm.js +900 -998
  36. package/static/show-png.html +0 -113
@@ -342,7 +342,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
342
342
  }
343
343
 
344
344
  getRepositories() {
345
- // Gets the list of repository names from the server
345
+ // Gets the list of repository names from the server.
346
346
  this.repositories.length = 0;
347
347
  fetch('repo/', postData({action: 'list'}))
348
348
  .then((response) => {
@@ -353,14 +353,13 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
353
353
  })
354
354
  .then((data) => {
355
355
  if(UI.postResponseOK(data)) {
356
- // NOTE: trim to prevent empty name strings
357
- const rl = data.trim().split('\n');
358
- for(let i = 0; i < rl.length; i++) {
359
- this.addRepository(rl[i].trim());
356
+ // NOTE: Trim to prevent empty name strings.
357
+ for(const r of data.trim().split('\n')) {
358
+ this.addRepository(r.trim());
360
359
  }
361
360
  }
362
- // NOTE: set index to first repository on list (typically local host)
363
- // unless the list is empty
361
+ // NOTE: Set index to first repository on list (typically local host)
362
+ // unless the list is empty.
364
363
  this.repository_index = Math.min(0, this.repositories.length - 1);
365
364
  this.updateDialog();
366
365
  })
@@ -545,7 +544,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
545
544
  }
546
545
 
547
546
  updateModulesTable() {
548
- // Refresh the module table
547
+ // Refresh the module table.
549
548
  let mcount = 0;
550
549
  const trl = [];
551
550
  if(this.repository_index >= 0) {
@@ -565,7 +564,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
565
564
  this.modules_count.innerHTML = pluralS(mcount, 'module');
566
565
  if(this.module_index >= 0) {
567
566
  UI.enableButtons('repo-load repo-include');
568
- // NOTE: only allow deletion from local host repository
567
+ // NOTE: Only allow deletion from local host repository.
569
568
  if(this.repository_index === 0 && this.isLocalHost) {
570
569
  UI.enableButtons(' repo-delete');
571
570
  } else {
@@ -577,7 +576,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
577
576
  }
578
577
 
579
578
  updateDialog() {
580
- // Refreshes all dialog elements
579
+ // Refreshe all dialog elements.
581
580
  const ol = [];
582
581
  for(let i = 0; i < this.repositories.length; i++) {
583
582
  ol.push('<option value="', i,
@@ -586,7 +585,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
586
585
  }
587
586
  this.repository_selector.innerHTML = ol.join('');
588
587
  UI.disableButtons('repo-access repo-remove repo-store');
589
- // NOTE: on remote installation, do not allow add/remove/store
588
+ // NOTE: On remote installation, do not allow add/remove/store.
590
589
  if(!this.isLocalHost) {
591
590
  UI.disableButtons('repo-add');
592
591
  } else if(this.repository_index >= 0) {
@@ -597,7 +596,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
597
596
  UI.enableButtons('repo-access');
598
597
  }
599
598
  if(r.name !== 'local host') {
600
- // NOTE: cannot remove 'local host'
599
+ // NOTE: Cannot remove 'local host'.
601
600
  UI.enableButtons('repo-remove');
602
601
  }
603
602
  }
@@ -605,7 +604,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
605
604
  }
606
605
 
607
606
  promptForInclusion(repo, file, node) {
608
- // Add entities defined in the parsed XML tree with root `node`
607
+ // Add entities defined in the parsed XML tree with root `node`.
609
608
  IO_CONTEXT = new IOContext(repo, file, node);
610
609
  const md = this.include_modal;
611
610
  md.element('name').innerHTML = IO_CONTEXT.file_name;
@@ -616,8 +615,8 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
616
615
  }
617
616
 
618
617
  updateActors() {
619
- // Adds actor (if specified) to model, and then updates the selector options
620
- // for each actor binding selector
618
+ // Add actor (if specified) to model, and then updates the selector options
619
+ // for each actor binding selector.
621
620
  if(!IO_CONTEXT) return;
622
621
  const
623
622
  aname = this.include_modal.element('actor').value.trim(),
@@ -637,25 +636,24 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
637
636
  }
638
637
 
639
638
  parameterBinding(name) {
640
- // Returns the selected option (as DOM element) of the the parameter
641
- // selector identified by its element name (!) in the Include modal
642
- const lst = document.getElementsByName(name);
643
- let e = null;
644
- for(let i = 0; i < lst.length; i++) {
645
- if(lst[i].type.indexOf('select') === 0) {
646
- e = lst[i];
639
+ // Return the selected option (as DOM element) of the the parameter
640
+ // selector identified by its element name (!) in the Include modal.
641
+ let sel = null;
642
+ for(const e of document.getElementsByName(name)) {
643
+ if(e.type.indexOf('select') === 0) {
644
+ sel = e;
647
645
  break;
648
646
  }
649
647
  }
650
- if(!e) UI.alert(`Parameter selector "${b.id}" not found`);
651
- return e;
648
+ if(!sel) UI.alert(`Parameter selector "${name}" not found`);
649
+ return sel;
652
650
  }
653
651
 
654
652
  performInclusion() {
655
- // Includes the selected model as "module" cluster in the model;
656
- // this is effectuated by "re-initializing" the current model using
653
+ // Include the selected model as "module" cluster in the model.
654
+ // This is effectuated by "re-initializing" the current model using
657
655
  // the XML of the model-to-be-included with the contextualization as
658
- // indicated by the modeler
656
+ // indicated by the modeler.
659
657
  if(!IO_CONTEXT) {
660
658
  UI.alert('Cannot include module without context');
661
659
  return;
@@ -667,7 +665,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
667
665
  pref.focus();
668
666
  return;
669
667
  }
670
- // NOTE: prefix must not already be in use as entity name
668
+ // NOTE: Prefix must not already be in use as entity name.
671
669
  let obj = MODEL.objectByName(IO_CONTEXT.prefix);
672
670
  if(obj) {
673
671
  UI.warningEntityExists(obj, IO_CONTEXT.prefix);
@@ -678,10 +676,10 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
678
676
  IO_CONTEXT.actor_name = this.include_modal.element('actor').value.trim();
679
677
  MODEL.clearSelection();
680
678
  IO_CONTEXT.bindParameters();
681
- // NOTE: including may affect focal cluster, so store it...
679
+ // NOTE: Including may affect focal cluster, so store it...
682
680
  const fc = MODEL.focal_cluster;
683
681
  MODEL.initFromXML(IO_CONTEXT.xml);
684
- // ... and restore it afterwards
682
+ // ... and restore it afterwards.
685
683
  MODEL.focal_cluster = fc;
686
684
  let counts = `: ${pluralS(IO_CONTEXT.added_nodes.length, 'node')}, ` +
687
685
  pluralS(IO_CONTEXT.added_links.length, 'link');
@@ -691,9 +689,9 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
691
689
  }
692
690
  UI.notify(`Model <tt>${IO_CONTEXT.file_name}</tt> included from ` +
693
691
  `<strong>${IO_CONTEXT.repo_name}</strong>${counts}`);
694
- // Get the containing cluster
692
+ // Get the containing cluster.
695
693
  obj = MODEL.objectByName(IO_CONTEXT.clusterName);
696
- // Position it in the focal cluster
694
+ // Position it in the focal cluster.
697
695
  if(obj instanceof Cluster) {
698
696
  obj.x = IO_CONTEXT.centroid_x;
699
697
  obj.y = IO_CONTEXT.centroid_y;
@@ -701,20 +699,20 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
701
699
  } else {
702
700
  UI.alert('Include failed to create a cluster');
703
701
  }
704
- // Reset the IO context
702
+ // Reset the IO context.
705
703
  IO_CONTEXT = null;
706
704
  this.include_modal.hide();
707
705
  MODEL.cleanUpActors();
708
706
  MODEL.focal_cluster.clearAllProcesses();
709
707
  UI.drawDiagram(MODEL);
710
- // Select the newly added cluster
708
+ // Select the newly added cluster.
711
709
  if(obj) MODEL.select(obj);
712
- // Update dataset manager if shown (as new datasets may have been added)
710
+ // Update dataset manager if shown (as new datasets may have been added).
713
711
  if(DATASET_MANAGER.visible) DATASET_MANAGER.updateDialog();
714
712
  }
715
713
 
716
714
  cancelInclusion() {
717
- // Clears the IO context and closes the inclusion dialog
715
+ // Clear the IO context and closes the inclusion dialog.
718
716
  IO_CONTEXT = null;
719
717
  this.include_modal.hide();
720
718
  }
@@ -724,7 +722,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
724
722
  this.store_modal.element('name').innerText =
725
723
  this.repositories[this.repository_index].name;
726
724
  this.store_modal.element('model-name').value =
727
- this.asFileName(MODEL.name);
725
+ asFileName(MODEL.name);
728
726
  this.store_modal.show('model-name');
729
727
  }
730
728
  }
@@ -746,7 +744,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
746
744
  this.store_bb_modal.element('name').innerText =
747
745
  this.repositories[this.repository_index].name;
748
746
  this.store_bb_modal.element('model-name').value =
749
- this.asFileName(MODEL.name);
747
+ asFileName(MODEL.name);
750
748
  this.store_bb_modal.show('model-name');
751
749
  }
752
750
  }
@@ -757,7 +755,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
757
755
  mn = this.store_bb_modal.element('model-name').value.trim(),
758
756
  r = this.repositories[this.repository_index];
759
757
  if(mn.length > 1) {
760
- // NOTE: second parameter indicates: store with "black box XML"
758
+ // NOTE: Second parameter indicates: store with "black box XML".
761
759
  r.storeModelAsModule(mn, true);
762
760
  this.store_bb_modal.hide();
763
761
  }
@@ -765,19 +763,19 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
765
763
  }
766
764
 
767
765
  loadModuleAsModel() {
768
- // Loads selected module as model
766
+ // Load selected module as model.
769
767
  this.confirm_load_modal.hide();
770
768
  if(this.repository_index >= 0 && this.module_index >= 0) {
771
- // NOTE: when loading new model, the stay-on-top dialogs must be reset
769
+ // NOTE: When loading new model, the stay-on-top dialogs must be reset.
772
770
  UI.hideStayOnTopDialogs();
773
771
  const r = this.repositories[this.repository_index];
774
- // NOTE: pass FALSE to indicate "no inclusion; load XML as model"
772
+ // NOTE: Pass FALSE to indicate "no inclusion; load XML as model".
775
773
  r.loadModule(this.module_index, false);
776
774
  }
777
775
  }
778
776
 
779
777
  includeModule() {
780
- // Includes selected module into the current model
778
+ // Include selected module into the current model.
781
779
  if(this.repository_index >= 0 && this.module_index >= 0) {
782
780
  const r = this.repositories[this.repository_index];
783
781
  r.loadModule(this.module_index, true);
@@ -785,7 +783,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
785
783
  }
786
784
 
787
785
  confirmLoadModuleAsModel() {
788
- // Prompts modeler to confirm loading the selected module as model
786
+ // Prompt modeler to confirm loading the selected module as model.
789
787
  if(this.repository_index >= 0 && this.module_index >= 0 &&
790
788
  document.getElementById('repo-load-btn').classList.contains('enab')) {
791
789
  const r = this.repositories[this.repository_index];
@@ -796,7 +794,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
796
794
  }
797
795
 
798
796
  confirmDeleteFromRepository() {
799
- // Prompts modeler to confirm deletion of the selected module
797
+ // Prompt modeler to confirm deletion of the selected module.
800
798
  if(this.repository_index >= 0 && this.module_index >= 0 &&
801
799
  document.getElementById('repo-delete-btn').classList.contains('enab')) {
802
800
  const r = this.repositories[this.repository_index];
@@ -808,7 +806,7 @@ class GUIRepositoryBrowser extends RepositoryBrowser {
808
806
  }
809
807
 
810
808
  deleteFromRepository() {
811
- // Deletes the selected modulle from the current repository
809
+ // Delete the selected modulle from the current repository.
812
810
  if(this.repository_index >= 0 && this.module_index >= 0) {
813
811
  const r = this.repositories[this.repository_index];
814
812
  if(r) r.deleteModule(this.module_index);
@@ -35,18 +35,18 @@ SOFTWARE.
35
35
  // CLASS ScaleUnitManager (modal dialog!)
36
36
  class ScaleUnitManager {
37
37
  constructor() {
38
- // Add the scale units modal
38
+ // Add the scale units modal.
39
39
  this.dialog = new ModalDialog('scale-units');
40
40
  this.dialog.close.addEventListener('click',
41
41
  () => SCALE_UNIT_MANAGER.dialog.hide());
42
- // Make the add, edit and delete buttons of this modal responsive
42
+ // Make the add, edit and delete buttons of this modal responsive.
43
43
  this.dialog.element('new-btn').addEventListener('click',
44
44
  () => SCALE_UNIT_MANAGER.promptForScaleUnit());
45
45
  this.dialog.element('edit-btn').addEventListener('click',
46
46
  () => SCALE_UNIT_MANAGER.editScaleUnit());
47
47
  this.dialog.element('delete-btn').addEventListener('click',
48
48
  () => SCALE_UNIT_MANAGER.deleteScaleUnit());
49
- // Add the scale unit definition modal
49
+ // Add the scale unit definition modal.
50
50
  this.new_scale_unit_modal = new ModalDialog('new-scale-unit');
51
51
  this.new_scale_unit_modal.ok.addEventListener(
52
52
  'click', () => SCALE_UNIT_MANAGER.addNewScaleUnit());
@@ -57,19 +57,19 @@ class ScaleUnitManager {
57
57
  }
58
58
 
59
59
  get selectedUnitIsBaseUnit() {
60
- // Returns TRUE iff selected unit is used as base unit for some unit
61
- for(let u in this.scale_units) if(this.scale_units.hasOwnProperty(u)) {
62
- if(this.scale_units[u].base_unit === this.selected_unit) return true;
60
+ // Return TRUE iff selected unit is used as base unit for some unit.
61
+ for(let k in this.scale_units) if(this.scale_units.hasOwnProperty(k)) {
62
+ if(this.scale_units[k].base_unit === this.selected_unit) return true;
63
63
  }
64
64
  return false;
65
65
  }
66
66
 
67
67
  show() {
68
- // Show the user-defined scale units for the current model
69
- // NOTE: add/edit/delete actions operate on this list, so changes
70
- // take immediate effect
68
+ // Show the user-defined scale units for the current model.
69
+ // NOTE: Add/edit/delete actions operate on this list, so changes
70
+ // take immediate effect.
71
71
  MODEL.cleanUpScaleUnits();
72
- // NOTE: unit name is key in the scale units object
72
+ // NOTE: Unit name is key in the scale units object.
73
73
  this.selected_unit = '';
74
74
  this.last_time_selected = 0;
75
75
  this.updateDialog();
@@ -78,7 +78,7 @@ class ScaleUnitManager {
78
78
 
79
79
  updateDialog() {
80
80
  // Create the HTML for the scale units table and update the state
81
- // of the action buttons
81
+ // of the action buttons.
82
82
  if(!MODEL.scale_units.hasOwnProperty(this.selected_unit)) {
83
83
  this.selected_unit = '';
84
84
  }
@@ -88,7 +88,7 @@ class ScaleUnitManager {
88
88
  ss = this.selected_unit;
89
89
  let ssid = 'scntr';
90
90
  if(keys.length <= 1) {
91
- // Only one key => must be the default '1'
91
+ // Only one key => must be the default '1'.
92
92
  sl.push('<tr><td><em>No units defined</em></td></tr>');
93
93
  } else {
94
94
  for(let i = 1; i < keys.length; i++) {
@@ -118,14 +118,14 @@ class ScaleUnitManager {
118
118
  }
119
119
 
120
120
  selectScaleUnit(event, symbol, focus) {
121
- // Select scale unit, and when double-clicked, allow to edit it
121
+ // Select scale unit, and when double-clicked, allow to edit it.
122
122
  const
123
123
  ss = this.selected_unit,
124
124
  now = Date.now(),
125
125
  dt = now - this.last_time_selected,
126
- // NOTE: Alt-click and double-click indicate: edit
126
+ // NOTE: Alt-click and double-click indicate: edit.
127
127
  // Consider click to be "double" if the same modifier was clicked
128
- // less than 300 ms ago
128
+ // less than 300 ms ago.
129
129
  edit = event.altKey || (symbol === ss && dt < 300);
130
130
  this.selected_unit = symbol;
131
131
  this.last_time_selected = now;
@@ -138,9 +138,9 @@ class ScaleUnitManager {
138
138
  }
139
139
 
140
140
  promptForScaleUnit(action='Define new', focus='name') {
141
- // Show the Add/Edit scale unit dialog for the indicated action
141
+ // Show the Add/Edit scale unit dialog for the indicated action.
142
142
  const md = this.new_scale_unit_modal;
143
- // NOTE: by default, let name and base unit be empty strings, not '1'
143
+ // NOTE: By default, let name and base unit be empty strings, not '1'.
144
144
  let sv = {name: '', scalar: '1', base_unit: '' };
145
145
  if(action === 'Edit' && this.selected_unit) {
146
146
  sv = MODEL.scale_units[this.selected_unit];
@@ -154,23 +154,23 @@ class ScaleUnitManager {
154
154
  }
155
155
 
156
156
  addNewScaleUnit() {
157
- // Add the new scale unit or update the one being edited
157
+ // Add the new scale unit or update the one being edited.
158
158
  const
159
159
  md = this.new_scale_unit_modal,
160
160
  edited = md.element('action').innerText === 'Edit',
161
- // NOTE: unit name cannot contain single quotes
161
+ // NOTE: Unit name cannot contain single quotes.
162
162
  s = UI.cleanName(md.element('name').value).replace("'", ''),
163
163
  v = md.element('scalar').value.trim(),
164
- // NOTE: accept empty base unit to denote '1'
164
+ // NOTE: Accept empty base unit to denote '1'.
165
165
  b = md.element('base').value.trim() || '1';
166
166
  if(!s) {
167
- // Do not accept empty string as name
167
+ // Do not accept empty string as name.
168
168
  UI.warn('Scale unit must have a name');
169
169
  md.element('name').focus();
170
170
  return;
171
171
  }
172
172
  if(MODEL.scale_units.hasOwnProperty(s) && !edited) {
173
- // Do not accept existing unit as name for new unit
173
+ // Do not accept existing unit as name for new unit.
174
174
  UI.warn(`Scale unit "${s}" is already defined`);
175
175
  md.element('name').focus();
176
176
  return;
@@ -194,7 +194,7 @@ class ScaleUnitManager {
194
194
  }
195
195
  const selu = this.selected_unit;
196
196
  if(edited && b !== s) {
197
- // Prevent inconsistencies across scalars
197
+ // Prevent inconsistencies across scalars.
198
198
  const cr = MODEL.scale_units[b].conversionRates();
199
199
  if(cr.hasOwnProperty(s)) {
200
200
  UI.warn(`Defining ${s} in terms of ${b} introduces a circular reference`);
@@ -203,13 +203,13 @@ class ScaleUnitManager {
203
203
  }
204
204
  }
205
205
  if(edited && s !== selu) {
206
- // First rename base units
207
- for(let u in MODEL.scale_units) if(MODEL.scale_units.hasOwnProperty(u)) {
208
- if(MODEL.scale_units[u].base_unit === selu) {
209
- MODEL.scale_units[u].base_unit = s;
206
+ // First rename base units.
207
+ for(let k in MODEL.scale_units) if(MODEL.scale_units.hasOwnProperty(k)) {
208
+ if(MODEL.scale_units[k].base_unit === selu) {
209
+ MODEL.scale_units[k].base_unit = s;
210
210
  }
211
211
  }
212
- // NOTE: renameScaleUnit replaces references to `s`, not the entry
212
+ // NOTE: renameScaleUnit replaces references to `s`, not the entry.
213
213
  MODEL.renameScaleUnit(selu, s);
214
214
  delete MODEL.scale_units[this.selected_unit];
215
215
  }
@@ -222,13 +222,13 @@ class ScaleUnitManager {
222
222
  }
223
223
 
224
224
  editScaleUnit() {
225
- // Allow user to edit name and/or value
225
+ // Allow user to edit name and/or value.
226
226
  if(this.selected_unit) this.promptForScaleUnit('Edit', 'scalar');
227
227
  }
228
228
 
229
229
  deleteScaleUnit() {
230
- // Allow user to delete
231
- // @@@TO DO: check whether scale unit is used in the model
230
+ // Allow user to delete.
231
+ // @@@TO DO: Check whether scale unit is used in the model.
232
232
  if(this.selected_unit && !this.selectedUnitIsBaseUnit) {
233
233
  delete MODEL.scale_units[this.selected_unit];
234
234
  this.updateDialog();
@@ -236,7 +236,7 @@ class ScaleUnitManager {
236
236
  }
237
237
 
238
238
  updateScaleUnits() {
239
- // Replace scale unit definitions of model by the new definitions
239
+ // Replace scale unit definitions of model by the new definitions.
240
240
  UI.updateScaleUnitList();
241
241
  this.dialog.hide();
242
242
  }