forked from niyeradori/QuickSmith-Web
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.js
726 lines (645 loc) · 21.4 KB
/
common.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
// the main data structure in a centralized place so that all pages can access it.
function copy_schObj(schObj1) {
var ELEMENT_SRC = schObj1.ELEMENT;
var ELEMENT_DEST = schObj.ELEMENT;
for (var key in schObj1)
{
if (schObj1.hasOwnProperty(key))
{
if(key !== "ELEMENT")
{
schObj[key] = schObj1[key];
// console.log(key + " -> " + schObj[key]);
}
else
{
// console.log("SCHOBJ ELEMENT" );
for (var key2 in ELEMENT_SRC)
{
var item1 = ELEMENT_SRC[key2];
var item = ELEMENT_DEST[key2];
for (var key3 in item1)
{
// console.log(key3 + " -> " + item1[key3]);
item[key3] = item1[key3];
}
}
}
}
}
}
function copy_smithObj(smithObj1) {
for (var key in smithObj1)
{
if (smithObj1.hasOwnProperty(key))
{
//if(key !== "sweepDatasets" || key !== "plotDatasets")
{
if(key !== "ctx") {
smithObj[key] = smithObj1[key];
//console.log(key + " -> " + smithObj[key]);
}
}
// else if (key == "sweepDatasets")
// {
// // console.log("SMITHOBJ sweepDatasets" );
// var data1 = smithObj1.sweepDatasets;
// var data = smithObj.sweepDatasets;
// for (var key2 in data1)
// {
// // console.log(key2 + " -> " + data1[key2]);
// var item1 = data1[key2];
// var item = data[key2];
// for (var key3 in item1)
// {
// console.log(key3 + " -> " + item1[key3]);
// item[key3] = item1[key3];
// }
// }
// }
// else if (key == "plotDatasets")
// {
// // console.log("SMITHOBJ sweepDatasets" );
// var data1A = smithObj1.plotDatasets;
// var dataA = smithObj.plotDatasets;
// for (var key4 in data1A)
// {
// // console.log(key2 + " -> " + data1[key2]);
// var item1A = data1A[key4];
// var itemA = dataA[key4];
// for (var key5 in item1A)
// {
// console.log(key5 + " -> " + item1A[key5]);
// itemA[key5] = item1A[key5];
// }
// }
// }
}
}
}
function AddIm(a, B, C, D) {
var ret = math.add(B,D);
return ret;
}
function AddRe(a, B, C, D) {
var ret = math.add(a,C);
return ret;
}
// function AmpGTOZI(R, Q, Z00) {
// var tmp; var ret
// tmp = (2 * R * Sin(pi * Q / 180)) / (1 + (R * R) - 2 * R * Cos(pi * Q / 180))
// ret = tmp * Z00;
// return ret;
// }
// function AmpGTOZR(R, Q, Z00) As Single
// var tmp; var ret;
// tmp = (1 - (R * R)) / (1 + (R * R) - (2 * R * Cos(Q * pi / 180)))
// ret = tmp * Z00;
// return ret;
// }
function GToZI(R, Q ){
var Z0 = schObj.Z0;
var Z1i = (2 * R * math.sin(Math.PI * Q / 180)) / (1 + (R * R) - 2 * R * math.cos(Math.PI * Q / 180));
return( Z1i * Z0);
}
function GToZR(R , Q ){
var Z0 = schObj.Z0;
var Z1r = (1 - (R * R)) / (1 + (R * R) - (2 * R * math.cos(Q * Math.PI / 180)));
return( Z1r * Z0);
}
function GToZIZ(R, Q, Z0 ){
// var Z0 = schObj.Z0;
var Z1i = (2 * R * math.sin(Math.PI * Q / 180)) / (1 + (R * R) - 2 * R * math.cos(Math.PI * Q / 180));
return( Z1i * Z0);
}
function GToZRZ(R , Q, Z0 ){
//var Z0 = schObj.Z0;
var Z1r = (1 - (R * R)) / (1 + (R * R) - (2 * R * math.cos(Q * Math.PI / 180)));
return( Z1r * Z0);
}
function DivIm(a, B, C, D) {
//(A+ Bj)/(C+ dj)
var DivIm = ((B * C) - (a * D)) / (C * C + D * D);
return DivIm;
}
function DivRe(a, B, C, D) {
// '(A+ Bj)/(C+ dj)
var DivRe = ((a * C) + (B * D)) / (C * C + D* D);
return DivRe;
}
function MulIm(a, B, C, D) {
// (A+Bj)* (C+Dj)
var MulIm = (a * D) + (B * C);
return MulIm;
}
function MulRe(a, B, C, D) {
// (A+Bj)* (C+Dj)
var MulRe = (a * C) - (B * D);
return MulRe;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function isEven(n) {
return n == parseFloat(n) ? (n % 2)===0 : void 0;
}
String.prototype.replaceAt = function (index, replacement) {
return this.substr(0, index) + replacement + this.substr(index + replacement.length);
};
/**
* Helper function to output a value in the console. Value will be formatted.
* @param {*} value
*/
function print(value) {
var precision = 16;
console.log(math.format(value, precision));
}
function getUnits(elementType) {
var units = "None";
switch (elementType) {
case "g":
units = "Magnitude/Degrees";
break;
case "r":
case "x":
units = "Ohms";
break;
case "c":
units = "pF";
break;
case "l":
units = "nH";
break;
case "t":
case "o":
case "s":
units = "Inches/MM/Deg./Wave Lengths";
break;
case "w":
units = "None";
break;
case "src":
case "prc":
units = "Ohms/pF";
break;
case "plc":
case "slc":
units = "nF/pF";
break;
default:
units = "None";
}
return units;
}
function getSign(n){
var sign = Math.sign(n);
var sign_txt;
if(sign == -1) sign_txt = " - " ;
else sign_txt = " + ";
return sign_txt;
}
function ZtoGammaA(ZXR, ZXI) {
var ZRN, ZIN, a1, a2, D, SR, SI, SM, SQ;
var Z0 = schObj.Z0;
ZRN = (ZXR / Z0);
ZIN = (ZXI / Z0);
a1 = ZRN - 1;
a2 = ZRN + 1;
D = Math.pow(a2, 2) + Math.pow(ZIN, 2);
SR = ((ZRN * ZRN) - 1 + (ZIN * ZIN)) / D;
SI = (2 * ZIN) / D;
SM = Math.sqrt(SR * SR + SI * SI);
if(SI == 0) SI = 0.00000000000001;
if(SR == 0) SR = 0.00000000000001;
SQ = (Math.atan(SI / SR) * 180 / Math.PI);
if(SR < 0 && SI > 0) SQ = 180 + SQ;
if (SR < 0 && SI < 0) SQ = -180 + SQ;
if(SM == 0) SQ = 0;
return SQ;
}
function ZtoGammaM(ZXR, ZXI) {
var ZRN, ZIN, a1, a2, D, SR, SI, SM, SQ;
var Z0 = schObj.Z0;
ZRN = (ZXR / Z0);
ZIN = (ZXI / Z0);
a1 = ZRN - 1;
a2 = ZRN + 1;
D = a2 * a2 + ZIN * ZIN;
SR = (ZRN * ZRN - 1 + ZIN * ZIN) / D;
SI = (2 * ZIN) / D;
return Math.sqrt(SR * SR + SI * SI);
}
//Below is a simple jQuery plugin to catch a long click or long press:
(function ($) {
$.fn.longClick = function (callback, timeout) {
// bind to element's mousedown event to track the longclick's beginning
$(this).mousedown(function (event) {
// save the initial event object
var initialEvent = event;
// set the delay after which the callback will be called
var timer = window.setTimeout(function () { callback(initialEvent); }, timeout);
// bind to global mouseup event for clearance
$(document).mouseup(function () {
// clear timer
window.clearTimeout(timer);
// unbind from global mouseup event
$(document).unbind("mouseup");
return true;
// use 'return false;' if you need to prevent default handler and
// stop event bubbling
});
return true;
// use 'return false;' if you need to prevent default handler and
// stop event bubbling
});
};
})(jQuery);
// usage
// (function ($) {
// $("#someDiv").longClick(function (e) {
// alert($(e.target).attr("id") + " was clicked"); },
// 1500);
// })(jQuery);
//jQuery plugin to catch a taphold event
(function ($) {
$.fn.taphold = function (callback, timeout) {
// bind to element's touchstart event to track the taphold's beginning
$(this).bind("touchstart", function (event) {
// save the initial event object
var initialEvent = event;
// set the delay after which the callback will be called
var timer = window.setTimeout(function () { callback(initialEvent); }, timeout);
// bind to global touchend and touchcancel events for clearance
$(document).bind("touchend touchcancel", function () {
// clear timer
window.clearTimeout(timer);
// unbind from touchend and touchcancel events
$(document).unbind("touchend touchcancel");
return true;
// use 'return false;' if you need to prevent default handler and
// stop event bubbling
});
return true;
// use 'return false;' if you need to prevent default handler and
// stop event bubbling
});
};
})(jQuery);
//usage
// (function ($) {
// $("#someDiv").taphold(function () {
// alert($(e.target).attr("id") + " was tapholded"); },
// 1500);
// })(jQuery);
//Combined jQuery plugin to catch both long click and taphold events
(function ($) {
$.fn.longclick = function (callback, timeout) {
var isIPad = $.isIPad();
var startEvents = isIPad ? "touchstart" : "mousedown";
var endEvents = isIPad ? "touchend touchcancel" : "mouseup";
$(this).bind(startEvents, function (event) {
// save the initial event object
var initialEvent = event;
// set delay after which the callback will be called
var timer = window.setTimeout(function () { callback(initialEvent); }, timeout);
// bind to global event(s) for clearance
$(document).bind(endEvents, function () {
// clear timer
window.clearTimeout(timer);
// reset global event handlers
$(document).unbind(endEvents);
return true;
// use 'return false;' if you need to prevent default handler and
// stop event bubbling
});
return true;
// use 'return false;' if you need to prevent default handler and
// stop event bubbling
});
};
})(jQuery);
// usage
// (function ($) {
// $("#someDiv").longclick(function () {
// alert($(e.target).attr("id") + " was clicked"); },
// 1500);
// })(jQuery);
// similar to String.IsNullOrEmpty
(function ($) {
$.isNullOrEmpty = function (str) {
return !str || $.trim(str) === ""; // the trim method is provided by jQuery
};
})(jQuery);
//usage
// var res = $.isNullOrEmpty(''); // true
// res = $.isNullOrEmpty("bla-bla-bla"); // false
// res = $.isNullOrEmpty(null); // true
// res = $.isNullOrEmpty(); // true
//Below is a simple jQuery plugin to detect whether a page is opened in an iPad:
(function ($) {
$.isIPad = function () {
return (typeof navigator != "undefined" &&
navigator && navigator.userAgent &&
navigator.userAgent.match(/iPad/i) != null);
};
})(jQuery);
// usage
// $(function(){
// if($.isIPad())
// alert('Hello, iPad');
// });
//The next plugin allows to detect an iPhone:
(function ($) {
$.isIPhone = function () {
if(!$.isIPad())
return (typeof navigator != "undefined" &&
navigator && navigator.userAgent &&
(navigator.userAgent.match(/iPhone/i) != null ||
navigator.userAgent.match(/iPod/i) != null));
return false;
};
})(jQuery);
//usage
// $(function(){
// if($.isIPhone())
// alert('Hello, iPhone');
// });
//To detect any Apple mobile devices (iPad, iPhone or iPod) you can use the following jQuery plugin:
(function ($) {
$.isAppleMobile = function () {
return (typeof navigator != "undefined" &&
navigator && navigator.userAgent &&
navigator.userAgent.match(/(iPad|iPhone|iPod)/i) != null);
};
})(jQuery);
// usage
// $(function(){
// if($.isAppleMobile())
// alert('Hello, Apple device');
// });
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
function disableScroll() {
// if (window.addEventListener) // older FF
// window.addEventListener('DOMMouseScroll', preventDefault, false);
// window.onwheel = preventDefault; // modern standard
// window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
// document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll() {
//if (window.removeEventListener)
// window.removeEventListener('DOMMouseScroll', preventDefault, false);
// window.onmousewheel = document.onmousewheel = null;
// window.onwheel = null;
window.ontouchmove = null;
// document.onkeydown = null;
}
function ShowMessage(title,msg) {
// var msg0 = " ZIN : " + Number(resultsObj.OUTPUT[0].ZRout).toFixed(3) + " + " + Number(resultsObj.OUTPUT[0].ZIout).toFixed(3) + "j" + " " + Number(resultsObj.OUTPUT[0].MAGout).toFixed(3) + " < " + Number(resultsObj.OUTPUT[0].ANGout).toFixed(3) + "\n" ;
BootstrapDialog.show({
//size: BootstrapDialog.SIZE_SMALL,
title: title,
message: msg,
buttons: [{
label: 'Close',
action: function(dialog) {
dialog.close();
}
}]
});
}
function ShowMessage_sm(title,msg) {
// var msg0 = " ZIN : " + Number(resultsObj.OUTPUT[0].ZRout).toFixed(3) + " + " + Number(resultsObj.OUTPUT[0].ZIout).toFixed(3) + "j" + " " + Number(resultsObj.OUTPUT[0].MAGout).toFixed(3) + " < " + Number(resultsObj.OUTPUT[0].ANGout).toFixed(3) + "\n" ;
BootstrapDialog.show({
size: BootstrapDialog.SIZE_SMALL,
title: title,
message: msg,
buttons: [{
label: 'Close',
action: function(dialog) {
dialog.close();
}
}]
});
}
function updateStepSize_prompt(current_val,element)
{
bootbox.prompt({
size: "small",
title: "Enter Step Size",
inputType: "text",
value: current_val,
callback: function(result) {
if (typeof result !== "undefined" && result !== null && isNumeric(result)) {
$(element).trigger("touchspin.updatesettings", { step: result });
}
}
});
}
/* Monotone cubic spline interpolation
Usage example:
var f = createInterpolant([0, 1, 2, 3, 4], [0, 1, 4, 9, 16]);
var message = '';
for (var x = 0; x <= 4; x += 0.5) {
var xSquared = f(x);
message += x + ' squared is about ' + xSquared + '\n';
}
alert(message);
*/
var createInterpolant = function(xs, ys) {
var i, length = xs.length;
// Deal with length issues
if (length != ys.length) { throw 'Need an equal count of xs and ys.'; }
if (length === 0) { return function(x) { return 0; }; }
if (length === 1) {
// Impl: Precomputing the result prevents problems if ys is mutated later and allows garbage collection of ys
// Impl: Unary plus properly converts values to numbers
var result = +ys[0];
return function(x) { return result; };
}
// Rearrange xs and ys so that xs is sorted
var indexes = [];
for (i = 0; i < length; i++) { indexes.push(i); }
indexes.sort(function(a, b) { return xs[a] < xs[b] ? -1 : 1; });
var oldXs = xs, oldYs = ys;
// Impl: Creating new arrays also prevents problems if the input arrays are mutated later
xs = []; ys = [];
// Impl: Unary plus properly converts values to numbers
for (i = 0; i < length; i++) { xs.push(+oldXs[indexes[i]]); ys.push(+oldYs[indexes[i]]); }
// Get consecutive differences and slopes
var dys = [], dxs = [], ms = [];
for (i = 0; i < length - 1; i++) {
var dx = xs[i + 1] - xs[i], dy = ys[i + 1] - ys[i];
dxs.push(dx); dys.push(dy); ms.push(dy/dx);
}
// Get degree-1 coefficients
var c1s = [ms[0]];
for (i = 0; i < dxs.length - 1; i++) {
var m = ms[i], mNext = ms[i + 1];
if (m*mNext <= 0) {
c1s.push(0);
} else {
var dx_ = dxs[i], dxNext = dxs[i + 1], common = dx_ + dxNext;
c1s.push(3*common/((common + dxNext)/m + (common + dx_)/mNext));
}
}
c1s.push(ms[ms.length - 1]);
// Get degree-2 and degree-3 coefficients
var c2s = [], c3s = [];
for (i = 0; i < c1s.length - 1; i++) {
var c1 = c1s[i], m_ = ms[i], invDx = 1/dxs[i], common_ = c1 + c1s[i + 1] - m_ - m_;
c2s.push((m_ - c1 - common_)*invDx); c3s.push(common_*invDx*invDx);
}
// Return interpolant function
return function(x) {
// The rightmost point in the dataset should give an exact result
var i = xs.length - 1;
if (x == xs[i]) { return ys[i]; }
// Search for the interval x is in, returning the corresponding y if x is one of the original xs
var low = 0, mid, high = c3s.length - 1;
while (low <= high) {
mid = Math.floor(0.5*(low + high));
var xHere = xs[mid];
if (xHere < x) { low = mid + 1; }
else if (xHere > x) { high = mid - 1; }
else { return ys[mid]; }
}
i = Math.max(0, high);
// Interpolate
var diff = x - xs[i], diffSq = diff*diff;
return ys[i] + c1s[i]*diff + c2s[i]*diffSq + c3s[i]*diff*diffSq;
};
};
function phase_unwrap(ys)
{
var length = ys.length; var i;
var xs = [];
if (length === 0) { return ys; }
var prevphase = 0;
var phase;
var offset = 0;
for (i = 0; i < length; i++)
{
phase = ys[i];
if (Math.abs(phase - prevphase) > 180) offset = offset - 360 * Math.sign(phase - prevphase);
prevphase = phase;
xs[i] = phase + offset;
}
// Do While Not EOF(1)
// Input #1, Filedata0, Filedata1, Filedata2
// If (Filedata0 <> 0) Then
// n = n + 1
// If gmah = 1 Then Filedata0 = Filedata0 / 1000000#
// xatemp(n) = Filedata0 'freq
// y1atemp(n) = Filedata1 ' mag
// 'y2atemp(n) = filedata2 ' phase
// ' code written to unwrap phase
// phase = Filedata2
// If (Abs(phase - prevphase) > 180) Then offset = offset - 360 * Sgn(phase - prevphase)
// prevphase = phase
// y2atemp(n) = phase + offset
// End If
// If (n > 1000) Then Exit Do
// Loop
return xs;
}
// var saveJSONtoFile = (function () {
// var a = document.createElement("a");
// document.body.appendChild(a);
// a.style = "display: none";
// return function (data, fileName) {
// var json = JSON.stringify(data),
// blob = new Blob([json], {type: "octet/stream"}),
// url = window.URL.createObjectURL(blob);
// a.href = url;
// a.download = fileName;
// a.click();
// window.URL.revokeObjectURL(url);
// };
// }());
// for Safari compatibility
// Safari 6.1+
// Blobs may be opened instead of saved sometimes—you may have to direct your Safari users to
// manually press ⌘+S to save the file in "Page Source" Format after it is opened. Using the application/octet-stream
// MIME type to force downloads can cause issues in Safari.
function saveJSONtoFile(data,fileName){
//var FileSaver = require('file-saver');
var json = JSON.stringify(data, null, "\t"); // beautified JSON
var blob = new Blob([json], {type: "text/plain;charset=utf-8"});
saveAs(blob, fileName);
}
// not tested
function isJSON (jsonString){
try {
var o = JSON.parse(jsonString);
// Handle non-exception-throwing cases:
// Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
// but... JSON.parse(null) returns null, and typeof null === "object",
// so we must check for that, too. Thankfully, null is falsey, so this suffices:
if (o && typeof o === "object") {
return true;
}
}
catch (e) {return false; }
return false;
}
function tryParseJSON (jsonString){
try {
var o = JSON.parse(jsonString);
// Handle non-exception-throwing cases:
// Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
// but... JSON.parse(null) returns null, and typeof null === "object",
// so we must check for that, too. Thankfully, null is falsey, so this suffices:
if (o && typeof o === "object") {
return o;
}
}
catch (e) { }
return false;
}
function is1Component (elType){
var retval = false;
switch (elType) {
case "w":
case "r":
case "l":
case "c":
case "x":
case "f":
retval = true;
break;
default:
retval = false;
}
return retval;
}
function is2Component (elType){
var retval;
switch (elType) {
case "w":
case "r":
case "l":
case "c":
case "x":
case "f":
retval = false;
break;
default:
retval = true;
}
return retval;
}