Compare commits

..

5 Commits

Author SHA1 Message Date
orangecoding
d09770dae2 fancy, almost impossible to see animation on dashboard 2026-02-05 09:54:42 +01:00
orangecoding
248e4d2562 improve tracking 2026-02-04 14:41:55 +01:00
orangecoding
7b8e961b49 adding confirmation dialog if to remove listing entirely from db or just hide it 2026-02-03 14:04:40 +01:00
orangecoding
f66ceccbb4 next release version 2026-01-29 13:01:39 +01:00
orangecoding
a3db725af6 fixing image rendering 2026-01-29 13:01:07 +01:00
12 changed files with 519 additions and 245 deletions

View File

@@ -107,7 +107,7 @@ listingsRouter.post('/watch', async (req, res) => {
});
listingsRouter.delete('/job', async (req, res) => {
const { jobId } = req.body;
const { jobId, hardDelete = false } = req.body;
const settings = await getSettings();
try {
if (settings.demoMode) {
@@ -115,7 +115,7 @@ listingsRouter.delete('/job', async (req, res) => {
return;
}
listingStorage.deleteListingsByJobId(jobId);
listingStorage.deleteListingsByJobId(jobId, hardDelete);
} catch (error) {
res.send(new Error(error));
logger.error(error);
@@ -124,10 +124,10 @@ listingsRouter.delete('/job', async (req, res) => {
});
listingsRouter.delete('/', async (req, res) => {
const { ids } = req.body;
const { ids, hardDelete = false } = req.body;
try {
if (Array.isArray(ids) && ids.length > 0) {
listingStorage.deleteListingsById(ids);
listingStorage.deleteListingsById(ids, hardDelete);
}
} catch (error) {
res.send(new Error(error));

View File

@@ -37,12 +37,12 @@ export const upsertJob = ({
if (existing) {
SqliteConnection.execute(
`UPDATE jobs
SET enabled = @enabled,
name = @name,
blacklist = @blacklist,
provider = @provider,
notification_adapter = @notification_adapter,
shared_with_user = @shareWithUsers
SET enabled = @enabled,
name = @name,
blacklist = @blacklist,
provider = @provider,
notification_adapter = @notification_adapter,
shared_with_user = @shareWithUsers
WHERE id = @id`,
{
id,
@@ -87,10 +87,10 @@ export const getJob = (jobId) => {
j.provider,
j.shared_with_user,
j.notification_adapter AS notificationAdapter,
(SELECT COUNT(1) FROM listings l WHERE l.job_id = j.id) AS numberOfFoundListings
FROM jobs j
WHERE j.id = @id
LIMIT 1`,
(SELECT COUNT(1) FROM listings l WHERE l.job_id = j.id AND l.is_active = 1 AND l.manually_deleted = 0) AS numberOfFoundListings
FROM jobs j
WHERE j.id = @id
LIMIT 1`,
{ id: jobId },
)[0];
if (!row) return null;
@@ -150,9 +150,10 @@ export const getJobs = () => {
j.provider,
j.shared_with_user,
j.notification_adapter AS notificationAdapter,
(SELECT COUNT(1) FROM listings l WHERE l.job_id = j.id) AS numberOfFoundListings
FROM jobs j
ORDER BY j.name IS NULL, j.name`,
(SELECT COUNT(1) FROM listings l WHERE l.job_id = j.id AND l.is_active = 1 AND l.manually_deleted = 0) AS numberOfFoundListings
FROM jobs j
WHERE j.enabled = 1
ORDER BY j.name IS NULL, j.name`,
);
return rows.map((row) => ({
...row,
@@ -250,11 +251,11 @@ export const queryJobs = ({
j.provider,
j.shared_with_user,
j.notification_adapter AS notificationAdapter,
(SELECT COUNT(1) FROM listings l WHERE l.job_id = j.id) AS numberOfFoundListings
(SELECT COUNT(1) FROM listings l WHERE l.job_id = j.id AND l.is_active = 1 AND l.manually_deleted = 0) AS numberOfFoundListings
FROM jobs j
${whereSql}
${orderSql}
LIMIT @limit OFFSET @offset`,
${orderSql}
LIMIT @limit OFFSET @offset`,
params,
);

View File

@@ -370,10 +370,18 @@ export const queryListings = ({
* Delete all listings for a given job id.
*
* @param {string} jobId - The job identifier whose listings should be removed.
* @returns {any} The result from SqliteConnection.execute (may contain changes count).
* @param {boolean} [hardDelete=false] - Whether to hard delete from DB or just mark as deleted.
* @returns {any} The result from SqliteConnection.execute.
*/
export const deleteListingsByJobId = (jobId) => {
export const deleteListingsByJobId = (jobId, hardDelete = false) => {
if (!jobId) return;
if (hardDelete) {
return SqliteConnection.execute(
`DELETE FROM listings
WHERE job_id = @jobId`,
{ jobId },
);
}
return SqliteConnection.execute(
`UPDATE listings
SET manually_deleted = 1
@@ -386,11 +394,19 @@ export const deleteListingsByJobId = (jobId) => {
* Delete listings by a list of listing IDs.
*
* @param {string[]} ids - Array of listing IDs to delete.
* @param {boolean} [hardDelete=false] - Whether to hard delete from DB or just mark as deleted.
* @returns {any} The result from SqliteConnection.execute.
*/
export const deleteListingsById = (ids) => {
export const deleteListingsById = (ids, hardDelete = false) => {
if (!Array.isArray(ids) || ids.length === 0) return;
const placeholders = ids.map(() => '?').join(',');
if (hardDelete) {
return SqliteConnection.execute(
`DELETE FROM listings
WHERE id IN (${placeholders})`,
ids,
);
}
return SqliteConnection.execute(
`UPDATE listings
SET manually_deleted = 1

View File

@@ -15,55 +15,67 @@ const deviceId = getUniqueId() || 'N/A';
const version = await getPackageVersion();
const FREDY_TRACKING_URL = 'https://fredy.orange-coding.net/tracking';
export const trackMainEvent = async () => {
const staticTrackingData = {
operatingSystem: os.platform(),
osVersion: os.release(),
arch: process.arch,
language: process.env.LANG || 'en',
nodeVersion: process.version || 'N/A',
deviceId,
version,
};
const shouldTrack = async () => {
const settings = await getSettings();
return settings.analyticsEnabled && !inDevMode();
};
const sendTrackingData = async (endpoint, payload) => {
try {
const settings = await getSettings();
if (settings.analyticsEnabled && !inDevMode()) {
const activeProvider = new Set();
const activeAdapter = new Set();
const jobs = getJobs();
if (jobs != null && jobs.length > 0) {
jobs.forEach((job) => {
job.provider.forEach((provider) => activeProvider.add(provider.id));
job.notificationAdapter.forEach((adapter) => activeAdapter.add(adapter.id));
});
const trackingObj = enrichTrackingObject({
adapter: Array.from(activeAdapter),
provider: Array.from(activeProvider),
});
await fetch(`${FREDY_TRACKING_URL}/main`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(trackingObj),
});
}
const response = await fetch(`${FREDY_TRACKING_URL}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: payload ? JSON.stringify(payload) : undefined,
});
if (!response.ok) {
logger.warn(`Error sending tracking data to ${endpoint}. Status: ${response.status}`);
}
} catch (error) {
logger.warn('Error sending tracking data', error);
logger.warn(`Error sending tracking data to ${endpoint}`, error);
}
};
export const trackMainEvent = async () => {
if (!(await shouldTrack())) return;
const activeProvider = new Set();
const activeAdapter = new Set();
const jobs = getJobs();
if (jobs != null && jobs.length > 0) {
jobs.forEach((job) => {
job.provider.forEach((provider) => activeProvider.add(provider.id));
job.notificationAdapter.forEach((adapter) => activeAdapter.add(adapter.id));
});
const trackingObj = await enrichTrackingObject({
adapter: Array.from(activeAdapter),
provider: Array.from(activeProvider),
});
await sendTrackingData('/main', trackingObj);
}
};
export const trackFeature = async (feature) => {
try {
const settings = await getSettings();
if (settings.analyticsEnabled && !inDevMode()) {
const trackingObj = await enrichTrackingObject({
feature,
});
if (!(await shouldTrack())) return;
await fetch(`${FREDY_TRACKING_URL}/feature`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(trackingObj),
});
}
} catch (error) {
logger.warn('Error tracking feature', error);
}
const trackingObj = await enrichTrackingObject({
feature,
});
await sendTrackingData('/feature', trackingObj);
};
/**
@@ -72,34 +84,17 @@ export const trackFeature = async (feature) => {
export async function trackDemoAccessed() {
const settings = await getSettings();
if (settings.analyticsEnabled && !inDevMode() && settings.demoMode) {
try {
await fetch(`${FREDY_TRACKING_URL}/demo/accessed`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
logger.warn('Error sending tracking data', error);
}
const trackingObj = await enrichTrackingObject({});
await sendTrackingData('/demo/accessed', trackingObj);
}
}
async function enrichTrackingObject(trackingObject) {
const settings = await getSettings();
const operatingSystem = os.platform();
const osVersion = os.release();
const arch = process.arch;
const language = process.env.LANG || 'en';
const nodeVersion = process.version || 'N/A';
return {
...trackingObject,
...staticTrackingData,
isDemo: settings.demoMode,
operatingSystem,
osVersion,
arch,
nodeVersion,
language,
deviceId,
version,
};
}

View File

@@ -1,6 +1,6 @@
{
"name": "fredy",
"version": "19.3.3",
"version": "19.3.6",
"description": "[F]ind [R]eal [E]states [d]amn eas[y].",
"scripts": {
"prepare": "husky",
@@ -63,7 +63,7 @@
"@douyinfe/semi-ui": "2.90.13",
"@douyinfe/semi-ui-19": "^2.90.13",
"@sendgrid/mail": "8.1.6",
"@vitejs/plugin-react": "5.1.2",
"@vitejs/plugin-react": "5.1.3",
"adm-zip": "^0.5.16",
"better-sqlite3": "^12.6.2",
"body-parser": "2.2.2",
@@ -95,12 +95,12 @@
"slack": "11.0.2",
"vite": "7.3.1",
"x-var": "^3.0.1",
"zustand": "^5.0.10"
"zustand": "^5.0.11"
},
"devDependencies": {
"@babel/core": "7.28.6",
"@babel/core": "7.29.0",
"@babel/eslint-parser": "7.28.6",
"@babel/preset-env": "7.28.6",
"@babel/preset-env": "7.29.0",
"@babel/preset-react": "7.28.5",
"chai": "6.2.2",
"eslint": "9.39.2",

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2026 by Christian Kellner.
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
*/
import React, { useState } from 'react';
import { Modal, Radio, RadioGroup, Typography } from '@douyinfe/semi-ui-19';
const { Text } = Typography;
const ListingDeletionModal = ({
visible,
onConfirm,
onCancel,
title = 'Delete Listings',
showOptions = true,
message = 'How would you like to delete the selected listing(s)?',
}) => {
const [deleteType, setDeleteType] = useState('soft');
const handleOk = () => {
onConfirm(!showOptions || deleteType === 'hard');
};
return (
<Modal
title={title}
visible={visible}
onOk={handleOk}
onCancel={onCancel}
okText="Confirm"
cancelText="Cancel"
style={{ maxWidth: '500px' }}
>
<div style={{ marginBottom: 16 }}>
<Text>{message}</Text>
</div>
{showOptions && (
<RadioGroup value={deleteType} onChange={(e) => setDeleteType(e.target.value)} style={{ width: '100%' }}>
<Radio value="soft" style={{ alignItems: 'flex-start', width: '100%' }}>
<div style={{ marginLeft: 8 }}>
<Text strong>Mark as deleted (Soft Delete)</Text>
<br />
<Text type="secondary">
Listings are kept in the database but marked as hidden. They will <b>not</b> re-appear during the next
scraping session.
</Text>
</div>
</Radio>
<Radio value="hard" style={{ marginTop: 16, alignItems: 'flex-start', width: '100%' }}>
<div style={{ marginLeft: 8 }}>
<Text strong>Remove from database (Hard Delete)</Text>
<br />
<Text type="secondary">
Listings are completely removed from the database.
<br />
<Text type="warning">
Consequence: They might re-appear when scraping the next time because Fredy won't know they were
previously found.
</Text>
</Text>
</div>
</Radio>
</RadioGroup>
)}
</Modal>
);
};
export default ListingDeletionModal;

View File

@@ -2,30 +2,29 @@
width: 100%;
height: 140px;
margin-bottom: 16px;
transition: transform 0.2s, box-shadow 0.2s;
transition: transform 0.2s;
background-color: rgba(36, 36, 36, 0.9);
backdrop-filter: blur(8px);
border: 1px solid var(--semi-color-border);
--pulse-color: rgba(255, 255, 255, 0.1);
position: relative;
z-index: 1;
overflow: visible;
&:hover {
transform: translateY(-4px);
background-color: rgba(36, 36, 36, 1);
&.blue {
box-shadow: 0 8px 24px -5px var(--semi-color-primary);
}
&.orange {
box-shadow: 0 8px 24px -5px var(--semi-color-warning);
}
&.green {
box-shadow: 0 8px 24px -5px var(--semi-color-success);
}
&.purple {
box-shadow: 0 8px 24px -5px var(--semi-color-info);
}
&.gray {
box-shadow: 0 8px 24px -5px rgba(255, 255, 255, 0.4);
}
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: inherit;
box-shadow: 0 4px 25px -2px var(--pulse-color);
opacity: 0;
animation: pulse 5s infinite ease-in-out;
pointer-events: none;
z-index: -1;
will-change: opacity;
}
&__icon {
@@ -46,22 +45,36 @@
}
&.blue {
box-shadow: 0 4px 20px -5px var(--semi-color-primary);
--pulse-color: var(--semi-color-primary);
box-shadow: 0 4px 20px -5px var(--pulse-color);
}
&.orange {
box-shadow: 0 4px 20px -5px var(--semi-color-warning);
--pulse-color: var(--semi-color-warning);
box-shadow: 0 4px 20px -5px var(--pulse-color);
}
&.green {
box-shadow: 0 4px 20px -5px var(--semi-color-success);
--pulse-color: var(--semi-color-success);
box-shadow: 0 4px 20px -5px var(--pulse-color);
}
&.purple {
box-shadow: 0 4px 20px -5px var(--semi-color-info);
--pulse-color: var(--semi-color-info);
box-shadow: 0 4px 20px -5px var(--pulse-color);
}
&.gray {
box-shadow: 0 4px 20px -5px rgba(255, 255, 255, 0.2);
--pulse-color: rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 20px -5px var(--pulse-color);
}
}
@keyframes pulse {
0%, 100% {
opacity: 0.1;
}
50% {
opacity: 0.5;
}
}

View File

@@ -35,6 +35,7 @@ import {
IconPlusCircle,
} from '@douyinfe/semi-icons';
import { useNavigate } from 'react-router-dom';
import ListingDeletionModal from '../../ListingDeletionModal.jsx';
import { useActions, useSelector } from '../../../services/state/store.js';
import { xhrDelete, xhrPut, xhrPost } from '../../../services/xhr.js';
import debounce from 'lodash/debounce';
@@ -60,6 +61,9 @@ const JobGrid = () => {
const [activityFilter, setActivityFilter] = useState(null);
const [showFilterBar, setShowFilterBar] = useState(false);
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
const [pendingDeletion, setPendingDeletion] = useState(null); // { type: 'job'|'listings', jobId }
const pendingJobIdRef = useRef(null);
const evtSourceRef = useRef(null);
@@ -125,24 +129,35 @@ const JobGrid = () => {
};
}, [handleFilterChange]);
const onJobRemoval = async (jobId) => {
try {
await xhrDelete('/api/jobs', { jobId });
Toast.success('Job successfully removed');
loadData();
actions.jobsData.getJobs(); // refresh select list too
} catch (error) {
Toast.error(error);
}
const onJobRemoval = (jobId) => {
setPendingDeletion({ type: 'job', jobId });
setDeleteModalVisible(true);
};
const onListingRemoval = async (jobId) => {
const onListingRemoval = (jobId) => {
setPendingDeletion({ type: 'listings', jobId });
setDeleteModalVisible(true);
};
const confirmDeletion = async (hardDelete) => {
const { type, jobId } = pendingDeletion;
try {
await xhrDelete('/api/listings/job', { jobId });
Toast.success('Listings successfully removed');
if (type === 'job') {
await xhrDelete('/api/jobs', { jobId });
Toast.success('Job and listings successfully removed');
} else if (type === 'listings') {
await xhrDelete('/api/listings/job', { jobId, hardDelete });
Toast.success('Listings successfully removed');
}
loadData();
if (type === 'job') {
actions.jobsData.getJobs(); // refresh select list too
}
} catch (error) {
Toast.error(error);
Toast.error(error.message || 'Error performing deletion');
} finally {
setDeleteModalVisible(false);
setPendingDeletion(null);
}
};
@@ -410,6 +425,21 @@ const JobGrid = () => {
/>
</div>
)}
<ListingDeletionModal
visible={deleteModalVisible}
title={pendingDeletion?.type === 'job' ? 'Delete Job' : 'Delete Listings'}
showOptions={pendingDeletion?.type !== 'job'}
message={
pendingDeletion?.type === 'job'
? 'Are you sure you want to delete this job? All associated listings will be removed from the database.'
: 'How would you like to delete the selected listing(s)?'
}
onConfirm={confirmDeletion}
onCancel={() => {
setDeleteModalVisible(false);
setPendingDeletion(null);
}}
/>
</div>
);
};

View File

@@ -35,6 +35,7 @@ import {
IconEyeOpened,
} from '@douyinfe/semi-icons';
import { useNavigate } from 'react-router-dom';
import ListingDeletionModal from '../../ListingDeletionModal.jsx';
import no_image from '../../../assets/no_image.jpg';
import * as timeService from '../../../services/time/timeService.js';
import { xhrDelete, xhrPost } from '../../../services/xhr.js';
@@ -65,6 +66,9 @@ const ListingsGrid = () => {
const [providerFilter, setProviderFilter] = useState(null);
const [showFilterBar, setShowFilterBar] = useState(false);
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
const [listingToDelete, setListingToDelete] = useState(null);
const loadData = () => {
actions.listingsData.getListingsData({
page,
@@ -106,6 +110,19 @@ const ListingsGrid = () => {
setPage(_page);
};
const confirmDeletion = async (hardDelete) => {
try {
await xhrDelete('/api/listings/', { ids: [listingToDelete], hardDelete });
Toast.success('Listing successfully removed');
loadData();
} catch (error) {
Toast.error(error.message || 'Error deleting listing');
} finally {
setDeleteModalVisible(false);
setListingToDelete(null);
}
};
const cap = (val) => {
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
};
@@ -312,15 +329,10 @@ const ListingsGrid = () => {
title="Remove"
type="danger"
size="small"
onClick={async (e) => {
onClick={(e) => {
e.stopPropagation();
try {
await xhrDelete('/api/listings/', { ids: [item.id] });
Toast.success('Listing(s) successfully removed');
loadData();
} catch (error) {
Toast.error(error);
}
setListingToDelete(item.id);
setDeleteModalVisible(true);
}}
icon={<IconDelete />}
/>
@@ -341,6 +353,14 @@ const ListingsGrid = () => {
/>
</div>
)}
<ListingDeletionModal
visible={deleteModalVisible}
onConfirm={confirmDeletion}
onCancel={() => {
setDeleteModalVisible(false);
setListingToDelete(null);
}}
/>
</div>
);
};

View File

@@ -324,7 +324,12 @@ export default function ListingDetail() {
<Row>
<Col span={24} lg={12}>
<div className="listing-detail__image-container">
<Image src={listing.image_url || no_image} fallback={no_image} preview={true} />
<Image
src={listing.image_url}
fallback={no_image}
style={{ width: '100%', height: '100%' }}
preview={true}
/>
</div>
</Col>
<Col span={24} lg={12}>

View File

@@ -19,6 +19,7 @@ import 'react-range-slider-input/dist/style.css';
import './Map.less';
import { xhrDelete } from '../../services/xhr.js';
import { Link, useNavigate } from 'react-router-dom';
import ListingDeletionModal from '../../components/ListingDeletionModal.jsx';
const { Text } = Typography;
@@ -85,6 +86,22 @@ export default function MapView() {
const [showFilterBar, setShowFilterBar] = useState(false);
const [distanceFilter, setDistanceFilter] = useState(0);
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
const [listingToDelete, setListingToDelete] = useState(null);
const confirmListingDeletion = async (hardDelete) => {
try {
await xhrDelete('/api/listings/', { ids: [listingToDelete], hardDelete });
Toast.success('Listing successfully removed');
fetchListings();
} catch (error) {
Toast.error(error.message || 'Error deleting listing');
} finally {
setDeleteModalVisible(false);
setListingToDelete(null);
}
};
useEffect(() => {
setPriceRange([0, getMaxPrice()]);
}, [listings]);
@@ -104,14 +121,9 @@ export default function MapView() {
};
useEffect(() => {
window.deleteListing = async (id) => {
try {
await xhrDelete('/api/listings/', { ids: [id] });
Toast.success('Listing successfully removed');
fetchListings();
} catch (error) {
Toast.error(error.message || 'Error deleting listing');
}
window.deleteListing = (id) => {
setListingToDelete(id);
setDeleteModalVisible(true);
};
window.viewDetails = (id) => {
@@ -378,7 +390,10 @@ export default function MapView() {
const popupContent = `
<div class="map-popup-content">
<img src="${listing.image_url || no_image}" alt="${listing.title}" />
<img
src="${listing.image_url}"
onerror="this.onerror=null;this.src='${no_image}'"
/>
<h4>${listing.title}</h4>
<div class="info">
<span><strong>Price:</strong> ${listing.price ? listing.price + ' €' : 'N/A'}</span>
@@ -559,6 +574,14 @@ export default function MapView() {
/>
<div ref={mapContainer} className="map-container" />
<ListingDeletionModal
visible={deleteModalVisible}
onConfirm={confirmListingDeletion}
onCancel={() => {
setDeleteModalVisible(false);
setListingToDelete(null);
}}
/>
</div>
);
}

301
yarn.lock
View File

@@ -20,25 +20,39 @@
js-tokens "^4.0.0"
picocolors "^1.1.1"
"@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.6":
"@babel/code-frame@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c"
integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
dependencies:
"@babel/helper-validator-identifier" "^7.28.5"
js-tokens "^4.0.0"
picocolors "^1.1.1"
"@babel/compat-data@^7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz"
integrity sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==
"@babel/core@7.28.6", "@babel/core@^7.28.5":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz"
integrity sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==
"@babel/compat-data@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d"
integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==
"@babel/core@7.29.0", "@babel/core@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322"
integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==
dependencies:
"@babel/code-frame" "^7.28.6"
"@babel/generator" "^7.28.6"
"@babel/code-frame" "^7.29.0"
"@babel/generator" "^7.29.0"
"@babel/helper-compilation-targets" "^7.28.6"
"@babel/helper-module-transforms" "^7.28.6"
"@babel/helpers" "^7.28.6"
"@babel/parser" "^7.28.6"
"@babel/parser" "^7.29.0"
"@babel/template" "^7.28.6"
"@babel/traverse" "^7.28.6"
"@babel/types" "^7.28.6"
"@babel/traverse" "^7.29.0"
"@babel/types" "^7.29.0"
"@jridgewell/remapping" "^2.3.5"
convert-source-map "^2.0.0"
debug "^4.1.0"
@@ -66,6 +80,17 @@
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
"@babel/generator@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.0.tgz#4cba5a76b3c71d8be31761b03329d5dc7768447f"
integrity sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==
dependencies:
"@babel/parser" "^7.29.0"
"@babel/types" "^7.29.0"
"@jridgewell/gen-mapping" "^0.3.12"
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3":
version "7.27.3"
resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz"
@@ -73,7 +98,7 @@
dependencies:
"@babel/types" "^7.27.3"
"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2", "@babel/helper-compilation-targets@^7.28.6":
"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz"
integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==
@@ -106,16 +131,16 @@
regexpu-core "^6.3.1"
semver "^6.3.1"
"@babel/helper-define-polyfill-provider@^0.6.5":
version "0.6.5"
resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz"
integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==
"@babel/helper-define-polyfill-provider@^0.6.6":
version "0.6.6"
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz#714dfe33d8bd710f556df59953720f6eeb6c1a14"
integrity sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==
dependencies:
"@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-plugin-utils" "^7.27.1"
debug "^4.4.1"
"@babel/helper-compilation-targets" "^7.28.6"
"@babel/helper-plugin-utils" "^7.28.6"
debug "^4.4.3"
lodash.debounce "^4.0.8"
resolve "^1.22.10"
resolve "^1.22.11"
"@babel/helper-globals@^7.28.0":
version "7.28.0"
@@ -138,7 +163,7 @@
"@babel/traverse" "^7.28.6"
"@babel/types" "^7.28.6"
"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3", "@babel/helper-module-transforms@^7.28.6":
"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz"
integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
@@ -224,6 +249,13 @@
dependencies:
"@babel/types" "^7.28.6"
"@babel/parser@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6"
integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==
dependencies:
"@babel/types" "^7.29.0"
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz"
@@ -304,14 +336,14 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-async-generator-functions@^7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.6.tgz"
integrity sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==
"@babel/plugin-transform-async-generator-functions@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz#63ed829820298f0bf143d5a4a68fb8c06ffd742f"
integrity sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==
dependencies:
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/helper-remap-async-to-generator" "^7.27.1"
"@babel/traverse" "^7.28.6"
"@babel/traverse" "^7.29.0"
"@babel/plugin-transform-async-to-generator@^7.28.6":
version "7.28.6"
@@ -395,10 +427,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.28.6.tgz"
integrity sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==
"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz#8014b8a6cfd0e7b92762724443bf0d2400f26df1"
integrity sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.28.5"
"@babel/helper-plugin-utils" "^7.28.6"
@@ -493,15 +525,15 @@
"@babel/helper-module-transforms" "^7.28.6"
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/plugin-transform-modules-systemjs@^7.28.5":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz"
integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==
"@babel/plugin-transform-modules-systemjs@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz#e458a95a17807c415924106a3ff188a3b8dee964"
integrity sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==
dependencies:
"@babel/helper-module-transforms" "^7.28.3"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-module-transforms" "^7.28.6"
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/helper-validator-identifier" "^7.28.5"
"@babel/traverse" "^7.28.5"
"@babel/traverse" "^7.29.0"
"@babel/plugin-transform-modules-umd@^7.27.1":
version "7.27.1"
@@ -511,13 +543,13 @@
"@babel/helper-module-transforms" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz"
integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==
"@babel/plugin-transform-named-capturing-groups-regex@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz#a26cd51e09c4718588fc4cce1c5d1c0152102d6a"
integrity sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-create-regexp-features-plugin" "^7.28.5"
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/plugin-transform-new-target@^7.27.1":
version "7.27.1"
@@ -652,10 +684,10 @@
"@babel/helper-annotate-as-pure" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-regenerator@^7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.6.tgz"
integrity sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==
"@babel/plugin-transform-regenerator@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz#dec237cec1b93330876d6da9992c4abd42c9d18b"
integrity sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==
dependencies:
"@babel/helper-plugin-utils" "^7.28.6"
@@ -741,12 +773,12 @@
"@babel/helper-create-regexp-features-plugin" "^7.28.5"
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/preset-env@7.28.6":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.6.tgz"
integrity sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==
"@babel/preset-env@7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.0.tgz#c55db400c515a303662faaefd2d87e796efa08d0"
integrity sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==
dependencies:
"@babel/compat-data" "^7.28.6"
"@babel/compat-data" "^7.29.0"
"@babel/helper-compilation-targets" "^7.28.6"
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/helper-validator-option" "^7.27.1"
@@ -760,7 +792,7 @@
"@babel/plugin-syntax-import-attributes" "^7.28.6"
"@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
"@babel/plugin-transform-arrow-functions" "^7.27.1"
"@babel/plugin-transform-async-generator-functions" "^7.28.6"
"@babel/plugin-transform-async-generator-functions" "^7.29.0"
"@babel/plugin-transform-async-to-generator" "^7.28.6"
"@babel/plugin-transform-block-scoped-functions" "^7.27.1"
"@babel/plugin-transform-block-scoping" "^7.28.6"
@@ -771,7 +803,7 @@
"@babel/plugin-transform-destructuring" "^7.28.5"
"@babel/plugin-transform-dotall-regex" "^7.28.6"
"@babel/plugin-transform-duplicate-keys" "^7.27.1"
"@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.28.6"
"@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.29.0"
"@babel/plugin-transform-dynamic-import" "^7.27.1"
"@babel/plugin-transform-explicit-resource-management" "^7.28.6"
"@babel/plugin-transform-exponentiation-operator" "^7.28.6"
@@ -784,9 +816,9 @@
"@babel/plugin-transform-member-expression-literals" "^7.27.1"
"@babel/plugin-transform-modules-amd" "^7.27.1"
"@babel/plugin-transform-modules-commonjs" "^7.28.6"
"@babel/plugin-transform-modules-systemjs" "^7.28.5"
"@babel/plugin-transform-modules-systemjs" "^7.29.0"
"@babel/plugin-transform-modules-umd" "^7.27.1"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.29.0"
"@babel/plugin-transform-new-target" "^7.27.1"
"@babel/plugin-transform-nullish-coalescing-operator" "^7.28.6"
"@babel/plugin-transform-numeric-separator" "^7.28.6"
@@ -798,7 +830,7 @@
"@babel/plugin-transform-private-methods" "^7.28.6"
"@babel/plugin-transform-private-property-in-object" "^7.28.6"
"@babel/plugin-transform-property-literals" "^7.27.1"
"@babel/plugin-transform-regenerator" "^7.28.6"
"@babel/plugin-transform-regenerator" "^7.29.0"
"@babel/plugin-transform-regexp-modifiers" "^7.28.6"
"@babel/plugin-transform-reserved-words" "^7.27.1"
"@babel/plugin-transform-shorthand-properties" "^7.27.1"
@@ -811,10 +843,10 @@
"@babel/plugin-transform-unicode-regex" "^7.27.1"
"@babel/plugin-transform-unicode-sets-regex" "^7.28.6"
"@babel/preset-modules" "0.1.6-no-external-plugins"
babel-plugin-polyfill-corejs2 "^0.4.14"
babel-plugin-polyfill-corejs3 "^0.13.0"
babel-plugin-polyfill-regenerator "^0.6.5"
core-js-compat "^3.43.0"
babel-plugin-polyfill-corejs2 "^0.4.15"
babel-plugin-polyfill-corejs3 "^0.14.0"
babel-plugin-polyfill-regenerator "^0.6.6"
core-js-compat "^3.48.0"
semver "^6.3.1"
"@babel/preset-modules@0.1.6-no-external-plugins":
@@ -865,6 +897,19 @@
"@babel/types" "^7.28.6"
debug "^4.3.1"
"@babel/traverse@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
dependencies:
"@babel/code-frame" "^7.29.0"
"@babel/generator" "^7.29.0"
"@babel/helper-globals" "^7.28.0"
"@babel/parser" "^7.29.0"
"@babel/template" "^7.28.6"
"@babel/types" "^7.29.0"
debug "^4.3.1"
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.4.4":
version "7.28.6"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz"
@@ -873,6 +918,14 @@
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.28.5"
"@babel/types@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
dependencies:
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.28.5"
"@dnd-kit/accessibility@^3.1.1":
version "3.1.1"
resolved "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz"
@@ -1483,10 +1536,10 @@
resolved "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz"
integrity sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==
"@rolldown/pluginutils@1.0.0-beta.53":
version "1.0.0-beta.53"
resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz"
integrity sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==
"@rolldown/pluginutils@1.0.0-rc.2":
version "1.0.0-rc.2"
resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz#10324e74cb3396cb7b616042ea7e9e6aa7d8d458"
integrity sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==
"@rollup/rollup-android-arm-eabi@4.49.0":
version "4.49.0"
@@ -1844,15 +1897,15 @@
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz"
integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==
"@vitejs/plugin-react@5.1.2":
version "5.1.2"
resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz"
integrity sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==
"@vitejs/plugin-react@5.1.3":
version "5.1.3"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-5.1.3.tgz#05eba092cc89a6ff89668d3f62258e2c5a8a9122"
integrity sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==
dependencies:
"@babel/core" "^7.28.5"
"@babel/core" "^7.29.0"
"@babel/plugin-transform-react-jsx-self" "^7.27.1"
"@babel/plugin-transform-react-jsx-source" "^7.27.1"
"@rolldown/pluginutils" "1.0.0-beta.53"
"@rolldown/pluginutils" "1.0.0-rc.2"
"@types/babel__core" "^7.20.5"
react-refresh "^0.18.0"
@@ -2068,29 +2121,29 @@ b4a@^1.6.4:
resolved "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz"
integrity sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==
babel-plugin-polyfill-corejs2@^0.4.14:
version "0.4.14"
resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz"
integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==
babel-plugin-polyfill-corejs2@^0.4.15:
version "0.4.15"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz#808fa349686eea4741807cfaaa2aa3aa57ce120a"
integrity sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==
dependencies:
"@babel/compat-data" "^7.27.7"
"@babel/helper-define-polyfill-provider" "^0.6.5"
"@babel/compat-data" "^7.28.6"
"@babel/helper-define-polyfill-provider" "^0.6.6"
semver "^6.3.1"
babel-plugin-polyfill-corejs3@^0.13.0:
version "0.13.0"
resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz"
integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==
babel-plugin-polyfill-corejs3@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz#65b06cda48d6e447e1e926681f5a247c6ae2b9cf"
integrity sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.6.5"
core-js-compat "^3.43.0"
"@babel/helper-define-polyfill-provider" "^0.6.6"
core-js-compat "^3.48.0"
babel-plugin-polyfill-regenerator@^0.6.5:
version "0.6.5"
resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz"
integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==
babel-plugin-polyfill-regenerator@^0.6.6:
version "0.6.6"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz#69f5dd263cab933c42fe5ea05e83443b374bd4bf"
integrity sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.6.5"
"@babel/helper-define-polyfill-provider" "^0.6.6"
bail@^2.0.0:
version "2.0.2"
@@ -2149,6 +2202,11 @@ base64-js@^1.3.1:
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
baseline-browser-mapping@^2.9.0:
version "2.9.19"
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488"
integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==
basic-ftp@^5.0.2:
version "5.0.5"
resolved "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz"
@@ -2240,7 +2298,7 @@ browser-stdout@^1.3.1:
resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz"
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
browserslist@^4.24.0, browserslist@^4.25.3:
browserslist@^4.24.0:
version "4.25.3"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz"
integrity sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==
@@ -2250,6 +2308,17 @@ browserslist@^4.24.0, browserslist@^4.25.3:
node-releases "^2.0.19"
update-browserslist-db "^1.1.3"
browserslist@^4.28.1:
version "4.28.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95"
integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==
dependencies:
baseline-browser-mapping "^2.9.0"
caniuse-lite "^1.0.30001759"
electron-to-chromium "^1.5.263"
node-releases "^2.0.27"
update-browserslist-db "^1.2.0"
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz"
@@ -2309,6 +2378,11 @@ caniuse-lite@^1.0.30001735:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz"
integrity sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==
caniuse-lite@^1.0.30001759:
version "1.0.30001767"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz#0279c498e862efb067938bba0a0aabafe8d0b730"
integrity sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==
ccount@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz"
@@ -2562,12 +2636,12 @@ copy-text-to-clipboard@^2.1.1:
resolved "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-2.2.0.tgz"
integrity sha512-WRvoIdnTs1rgPMkgA2pUOa/M4Enh2uzCwdKsOMYNAJiz/4ZvEJgmbF4OmninPmlFdAWisfeh0tH+Cpf7ni3RqQ==
core-js-compat@^3.43.0:
version "3.45.1"
resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz"
integrity sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==
core-js-compat@^3.48.0:
version "3.48.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.48.0.tgz#7efbe1fc1cbad44008190462217cc5558adaeaa6"
integrity sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==
dependencies:
browserslist "^4.25.3"
browserslist "^4.28.1"
core-js@^3.22.4:
version "3.47.0"
@@ -2670,7 +2744,7 @@ debug@3.2.7:
dependencies:
ms "^2.1.1"
debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.4.1, debug@^4.4.3:
debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.4.3:
version "4.4.3"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
@@ -2851,6 +2925,11 @@ electron-to-chromium@^1.5.204:
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.211.tgz"
integrity sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==
electron-to-chromium@^1.5.263:
version "1.5.283"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.283.tgz#51d492c37c2d845a0dccb113fe594880c8616de8"
integrity sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==
emoji-regex@^10.3.0:
version "10.5.0"
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz"
@@ -4063,7 +4142,7 @@ is-callable@^1.2.7:
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-core-module@^2.13.0, is-core-module@^2.16.0:
is-core-module@^2.13.0, is-core-module@^2.16.0, is-core-module@^2.16.1:
version "2.16.1"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz"
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
@@ -5417,6 +5496,11 @@ node-releases@^2.0.19:
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz"
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
node-releases@^2.0.27:
version "2.0.27"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e"
integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==
nodemon@^3.1.11:
version "3.1.11"
resolved "https://registry.npmjs.org/nodemon/-/nodemon-3.1.11.tgz"
@@ -6421,7 +6505,7 @@ resolve-protobuf-schema@^2.1.0:
dependencies:
protocol-buffers-schema "^3.3.1"
resolve@^1.1.6, resolve@^1.22.10:
resolve@^1.1.6:
version "1.22.10"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz"
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
@@ -6430,6 +6514,15 @@ resolve@^1.1.6, resolve@^1.22.10:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^1.22.11:
version "1.22.11"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262"
integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==
dependencies:
is-core-module "^2.16.1"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^2.0.0-next.5:
version "2.0.0-next.5"
resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz"
@@ -7359,6 +7452,14 @@ update-browserslist-db@^1.1.3:
escalade "^3.2.0"
picocolors "^1.1.1"
update-browserslist-db@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d"
integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==
dependencies:
escalade "^3.2.0"
picocolors "^1.1.1"
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
@@ -7633,10 +7734,10 @@ zod@^3.24.1:
resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz"
integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==
zustand@^5.0.10:
version "5.0.10"
resolved "https://registry.npmjs.org/zustand/-/zustand-5.0.10.tgz"
integrity sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==
zustand@^5.0.11:
version "5.0.11"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.11.tgz#99f912e590de1ca9ce6c6d1cab6cdb1f034ab494"
integrity sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==
zwitch@^2.0.0:
version "2.0.4"