linny-r 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -35
- package/package.json +1 -1
- package/server.js +114 -43
- package/static/images/octaeder.svg +993 -0
- package/static/index.html +22 -617
- package/static/linny-r.css +32 -378
- package/static/scripts/linny-r-ctrl.js +59 -5
- package/static/scripts/linny-r-gui.js +198 -56
- package/static/scripts/linny-r-model.js +127 -41
- package/static/scripts/linny-r-utils.js +32 -11
- package/static/scripts/linny-r-vm.js +40 -14
package/static/linny-r.css
CHANGED
@@ -288,6 +288,11 @@ img.blink {
|
|
288
288
|
animation: blink 1s step-start 0s infinite;
|
289
289
|
}
|
290
290
|
|
291
|
+
#stop-btn.blink {
|
292
|
+
cursor: default;
|
293
|
+
pointer-events: none;
|
294
|
+
}
|
295
|
+
|
291
296
|
img.mbtn {
|
292
297
|
width: 21px;
|
293
298
|
height: 21px;
|
@@ -346,20 +351,6 @@ div.contbtn {
|
|
346
351
|
cursor: pointer;
|
347
352
|
}
|
348
353
|
|
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
|
-
|
363
354
|
input {
|
364
355
|
vertical-align: baseline;
|
365
356
|
}
|
@@ -4283,6 +4274,17 @@ img.finder {
|
|
4283
4274
|
width: 50%;
|
4284
4275
|
}
|
4285
4276
|
|
4277
|
+
/* NOTE: Finder buttons are initially invisible */
|
4278
|
+
|
4279
|
+
#finder-edit-btn {
|
4280
|
+
position: absolute;
|
4281
|
+
height: 16px;
|
4282
|
+
width: 16px;
|
4283
|
+
bottom: 1px;
|
4284
|
+
right: calc(50% + 24px);
|
4285
|
+
display: none;
|
4286
|
+
}
|
4287
|
+
|
4286
4288
|
#finder-copy-btn {
|
4287
4289
|
position: absolute;
|
4288
4290
|
height: 16px;
|
@@ -4770,372 +4772,24 @@ div.call-stack-expr {
|
|
4770
4772
|
padding-bottom: 3px;
|
4771
4773
|
}
|
4772
4774
|
|
4773
|
-
/*
|
4774
|
-
|
4775
|
-
#fr00 {
|
4776
|
-
visibility: hidden;
|
4777
|
-
animation: 3s show infinite;
|
4778
|
-
animation-delay: 0.05s;
|
4779
|
-
}
|
4780
|
-
|
4781
|
-
#fr01 {
|
4782
|
-
visibility: hidden;
|
4783
|
-
animation: 3s show infinite;
|
4784
|
-
animation-delay: 0.1s;
|
4785
|
-
}
|
4786
|
-
|
4787
|
-
#fr02 {
|
4788
|
-
visibility: hidden;
|
4789
|
-
animation: 3s show infinite;
|
4790
|
-
animation-delay: 0.15s;
|
4791
|
-
}
|
4792
|
-
|
4793
|
-
#fr03 {
|
4794
|
-
visibility: hidden;
|
4795
|
-
animation: 3s show infinite;
|
4796
|
-
animation-delay: 0.2s;
|
4797
|
-
}
|
4775
|
+
/* The UPDATING modal notifies that update is in progress */
|
4798
4776
|
|
4799
|
-
#
|
4800
|
-
|
4801
|
-
|
4802
|
-
animation-delay: 0.25s;
|
4777
|
+
#updating-dlg {
|
4778
|
+
width: 325px;
|
4779
|
+
height: 85px;
|
4803
4780
|
}
|
4804
4781
|
|
4805
|
-
#
|
4806
|
-
|
4807
|
-
|
4808
|
-
|
4809
|
-
|
4810
|
-
|
4811
|
-
#fr06 {
|
4812
|
-
visibility: hidden;
|
4813
|
-
animation: 3s show infinite;
|
4814
|
-
animation-delay: 0.35s;
|
4815
|
-
}
|
4816
|
-
|
4817
|
-
#fr07 {
|
4818
|
-
visibility: hidden;
|
4819
|
-
animation: 3s show infinite;
|
4820
|
-
animation-delay: 0.4s;
|
4821
|
-
}
|
4822
|
-
|
4823
|
-
#fr08 {
|
4824
|
-
visibility: hidden;
|
4825
|
-
animation: 3s show infinite;
|
4826
|
-
animation-delay: 0.45s;
|
4827
|
-
}
|
4828
|
-
|
4829
|
-
#fr09 {
|
4830
|
-
visibility: hidden;
|
4831
|
-
animation: 3s show infinite;
|
4832
|
-
animation-delay: 0.5s;
|
4833
|
-
}
|
4834
|
-
|
4835
|
-
#fr10 {
|
4836
|
-
visibility: hidden;
|
4837
|
-
animation: 3s show infinite;
|
4838
|
-
animation-delay: 0.55s;
|
4839
|
-
}
|
4840
|
-
|
4841
|
-
#fr11 {
|
4842
|
-
visibility: hidden;
|
4843
|
-
animation: 3s show infinite;
|
4844
|
-
animation-delay: 0.6s;
|
4845
|
-
}
|
4846
|
-
|
4847
|
-
#fr12 {
|
4848
|
-
visibility: hidden;
|
4849
|
-
animation: 3s show infinite;
|
4850
|
-
animation-delay: 0.65s;
|
4851
|
-
}
|
4852
|
-
|
4853
|
-
#fr13 {
|
4854
|
-
visibility: hidden;
|
4855
|
-
animation: 3s show infinite;
|
4856
|
-
animation-delay: 0.7s;
|
4857
|
-
}
|
4858
|
-
|
4859
|
-
#fr14 {
|
4860
|
-
visibility: hidden;
|
4861
|
-
animation: 3s show infinite;
|
4862
|
-
animation-delay: 0.75s;
|
4863
|
-
}
|
4864
|
-
|
4865
|
-
#fr15 {
|
4866
|
-
visibility: hidden;
|
4867
|
-
animation: 3s show infinite;
|
4868
|
-
animation-delay: 0.8s;
|
4869
|
-
}
|
4870
|
-
|
4871
|
-
#fr16 {
|
4872
|
-
visibility: hidden;
|
4873
|
-
animation: 3s show infinite;
|
4874
|
-
animation-delay: 0.85s;
|
4875
|
-
}
|
4876
|
-
|
4877
|
-
#fr17 {
|
4878
|
-
visibility: hidden;
|
4879
|
-
animation: 3s show infinite;
|
4880
|
-
animation-delay: 0.9s;
|
4881
|
-
}
|
4882
|
-
|
4883
|
-
#fr18 {
|
4884
|
-
visibility: hidden;
|
4885
|
-
animation: 3s show infinite;
|
4886
|
-
animation-delay: 0.95s;
|
4887
|
-
}
|
4888
|
-
|
4889
|
-
#fr19 {
|
4890
|
-
visibility: hidden;
|
4891
|
-
animation: 3s show infinite;
|
4892
|
-
animation-delay: 1s;
|
4893
|
-
}
|
4894
|
-
|
4895
|
-
#fr20 {
|
4896
|
-
visibility: hidden;
|
4897
|
-
animation: 3s show infinite;
|
4898
|
-
animation-delay: 1.05s;
|
4899
|
-
}
|
4900
|
-
|
4901
|
-
#fr21 {
|
4902
|
-
visibility: hidden;
|
4903
|
-
animation: 3s show infinite;
|
4904
|
-
animation-delay: 1.1s;
|
4905
|
-
}
|
4906
|
-
|
4907
|
-
#fr22 {
|
4908
|
-
visibility: hidden;
|
4909
|
-
animation: 3s show infinite;
|
4910
|
-
animation-delay: 1.15s;
|
4911
|
-
}
|
4912
|
-
|
4913
|
-
#fr23 {
|
4914
|
-
visibility: hidden;
|
4915
|
-
animation: 3s show infinite;
|
4916
|
-
animation-delay: 1.2s;
|
4917
|
-
}
|
4918
|
-
|
4919
|
-
#fr24 {
|
4920
|
-
visibility: hidden;
|
4921
|
-
animation: 3s show infinite;
|
4922
|
-
animation-delay: 1.25s;
|
4923
|
-
}
|
4924
|
-
|
4925
|
-
#fr25 {
|
4926
|
-
visibility: hidden;
|
4927
|
-
animation: 3s show infinite;
|
4928
|
-
animation-delay: 1.3s;
|
4929
|
-
}
|
4930
|
-
|
4931
|
-
#fr26 {
|
4932
|
-
visibility: hidden;
|
4933
|
-
animation: 3s show infinite;
|
4934
|
-
animation-delay: 1.35s;
|
4935
|
-
}
|
4936
|
-
|
4937
|
-
#fr27 {
|
4938
|
-
visibility: hidden;
|
4939
|
-
animation: 3s show infinite;
|
4940
|
-
animation-delay: 1.4s;
|
4941
|
-
}
|
4942
|
-
|
4943
|
-
#fr28 {
|
4944
|
-
visibility: hidden;
|
4945
|
-
animation: 3s show infinite;
|
4946
|
-
animation-delay: 1.45s;
|
4947
|
-
}
|
4948
|
-
|
4949
|
-
#fr29 {
|
4950
|
-
visibility: hidden;
|
4951
|
-
animation: 3s show infinite;
|
4952
|
-
animation-delay: 1.5s;
|
4953
|
-
}
|
4954
|
-
|
4955
|
-
#fr30 {
|
4956
|
-
visibility: hidden;
|
4957
|
-
animation: 3s show infinite;
|
4958
|
-
animation-delay: 1.55s;
|
4959
|
-
}
|
4960
|
-
|
4961
|
-
#fr31 {
|
4962
|
-
visibility: hidden;
|
4963
|
-
animation: 3s show infinite;
|
4964
|
-
animation-delay: 1.6s;
|
4965
|
-
}
|
4966
|
-
|
4967
|
-
#fr32 {
|
4968
|
-
visibility: hidden;
|
4969
|
-
animation: 3s show infinite;
|
4970
|
-
animation-delay: 1.65s;
|
4971
|
-
}
|
4972
|
-
|
4973
|
-
#fr33 {
|
4974
|
-
visibility: hidden;
|
4975
|
-
animation: 3s show infinite;
|
4976
|
-
animation-delay: 1.7s;
|
4977
|
-
}
|
4978
|
-
|
4979
|
-
#fr34 {
|
4980
|
-
visibility: hidden;
|
4981
|
-
animation: 3s show infinite;
|
4982
|
-
animation-delay: 1.75s;
|
4983
|
-
}
|
4984
|
-
|
4985
|
-
#fr35 {
|
4986
|
-
visibility: hidden;
|
4987
|
-
animation: 3s show infinite;
|
4988
|
-
animation-delay: 1.8s;
|
4989
|
-
}
|
4990
|
-
|
4991
|
-
#fr36 {
|
4992
|
-
visibility: hidden;
|
4993
|
-
animation: 3s show infinite;
|
4994
|
-
animation-delay: 1.85s;
|
4995
|
-
}
|
4996
|
-
|
4997
|
-
#fr37 {
|
4998
|
-
visibility: hidden;
|
4999
|
-
animation: 3s show infinite;
|
5000
|
-
animation-delay: 1.9s;
|
5001
|
-
}
|
5002
|
-
|
5003
|
-
#fr38 {
|
5004
|
-
visibility: hidden;
|
5005
|
-
animation: 3s show infinite;
|
5006
|
-
animation-delay: 1.95s;
|
5007
|
-
}
|
5008
|
-
|
5009
|
-
#fr39 {
|
5010
|
-
visibility: hidden;
|
5011
|
-
animation: 3s show infinite;
|
5012
|
-
animation-delay: 2s;
|
5013
|
-
}
|
5014
|
-
|
5015
|
-
#fr40 {
|
5016
|
-
visibility: hidden;
|
5017
|
-
animation: 3s show infinite;
|
5018
|
-
animation-delay: 2.05s;
|
5019
|
-
}
|
5020
|
-
|
5021
|
-
#fr41 {
|
5022
|
-
visibility: hidden;
|
5023
|
-
animation: 3s show infinite;
|
5024
|
-
animation-delay: 2.1s;
|
5025
|
-
}
|
5026
|
-
|
5027
|
-
#fr42 {
|
5028
|
-
visibility: hidden;
|
5029
|
-
animation: 3s show infinite;
|
5030
|
-
animation-delay: 2.15s;
|
5031
|
-
}
|
5032
|
-
|
5033
|
-
#fr43 {
|
5034
|
-
visibility: hidden;
|
5035
|
-
animation: 3s show infinite;
|
5036
|
-
animation-delay: 2.2s;
|
5037
|
-
}
|
5038
|
-
|
5039
|
-
#fr44 {
|
5040
|
-
visibility: hidden;
|
5041
|
-
animation: 3s show infinite;
|
5042
|
-
animation-delay: 2.25s;
|
5043
|
-
}
|
5044
|
-
|
5045
|
-
#fr45 {
|
5046
|
-
visibility: hidden;
|
5047
|
-
animation: 3s show infinite;
|
5048
|
-
animation-delay: 2.3s;
|
5049
|
-
}
|
5050
|
-
|
5051
|
-
#fr46 {
|
5052
|
-
visibility: hidden;
|
5053
|
-
animation: 3s show infinite;
|
5054
|
-
animation-delay: 2.35s;
|
5055
|
-
}
|
5056
|
-
|
5057
|
-
#fr47 {
|
5058
|
-
visibility: hidden;
|
5059
|
-
animation: 3s show infinite;
|
5060
|
-
animation-delay: 2.4s;
|
5061
|
-
}
|
5062
|
-
|
5063
|
-
#fr48 {
|
5064
|
-
visibility: hidden;
|
5065
|
-
animation: 3s show infinite;
|
5066
|
-
animation-delay: 2.45s;
|
5067
|
-
}
|
5068
|
-
|
5069
|
-
#fr49 {
|
5070
|
-
visibility: hidden;
|
5071
|
-
animation: 3s show infinite;
|
5072
|
-
animation-delay: 2.5s;
|
5073
|
-
}
|
5074
|
-
|
5075
|
-
#fr50 {
|
5076
|
-
visibility: hidden;
|
5077
|
-
animation: 3s show infinite;
|
5078
|
-
animation-delay: 2.55s;
|
5079
|
-
}
|
5080
|
-
|
5081
|
-
#fr51 {
|
5082
|
-
visibility: hidden;
|
5083
|
-
animation: 3s show infinite;
|
5084
|
-
animation-delay: 2.6s;
|
5085
|
-
}
|
5086
|
-
|
5087
|
-
#fr52 {
|
5088
|
-
visibility: hidden;
|
5089
|
-
animation: 3s show infinite;
|
5090
|
-
animation-delay: 2.65s;
|
5091
|
-
}
|
5092
|
-
|
5093
|
-
#fr53 {
|
5094
|
-
visibility: hidden;
|
5095
|
-
animation: 3s show infinite;
|
5096
|
-
animation-delay: 2.7s;
|
5097
|
-
}
|
5098
|
-
|
5099
|
-
#fr54 {
|
5100
|
-
visibility: hidden;
|
5101
|
-
animation: 3s show infinite;
|
5102
|
-
animation-delay: 2.75s;
|
5103
|
-
}
|
5104
|
-
|
5105
|
-
#fr55 {
|
5106
|
-
visibility: hidden;
|
5107
|
-
animation: 3s show infinite;
|
5108
|
-
animation-delay: 2.8s;
|
5109
|
-
}
|
5110
|
-
|
5111
|
-
#fr56 {
|
5112
|
-
visibility: hidden;
|
5113
|
-
animation: 3s show infinite;
|
5114
|
-
animation-delay: 2.85s;
|
5115
|
-
}
|
5116
|
-
|
5117
|
-
#fr57 {
|
5118
|
-
visibility: hidden;
|
5119
|
-
animation: 3s show infinite;
|
5120
|
-
animation-delay: 2.9s;
|
5121
|
-
}
|
5122
|
-
|
5123
|
-
#fr58 {
|
5124
|
-
visibility: hidden;
|
5125
|
-
animation: 3s show infinite;
|
5126
|
-
animation-delay: 2.95s;
|
5127
|
-
}
|
5128
|
-
|
5129
|
-
#fr59 {
|
5130
|
-
visibility: hidden;
|
5131
|
-
animation: 3s show infinite;
|
5132
|
-
animation-delay: 3s;
|
5133
|
-
}
|
5134
|
-
|
5135
|
-
@keyframes show {
|
5136
|
-
0% { visibility: visible;}
|
5137
|
-
1.666% { visibility: visible; }
|
5138
|
-
1.667% { visibility: hidden; }
|
5139
|
-
100% { visibility: hidden; }
|
4782
|
+
#updating-msg {
|
4783
|
+
position: absolute;
|
4784
|
+
top: 29px;
|
4785
|
+
left: 68px;
|
4786
|
+
font-size: 13px;
|
5140
4787
|
}
|
5141
4788
|
|
4789
|
+
#updating-icon {
|
4790
|
+
position: absolute;
|
4791
|
+
top: 26px;
|
4792
|
+
left: 7px;
|
4793
|
+
width: 60px;
|
4794
|
+
height: 60px;
|
4795
|
+
}
|
@@ -302,14 +302,20 @@ class Controller {
|
|
302
302
|
(name.startsWith(this.BLACK_BOX) || name[0].match(/[\w]/));
|
303
303
|
}
|
304
304
|
|
305
|
-
prefixesAndName(name) {
|
305
|
+
prefixesAndName(name, key=false) {
|
306
306
|
// Returns name split exclusively at '[non-space]: [non-space]'
|
307
|
+
let sep = this.PREFIXER,
|
308
|
+
space = ' ';
|
309
|
+
if(key) {
|
310
|
+
sep = ':_';
|
311
|
+
space = '_';
|
312
|
+
}
|
307
313
|
const
|
308
|
-
s = name.split(
|
314
|
+
s = name.split(sep),
|
309
315
|
pan = [s[0]];
|
310
316
|
for(let i = 1; i < s.length; i++) {
|
311
317
|
const j = pan.length - 1;
|
312
|
-
if(s[i].startsWith(
|
318
|
+
if(s[i].startsWith(space) || (i > 0 && pan[j].endsWith(space))) {
|
313
319
|
pan[j] += s[i];
|
314
320
|
} else {
|
315
321
|
pan.push(s[i]);
|
@@ -350,14 +356,20 @@ class Controller {
|
|
350
356
|
this.LINK_ARROW : this.CONSTRAINT_ARROW),
|
351
357
|
nodes = name.split(arrow);
|
352
358
|
for(let i = 0; i < nodes.length; i++) {
|
353
|
-
nodes[i] = nodes[i].replace(/^:\s*/, prefix)
|
359
|
+
nodes[i] = nodes[i].replace(/^:\s*/, prefix)
|
360
|
+
// NOTE: An embedded double prefix, e.g., "xxx: : yyy" indicates
|
361
|
+
// that the second colon+space should be replaced by the prefix.
|
362
|
+
// This "double prefix" may occur only once in an entity name,
|
363
|
+
// hence no global regexp.
|
364
|
+
.replace(/(\w+):\s+:\s+(\w+)/, `$1: ${prefix}$2`);
|
354
365
|
}
|
355
366
|
return nodes.join(arrow);
|
356
367
|
}
|
357
368
|
|
358
369
|
tailNumber(name) {
|
359
370
|
// Returns the string of digits at the end of `name`. If not there,
|
360
|
-
// check prefixes (if any) from right to left for a tail number.
|
371
|
+
// check prefixes (if any) *from right to left* for a tail number.
|
372
|
+
// Thus, the number that is "closest" to the name part is returned.
|
361
373
|
const pan = UI.prefixesAndName(name);
|
362
374
|
let n = endsWithDigits(pan.pop());
|
363
375
|
while(!n && pan.length > 0) {
|
@@ -366,6 +378,48 @@ class Controller {
|
|
366
378
|
return n;
|
367
379
|
}
|
368
380
|
|
381
|
+
compareFullNames(n1, n2, key=false) {
|
382
|
+
// Compare full names, considering prefixes in *left-to-right* order
|
383
|
+
// while taking into account the tailnumber for each part so that
|
384
|
+
// "xx: yy2: nnn" comes before "xx: yy10: nnn".
|
385
|
+
if(n1 === n2) return 0;
|
386
|
+
if(key) {
|
387
|
+
// NOTE: Replacing link and constraint arrows by two prefixers
|
388
|
+
// ensures that sort wil be first on FROM node, and then on TO node.
|
389
|
+
const p2 = UI.PREFIXER + UI.PREFIXER;
|
390
|
+
// Keys for links and constraints are not based on their names,
|
391
|
+
// so look up their names before comparing.
|
392
|
+
if(n1.indexOf('____') > 0 && MODEL.constraints[n1]) {
|
393
|
+
n1 = MODEL.constraints[n1].displayName
|
394
|
+
.replace(UI.CONSTRAINT_ARROW, p2);
|
395
|
+
} else if(n1.indexOf('___') > 0 && MODEL.links[n1]) {
|
396
|
+
n1 = MODEL.links[n1].displayName
|
397
|
+
.replace(UI.LINK_ARROW, p2);
|
398
|
+
}
|
399
|
+
if(n2.indexOf('____') > 0 && MODEL.constraints[n2]) {
|
400
|
+
n2 = MODEL.constraints[n2].displayName.
|
401
|
+
replace(UI.CONSTRAINT_ARROW, p2);
|
402
|
+
} else if(n2.indexOf('___') > 0 && MODEL.links[n2]) {
|
403
|
+
n2 = MODEL.links[n2].displayName
|
404
|
+
.replace(UI.LINK_ARROW, p2);
|
405
|
+
}
|
406
|
+
n1 = n1.toLowerCase().replaceAll(' ', '_');
|
407
|
+
n2 = n2.toLowerCase().replaceAll(' ', '_');
|
408
|
+
}
|
409
|
+
const
|
410
|
+
pan1 = UI.prefixesAndName(n1, key),
|
411
|
+
pan2 = UI.prefixesAndName(n2, key),
|
412
|
+
sl = Math.min(pan1.length, pan2.length);
|
413
|
+
let i = 0;
|
414
|
+
while(i < sl) {
|
415
|
+
const c = compareWithTailNumbers(pan1[i], pan2[i]);
|
416
|
+
if(c !== 0) return c;
|
417
|
+
i++;
|
418
|
+
}
|
419
|
+
return pan1.length - pan2.length;
|
420
|
+
}
|
421
|
+
|
422
|
+
|
369
423
|
nameToID(name) {
|
370
424
|
// Returns a name in lower case with link arrow replaced by three
|
371
425
|
// underscores, constraint link arrow by four underscores, and spaces
|