mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-26 23:54:09 +01:00
Compare commits
10 Commits
renovate/p
...
fix/5496-g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf50ce5237 | ||
|
|
8bfd47758a | ||
|
|
88fd141276 | ||
|
|
454238867b | ||
|
|
6025ec663c | ||
|
|
2346801c30 | ||
|
|
d7eb94dc89 | ||
|
|
e20b079707 | ||
|
|
6e869ff8dc | ||
|
|
9df18da01c |
5
.changeset/tricky-rivers-stand.md
Normal file
5
.changeset/tricky-rivers-stand.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'mermaid': patch
|
||||
---
|
||||
|
||||
fix: validate dates and tick interval to prevent UI freeze/crash in gantt diagramtype
|
||||
@@ -118,6 +118,15 @@ describe('Gantt diagram', () => {
|
||||
);
|
||||
});
|
||||
it('should FAIL rendering a gantt chart for issue #1060 with invalid date', () => {
|
||||
let errorCaught = false;
|
||||
|
||||
cy.on('uncaught:exception', (err) => {
|
||||
// Expect error related to invalid or missing date format
|
||||
expect(err.message).to.include('Invalid date');
|
||||
errorCaught = true;
|
||||
return false; // prevent Cypress from failing the test
|
||||
});
|
||||
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
@@ -150,12 +159,16 @@ describe('Gantt diagram', () => {
|
||||
|
||||
section Plasma Calls & updates
|
||||
OVM :ovm, 2019-07-12, 120d
|
||||
Plasma call 26 :pc26, 2019-08-21, 1d
|
||||
Plasma call 27 :pc27, 2019-09-03, 1d
|
||||
Plasma call 28 :pc28, 2019-09-17, 1d
|
||||
`,
|
||||
Plasma call 26 :pc26, 2019-08-21, 1d
|
||||
Plasma call 27 :pc27, 2019-09-03, 1d
|
||||
Plasma call 28 :pc28, 2019-09-17, 1d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
|
||||
cy.then(() => {
|
||||
expect(errorCaught, 'Expected rendering to fail with invalid date error').to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should default to showing today marker', () => {
|
||||
|
||||
@@ -286,9 +286,9 @@ erDiagram
|
||||
accTitle: This is a title
|
||||
accDescr: This is a description
|
||||
|
||||
dateFormat :YYYY-MM-DD
|
||||
dateFormat YYYY-MM-DD
|
||||
title :Adding GANTT diagram functionality to mermaid
|
||||
excludes :excludes the named dates/days from being included in a charted task..
|
||||
excludes :excludes the named dates/days from being included in a charted task.
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
|
||||
@@ -402,7 +402,7 @@ block
|
||||
blockArrowId4<["Label"]>(down)
|
||||
blockArrowId5<["Label"]>(x)
|
||||
blockArrowId6<["Label"]>(y)
|
||||
blockArrowId6<["Label"]>(x, down)
|
||||
blockArrowId7<["Label"]>(x, down)
|
||||
```
|
||||
|
||||
```mermaid
|
||||
@@ -413,7 +413,7 @@ block
|
||||
blockArrowId4<["Label"]>(down)
|
||||
blockArrowId5<["Label"]>(x)
|
||||
blockArrowId6<["Label"]>(y)
|
||||
blockArrowId6<["Label"]>(x, down)
|
||||
blockArrowId7<["Label"]>(x, down)
|
||||
```
|
||||
|
||||
#### Example - Space Blocks
|
||||
|
||||
@@ -62,7 +62,7 @@ radar-beta
|
||||
radar-beta
|
||||
title Restaurant Comparison
|
||||
axis food["Food Quality"], service["Service"], price["Price"]
|
||||
axis ambiance["Ambiance"],
|
||||
axis ambiance["Ambiance"]
|
||||
|
||||
curve a["Restaurant A"]{4, 3, 2, 4}
|
||||
curve b["Restaurant B"]{3, 4, 3, 3}
|
||||
@@ -78,7 +78,7 @@ radar-beta
|
||||
radar-beta
|
||||
title Restaurant Comparison
|
||||
axis food["Food Quality"], service["Service"], price["Price"]
|
||||
axis ambiance["Ambiance"],
|
||||
axis ambiance["Ambiance"]
|
||||
|
||||
curve a["Restaurant A"]{4, 3, 2, 4}
|
||||
curve b["Restaurant B"]{3, 4, 3, 3}
|
||||
|
||||
@@ -300,6 +300,16 @@ const getStartDate = function (prevTime, dateFormat, str) {
|
||||
} else {
|
||||
log.debug('Invalid date:' + str);
|
||||
log.debug('With date format:' + dateFormat.trim());
|
||||
|
||||
// Only allow fallback for formats that are simple timestamps (x, X)
|
||||
// which represent Unix timestamps. For all other formats, if dayjs
|
||||
// strict parsing fails - throws an error.
|
||||
const isTimestampFormat = dateFormat.trim() === 'x' || dateFormat.trim() === 'X';
|
||||
|
||||
if (!isTimestampFormat) {
|
||||
throw new Error(`Invalid date: "${str}" does not match format "${dateFormat.trim()}".`);
|
||||
}
|
||||
|
||||
const d = new Date(str);
|
||||
if (
|
||||
d === undefined ||
|
||||
|
||||
@@ -503,6 +503,51 @@ describe('when using the ganttDb', function () {
|
||||
it('should reject dates with ridiculous years', function () {
|
||||
ganttDb.setDateFormat('YYYYMMDD');
|
||||
ganttDb.addTask('test1', 'id1,202304,1d');
|
||||
expect(() => ganttDb.getTasks()).toThrowError('Invalid date:202304');
|
||||
expect(() => ganttDb.getTasks()).toThrowError(/Invalid date/);
|
||||
});
|
||||
|
||||
describe('when using non-standard date formats (issue #5496)', function () {
|
||||
it('should reject invalid dates when using seconds-only format', function () {
|
||||
ganttDb.setDateFormat('ss');
|
||||
ganttDb.addTask('RTT', 'rtt, 0, 20');
|
||||
expect(() => ganttDb.getTasks()).toThrowError(/Invalid date/);
|
||||
});
|
||||
|
||||
it('should reject invalid dates when using time-only formats without year', function () {
|
||||
// Formats without year info should not fall back to new Date()
|
||||
ganttDb.setDateFormat('HH:mm');
|
||||
ganttDb.addTask('test', 'id1, invalid_date, 1h');
|
||||
expect(() => ganttDb.getTasks()).toThrowError(/Invalid date/);
|
||||
});
|
||||
|
||||
it('should allow valid seconds-only format when date matches', function () {
|
||||
// Valid case - the date format 'ss' should work when the value is valid
|
||||
ganttDb.setDateFormat('ss');
|
||||
ganttDb.addTask('Task', 'task1, 00, 6s');
|
||||
// This should not throw - 00 is a valid 'ss' value
|
||||
const tasks = ganttDb.getTasks();
|
||||
expect(tasks).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should reject dates with typos in year like 202-12-01 instead of 2024-12-01', function () {
|
||||
ganttDb.setDateFormat('YYYY-MM-DD');
|
||||
ganttDb.addSection('Vacation');
|
||||
ganttDb.addTask('London', '2024-12-01, 7d');
|
||||
ganttDb.addTask('London', '202-12-01, 7d');
|
||||
expect(() => ganttDb.getTasks()).toThrowError(/Invalid date/);
|
||||
});
|
||||
|
||||
it('should work correctly with valid YYYY-MM-DD dates', function () {
|
||||
// Valid case - both dates are correctly formatted
|
||||
ganttDb.setDateFormat('YYYY-MM-DD');
|
||||
ganttDb.addSection('Vacation');
|
||||
ganttDb.addTask('London Trip 1', '2024-12-01, 7d');
|
||||
ganttDb.addTask('London Trip 2', '2024-12-15, 7d');
|
||||
const tasks = ganttDb.getTasks();
|
||||
expect(tasks).toHaveLength(2);
|
||||
// Verify years are correct (2024)
|
||||
expect(tasks[0].startTime.getFullYear()).toBe(2024);
|
||||
expect(tasks[1].startTime.getFullYear()).toBe(2024);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -78,6 +78,7 @@ const getMaxIntersections = (tasks, orderOffset) => {
|
||||
};
|
||||
|
||||
let w;
|
||||
const MAX_TICK_COUNT = 10000;
|
||||
export const draw = function (text, id, version, diagObj) {
|
||||
const conf = getConfig().gantt;
|
||||
|
||||
@@ -602,6 +603,30 @@ export const draw = function (text, id, version, diagObj) {
|
||||
.attr('class', 'exclude-range');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the estimated number of ticks based on the time domain and tick interval.
|
||||
* Returns the count or Infinity if there would be too many ticks.
|
||||
* @param {Date} minTime - The minimum time in the domain
|
||||
* @param {Date} maxTime - The maximum time in the domain
|
||||
* @param {number} every - The interval count (e.g., 1 for "1second")
|
||||
* @param {string} interval - The interval unit (e.g., "second", "day")
|
||||
* @returns {number} The estimated number of ticks
|
||||
*/
|
||||
function getEstimatedTickCount(minTime, maxTime, every, interval) {
|
||||
const timeDiffMs = maxTime - minTime;
|
||||
const msPerUnit = {
|
||||
millisecond: 1,
|
||||
second: 1000,
|
||||
minute: 60 * 1000,
|
||||
hour: 60 * 60 * 1000,
|
||||
day: 24 * 60 * 60 * 1000,
|
||||
week: 7 * 24 * 60 * 60 * 1000,
|
||||
month: 30 * 24 * 60 * 60 * 1000, // Approximate
|
||||
};
|
||||
const intervalMs = (msPerUnit[interval] || msPerUnit.day) * every;
|
||||
return Math.ceil(timeDiffMs / intervalMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theSidePad
|
||||
* @param theTopPad
|
||||
@@ -630,32 +655,47 @@ export const draw = function (text, id, version, diagObj) {
|
||||
);
|
||||
|
||||
if (resultTickInterval !== null) {
|
||||
const every = resultTickInterval[1];
|
||||
const every = parseInt(resultTickInterval[1], 10);
|
||||
const interval = resultTickInterval[2];
|
||||
const weekday = diagObj.db.getWeekday() || conf.weekday;
|
||||
|
||||
switch (interval) {
|
||||
case 'millisecond':
|
||||
bottomXAxis.ticks(timeMillisecond.every(every));
|
||||
break;
|
||||
case 'second':
|
||||
bottomXAxis.ticks(timeSecond.every(every));
|
||||
break;
|
||||
case 'minute':
|
||||
bottomXAxis.ticks(timeMinute.every(every));
|
||||
break;
|
||||
case 'hour':
|
||||
bottomXAxis.ticks(timeHour.every(every));
|
||||
break;
|
||||
case 'day':
|
||||
bottomXAxis.ticks(timeDay.every(every));
|
||||
break;
|
||||
case 'week':
|
||||
bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
|
||||
break;
|
||||
case 'month':
|
||||
bottomXAxis.ticks(timeMonth.every(every));
|
||||
break;
|
||||
// Get the time domain to check tick count
|
||||
const domain = timeScale.domain();
|
||||
const minTime = domain[0];
|
||||
const maxTime = domain[1];
|
||||
const estimatedTicks = getEstimatedTickCount(minTime, maxTime, every, interval);
|
||||
|
||||
if (estimatedTicks > MAX_TICK_COUNT) {
|
||||
log.warn(
|
||||
`The tick interval "${every}${interval}" would generate ${estimatedTicks} ticks, ` +
|
||||
`which exceeds the maximum allowed (${MAX_TICK_COUNT}). ` +
|
||||
`This may indicate an invalid date or time range. Skipping custom tick interval.`
|
||||
);
|
||||
// D3 using its default automatic tick generation
|
||||
} else {
|
||||
switch (interval) {
|
||||
case 'millisecond':
|
||||
bottomXAxis.ticks(timeMillisecond.every(every));
|
||||
break;
|
||||
case 'second':
|
||||
bottomXAxis.ticks(timeSecond.every(every));
|
||||
break;
|
||||
case 'minute':
|
||||
bottomXAxis.ticks(timeMinute.every(every));
|
||||
break;
|
||||
case 'hour':
|
||||
bottomXAxis.ticks(timeHour.every(every));
|
||||
break;
|
||||
case 'day':
|
||||
bottomXAxis.ticks(timeDay.every(every));
|
||||
break;
|
||||
case 'week':
|
||||
bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
|
||||
break;
|
||||
case 'month':
|
||||
bottomXAxis.ticks(timeMonth.every(every));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,32 +717,41 @@ export const draw = function (text, id, version, diagObj) {
|
||||
.tickFormat(timeFormat(axisFormat));
|
||||
|
||||
if (resultTickInterval !== null) {
|
||||
const every = resultTickInterval[1];
|
||||
const every = parseInt(resultTickInterval[1], 10);
|
||||
const interval = resultTickInterval[2];
|
||||
const weekday = diagObj.db.getWeekday() || conf.weekday;
|
||||
|
||||
switch (interval) {
|
||||
case 'millisecond':
|
||||
topXAxis.ticks(timeMillisecond.every(every));
|
||||
break;
|
||||
case 'second':
|
||||
topXAxis.ticks(timeSecond.every(every));
|
||||
break;
|
||||
case 'minute':
|
||||
topXAxis.ticks(timeMinute.every(every));
|
||||
break;
|
||||
case 'hour':
|
||||
topXAxis.ticks(timeHour.every(every));
|
||||
break;
|
||||
case 'day':
|
||||
topXAxis.ticks(timeDay.every(every));
|
||||
break;
|
||||
case 'week':
|
||||
topXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
|
||||
break;
|
||||
case 'month':
|
||||
topXAxis.ticks(timeMonth.every(every));
|
||||
break;
|
||||
// Get the time domain to check tick count
|
||||
const domain = timeScale.domain();
|
||||
const minTime = domain[0];
|
||||
const maxTime = domain[1];
|
||||
const estimatedTicks = getEstimatedTickCount(minTime, maxTime, every, interval);
|
||||
|
||||
// Only apply custom ticks if the count is reasonable
|
||||
if (estimatedTicks <= MAX_TICK_COUNT) {
|
||||
switch (interval) {
|
||||
case 'millisecond':
|
||||
topXAxis.ticks(timeMillisecond.every(every));
|
||||
break;
|
||||
case 'second':
|
||||
topXAxis.ticks(timeSecond.every(every));
|
||||
break;
|
||||
case 'minute':
|
||||
topXAxis.ticks(timeMinute.every(every));
|
||||
break;
|
||||
case 'hour':
|
||||
topXAxis.ticks(timeHour.every(every));
|
||||
break;
|
||||
case 'day':
|
||||
topXAxis.ticks(timeDay.every(every));
|
||||
break;
|
||||
case 'week':
|
||||
topXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
|
||||
break;
|
||||
case 'month':
|
||||
topXAxis.ticks(timeMonth.every(every));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"font-awesome": "^4.7.0",
|
||||
"jiti": "^2.4.2",
|
||||
"mermaid": "workspace:^",
|
||||
"vue": "^3.5.25"
|
||||
"vue": "^3.5.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/carbon": "^1.2.14",
|
||||
|
||||
@@ -283,7 +283,7 @@ block
|
||||
blockArrowId4<["Label"]>(down)
|
||||
blockArrowId5<["Label"]>(x)
|
||||
blockArrowId6<["Label"]>(y)
|
||||
blockArrowId6<["Label"]>(x, down)
|
||||
blockArrowId7<["Label"]>(x, down)
|
||||
```
|
||||
|
||||
#### Example - Space Blocks
|
||||
|
||||
@@ -42,7 +42,7 @@ radar-beta
|
||||
radar-beta
|
||||
title Restaurant Comparison
|
||||
axis food["Food Quality"], service["Service"], price["Price"]
|
||||
axis ambiance["Ambiance"],
|
||||
axis ambiance["Ambiance"]
|
||||
|
||||
curve a["Restaurant A"]{4, 3, 2, 4}
|
||||
curve b["Restaurant B"]{3, 4, 3, 3}
|
||||
|
||||
212
pnpm-lock.yaml
generated
212
pnpm-lock.yaml
generated
@@ -479,7 +479,7 @@ importers:
|
||||
version: 7.4.47
|
||||
'@vueuse/core':
|
||||
specifier: ^13.9.0
|
||||
version: 13.9.0(vue@3.5.25(typescript@5.9.2))
|
||||
version: 13.9.0(vue@3.5.24(typescript@5.9.2))
|
||||
font-awesome:
|
||||
specifier: ^4.7.0
|
||||
version: 4.7.0
|
||||
@@ -490,8 +490,8 @@ importers:
|
||||
specifier: workspace:^
|
||||
version: link:../..
|
||||
vue:
|
||||
specifier: ^3.5.25
|
||||
version: 3.5.25(typescript@5.9.2)
|
||||
specifier: ^3.5.24
|
||||
version: 3.5.24(typescript@5.9.2)
|
||||
devDependencies:
|
||||
'@iconify-json/carbon':
|
||||
specifier: ^1.2.14
|
||||
@@ -504,7 +504,7 @@ importers:
|
||||
version: 1.0.1(vite-plugin-pwa@1.0.3(vite@7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0))
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2(vite@7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))
|
||||
version: 6.0.2(vite@7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.24(typescript@5.9.2))
|
||||
fast-glob:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
@@ -519,7 +519,7 @@ importers:
|
||||
version: 66.5.9(postcss@8.5.6)(vite@7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))
|
||||
unplugin-vue-components:
|
||||
specifier: ^28.8.0
|
||||
version: 28.8.0(@babel/parser@7.28.5)(vue@3.5.25(typescript@5.9.2))
|
||||
version: 28.8.0(@babel/parser@7.28.5)(vue@3.5.24(typescript@5.9.2))
|
||||
vite:
|
||||
specifier: ^7.0.8
|
||||
version: 7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
|
||||
@@ -3705,39 +3705,39 @@ packages:
|
||||
'@vue/compiler-core@3.5.21':
|
||||
resolution: {integrity: sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==}
|
||||
|
||||
'@vue/compiler-core@3.5.23':
|
||||
resolution: {integrity: sha512-nW7THWj5HOp085ROk65LwaoxuzDsjIxr485F4iu63BoxsXoSqKqmsUUoP4A7Gl67DgIgi0zJ8JFgHfvny/74MA==}
|
||||
|
||||
'@vue/compiler-core@3.5.24':
|
||||
resolution: {integrity: sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==}
|
||||
|
||||
'@vue/compiler-core@3.5.25':
|
||||
resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==}
|
||||
|
||||
'@vue/compiler-dom@3.5.21':
|
||||
resolution: {integrity: sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==}
|
||||
|
||||
'@vue/compiler-dom@3.5.23':
|
||||
resolution: {integrity: sha512-AT8RMw0vEzzzO0JU5gY0F6iCzaWUIh/aaRVordzMBKXRpoTllTT4kocHDssByPsvodNCfump/Lkdow2mT/O5KQ==}
|
||||
|
||||
'@vue/compiler-dom@3.5.24':
|
||||
resolution: {integrity: sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==}
|
||||
|
||||
'@vue/compiler-dom@3.5.25':
|
||||
resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==}
|
||||
|
||||
'@vue/compiler-sfc@3.5.21':
|
||||
resolution: {integrity: sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==}
|
||||
|
||||
'@vue/compiler-sfc@3.5.23':
|
||||
resolution: {integrity: sha512-3QTEUo4qg7FtQwaDJa8ou1CUikx5WTtZlY61rRRDu3lK2ZKrGoAGG8mvDgOpDsQ4A1bez9s+WtBB6DS2KuFCPw==}
|
||||
|
||||
'@vue/compiler-sfc@3.5.24':
|
||||
resolution: {integrity: sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==}
|
||||
|
||||
'@vue/compiler-sfc@3.5.25':
|
||||
resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==}
|
||||
|
||||
'@vue/compiler-ssr@3.5.21':
|
||||
resolution: {integrity: sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==}
|
||||
|
||||
'@vue/compiler-ssr@3.5.23':
|
||||
resolution: {integrity: sha512-Hld2xphbMjXs9Q9WKxPf2EqmE+Rq/FEDnK/wUBtmYq74HCV4XDdSCheAaB823OQXIIFGq9ig/RbAZkF9s4U0Ow==}
|
||||
|
||||
'@vue/compiler-ssr@3.5.24':
|
||||
resolution: {integrity: sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==}
|
||||
|
||||
'@vue/compiler-ssr@3.5.25':
|
||||
resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==}
|
||||
|
||||
'@vue/devtools-api@7.7.7':
|
||||
resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==}
|
||||
|
||||
@@ -3750,40 +3750,40 @@ packages:
|
||||
'@vue/reactivity@3.5.21':
|
||||
resolution: {integrity: sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA==}
|
||||
|
||||
'@vue/reactivity@3.5.25':
|
||||
resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==}
|
||||
'@vue/reactivity@3.5.24':
|
||||
resolution: {integrity: sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==}
|
||||
|
||||
'@vue/runtime-core@3.5.21':
|
||||
resolution: {integrity: sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA==}
|
||||
|
||||
'@vue/runtime-core@3.5.25':
|
||||
resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==}
|
||||
'@vue/runtime-core@3.5.24':
|
||||
resolution: {integrity: sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==}
|
||||
|
||||
'@vue/runtime-dom@3.5.21':
|
||||
resolution: {integrity: sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w==}
|
||||
|
||||
'@vue/runtime-dom@3.5.25':
|
||||
resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==}
|
||||
'@vue/runtime-dom@3.5.24':
|
||||
resolution: {integrity: sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==}
|
||||
|
||||
'@vue/server-renderer@3.5.21':
|
||||
resolution: {integrity: sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA==}
|
||||
peerDependencies:
|
||||
vue: 3.5.21
|
||||
|
||||
'@vue/server-renderer@3.5.25':
|
||||
resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==}
|
||||
'@vue/server-renderer@3.5.24':
|
||||
resolution: {integrity: sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==}
|
||||
peerDependencies:
|
||||
vue: 3.5.25
|
||||
vue: 3.5.24
|
||||
|
||||
'@vue/shared@3.5.21':
|
||||
resolution: {integrity: sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==}
|
||||
|
||||
'@vue/shared@3.5.23':
|
||||
resolution: {integrity: sha512-0YZ1DYuC5o/YJPf6pFdt2KYxVGDxkDbH/1NYJnVJWUkzr8ituBEmFVQRNX2gCaAsFEjEDnLkWpgqlZA7htgS/g==}
|
||||
|
||||
'@vue/shared@3.5.24':
|
||||
resolution: {integrity: sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==}
|
||||
|
||||
'@vue/shared@3.5.25':
|
||||
resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==}
|
||||
|
||||
'@vueuse/core@12.8.2':
|
||||
resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==}
|
||||
|
||||
@@ -9828,8 +9828,8 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
vue@3.5.25:
|
||||
resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==}
|
||||
vue@3.5.24:
|
||||
resolution: {integrity: sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
@@ -14378,11 +14378,11 @@ snapshots:
|
||||
vite: 5.4.20(@types/node@22.19.1)(terser@5.44.1)
|
||||
vue: 3.5.21(typescript@5.9.2)
|
||||
|
||||
'@vitejs/plugin-vue@6.0.2(vite@7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))':
|
||||
'@vitejs/plugin-vue@6.0.2(vite@7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.24(typescript@5.9.2))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.50
|
||||
vite: 7.1.11(@types/node@22.19.1)(jiti@2.5.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
|
||||
'@vitest/coverage-v8@3.2.4(vitest@3.2.4)':
|
||||
dependencies:
|
||||
@@ -14415,7 +14415,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@vitest/spy': 3.2.4
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.21
|
||||
magic-string: 0.30.19
|
||||
optionalDependencies:
|
||||
vite: 7.1.11(@types/node@22.19.1)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
|
||||
|
||||
@@ -14432,7 +14432,7 @@ snapshots:
|
||||
'@vitest/snapshot@3.2.4':
|
||||
dependencies:
|
||||
'@vitest/pretty-format': 3.2.4
|
||||
magic-string: 0.30.21
|
||||
magic-string: 0.30.19
|
||||
pathe: 2.0.3
|
||||
|
||||
'@vitest/spy@3.2.4':
|
||||
@@ -14464,18 +14464,18 @@ snapshots:
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-core@3.5.24':
|
||||
'@vue/compiler-core@3.5.23':
|
||||
dependencies:
|
||||
'@babel/parser': 7.28.5
|
||||
'@vue/shared': 3.5.24
|
||||
'@vue/shared': 3.5.23
|
||||
entities: 4.5.0
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-core@3.5.25':
|
||||
'@vue/compiler-core@3.5.24':
|
||||
dependencies:
|
||||
'@babel/parser': 7.28.5
|
||||
'@vue/shared': 3.5.25
|
||||
'@vue/shared': 3.5.24
|
||||
entities: 4.5.0
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.2.1
|
||||
@@ -14485,16 +14485,16 @@ snapshots:
|
||||
'@vue/compiler-core': 3.5.21
|
||||
'@vue/shared': 3.5.21
|
||||
|
||||
'@vue/compiler-dom@3.5.23':
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.5.23
|
||||
'@vue/shared': 3.5.23
|
||||
|
||||
'@vue/compiler-dom@3.5.24':
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.5.24
|
||||
'@vue/shared': 3.5.24
|
||||
|
||||
'@vue/compiler-dom@3.5.25':
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
|
||||
'@vue/compiler-sfc@3.5.21':
|
||||
dependencies:
|
||||
'@babel/parser': 7.28.4
|
||||
@@ -14507,6 +14507,18 @@ snapshots:
|
||||
postcss: 8.5.6
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-sfc@3.5.23':
|
||||
dependencies:
|
||||
'@babel/parser': 7.28.5
|
||||
'@vue/compiler-core': 3.5.23
|
||||
'@vue/compiler-dom': 3.5.23
|
||||
'@vue/compiler-ssr': 3.5.23
|
||||
'@vue/shared': 3.5.23
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.21
|
||||
postcss: 8.5.6
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-sfc@3.5.24':
|
||||
dependencies:
|
||||
'@babel/parser': 7.28.5
|
||||
@@ -14519,33 +14531,21 @@ snapshots:
|
||||
postcss: 8.5.6
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-sfc@3.5.25':
|
||||
dependencies:
|
||||
'@babel/parser': 7.28.5
|
||||
'@vue/compiler-core': 3.5.25
|
||||
'@vue/compiler-dom': 3.5.25
|
||||
'@vue/compiler-ssr': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.21
|
||||
postcss: 8.5.6
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-ssr@3.5.21':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.21
|
||||
'@vue/shared': 3.5.21
|
||||
|
||||
'@vue/compiler-ssr@3.5.23':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.23
|
||||
'@vue/shared': 3.5.23
|
||||
|
||||
'@vue/compiler-ssr@3.5.24':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.24
|
||||
'@vue/shared': 3.5.24
|
||||
|
||||
'@vue/compiler-ssr@3.5.25':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
|
||||
'@vue/devtools-api@7.7.7':
|
||||
dependencies:
|
||||
'@vue/devtools-kit': 7.7.7
|
||||
@@ -14568,19 +14568,19 @@ snapshots:
|
||||
dependencies:
|
||||
'@vue/shared': 3.5.21
|
||||
|
||||
'@vue/reactivity@3.5.25':
|
||||
'@vue/reactivity@3.5.24':
|
||||
dependencies:
|
||||
'@vue/shared': 3.5.25
|
||||
'@vue/shared': 3.5.24
|
||||
|
||||
'@vue/runtime-core@3.5.21':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.5.21
|
||||
'@vue/shared': 3.5.21
|
||||
|
||||
'@vue/runtime-core@3.5.25':
|
||||
'@vue/runtime-core@3.5.24':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
'@vue/reactivity': 3.5.24
|
||||
'@vue/shared': 3.5.24
|
||||
|
||||
'@vue/runtime-dom@3.5.21':
|
||||
dependencies:
|
||||
@@ -14589,11 +14589,11 @@ snapshots:
|
||||
'@vue/shared': 3.5.21
|
||||
csstype: 3.1.3
|
||||
|
||||
'@vue/runtime-dom@3.5.25':
|
||||
'@vue/runtime-dom@3.5.24':
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.5.25
|
||||
'@vue/runtime-core': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
'@vue/reactivity': 3.5.24
|
||||
'@vue/runtime-core': 3.5.24
|
||||
'@vue/shared': 3.5.24
|
||||
csstype: 3.1.3
|
||||
|
||||
'@vue/server-renderer@3.5.21(vue@3.5.21(typescript@5.7.3))':
|
||||
@@ -14608,30 +14608,30 @@ snapshots:
|
||||
'@vue/shared': 3.5.21
|
||||
vue: 3.5.21(typescript@5.9.2)
|
||||
|
||||
'@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.7.3))':
|
||||
'@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.7.3))':
|
||||
dependencies:
|
||||
'@vue/compiler-ssr': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
vue: 3.5.25(typescript@5.7.3)
|
||||
'@vue/compiler-ssr': 3.5.24
|
||||
'@vue/shared': 3.5.24
|
||||
vue: 3.5.24(typescript@5.7.3)
|
||||
|
||||
'@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.9.2))':
|
||||
'@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.9.2))':
|
||||
dependencies:
|
||||
'@vue/compiler-ssr': 3.5.25
|
||||
'@vue/shared': 3.5.25
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
'@vue/compiler-ssr': 3.5.24
|
||||
'@vue/shared': 3.5.24
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
|
||||
'@vue/shared@3.5.21': {}
|
||||
|
||||
'@vue/shared@3.5.24': {}
|
||||
'@vue/shared@3.5.23': {}
|
||||
|
||||
'@vue/shared@3.5.25': {}
|
||||
'@vue/shared@3.5.24': {}
|
||||
|
||||
'@vueuse/core@12.8.2(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
'@vueuse/metadata': 12.8.2
|
||||
'@vueuse/shared': 12.8.2(typescript@5.7.3)
|
||||
vue: 3.5.25(typescript@5.7.3)
|
||||
vue: 3.5.24(typescript@5.7.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
@@ -14640,22 +14640,22 @@ snapshots:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
'@vueuse/metadata': 12.8.2
|
||||
'@vueuse/shared': 12.8.2(typescript@5.9.2)
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vueuse/core@13.9.0(vue@3.5.25(typescript@5.9.2))':
|
||||
'@vueuse/core@13.9.0(vue@3.5.24(typescript@5.9.2))':
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
'@vueuse/metadata': 13.9.0
|
||||
'@vueuse/shared': 13.9.0(vue@3.5.25(typescript@5.9.2))
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
'@vueuse/shared': 13.9.0(vue@3.5.24(typescript@5.9.2))
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
|
||||
'@vueuse/integrations@12.8.2(axios@1.13.2)(change-case@5.4.4)(focus-trap@7.6.5)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@vueuse/core': 12.8.2(typescript@5.7.3)
|
||||
'@vueuse/shared': 12.8.2(typescript@5.7.3)
|
||||
vue: 3.5.25(typescript@5.7.3)
|
||||
vue: 3.5.24(typescript@5.7.3)
|
||||
optionalDependencies:
|
||||
axios: 1.13.2(debug@4.4.3)
|
||||
change-case: 5.4.4
|
||||
@@ -14667,7 +14667,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@vueuse/core': 12.8.2(typescript@5.9.2)
|
||||
'@vueuse/shared': 12.8.2(typescript@5.9.2)
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
optionalDependencies:
|
||||
axios: 1.13.2(debug@4.4.3)
|
||||
change-case: 5.4.4
|
||||
@@ -14681,19 +14681,19 @@ snapshots:
|
||||
|
||||
'@vueuse/shared@12.8.2(typescript@5.7.3)':
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.7.3)
|
||||
vue: 3.5.24(typescript@5.7.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vueuse/shared@12.8.2(typescript@5.9.2)':
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vueuse/shared@13.9.0(vue@3.5.25(typescript@5.9.2))':
|
||||
'@vueuse/shared@13.9.0(vue@3.5.24(typescript@5.9.2))':
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
|
||||
'@wdio/config@7.31.1(typescript@5.7.3)':
|
||||
dependencies:
|
||||
@@ -16467,7 +16467,7 @@ snapshots:
|
||||
detective-vue2@2.2.0(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@dependents/detective-less': 5.0.1
|
||||
'@vue/compiler-sfc': 3.5.24
|
||||
'@vue/compiler-sfc': 3.5.23
|
||||
detective-es6: 5.0.1
|
||||
detective-sass: 6.0.1
|
||||
detective-scss: 5.0.1
|
||||
@@ -21583,7 +21583,7 @@ snapshots:
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.3
|
||||
|
||||
unplugin-vue-components@28.8.0(@babel/parser@7.28.5)(vue@3.5.25(typescript@5.9.2)):
|
||||
unplugin-vue-components@28.8.0(@babel/parser@7.28.5)(vue@3.5.24(typescript@5.9.2)):
|
||||
dependencies:
|
||||
chokidar: 3.6.0
|
||||
debug: 4.4.3(supports-color@8.1.1)
|
||||
@@ -21593,7 +21593,7 @@ snapshots:
|
||||
tinyglobby: 0.2.15
|
||||
unplugin: 2.3.10
|
||||
unplugin-utils: 0.2.5
|
||||
vue: 3.5.25(typescript@5.9.2)
|
||||
vue: 3.5.24(typescript@5.9.2)
|
||||
optionalDependencies:
|
||||
'@babel/parser': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
@@ -21983,23 +21983,23 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.9.2
|
||||
|
||||
vue@3.5.25(typescript@5.7.3):
|
||||
vue@3.5.24(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.25
|
||||
'@vue/compiler-sfc': 3.5.25
|
||||
'@vue/runtime-dom': 3.5.25
|
||||
'@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.7.3))
|
||||
'@vue/shared': 3.5.25
|
||||
'@vue/compiler-dom': 3.5.24
|
||||
'@vue/compiler-sfc': 3.5.24
|
||||
'@vue/runtime-dom': 3.5.24
|
||||
'@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.7.3))
|
||||
'@vue/shared': 3.5.24
|
||||
optionalDependencies:
|
||||
typescript: 5.7.3
|
||||
|
||||
vue@3.5.25(typescript@5.9.2):
|
||||
vue@3.5.24(typescript@5.9.2):
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.25
|
||||
'@vue/compiler-sfc': 3.5.25
|
||||
'@vue/runtime-dom': 3.5.25
|
||||
'@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.9.2))
|
||||
'@vue/shared': 3.5.25
|
||||
'@vue/compiler-dom': 3.5.24
|
||||
'@vue/compiler-sfc': 3.5.24
|
||||
'@vue/runtime-dom': 3.5.24
|
||||
'@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.9.2))
|
||||
'@vue/shared': 3.5.24
|
||||
optionalDependencies:
|
||||
typescript: 5.9.2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user