maidr 2.7.1 → 2.9.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/dist/maidr.js +154 -154
- package/dist/maidr.min.js +1 -1
- package/package.json +1 -1
package/dist/maidr.js
CHANGED
|
@@ -88,6 +88,7 @@ class Constants {
|
|
|
88
88
|
skillLevel = 'basic'; // basic / intermediate / expert
|
|
89
89
|
skillLevelOther = ''; // custom skill level
|
|
90
90
|
autoInitLLM = true; // auto initialize LLM on page load
|
|
91
|
+
verboseText = '';
|
|
91
92
|
|
|
92
93
|
// user controls (not exposed to menu, with shortcuts usually)
|
|
93
94
|
showDisplay = 1; // true / false
|
|
@@ -924,6 +925,7 @@ class ChatLLM {
|
|
|
924
925
|
constructor() {
|
|
925
926
|
this.firstTime = true;
|
|
926
927
|
this.firstMulti = true;
|
|
928
|
+
this.firstOpen = true;
|
|
927
929
|
this.shown = false;
|
|
928
930
|
this.CreateComponent();
|
|
929
931
|
this.SetEvents();
|
|
@@ -1132,7 +1134,8 @@ class ChatLLM {
|
|
|
1132
1134
|
}
|
|
1133
1135
|
} else if (e.type == 'keyup') {
|
|
1134
1136
|
// check for alt shift c
|
|
1135
|
-
if (e.key == 'C' && (e.
|
|
1137
|
+
if (e.key == 'C' && (e.ctrlKey || e.metaKey) && e.shiftKey) {
|
|
1138
|
+
e.preventDefault();
|
|
1136
1139
|
// get the last message
|
|
1137
1140
|
let elem = document.querySelector(
|
|
1138
1141
|
'#chatLLM_chat_history > .chatLLM_message_other:last-of-type'
|
|
@@ -1140,6 +1143,10 @@ class ChatLLM {
|
|
|
1140
1143
|
if (elem) {
|
|
1141
1144
|
text = elem.innerHTML;
|
|
1142
1145
|
}
|
|
1146
|
+
} else if (e.key == 'A' && (e.ctrlKey || e.metaKey) && e.shiftKey) {
|
|
1147
|
+
e.preventDefault();
|
|
1148
|
+
// get html of the full chat history
|
|
1149
|
+
text = document.getElementById('chatLLM_chat_history').innerHTML;
|
|
1143
1150
|
}
|
|
1144
1151
|
}
|
|
1145
1152
|
|
|
@@ -1157,7 +1164,11 @@ class ChatLLM {
|
|
|
1157
1164
|
// kill more than 2 newlines in a row
|
|
1158
1165
|
markdown = markdown.replace(/\n{3,}/g, '\n\n');
|
|
1159
1166
|
|
|
1160
|
-
|
|
1167
|
+
try {
|
|
1168
|
+
navigator.clipboard.writeText(markdown);
|
|
1169
|
+
} catch (err) {
|
|
1170
|
+
console.error('Failed to copy: ', err);
|
|
1171
|
+
}
|
|
1161
1172
|
return markdown;
|
|
1162
1173
|
}
|
|
1163
1174
|
}
|
|
@@ -1219,14 +1230,30 @@ class ChatLLM {
|
|
|
1219
1230
|
* @returns {void}
|
|
1220
1231
|
*/
|
|
1221
1232
|
async Submit(text, firsttime = false) {
|
|
1233
|
+
// misc init
|
|
1234
|
+
let img = null;
|
|
1235
|
+
this.firstMulti = true;
|
|
1236
|
+
|
|
1237
|
+
// if this is the user's first message (or we're gemini, in which case we need to send every time), prepend prompt with user position
|
|
1238
|
+
if (
|
|
1239
|
+
(this.firstOpen || constants.LLMModel == 'gemini') &&
|
|
1240
|
+
!firsttime &&
|
|
1241
|
+
constants.verboseText.length > 0
|
|
1242
|
+
) {
|
|
1243
|
+
text =
|
|
1244
|
+
"Here is the current position in the chart; no response necessarily needed, use this info only if it's relevant to future questions: " +
|
|
1245
|
+
constants.verboseText +
|
|
1246
|
+
'. My question is: ' +
|
|
1247
|
+
text;
|
|
1248
|
+
|
|
1249
|
+
this.firstOpen = false;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1222
1252
|
// start waiting sound
|
|
1223
1253
|
if (constants.playLLMWaitingSound) {
|
|
1224
1254
|
this.WaitingSound(true);
|
|
1225
1255
|
}
|
|
1226
1256
|
|
|
1227
|
-
let img = null;
|
|
1228
|
-
this.firstMulti = true;
|
|
1229
|
-
|
|
1230
1257
|
if (constants.LLMOpenAiMulti || constants.LLMModel == 'openai') {
|
|
1231
1258
|
if (firsttime) {
|
|
1232
1259
|
img = await this.ConvertSVGtoJPG(singleMaidr.id, 'openai');
|
|
@@ -1640,6 +1667,7 @@ class ChatLLM {
|
|
|
1640
1667
|
document.getElementById('chatLLM_modal_backdrop').classList.add('hidden');
|
|
1641
1668
|
this.whereWasMyFocus.focus();
|
|
1642
1669
|
this.whereWasMyFocus = null;
|
|
1670
|
+
this.firstOpen = true;
|
|
1643
1671
|
}
|
|
1644
1672
|
}
|
|
1645
1673
|
|
|
@@ -2305,7 +2333,7 @@ class Tracker {
|
|
|
2305
2333
|
//console.log("x_tickmark: '", x_tickmark, "', y_tickmark: '", y_tickmark, "', x_label: '", x_label, "', y_label: '", y_label, "', value: '", value, "', fill_value: '", fill_value);
|
|
2306
2334
|
|
|
2307
2335
|
this.SetData('events', eventToLog);
|
|
2308
|
-
console.log('logged an event');
|
|
2336
|
+
//console.log('logged an event');
|
|
2309
2337
|
}
|
|
2310
2338
|
|
|
2311
2339
|
SetData(key, value) {
|
|
@@ -3306,9 +3334,10 @@ class Display {
|
|
|
3306
3334
|
|
|
3307
3335
|
let output = '';
|
|
3308
3336
|
let verboseText = '';
|
|
3337
|
+
let terseText = '';
|
|
3309
3338
|
let reviewText = '';
|
|
3310
3339
|
if (constants.chartType == 'bar') {
|
|
3311
|
-
// {legend x} is {colname x}, {legend y} is {value y}
|
|
3340
|
+
// verbose: {legend x} is {colname x}, {legend y} is {value y}
|
|
3312
3341
|
if (plot.columnLabels[position.x]) {
|
|
3313
3342
|
if (plot.plotLegend.x.length > 0) {
|
|
3314
3343
|
verboseText += plot.plotLegend.x + ' is ';
|
|
@@ -3321,20 +3350,16 @@ class Display {
|
|
|
3321
3350
|
}
|
|
3322
3351
|
verboseText += plot.plotData[position.x];
|
|
3323
3352
|
}
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
plot.plotData[position.x] +
|
|
3333
|
-
'</p>\n';
|
|
3334
|
-
} else if (constants.textMode == 'verbose') {
|
|
3335
|
-
output += '<p>' + verboseText + '</p>\n';
|
|
3336
|
-
}
|
|
3353
|
+
// terse: {colname} {value}
|
|
3354
|
+
terseText +=
|
|
3355
|
+
'<p>' +
|
|
3356
|
+
plot.columnLabels[position.x] +
|
|
3357
|
+
' ' +
|
|
3358
|
+
plot.plotData[position.x] +
|
|
3359
|
+
'</p>\n';
|
|
3360
|
+
verboseText = '<p>' + verboseText + '</p>\n';
|
|
3337
3361
|
} else if (constants.chartType == 'heat') {
|
|
3362
|
+
// verbose
|
|
3338
3363
|
// col name and value
|
|
3339
3364
|
if (constants.navigation == 1) {
|
|
3340
3365
|
verboseText +=
|
|
@@ -3367,31 +3392,25 @@ class Display {
|
|
|
3367
3392
|
verboseText += plot.data[position.y][position.x];
|
|
3368
3393
|
// }
|
|
3369
3394
|
}
|
|
3370
|
-
// terse
|
|
3371
|
-
if (constants.
|
|
3372
|
-
//
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
plot.y_labels[position.y] +
|
|
3388
|
-
', ' +
|
|
3389
|
-
plot.data[position.y][position.x] +
|
|
3390
|
-
'</p>\n';
|
|
3391
|
-
}
|
|
3392
|
-
} else if (constants.textMode == 'verbose') {
|
|
3393
|
-
output += '<p>' + verboseText + '</p>\n';
|
|
3395
|
+
// terse: value only
|
|
3396
|
+
if (constants.navigation == 1) {
|
|
3397
|
+
// column navigation
|
|
3398
|
+
terseText +=
|
|
3399
|
+
'<p>' +
|
|
3400
|
+
plot.x_labels[position.x] +
|
|
3401
|
+
', ' +
|
|
3402
|
+
plot.data[position.y][position.x] +
|
|
3403
|
+
'</p>\n';
|
|
3404
|
+
} else {
|
|
3405
|
+
// row navigation
|
|
3406
|
+
terseText +=
|
|
3407
|
+
'<p>' +
|
|
3408
|
+
plot.y_labels[position.y] +
|
|
3409
|
+
', ' +
|
|
3410
|
+
plot.data[position.y][position.x] +
|
|
3411
|
+
'</p>\n';
|
|
3394
3412
|
}
|
|
3413
|
+
verboseText = '<p>' + verboseText + '</p>\n';
|
|
3395
3414
|
} else if (constants.chartType == 'box') {
|
|
3396
3415
|
// setup
|
|
3397
3416
|
let val = 0;
|
|
@@ -3402,8 +3421,6 @@ class Display {
|
|
|
3402
3421
|
let sectionKey = plot.GetSectionKey(
|
|
3403
3422
|
constants.plotOrientation == 'vert' ? position.y : position.x
|
|
3404
3423
|
);
|
|
3405
|
-
let textTerse = '';
|
|
3406
|
-
let textVerbose = '';
|
|
3407
3424
|
|
|
3408
3425
|
if (sectionKey == 'lower_outlier' || sectionKey == 'upper_outlier') {
|
|
3409
3426
|
isOutlier = true;
|
|
@@ -3422,67 +3439,64 @@ class Display {
|
|
|
3422
3439
|
|
|
3423
3440
|
// group label for verbose
|
|
3424
3441
|
if (constants.navigation) {
|
|
3425
|
-
if (plot.x_group_label)
|
|
3442
|
+
if (plot.x_group_label) verboseText += plot.x_group_label;
|
|
3426
3443
|
} else if (!constants.navigation) {
|
|
3427
|
-
if (plot.y_group_label)
|
|
3444
|
+
if (plot.y_group_label) verboseText += plot.y_group_label;
|
|
3428
3445
|
}
|
|
3429
3446
|
// and axes label
|
|
3430
3447
|
if (constants.navigation) {
|
|
3431
3448
|
if (plot.x_labels[plotPos]) {
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3449
|
+
verboseText += ' is ';
|
|
3450
|
+
terseText += plot.x_labels[plotPos] + ', ';
|
|
3451
|
+
verboseText += plot.x_labels[plotPos] + ', ';
|
|
3435
3452
|
} else {
|
|
3436
|
-
|
|
3453
|
+
verboseText += ', ';
|
|
3437
3454
|
}
|
|
3438
3455
|
} else if (!constants.navigation) {
|
|
3439
3456
|
if (plot.y_labels[plotPos]) {
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3457
|
+
verboseText += ' is ';
|
|
3458
|
+
terseText += plot.y_labels[plotPos] + ', ';
|
|
3459
|
+
verboseText += plot.y_labels[plotPos] + ', ';
|
|
3443
3460
|
} else {
|
|
3444
|
-
|
|
3461
|
+
verboseText += ', ';
|
|
3445
3462
|
}
|
|
3446
3463
|
}
|
|
3447
3464
|
// outliers
|
|
3448
3465
|
if (isOutlier) {
|
|
3449
|
-
|
|
3450
|
-
|
|
3466
|
+
terseText += numPoints + ' ';
|
|
3467
|
+
verboseText += numPoints + ' ';
|
|
3451
3468
|
}
|
|
3452
3469
|
// label
|
|
3453
|
-
|
|
3454
|
-
if (numPoints == 1)
|
|
3470
|
+
verboseText += resources.GetString(sectionKey);
|
|
3471
|
+
if (numPoints == 1) verboseText += ' is ';
|
|
3455
3472
|
else {
|
|
3456
|
-
|
|
3457
|
-
if (numPoints > 1)
|
|
3473
|
+
verboseText += 's ';
|
|
3474
|
+
if (numPoints > 1) verboseText += ' are ';
|
|
3458
3475
|
}
|
|
3459
3476
|
if (
|
|
3460
3477
|
isOutlier ||
|
|
3461
3478
|
(constants.navigation && constants.plotOrientation == 'horz') ||
|
|
3462
3479
|
(!constants.navigation && constants.plotOrientation == 'vert')
|
|
3463
3480
|
) {
|
|
3464
|
-
|
|
3481
|
+
terseText += resources.GetString(sectionKey);
|
|
3465
3482
|
|
|
3466
3483
|
// grammar
|
|
3467
3484
|
if (numPoints != 1) {
|
|
3468
|
-
|
|
3485
|
+
terseText += 's';
|
|
3469
3486
|
}
|
|
3470
|
-
|
|
3487
|
+
terseText += ' ';
|
|
3471
3488
|
}
|
|
3472
3489
|
// val
|
|
3473
3490
|
if (plot.plotData[plotPos][sectionKey] == null && !isOutlier) {
|
|
3474
|
-
|
|
3475
|
-
|
|
3491
|
+
terseText += 'empty';
|
|
3492
|
+
verboseText += 'empty';
|
|
3476
3493
|
} else {
|
|
3477
|
-
|
|
3478
|
-
|
|
3494
|
+
terseText += val;
|
|
3495
|
+
verboseText += val;
|
|
3479
3496
|
}
|
|
3480
3497
|
|
|
3481
|
-
verboseText =
|
|
3482
|
-
|
|
3483
|
-
output = '<p>' + textVerbose + '</p>\n';
|
|
3484
|
-
else if (constants.textMode == 'terse')
|
|
3485
|
-
output = '<p>' + textTerse + '</p>\n';
|
|
3498
|
+
verboseText = '<p>' + verboseText + '</p>\n';
|
|
3499
|
+
terseText = '<p>' + terseText + '</p>\n';
|
|
3486
3500
|
} else if (
|
|
3487
3501
|
[].concat(singleMaidr.type).includes('point') ||
|
|
3488
3502
|
[].concat(singleMaidr.type).includes('smooth')
|
|
@@ -3499,20 +3513,15 @@ class Display {
|
|
|
3499
3513
|
plot.y[position.x].join(', ') +
|
|
3500
3514
|
']';
|
|
3501
3515
|
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
']' +
|
|
3512
|
-
'</p>\n';
|
|
3513
|
-
} else if (constants.textMode == 'verbose') {
|
|
3514
|
-
// set from verboseText
|
|
3515
|
-
}
|
|
3516
|
+
// terse
|
|
3517
|
+
terseText +=
|
|
3518
|
+
'<p>' +
|
|
3519
|
+
plot.x[position.x] +
|
|
3520
|
+
', ' +
|
|
3521
|
+
'[' +
|
|
3522
|
+
plot.y[position.x].join(', ') +
|
|
3523
|
+
']' +
|
|
3524
|
+
'</p>\n';
|
|
3516
3525
|
} else if (constants.chartType == 'smooth') {
|
|
3517
3526
|
// best fit smooth layer
|
|
3518
3527
|
verboseText +=
|
|
@@ -3524,42 +3533,31 @@ class Display {
|
|
|
3524
3533
|
' ' +
|
|
3525
3534
|
plot.curvePoints[positionL1.x]; // verbose mode: x and y values
|
|
3526
3535
|
|
|
3527
|
-
|
|
3528
|
-
// do nothing
|
|
3529
|
-
} else if (constants.textMode == 'terse') {
|
|
3530
|
-
// terse mode: gradient trend
|
|
3531
|
-
// output += '<p>' + plot.gradient[positionL1.x] + '<p>\n';
|
|
3536
|
+
// terse mode: gradient trend
|
|
3532
3537
|
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
} else if (constants.textMode == 'verbose') {
|
|
3536
|
-
// set from verboseText
|
|
3537
|
-
}
|
|
3538
|
+
// display absolute gradient of the graph
|
|
3539
|
+
terseText += '<p>' + plot.curvePoints[positionL1.x] + '<p>\n';
|
|
3538
3540
|
}
|
|
3539
|
-
|
|
3540
|
-
output = '<p>' + verboseText + '</p>\n';
|
|
3541
|
+
verboseText = '<p>' + verboseText + '</p>\n';
|
|
3541
3542
|
} else if (constants.chartType == 'hist') {
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
}
|
|
3561
|
-
output += plot.plotData[position.x].y;
|
|
3562
|
-
}
|
|
3543
|
+
// terse: {x}, {y}
|
|
3544
|
+
terseText =
|
|
3545
|
+
'<p>' +
|
|
3546
|
+
plot.plotData[position.x].x +
|
|
3547
|
+
', ' +
|
|
3548
|
+
plot.plotData[position.x].y +
|
|
3549
|
+
'</p>\n';
|
|
3550
|
+
// verbose: {xlabel} is xmin through xmax, {ylabel} is y
|
|
3551
|
+
verboseText = '<p>';
|
|
3552
|
+
if (plot.legendX) {
|
|
3553
|
+
verboseText = plot.legendX + ' is ';
|
|
3554
|
+
}
|
|
3555
|
+
verboseText += plot.plotData[position.x].xmin;
|
|
3556
|
+
verboseText += ' through ' + plot.plotData[position.x].xmax + ', ';
|
|
3557
|
+
if (plot.legendY) {
|
|
3558
|
+
verboseText += plot.legendY + ' is ';
|
|
3559
|
+
}
|
|
3560
|
+
verboseText += plot.plotData[position.x].y;
|
|
3563
3561
|
} else if (constants.chartType == 'line') {
|
|
3564
3562
|
// line layer
|
|
3565
3563
|
if (plot.plotLegend) {
|
|
@@ -3571,19 +3569,15 @@ class Display {
|
|
|
3571
3569
|
}
|
|
3572
3570
|
verboseText += plot.pointValuesY[position.x];
|
|
3573
3571
|
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
} else if (constants.textMode == 'verbose') {
|
|
3584
|
-
// set from verboseText
|
|
3585
|
-
output += '<p>' + verboseText + '</p>\n';
|
|
3586
|
-
}
|
|
3572
|
+
// terse
|
|
3573
|
+
terseText +=
|
|
3574
|
+
'<p>' +
|
|
3575
|
+
plot.pointValuesX[position.x] +
|
|
3576
|
+
', ' +
|
|
3577
|
+
plot.pointValuesY[position.x] +
|
|
3578
|
+
'</p>\n';
|
|
3579
|
+
|
|
3580
|
+
verboseText = '<p>' + verboseText + '</p>\n';
|
|
3587
3581
|
} else if (
|
|
3588
3582
|
constants.chartType == 'stacked_bar' ||
|
|
3589
3583
|
constants.chartType == 'stacked_normalized_bar' ||
|
|
@@ -3600,30 +3594,33 @@ class Display {
|
|
|
3600
3594
|
verboseText += plot.fill[position.y] + ', ';
|
|
3601
3595
|
verboseText += 'value is ' + plot.plotData[position.x][position.y];
|
|
3602
3596
|
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
' is ' +
|
|
3612
|
-
plot.plotData[position.x][position.y] +
|
|
3613
|
-
'</p>\n';
|
|
3614
|
-
} else {
|
|
3615
|
-
output +=
|
|
3616
|
-
'<p>' +
|
|
3617
|
-
plot.fill[position.y] +
|
|
3618
|
-
' is ' +
|
|
3619
|
-
plot.plotData[position.x][position.y] +
|
|
3620
|
-
'</p>\n';
|
|
3621
|
-
}
|
|
3597
|
+
// navigation == 1 ? {colname x} : {colname y} is {plotData[x][y]}
|
|
3598
|
+
if (constants.navigation == 1) {
|
|
3599
|
+
terseText +=
|
|
3600
|
+
'<p>' +
|
|
3601
|
+
plot.level[position.x] +
|
|
3602
|
+
' is ' +
|
|
3603
|
+
plot.plotData[position.x][position.y] +
|
|
3604
|
+
'</p>\n';
|
|
3622
3605
|
} else {
|
|
3623
|
-
|
|
3606
|
+
terseText +=
|
|
3607
|
+
'<p>' +
|
|
3608
|
+
plot.fill[position.y] +
|
|
3609
|
+
' is ' +
|
|
3610
|
+
plot.plotData[position.x][position.y] +
|
|
3611
|
+
'</p>\n';
|
|
3624
3612
|
}
|
|
3613
|
+
verboseText = '<p>' + verboseText + '</p>\n';
|
|
3625
3614
|
}
|
|
3626
3615
|
|
|
3616
|
+
// set outout text
|
|
3617
|
+
if (constants.textMode == 'verbose') {
|
|
3618
|
+
output = verboseText;
|
|
3619
|
+
} else if (constants.textMode == 'terse') {
|
|
3620
|
+
output = terseText;
|
|
3621
|
+
}
|
|
3622
|
+
constants.verboseText = verboseText;
|
|
3623
|
+
|
|
3627
3624
|
if (constants.infoDiv) constants.infoDiv.innerHTML = output;
|
|
3628
3625
|
if (constants.review) {
|
|
3629
3626
|
if (output.length > 0) {
|
|
@@ -7571,6 +7568,9 @@ class Control {
|
|
|
7571
7568
|
// caption
|
|
7572
7569
|
display.displayInfo('caption', plot.caption);
|
|
7573
7570
|
pressedL = false;
|
|
7571
|
+
} else if (e.key == 'f') {
|
|
7572
|
+
display.displayInfo('fill', plot.fill);
|
|
7573
|
+
pressedL = false;
|
|
7574
7574
|
} else if (e.key != 'l') {
|
|
7575
7575
|
pressedL = false;
|
|
7576
7576
|
}
|