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.
@@ -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
- /* Linny-R logo icon animation in 60 frames */
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
- #fr04 {
4800
- visibility: hidden;
4801
- animation: 3s show infinite;
4802
- animation-delay: 0.25s;
4777
+ #updating-dlg {
4778
+ width: 325px;
4779
+ height: 85px;
4803
4780
  }
4804
4781
 
4805
- #fr05 {
4806
- visibility: hidden;
4807
- animation: 3s show infinite;
4808
- animation-delay: 0.3s;
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(this.PREFIXER),
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(' ') || (i > 0 && pan[j].endsWith(' '))) {
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