linny-r 1.3.4 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/static/index.html +6 -12
- package/static/linny-r.css +28 -2
- package/static/scripts/linny-r-ctrl.js +40 -8
- package/static/scripts/linny-r-gui.js +124 -65
- package/static/scripts/linny-r-model.js +474 -143
- package/static/scripts/linny-r-utils.js +134 -12
- package/static/scripts/linny-r-vm.js +806 -390
package/package.json
CHANGED
package/static/index.html
CHANGED
@@ -165,7 +165,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
165
165
|
// Inform user that newer version exists
|
166
166
|
UI.check_update_modal.element('msg').innerHTML = [
|
167
167
|
'<a href="', GITHUB_REPOSITORY,
|
168
|
-
'/wiki/Linny-R-version-history
|
168
|
+
'/wiki/Linny-R-version-history#version-',
|
169
169
|
info[1].replaceAll('.', ''), '" ',
|
170
170
|
'title="Click to view version release notes" ',
|
171
171
|
'target="_blank">Version <strong>',
|
@@ -354,7 +354,7 @@ and move the cursor over the status bar">
|
|
354
354
|
<img id="clone-btn" class="btn disab sep" src="images/clone.png"
|
355
355
|
title="Copy selection (Ctrl-C) – Alt-click to clone (Alt-C)">
|
356
356
|
<img id="paste-btn" class="btn disab sep" src="images/paste.png"
|
357
|
-
title="Paste selection (Ctrl-V)
|
357
|
+
title="Paste selection (Ctrl-V)">
|
358
358
|
<img id="delete-btn" class="btn disab sep" src="images/delete.png"
|
359
359
|
title="Delete">
|
360
360
|
<img id="undo-btn" class="btn enab" src="images/undo.png"
|
@@ -1098,7 +1098,7 @@ NOTE: Unit symbols are case-sensitive, so BTU ≠ Btu">
|
|
1098
1098
|
<div id="note-modal" class="modal">
|
1099
1099
|
<div id="note-dlg" class="inp-dlg">
|
1100
1100
|
<div class="dlg-title">
|
1101
|
-
<span id="note-action">Add</span> note
|
1101
|
+
<span id="note-action">Add</span> note <span id="note-number"></span>
|
1102
1102
|
<img class="cancel-btn" src="images/cancel.png">
|
1103
1103
|
<img class="ok-btn" src="images/ok.png">
|
1104
1104
|
</div>
|
@@ -1280,6 +1280,9 @@ NOTE: Unit symbols are case-sensitive, so BTU ≠ Btu">
|
|
1280
1280
|
<div id="process-dlg" class="inp-dlg">
|
1281
1281
|
<div class="dlg-title">
|
1282
1282
|
Process properties
|
1283
|
+
<div class="simbtn">
|
1284
|
+
<img id="process-sim-btn" class="btn sim enab" src="images/process.png">
|
1285
|
+
</div>
|
1283
1286
|
<img class="cancel-btn" src="images/cancel.png">
|
1284
1287
|
<img class="ok-btn" src="images/ok.png">
|
1285
1288
|
</div>
|
@@ -2849,15 +2852,6 @@ where X can be one or several of these letters: ABCDELPQ">
|
|
2849
2852
|
Auto-increment tail number
|
2850
2853
|
</div>
|
2851
2854
|
</div>
|
2852
|
-
<div class="paste-option">
|
2853
|
-
<div id="paste-near-box" class="box checked"></div>
|
2854
|
-
<div class="paste-tactic">
|
2855
|
-
Link to nearest eligible node
|
2856
|
-
</div>
|
2857
|
-
</div>
|
2858
|
-
<div style="font-weight: bold; margin:4px 2px 2px 2px">
|
2859
|
-
Mapping of nodes to link from/to:
|
2860
|
-
</div>
|
2861
2855
|
<div id="paste-scroll-area">
|
2862
2856
|
</div>
|
2863
2857
|
</div>
|
package/static/linny-r.css
CHANGED
@@ -346,6 +346,20 @@ div.contbtn {
|
|
346
346
|
cursor: pointer;
|
347
347
|
}
|
348
348
|
|
349
|
+
div.simbtn {
|
350
|
+
display: none;
|
351
|
+
margin-left: 5px;
|
352
|
+
}
|
353
|
+
|
354
|
+
img.sim {
|
355
|
+
height: 14px;
|
356
|
+
width: 14px;
|
357
|
+
}
|
358
|
+
|
359
|
+
img.sim.enab:hover {
|
360
|
+
background-color: #9e96e5;
|
361
|
+
}
|
362
|
+
|
349
363
|
input {
|
350
364
|
vertical-align: baseline;
|
351
365
|
}
|
@@ -508,6 +522,12 @@ div.notification-msg.first-msg {
|
|
508
522
|
color: black;
|
509
523
|
}
|
510
524
|
|
525
|
+
span.node-details {
|
526
|
+
font-style: italic;
|
527
|
+
color: Gray;
|
528
|
+
margin-left: 15px;
|
529
|
+
}
|
530
|
+
|
511
531
|
#issue-panel {
|
512
532
|
display: none;
|
513
533
|
background-color: Yellow;
|
@@ -2024,6 +2044,7 @@ div.io-box {
|
|
2024
2044
|
bottom: 2px;
|
2025
2045
|
left: 2px;
|
2026
2046
|
width: 40%;
|
2047
|
+
height: 59px;
|
2027
2048
|
}
|
2028
2049
|
|
2029
2050
|
#dataset-outcome {
|
@@ -2241,8 +2262,13 @@ td.equation-selector {
|
|
2241
2262
|
}
|
2242
2263
|
|
2243
2264
|
td.wildcard {
|
2265
|
+
color: #400080;
|
2266
|
+
}
|
2267
|
+
|
2268
|
+
span.wildcard {
|
2244
2269
|
font-weight: bold;
|
2245
|
-
|
2270
|
+
font-style: normal;
|
2271
|
+
color: #a00040;
|
2246
2272
|
}
|
2247
2273
|
|
2248
2274
|
td.dataset-expression,
|
@@ -4670,7 +4696,7 @@ div.docu-sym:hover {
|
|
4670
4696
|
|
4671
4697
|
/* the CALL STACK modal displays the VM call stack */
|
4672
4698
|
#call-stack-dlg {
|
4673
|
-
width:
|
4699
|
+
width: 320px;
|
4674
4700
|
height: 250px;
|
4675
4701
|
}
|
4676
4702
|
|
@@ -36,6 +36,7 @@ SOFTWARE.
|
|
36
36
|
class Controller {
|
37
37
|
constructor() {
|
38
38
|
this.console = true;
|
39
|
+
this.browser_name = '';
|
39
40
|
// Initialize *graphical* controller elements as non-existent
|
40
41
|
this.paper = null;
|
41
42
|
this.buttons = {};
|
@@ -68,7 +69,8 @@ class Controller {
|
|
68
69
|
this.ERROR = {
|
69
70
|
CREATE_FAILED: 'ERROR: failed to create a new SVG element',
|
70
71
|
APPEND_FAILED: 'ERROR: failed to append SVG element to DOM',
|
71
|
-
NO_DATASET_DOT: '"." only makes sense in dataset modifier expressions'
|
72
|
+
NO_DATASET_DOT: '"." only makes sense in dataset modifier expressions',
|
73
|
+
NO_NUMBER_CONTEXT: 'Number # is undefined in this context'
|
72
74
|
};
|
73
75
|
this.WARNING = {
|
74
76
|
NO_CONNECTION: 'No connection with server',
|
@@ -291,8 +293,8 @@ class Controller {
|
|
291
293
|
// Returns TRUE if `name` is a valid Linny-R entity name. These names
|
292
294
|
// must not be empty strings, may not contain brackets, backslashes or
|
293
295
|
// vertical bars, may not end with a colon, and must start with an
|
294
|
-
// underscore, a letter or a digit.
|
295
|
-
//
|
296
|
+
// underscore, a letter or a digit.
|
297
|
+
// These rules are enforced to avoid parsing issues with variable names.
|
296
298
|
// NOTE: normalize to also accept letters with accents
|
297
299
|
if(name === this.TOP_CLUSTER_NAME) return true;
|
298
300
|
name = name.normalize('NFKD').trim();
|
@@ -316,6 +318,14 @@ class Controller {
|
|
316
318
|
return pan;
|
317
319
|
}
|
318
320
|
|
321
|
+
completePrefix(name) {
|
322
|
+
// Returns the prefix part (including the final colon plus space),
|
323
|
+
// or the empty string if none.
|
324
|
+
const p = UI.prefixesAndName(name);
|
325
|
+
p[p.length - 1] = '';
|
326
|
+
return p.join(UI.PREFIXER);
|
327
|
+
}
|
328
|
+
|
319
329
|
sharedPrefix(n1, n2) {
|
320
330
|
const
|
321
331
|
pan1 = this.prefixesAndName(n1),
|
@@ -331,15 +341,37 @@ class Controller {
|
|
331
341
|
return shared.join(this.PREFIXER);
|
332
342
|
}
|
333
343
|
|
344
|
+
colonPrefixedName(name, prefix) {
|
345
|
+
// Replaces a leading colon in `name` by `prefix`.
|
346
|
+
// If `name` identifies a link or a constraint, this is applied to
|
347
|
+
// both node names.
|
348
|
+
const
|
349
|
+
arrow = (name.indexOf(this.LINK_ARROW) >= 0 ?
|
350
|
+
this.LINK_ARROW : this.CONSTRAINT_ARROW),
|
351
|
+
nodes = name.split(arrow);
|
352
|
+
for(let i = 0; i < nodes.length; i++) {
|
353
|
+
nodes[i] = nodes[i].replace(/^:\s*/, prefix);
|
354
|
+
}
|
355
|
+
return nodes.join(arrow);
|
356
|
+
}
|
357
|
+
|
334
358
|
nameToID(name) {
|
335
359
|
// Returns a name in lower case with link arrow replaced by three
|
336
360
|
// underscores, constraint link arrow by four underscores, and spaces
|
337
361
|
// converted to underscores; in this way, IDs will always be valid
|
338
|
-
// JavaScript object properties
|
339
|
-
// NOTE:
|
340
|
-
//
|
341
|
-
|
342
|
-
|
362
|
+
// JavaScript object properties.
|
363
|
+
// NOTE: Links and constraints are a special case, because their IDs
|
364
|
+
// depend on the *codes* of their nodes.
|
365
|
+
if(name.indexOf(UI.LINK_ARROW) >= 0 ||
|
366
|
+
name.indexOf(UI.CONSTRAINT_ARROW) >= 0) {
|
367
|
+
const obj = MODEL.objectByName(name);
|
368
|
+
if(obj) return obj.identifier;
|
369
|
+
// Empty string signals failure.
|
370
|
+
return '';
|
371
|
+
}
|
372
|
+
// NOTE: replace single quotes by Unicode apostrophe so that they
|
373
|
+
// cannot interfere with JavaScript strings delimited by single quotes.
|
374
|
+
return name.toLowerCase().replace(/\s/g, '_').replace("'", '\u2019');
|
343
375
|
}
|
344
376
|
|
345
377
|
htmlEquationName(n) {
|