chartjs-plugin-chart2music 0.6.1 → 0.7.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/README.md +93 -77
- package/dist/plugin.amd.js +174 -43
- package/dist/plugin.cjs +333 -230
- package/dist/plugin.d.ts +8 -1
- package/dist/plugin.js +174 -43
- package/dist/plugin.mjs +174 -43
- package/package.json +52 -23
package/dist/plugin.mjs
CHANGED
|
@@ -84,7 +84,8 @@ const chartjs_c2m_converter = {
|
|
|
84
84
|
boxplot: "box",
|
|
85
85
|
radar: "bar",
|
|
86
86
|
wordCloud: "bar",
|
|
87
|
-
scatter: "scatter"
|
|
87
|
+
scatter: "scatter",
|
|
88
|
+
matrix: "matrix"
|
|
88
89
|
};
|
|
89
90
|
const processChartType = (chart) => {
|
|
90
91
|
const topLevelType = chart.config.type;
|
|
@@ -134,13 +135,13 @@ const generateAxisInfo = (chartAxisInfo, chart) => {
|
|
|
134
135
|
}
|
|
135
136
|
return axis;
|
|
136
137
|
};
|
|
137
|
-
const generateAxes = (chart) => {
|
|
138
|
+
const generateAxes = (chart, options) => {
|
|
138
139
|
const axes = {
|
|
139
140
|
x: {
|
|
140
141
|
...generateAxisInfo(chart.options?.scales?.x, chart),
|
|
141
142
|
},
|
|
142
143
|
y: {
|
|
143
|
-
format: (value) => value.toLocaleString(),
|
|
144
|
+
format: options?.axes?.y?.format || ((value) => value.toLocaleString()),
|
|
144
145
|
...generateAxisInfo(chart.options?.scales?.y, chart),
|
|
145
146
|
}
|
|
146
147
|
};
|
|
@@ -159,6 +160,55 @@ const whichDataStructure = (data) => {
|
|
|
159
160
|
}
|
|
160
161
|
return data;
|
|
161
162
|
};
|
|
163
|
+
const labelIndex = (labels, value) => {
|
|
164
|
+
let index = labels.indexOf(value);
|
|
165
|
+
if (index === -1) {
|
|
166
|
+
labels.push(value);
|
|
167
|
+
index = labels.length - 1;
|
|
168
|
+
}
|
|
169
|
+
return index;
|
|
170
|
+
};
|
|
171
|
+
const processMatrixDataPoints = (data, datasetIndex, xLabels, yLabels) => {
|
|
172
|
+
return data.map((point, index) => {
|
|
173
|
+
const x = typeof point.x === "string" ? labelIndex(xLabels, point.x) : point.x;
|
|
174
|
+
const y = typeof point.y === "string" ? labelIndex(yLabels, point.y) : point.y;
|
|
175
|
+
return {
|
|
176
|
+
...point,
|
|
177
|
+
x,
|
|
178
|
+
y,
|
|
179
|
+
custom: {
|
|
180
|
+
...point.custom,
|
|
181
|
+
group: datasetIndex,
|
|
182
|
+
datasetIndex,
|
|
183
|
+
index
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
const processMatrixData = (data) => {
|
|
189
|
+
const xLabels = [];
|
|
190
|
+
const yLabels = [];
|
|
191
|
+
// Chart2Music represents matrix rows as groups and columns as points within
|
|
192
|
+
// each group. This preserves two-dimensional keyboard navigation.
|
|
193
|
+
const result = {};
|
|
194
|
+
data.datasets.forEach((obj, index) => {
|
|
195
|
+
const points = processMatrixDataPoints(obj.data, index, xLabels, yLabels);
|
|
196
|
+
points.forEach((point) => {
|
|
197
|
+
const rowLabel = typeof point.y === "number" && yLabels[point.y] !== undefined
|
|
198
|
+
? yLabels[point.y]
|
|
199
|
+
: String(point.y);
|
|
200
|
+
const groupName = data.datasets.length === 1
|
|
201
|
+
? rowLabel
|
|
202
|
+
: `${obj.label ?? `Group ${index + 1}`}: ${rowLabel}`;
|
|
203
|
+
if (!result[groupName]) {
|
|
204
|
+
result[groupName] = [];
|
|
205
|
+
}
|
|
206
|
+
result[groupName].push(point);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
Object.values(result).forEach((row) => row.sort((a, b) => a.x - b.x));
|
|
210
|
+
return { groups: Object.keys(result), data: result, xLabels, yLabels };
|
|
211
|
+
};
|
|
162
212
|
const scrubX = (data) => {
|
|
163
213
|
const blackboard = JSON.parse(JSON.stringify(data));
|
|
164
214
|
let labels = [];
|
|
@@ -173,11 +223,18 @@ const scrubX = (data) => {
|
|
|
173
223
|
});
|
|
174
224
|
return { labels, data: blackboard };
|
|
175
225
|
}
|
|
226
|
+
else {
|
|
227
|
+
// Grouped
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
176
230
|
};
|
|
177
231
|
const processData = (data, c2m_types) => {
|
|
178
232
|
if (c2m_types === "box") {
|
|
179
233
|
return processBoxData(data);
|
|
180
234
|
}
|
|
235
|
+
if (c2m_types === "matrix") {
|
|
236
|
+
return processMatrixData(data);
|
|
237
|
+
}
|
|
181
238
|
let groups = [];
|
|
182
239
|
if (data.datasets.length === 1) {
|
|
183
240
|
return {
|
|
@@ -209,26 +266,36 @@ const determineCCElement = (canvas, provided) => {
|
|
|
209
266
|
canvas.insertAdjacentElement("afterend", cc);
|
|
210
267
|
return cc;
|
|
211
268
|
};
|
|
269
|
+
const createDataSnapshot = (chart) => {
|
|
270
|
+
return JSON.stringify({
|
|
271
|
+
datasets: chart.data.datasets.map(ds => ds.data),
|
|
272
|
+
labels: chart.data.labels
|
|
273
|
+
});
|
|
274
|
+
};
|
|
212
275
|
const displayPoint = (chart) => {
|
|
213
276
|
if (!chartStates.has(chart)) {
|
|
214
277
|
return;
|
|
215
278
|
}
|
|
216
|
-
const { c2m: ref
|
|
279
|
+
const { c2m: ref } = chartStates.get(chart);
|
|
217
280
|
const { point, index } = ref.getCurrent();
|
|
281
|
+
// Use Chart2Music's internal visible group tracking
|
|
282
|
+
// @ts-ignore - accessing internal Chart2Music property
|
|
283
|
+
const visibleGroupIndices = ref._visible_group_indices?.slice(1) || [];
|
|
218
284
|
try {
|
|
219
285
|
const highlightElements = [];
|
|
220
286
|
if ("custom" in point) {
|
|
287
|
+
const customPoint = point;
|
|
221
288
|
highlightElements.push({
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// @ts-ignore
|
|
225
|
-
index: point.custom.index
|
|
289
|
+
datasetIndex: customPoint.custom.datasetIndex ?? customPoint.custom.group,
|
|
290
|
+
index: customPoint.custom.index
|
|
226
291
|
});
|
|
227
292
|
}
|
|
228
293
|
else {
|
|
229
|
-
|
|
294
|
+
// For stacked charts, Chart2Music includes an "All" group at index 0,
|
|
295
|
+
// so we subtract 1 to get the actual dataset index
|
|
296
|
+
visibleGroupIndices.forEach((groupIndex) => {
|
|
230
297
|
highlightElements.push({
|
|
231
|
-
datasetIndex,
|
|
298
|
+
datasetIndex: groupIndex - 1,
|
|
232
299
|
index
|
|
233
300
|
});
|
|
234
301
|
});
|
|
@@ -244,11 +311,10 @@ const displayPoint = (chart) => {
|
|
|
244
311
|
const generateChart = (chart, options) => {
|
|
245
312
|
const { valid, c2m_types, invalidType } = processChartType(chart);
|
|
246
313
|
if (!valid) {
|
|
247
|
-
// @ts-ignore
|
|
248
314
|
options.errorCallback?.(`Unable to connect chart2music to chart. The chart is of type "${invalidType}", which is not one of the supported chart types for this plugin. This plugin supports: ${Object.keys(chartjs_c2m_converter).join(", ")}`);
|
|
249
315
|
return;
|
|
250
316
|
}
|
|
251
|
-
let axes = generateAxes(chart);
|
|
317
|
+
let axes = generateAxes(chart, options);
|
|
252
318
|
if (chart.config.type === "wordCloud") {
|
|
253
319
|
delete axes.x.minimum;
|
|
254
320
|
delete axes.x.maximum;
|
|
@@ -263,8 +329,20 @@ const generateChart = (chart, options) => {
|
|
|
263
329
|
}
|
|
264
330
|
// Generate CC element
|
|
265
331
|
const cc = determineCCElement(chart.canvas, options.cc);
|
|
266
|
-
const
|
|
332
|
+
const processedData = processData(chart.data, c2m_types);
|
|
333
|
+
const { data } = processedData;
|
|
267
334
|
// lastDataObj = JSON.stringify(data);
|
|
335
|
+
if (c2m_types === "matrix") {
|
|
336
|
+
if (processedData.xLabels?.length > 0) {
|
|
337
|
+
axes.x.valueLabels = processedData.xLabels.slice(0);
|
|
338
|
+
}
|
|
339
|
+
if (processedData.yLabels?.length > 0) {
|
|
340
|
+
// Category labels provide the Matrix Plot's Y-axis formatter.
|
|
341
|
+
// The general numeric formatter would otherwise announce row indexes.
|
|
342
|
+
delete axes.y.format;
|
|
343
|
+
axes.y.valueLabels = processedData.yLabels.slice(0);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
268
346
|
let scrub = scrubX(data);
|
|
269
347
|
if (scrub?.labels && scrub?.labels?.length > 0) { // Something was scrubbed
|
|
270
348
|
if (!chart.data.labels || chart.data.labels.length === 0) {
|
|
@@ -286,6 +364,13 @@ const generateChart = (chart, options) => {
|
|
|
286
364
|
...(options.axes?.y)
|
|
287
365
|
},
|
|
288
366
|
};
|
|
367
|
+
// Start with plugin's internal onFocusCallback
|
|
368
|
+
const pluginOnFocusCallback = () => {
|
|
369
|
+
displayPoint(chart);
|
|
370
|
+
};
|
|
371
|
+
// Merge user's options, wrapping onFocusCallback if provided
|
|
372
|
+
const userOptions = options.options || {};
|
|
373
|
+
const userOnFocusCallback = userOptions.onFocusCallback;
|
|
289
374
|
const c2mOptions = {
|
|
290
375
|
cc,
|
|
291
376
|
element: chart.canvas,
|
|
@@ -294,10 +379,13 @@ const generateChart = (chart, options) => {
|
|
|
294
379
|
title: determineChartTitle(chart.options),
|
|
295
380
|
axes,
|
|
296
381
|
options: {
|
|
297
|
-
|
|
298
|
-
onFocusCallback:
|
|
299
|
-
|
|
300
|
-
|
|
382
|
+
...userOptions,
|
|
383
|
+
onFocusCallback: userOnFocusCallback
|
|
384
|
+
? (point) => {
|
|
385
|
+
pluginOnFocusCallback();
|
|
386
|
+
userOnFocusCallback(point);
|
|
387
|
+
}
|
|
388
|
+
: pluginOnFocusCallback
|
|
301
389
|
}
|
|
302
390
|
};
|
|
303
391
|
if (Array.isArray(c2mOptions.data)) {
|
|
@@ -306,8 +394,9 @@ const generateChart = (chart, options) => {
|
|
|
306
394
|
return {
|
|
307
395
|
...point,
|
|
308
396
|
custom: {
|
|
309
|
-
|
|
310
|
-
|
|
397
|
+
...point.custom,
|
|
398
|
+
group: point.custom?.group ?? 0,
|
|
399
|
+
index: point.custom?.index ?? index
|
|
311
400
|
}
|
|
312
401
|
};
|
|
313
402
|
});
|
|
@@ -326,10 +415,11 @@ const generateChart = (chart, options) => {
|
|
|
326
415
|
}
|
|
327
416
|
}
|
|
328
417
|
else {
|
|
329
|
-
const
|
|
418
|
+
const dataObj = c2mOptions.data;
|
|
419
|
+
const groups = Object.keys(dataObj);
|
|
330
420
|
groups.forEach((groupName, groupNumber) => {
|
|
331
|
-
if (!isNaN(
|
|
332
|
-
|
|
421
|
+
if (!isNaN(dataObj[groupName][0])) {
|
|
422
|
+
dataObj[groupName] = dataObj[groupName].map((num, index) => {
|
|
333
423
|
return {
|
|
334
424
|
x: index,
|
|
335
425
|
y: num,
|
|
@@ -341,26 +431,25 @@ const generateChart = (chart, options) => {
|
|
|
341
431
|
});
|
|
342
432
|
}
|
|
343
433
|
else {
|
|
344
|
-
|
|
434
|
+
dataObj[groupName] = dataObj[groupName].map((point, index) => {
|
|
345
435
|
return {
|
|
346
436
|
...point,
|
|
347
437
|
custom: {
|
|
348
|
-
|
|
349
|
-
|
|
438
|
+
...point.custom,
|
|
439
|
+
group: point.custom?.group ?? groupNumber,
|
|
440
|
+
index: point.custom?.index ?? index
|
|
350
441
|
}
|
|
351
442
|
};
|
|
352
443
|
});
|
|
353
444
|
}
|
|
354
445
|
});
|
|
355
446
|
}
|
|
356
|
-
// @ts-ignore
|
|
357
447
|
if (chart.config.options?.scales?.x?.stacked) {
|
|
358
|
-
|
|
359
|
-
|
|
448
|
+
if (c2mOptions.options) {
|
|
449
|
+
c2mOptions.options.stack = true;
|
|
450
|
+
}
|
|
360
451
|
}
|
|
361
|
-
// @ts-ignore
|
|
362
452
|
if (options.audioEngine) {
|
|
363
|
-
// @ts-ignore
|
|
364
453
|
c2mOptions.audioEngine = options.audioEngine;
|
|
365
454
|
}
|
|
366
455
|
if (c2mOptions.data.length === 0) {
|
|
@@ -372,7 +461,6 @@ const generateChart = (chart, options) => {
|
|
|
372
461
|
const { err, data: c2m } = c2mChart(c2mOptions);
|
|
373
462
|
/* istanbul-ignore-next */
|
|
374
463
|
if (err) {
|
|
375
|
-
// @ts-ignore
|
|
376
464
|
options.errorCallback?.(err);
|
|
377
465
|
return;
|
|
378
466
|
}
|
|
@@ -381,12 +469,32 @@ const generateChart = (chart, options) => {
|
|
|
381
469
|
}
|
|
382
470
|
chartStates.set(chart, {
|
|
383
471
|
c2m,
|
|
384
|
-
|
|
472
|
+
lastDataSnapshot: createDataSnapshot(chart)
|
|
385
473
|
});
|
|
474
|
+
if (c2m_types === "matrix") {
|
|
475
|
+
const matrixKeydown = (event) => {
|
|
476
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
event.preventDefault();
|
|
480
|
+
event.stopImmediatePropagation();
|
|
481
|
+
const actions = c2m._availableActions;
|
|
482
|
+
if (event.key === "ArrowUp") {
|
|
483
|
+
actions.next_category();
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
actions.previous_category();
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
chart.canvas.addEventListener("keydown", matrixKeydown, true);
|
|
490
|
+
const state = chartStates.get(chart);
|
|
491
|
+
state.matrixKeydown = matrixKeydown;
|
|
492
|
+
state.matrixKeydownTarget = chart.canvas;
|
|
493
|
+
}
|
|
386
494
|
};
|
|
387
495
|
const plugin = {
|
|
388
496
|
id: "chartjs2music",
|
|
389
|
-
afterInit: (chart,
|
|
497
|
+
afterInit: (chart, _args, options) => {
|
|
390
498
|
if (!chartStates.has(chart)) {
|
|
391
499
|
generateChart(chart, options);
|
|
392
500
|
// Remove tooltip when the chart blurs
|
|
@@ -413,19 +521,17 @@ const plugin = {
|
|
|
413
521
|
if (!chartStates.has(chart)) {
|
|
414
522
|
generateChart(chart, options);
|
|
415
523
|
}
|
|
416
|
-
const { c2m: ref
|
|
524
|
+
const { c2m: ref } = chartStates.get(chart);
|
|
417
525
|
if (!ref) {
|
|
418
526
|
return;
|
|
419
527
|
}
|
|
420
|
-
|
|
421
|
-
const groups =
|
|
422
|
-
|
|
423
|
-
if (ref._options.stack) {
|
|
528
|
+
const refInternal = ref;
|
|
529
|
+
const groups = refInternal._groups.slice(0);
|
|
530
|
+
if (refInternal._options.stack) {
|
|
424
531
|
groups.shift();
|
|
425
532
|
}
|
|
426
533
|
if (args.mode === "hide") {
|
|
427
534
|
const err = ref.setCategoryVisibility(groups[args.index], false);
|
|
428
|
-
visible_groups.splice(args.index, 1);
|
|
429
535
|
if (err) {
|
|
430
536
|
console.error(err);
|
|
431
537
|
}
|
|
@@ -433,24 +539,49 @@ const plugin = {
|
|
|
433
539
|
}
|
|
434
540
|
if (args.mode === "show") {
|
|
435
541
|
const err = ref.setCategoryVisibility(groups[args.index], true);
|
|
436
|
-
visible_groups.push(args.index);
|
|
437
542
|
if (err) {
|
|
438
543
|
console.error(err);
|
|
439
544
|
}
|
|
440
545
|
return;
|
|
441
546
|
}
|
|
442
547
|
},
|
|
548
|
+
afterDatasetsUpdate: (chart, _args, options) => {
|
|
549
|
+
const state = chartStates.get(chart);
|
|
550
|
+
if (!state?.c2m)
|
|
551
|
+
return;
|
|
552
|
+
// Check if data has changed
|
|
553
|
+
const currentSnapshot = createDataSnapshot(chart);
|
|
554
|
+
if (currentSnapshot === state.lastDataSnapshot) {
|
|
555
|
+
return; // No data change, skip update
|
|
556
|
+
}
|
|
557
|
+
// Get chart type
|
|
558
|
+
const { valid, c2m_types } = processChartType(chart);
|
|
559
|
+
if (!valid)
|
|
560
|
+
return;
|
|
561
|
+
// Process data and generate axes
|
|
562
|
+
const { data } = processData(chart.data, c2m_types);
|
|
563
|
+
const axes = generateAxes(chart, options);
|
|
564
|
+
// Update Chart2Music with new data
|
|
565
|
+
state.c2m.setData(data, axes);
|
|
566
|
+
// Update snapshot
|
|
567
|
+
state.lastDataSnapshot = currentSnapshot;
|
|
568
|
+
},
|
|
443
569
|
afterDestroy: (chart) => {
|
|
444
|
-
const
|
|
445
|
-
if (!
|
|
570
|
+
const state = chartStates.get(chart);
|
|
571
|
+
if (!state?.c2m) {
|
|
446
572
|
return;
|
|
447
573
|
}
|
|
574
|
+
const { c2m: ref } = state;
|
|
575
|
+
if (state?.matrixKeydown && state.matrixKeydownTarget) {
|
|
576
|
+
state.matrixKeydownTarget.removeEventListener("keydown", state.matrixKeydown, true);
|
|
577
|
+
}
|
|
448
578
|
ref.cleanUp();
|
|
449
579
|
},
|
|
450
580
|
defaults: {
|
|
451
581
|
cc: null,
|
|
452
582
|
audioEngine: null,
|
|
453
|
-
errorCallback: null
|
|
583
|
+
errorCallback: null,
|
|
584
|
+
options: {}
|
|
454
585
|
}
|
|
455
586
|
};
|
|
456
587
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartjs-plugin-chart2music",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Chart.js plugin for Chart2Music. Turns chart.js charts into music so the blind can hear data.",
|
|
6
6
|
"main": "dist/plugin.js",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
},
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"scripts": {
|
|
37
|
-
"start": "
|
|
37
|
+
"start": "storybook dev -p 6006",
|
|
38
|
+
"storybook": "storybook dev -p 6006",
|
|
39
|
+
"build-storybook": "storybook build",
|
|
38
40
|
"build": "rollup -c rollup.config.js --silent && yarn build-cjs",
|
|
39
41
|
"build-cjs": "babel ./dist/plugin.mjs --out-file ./dist/plugin.cjs",
|
|
40
42
|
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
|
|
@@ -43,32 +45,59 @@
|
|
|
43
45
|
"prepack": "npm run clean && npm run build"
|
|
44
46
|
},
|
|
45
47
|
"devDependencies": {
|
|
46
|
-
"@babel/cli": "
|
|
47
|
-
"@babel/core": "
|
|
48
|
-
"@babel/plugin-transform-modules-commonjs": "
|
|
49
|
-
"@babel/preset-env": "
|
|
50
|
-
"@rollup/plugin-typescript": "12.
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"
|
|
48
|
+
"@babel/cli": "^8.0.4",
|
|
49
|
+
"@babel/core": "^8.0.1",
|
|
50
|
+
"@babel/plugin-transform-modules-commonjs": "^8.0.1",
|
|
51
|
+
"@babel/preset-env": "^8.0.2",
|
|
52
|
+
"@rollup/plugin-typescript": "12.3.0",
|
|
53
|
+
"@storybook/html-vite": "10.5.0",
|
|
54
|
+
"@sgratzl/chartjs-chart-boxplot": "4.4.5",
|
|
55
|
+
"@types/jest": "^30.0.0",
|
|
56
|
+
"canvas": "^3.2.3",
|
|
54
57
|
"chartjs-adapter-luxon": "1.3.1",
|
|
55
|
-
"chartjs-chart-
|
|
56
|
-
"chartjs-
|
|
57
|
-
"
|
|
58
|
+
"chartjs-chart-matrix": "3.0.5",
|
|
59
|
+
"chartjs-chart-wordcloud": "4.4.5",
|
|
60
|
+
"chartjs-plugin-a11y-legend": "0.2.2",
|
|
61
|
+
"cross-env": "^10.1.0",
|
|
58
62
|
"depcheck": "1.4.7",
|
|
59
|
-
"jest": "
|
|
60
|
-
"jest-environment-jsdom": "
|
|
61
|
-
"luxon": "3.
|
|
62
|
-
"rimraf": "6.
|
|
63
|
-
"rollup": "4.
|
|
63
|
+
"jest": "^30.4.2",
|
|
64
|
+
"jest-environment-jsdom": "^30.4.1",
|
|
65
|
+
"luxon": "^3.7.2",
|
|
66
|
+
"rimraf": "^6.1.3",
|
|
67
|
+
"rollup": "^4.62.2",
|
|
64
68
|
"rollup-plugin-copy": "3.5.0",
|
|
65
|
-
"
|
|
69
|
+
"storybook": "10.5.0",
|
|
70
|
+
"ts-jest": "^29.4.11",
|
|
66
71
|
"tslib": "2.8.1",
|
|
67
|
-
"typescript": "5.
|
|
68
|
-
"vite": "
|
|
72
|
+
"typescript": "5.9.3",
|
|
73
|
+
"vite": "^8.1.4"
|
|
69
74
|
},
|
|
70
75
|
"dependencies": {
|
|
71
|
-
"chart.js": "4.
|
|
72
|
-
"chart2music": "1.
|
|
76
|
+
"chart.js": "4.5.1",
|
|
77
|
+
"chart2music": "1.20.0"
|
|
78
|
+
},
|
|
79
|
+
"resolutions": {
|
|
80
|
+
"@babel/core": "^8.0.1",
|
|
81
|
+
"brace-expansion": "^1.1.13",
|
|
82
|
+
"@babel/cli/**/brace-expansion": "^1.1.13",
|
|
83
|
+
"@babel/cli/**/minimatch": "^3.1.4",
|
|
84
|
+
"@babel/cli/**/picomatch": "^2.3.2",
|
|
85
|
+
"@rollup/plugin-typescript/**/picomatch": "^4.0.4",
|
|
86
|
+
"canvas/**/tar-fs": "^2.1.3",
|
|
87
|
+
"depcheck/**/brace-expansion": "^2.0.3",
|
|
88
|
+
"depcheck/**/js-yaml": "^3.15.0",
|
|
89
|
+
"depcheck/**/lodash": "^4.18.1",
|
|
90
|
+
"depcheck/**/minimatch": "^7.4.8",
|
|
91
|
+
"depcheck/**/picomatch": "^2.3.2",
|
|
92
|
+
"depcheck/**/postcss": "^8.5.10",
|
|
93
|
+
"jest/**/brace-expansion": "^1.1.13",
|
|
94
|
+
"jest/**/js-yaml": "^3.15.0",
|
|
95
|
+
"jest/**/minimatch": "^3.1.4",
|
|
96
|
+
"jest/**/picomatch": "^2.3.2",
|
|
97
|
+
"rollup-plugin-copy/**/brace-expansion": "^1.1.13",
|
|
98
|
+
"rollup-plugin-copy/**/minimatch": "^3.1.4",
|
|
99
|
+
"rollup-plugin-copy/**/picomatch": "^2.3.2",
|
|
100
|
+
"**/ws": "^8.21.0",
|
|
101
|
+
"**/yaml": "^1.10.3"
|
|
73
102
|
}
|
|
74
103
|
}
|