From 4dd0370ec187f90fe7fe0eafd03424fff5d82210 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Thu, 22 Jan 2026 16:09:36 +0100 Subject: [PATCH] Calculating the distance (#255) * migra for distance * adding distance calculator * adding ability to store home address * improve distance calculation * calculating distance * show distance in grid view * upgrading dependencies * moving to react 19 * ability to clone a job * fixing tests * polishing --- lib/FredyPipelineExecutioner.js | 41 ++ lib/api/api.js | 5 +- lib/api/routes/featureRouter.js | 17 - lib/api/routes/userSettingsRoute.js | 66 ++ lib/features.js | 10 +- lib/services/crons/geocoding-cron.js | 28 +- lib/services/geocoding/autocompleteService.js | 26 + .../geocoding/client/nominatimClient.js | 47 ++ lib/services/geocoding/distanceService.js | 61 ++ lib/services/listings/distanceCalculator.js | 35 + lib/services/storage/listingsStorage.js | 54 ++ .../storage/migrations/sql/8.distances.js | 12 + .../sql/9.user-settings-unique-constraint.js | 20 + lib/services/storage/settingsStorage.js | 23 +- lib/services/tracking/Tracker.js | 19 + package-lock.json | 262 +++++--- package.json | 13 +- test/mocks/mockStore.js | 14 + test/utils.js | 9 + ui/src/App.jsx | 13 +- ui/src/Index.jsx | 4 +- ui/src/components/footer/FredyFooter.jsx | 2 +- ui/src/components/grid/jobs/JobGrid.jsx | 96 ++- .../components/grid/listings/ListingsGrid.jsx | 26 +- ui/src/components/headline/Headline.jsx | 2 +- ui/src/components/logout/Logout.jsx | 2 +- ui/src/components/navigation/Navigation.jsx | 15 +- ui/src/components/segment/SegmentPart.jsx | 2 +- .../table/NotificationAdapterTable.jsx | 2 +- ui/src/components/table/ProviderTable.jsx | 2 +- ui/src/components/table/UserTable.jsx | 2 +- ui/src/components/tracking/TrackingModal.jsx | 2 +- ui/src/components/version/VersionBanner.jsx | 4 +- ui/src/views/dashboard/Dashboard.jsx | 2 +- .../views/generalSettings/GeneralSettings.jsx | 6 +- ui/src/views/jobs/mutation/JobMutation.jsx | 22 +- .../NotificationAdapterMutator.jsx | 2 +- .../NotificationHelpDisplay.jsx | 2 +- .../components/provider/ProviderMutator.jsx | 2 +- ui/src/views/listings/Map.jsx | 16 +- .../management/WatchlistManagement.jsx | 2 +- ui/src/views/login/Login.jsx | 2 +- ui/src/views/user/UserRemovalModal.jsx | 2 +- ui/src/views/user/Users.jsx | 4 +- ui/src/views/user/mutation/UserMutator.jsx | 2 +- ui/src/views/userSettings/UserSettings.jsx | 119 ++++ yarn.lock | 631 +++++++----------- 47 files changed, 1135 insertions(+), 615 deletions(-) delete mode 100644 lib/api/routes/featureRouter.js create mode 100644 lib/api/routes/userSettingsRoute.js create mode 100644 lib/services/geocoding/autocompleteService.js create mode 100644 lib/services/geocoding/distanceService.js create mode 100644 lib/services/listings/distanceCalculator.js create mode 100644 lib/services/storage/migrations/sql/8.distances.js create mode 100644 lib/services/storage/migrations/sql/9.user-settings-unique-constraint.js create mode 100644 ui/src/views/userSettings/UserSettings.jsx diff --git a/lib/FredyPipelineExecutioner.js b/lib/FredyPipelineExecutioner.js index eb97cee..184d897 100755 --- a/lib/FredyPipelineExecutioner.js +++ b/lib/FredyPipelineExecutioner.js @@ -5,11 +5,15 @@ import { NoNewListingsWarning } from './errors.js'; import { storeListings, getKnownListingHashesForJobAndProvider } from './services/storage/listingsStorage.js'; +import { getJob } from './services/storage/jobStorage.js'; import * as notify from './notification/notify.js'; import Extractor from './services/extractor/extractor.js'; import urlModifier from './services/queryStringMutator.js'; import logger from './services/logger.js'; import { geocodeAddress } from './services/geocoding/geoCodingService.js'; +import { distanceMeters } from './services/listings/distanceCalculator.js'; +import { getUserSettings } from './services/storage/settingsStorage.js'; +import { updateListingDistance } from './services/storage/listingsStorage.js'; /** * @typedef {Object} Listing @@ -82,6 +86,7 @@ class FredyPipelineExecutioner { .then(this._findNew.bind(this)) .then(this._geocode.bind(this)) .then(this._save.bind(this)) + .then(this._calculateDistance.bind(this)) .then(this._filterBySimilarListings.bind(this)) .then(this._notify.bind(this)) .catch(this._handleError.bind(this)); @@ -201,6 +206,42 @@ class FredyPipelineExecutioner { return newListings; } + /** + * Calculate distance for new listings. + * + * @param {Listing[]} listings + * @returns {Listing[]} + * @private + */ + _calculateDistance(listings) { + if (listings.length === 0) return []; + + const job = getJob(this._jobKey); + const userId = job?.userId; + + if (userId == null || typeof userId !== 'string') { + logger.debug('Skipping distance calculation: userId is missing or invalid'); + return listings; + } + + const userSettings = getUserSettings(userId); + const homeAddress = userSettings?.home_address; + + if (!homeAddress || !homeAddress.coords) { + return listings; + } + + const { lat, lng } = homeAddress.coords; + for (const listing of listings) { + if (listing.latitude != null && listing.longitude != null) { + const dist = distanceMeters(lat, lng, listing.latitude, listing.longitude); + updateListingDistance(listing.id, dist); + listing.distance_to_destination = dist; + } + } + return listings; + } + /** * Remove listings that are similar to already known entries according to the similarity cache. * Adds the remaining listings to the cache. diff --git a/lib/api/api.js b/lib/api/api.js index 6e57d73..338d457 100644 --- a/lib/api/api.js +++ b/lib/api/api.js @@ -10,6 +10,7 @@ import { providerRouter } from './routes/providerRouter.js'; import { versionRouter } from './routes/versionRouter.js'; import { loginRouter } from './routes/loginRoute.js'; import { userRouter } from './routes/userRoute.js'; +import { userSettingsRouter } from './routes/userSettingsRoute.js'; import { jobRouter } from './routes/jobRouter.js'; import bodyParser from 'body-parser'; import restana from 'restana'; @@ -20,7 +21,6 @@ import { demoRouter } from './routes/demoRouter.js'; import logger from '../services/logger.js'; import { listingsRouter } from './routes/listingsRouter.js'; import { getSettings } from '../services/storage/settingsStorage.js'; -import { featureRouter } from './routes/featureRouter.js'; import { dashboardRouter } from './routes/dashboardRouter.js'; import { backupRouter } from './routes/backupRouter.js'; const service = restana(); @@ -36,6 +36,7 @@ service.use('/api/version', authInterceptor()); service.use('/api/listings', authInterceptor()); service.use('/api/dashboard', authInterceptor()); service.use('/api/features', authInterceptor()); +service.use('/api/user/settings', authInterceptor()); // /admin can only be accessed when user is having admin permissions service.use('/api/admin', adminInterceptor()); @@ -44,11 +45,11 @@ service.use('/api/admin/generalSettings', generalSettingsRouter); service.use('/api/admin/backup', backupRouter); service.use('/api/jobs/provider', providerRouter); service.use('/api/admin/users', userRouter); +service.use('/api/user/settings', userSettingsRouter); service.use('/api/version', versionRouter); service.use('/api/jobs', jobRouter); service.use('/api/login', loginRouter); service.use('/api/listings', listingsRouter); -service.use('/api/features', featureRouter); service.use('/api/dashboard', dashboardRouter); //this route is unsecured intentionally as it is being queried from the login page service.use('/api/demo', demoRouter); diff --git a/lib/api/routes/featureRouter.js b/lib/api/routes/featureRouter.js deleted file mode 100644 index 960091b..0000000 --- a/lib/api/routes/featureRouter.js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2026 by Christian Kellner. - * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause - */ - -import restana from 'restana'; -import getFeatures from '../../features.js'; -const service = restana(); -const featureRouter = service.newRouter(); - -featureRouter.get('/', async (req, res) => { - const features = getFeatures(); - res.body = Object.assign({}, { features }); - res.send(); -}); - -export { featureRouter }; diff --git a/lib/api/routes/userSettingsRoute.js b/lib/api/routes/userSettingsRoute.js new file mode 100644 index 0000000..956b1f4 --- /dev/null +++ b/lib/api/routes/userSettingsRoute.js @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2026 by Christian Kellner. + * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause + */ + +import restana from 'restana'; +import SqliteConnection from '../../services/storage/SqliteConnection.js'; +import { upsertSettings } from '../../services/storage/settingsStorage.js'; +import { geocodeAddress } from '../../services/geocoding/geoCodingService.js'; +import { autocompleteAddress } from '../../services/geocoding/autocompleteService.js'; +import { calculateDistanceForUser } from '../../services/geocoding/distanceService.js'; +import { fromJson } from '../../utils.js'; +import { trackFeature } from '../../services/tracking/Tracker.js'; +import { FEATURES } from '../../features.js'; + +const service = restana(); +const userSettingsRouter = service.newRouter(); + +userSettingsRouter.get('/', async (req, res) => { + const userId = req.session.currentUser; + const rows = SqliteConnection.query('SELECT name, value FROM settings WHERE user_id = @userId', { userId }); + const settings = {}; + for (const r of rows) { + settings[r.name] = fromJson(r.value, null); + } + res.body = settings; + res.send(); +}); + +userSettingsRouter.get('/autocomplete', async (req, res) => { + const { q } = req.query; + try { + const results = await autocompleteAddress(q); + res.body = results; + res.send(); + } catch (error) { + res.status(500).send({ error: error.message }); + } +}); + +userSettingsRouter.post('/', async (req, res) => { + const userId = req.session.currentUser; + const { home_address } = req.body; + + try { + if (home_address) { + await trackFeature(FEATURES.DISTANCE_ADDRESS_ENTERED); + const coords = await geocodeAddress(home_address); + if (coords && coords.lat !== -1) { + upsertSettings({ home_address: { address: home_address, coords } }, userId); + calculateDistanceForUser(userId); + res.send({ success: true, coords }); + } else { + res.status(400).send({ error: 'Could not geocode address' }); + } + } else { + // If address is empty, maybe clear it? + upsertSettings({ home_address: null }, userId); + res.send({ success: true }); + } + } catch (error) { + res.status(500).send({ error: error.message }); + } +}); + +export { userSettingsRouter }; diff --git a/lib/features.js b/lib/features.js index 75227a3..7d8f5af 100644 --- a/lib/features.js +++ b/lib/features.js @@ -3,12 +3,6 @@ * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause */ -const FEATURES = { - WATCHLIST_MANAGEMENT: false, +export const FEATURES = { + DISTANCE_ADDRESS_ENTERED: 'DISTANCE_ADDRESS_ENTERED', }; - -export default function getFeatures() { - return { - ...FEATURES, - }; -} diff --git a/lib/services/crons/geocoding-cron.js b/lib/services/crons/geocoding-cron.js index eca4c15..1e67f2e 100644 --- a/lib/services/crons/geocoding-cron.js +++ b/lib/services/crons/geocoding-cron.js @@ -6,22 +6,28 @@ import cron from 'node-cron'; import { getListingsToGeocode, updateListingGeocoordinates } from '../storage/listingsStorage.js'; import { geocodeAddress, isGeocodingPaused } from '../geocoding/geoCodingService.js'; +import { getJobs } from '../storage/jobStorage.js'; +import { calculateDistanceForJob } from '../geocoding/distanceService.js'; async function runTask() { const listings = getListingsToGeocode(); - if (listings.length === 0) { - return; + if (listings.length > 0) { + for (const listing of listings) { + if (isGeocodingPaused()) { + break; + } + + const coords = await geocodeAddress(listing.address); + if (coords) { + updateListingGeocoordinates(listing.id, coords.lat, coords.lng); + } + } } - for (const listing of listings) { - if (isGeocodingPaused()) { - break; - } - - const coords = await geocodeAddress(listing.address); - if (coords) { - updateListingGeocoordinates(listing.id, coords.lat, coords.lng); - } + //additional run + const jobs = getJobs(); + for (const job of jobs) { + calculateDistanceForJob(job.id, job.userId); } } diff --git a/lib/services/geocoding/autocompleteService.js b/lib/services/geocoding/autocompleteService.js new file mode 100644 index 0000000..d3bcff3 --- /dev/null +++ b/lib/services/geocoding/autocompleteService.js @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2026 by Christian Kellner. + * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause + */ + +import { autocomplete as nominatimAutocomplete } from './client/nominatimClient.js'; +import logger from '../logger.js'; + +/** + * Autocompletes an address using Nominatim. + * + * @param {string} query - The search query. + * @returns {Promise} List of matching addresses. + */ +export async function autocompleteAddress(query) { + if (!query) { + return []; + } + + try { + return await nominatimAutocomplete(query); + } catch (error) { + logger.error('Error during address autocomplete:', error); + return []; + } +} diff --git a/lib/services/geocoding/client/nominatimClient.js b/lib/services/geocoding/client/nominatimClient.js index fdc70d3..be28454 100644 --- a/lib/services/geocoding/client/nominatimClient.js +++ b/lib/services/geocoding/client/nominatimClient.js @@ -100,6 +100,53 @@ async function doGeocode(address) { } } +/** + * Autocompletes an address using Nominatim. + * + * @param {string} query - The search query. + * @returns {Promise} List of matching addresses. + */ +async function doAutocomplete(query) { + if (Date.now() - last429 < PAUSE_DURATION) { + return []; + } + + const url = `${API_URL}?q=${encodeURIComponent(query)}&format=json&addressdetails=1&limit=5&countrycodes=de`; + + try { + const response = await fetch(url, { + agent, + headers: { + 'User-Agent': userAgent, + }, + }); + + if (response.status === 429) { + logger.warn('Nominatim rate limit hit. Pausing for 1 hour.'); + last429 = Date.now(); + return []; + } + + if (!response.ok) { + logger.error(`Nominatim API error: ${response.status} ${response.statusText}`); + return []; + } + + const data = await response.json(); + + if (Array.isArray(data)) { + return data.map((item) => item.display_name); + } + + return []; + } catch (error) { + logger.error('Error during Nominatim autocomplete:', error); + return []; + } +} + export const geocode = throttle(doGeocode); +export const autocomplete = throttle(doAutocomplete); + export const isPaused = () => Date.now() - last429 < PAUSE_DURATION; diff --git a/lib/services/geocoding/distanceService.js b/lib/services/geocoding/distanceService.js new file mode 100644 index 0000000..2e15fd7 --- /dev/null +++ b/lib/services/geocoding/distanceService.js @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2026 by Christian Kellner. + * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause + */ + +import { distanceMeters } from '../listings/distanceCalculator.js'; +import { + getListingsToCalculateDistance, + getListingsForUserToCalculateDistance, + updateListingDistance, +} from '../storage/listingsStorage.js'; +import { getUserSettings } from '../storage/settingsStorage.js'; + +/** + * Calculates and updates distances for listings of a specific job. + * Only processes listings where distance_to_destination is null. + * + * @param {string} jobId + * @param {string} userId + * @returns {void} + */ +export function calculateDistanceForJob(jobId, userId) { + const userSettings = getUserSettings(userId); + const homeAddress = userSettings.home_address; + + if (!homeAddress || !homeAddress.coords) { + return; + } + + const listings = getListingsToCalculateDistance(jobId); + const { lat, lng } = homeAddress.coords; + + for (const listing of listings) { + const dist = distanceMeters(lat, lng, listing.latitude, listing.longitude); + updateListingDistance(listing.id, dist); + } +} + +/** + * Calculates and updates distances for all active listings of a user. + * Usually called when the user updates their home address. + * + * @param {string} userId + * @returns {void} + */ +export function calculateDistanceForUser(userId) { + const userSettings = getUserSettings(userId); + const homeAddress = userSettings.home_address; + + if (!homeAddress || !homeAddress.coords) { + return; + } + + const listings = getListingsForUserToCalculateDistance(userId); + const { lat, lng } = homeAddress.coords; + + for (const listing of listings) { + const dist = distanceMeters(lat, lng, listing.latitude, listing.longitude); + updateListingDistance(listing.id, dist); + } +} diff --git a/lib/services/listings/distanceCalculator.js b/lib/services/listings/distanceCalculator.js new file mode 100644 index 0000000..549ad48 --- /dev/null +++ b/lib/services/listings/distanceCalculator.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2026 by Christian Kellner. + * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause + */ + +const R = 6371000; // Earth radius in meters +/** + * Calculate the great-circle distance between two points on Earth using the Haversine formula. + * This is to calculate the distance between the listing address & the address provided by the user. I know, it is only + * a rough estimation as this calculates the distance as a straight line, but it's more convenient than using an external + * service and still gives a good approximation for sorting purposes. + * Returns distance in meters. + * + * @param {number} lat1 + * @param {number} lon1 + * @param {number} lat2 + * @param {number} lon2 + * @returns {number} + */ +export function distanceMeters(lat1, lon1, lat2, lon2) { + const toRad = (deg) => (deg * Math.PI) / 180; + + const phi1 = toRad(lat1); + const phi2 = toRad(lat2); + const dPhi = toRad(lat2 - lat1); + const dLambda = toRad(lon2 - lon1); + + const a = + Math.sin(dPhi / 2) * Math.sin(dPhi / 2) + + Math.cos(phi1) * Math.cos(phi2) * Math.sin(dLambda / 2) * Math.sin(dLambda / 2); + + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return Math.round(R * c * 10) / 10; +} diff --git a/lib/services/storage/listingsStorage.js b/lib/services/storage/listingsStorage.js index d376312..715543f 100755 --- a/lib/services/storage/listingsStorage.js +++ b/lib/services/storage/listingsStorage.js @@ -502,3 +502,57 @@ export const getGeocoordinatesByAddress = (address) => { )[0]; return row ? { lat: row.latitude, lng: row.longitude } : null; }; + +/** + * Return all active listings for a given job that have geocoordinates but no distance set. + * + * @param {string} jobId + * @returns {Object[]} + */ +export const getListingsToCalculateDistance = (jobId) => { + return SqliteConnection.query( + `SELECT id, latitude, longitude + FROM listings + WHERE job_id = @jobId + AND is_active = 1 + AND latitude IS NOT NULL + AND longitude IS NOT NULL + AND distance_to_destination IS NULL`, + { jobId }, + ); +}; + +/** + * Return all active listings for a given user (across all jobs) that have geocoordinates. + * + * @param {string} userId + * @returns {Object[]} + */ +export const getListingsForUserToCalculateDistance = (userId) => { + return SqliteConnection.query( + `SELECT l.id, l.latitude, l.longitude + FROM listings l + JOIN jobs j ON l.job_id = j.id + WHERE j.user_id = @userId + AND l.is_active = 1 + AND l.latitude IS NOT NULL + AND l.longitude IS NOT NULL`, + { userId }, + ); +}; + +/** + * Update the distance to destination for a listing. + * + * @param {string} id + * @param {number} distance + * @returns {void} + */ +export const updateListingDistance = (id, distance) => { + SqliteConnection.execute( + `UPDATE listings + SET distance_to_destination = @distance + WHERE id = @id`, + { id, distance }, + ); +}; diff --git a/lib/services/storage/migrations/sql/8.distances.js b/lib/services/storage/migrations/sql/8.distances.js new file mode 100644 index 0000000..6419075 --- /dev/null +++ b/lib/services/storage/migrations/sql/8.distances.js @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2026 by Christian Kellner. + * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause + */ + +// Migration: Removing city field and adding distance field + +export function up(db) { + db.exec(` + ALTER TABLE listings ADD COLUMN distance_to_destination INTEGER; + `); +} diff --git a/lib/services/storage/migrations/sql/9.user-settings-unique-constraint.js b/lib/services/storage/migrations/sql/9.user-settings-unique-constraint.js new file mode 100644 index 0000000..47b32f3 --- /dev/null +++ b/lib/services/storage/migrations/sql/9.user-settings-unique-constraint.js @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 by Christian Kellner. + * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause + */ + +export function up(db) { + // 1. Remove old unique index + db.exec(`DROP INDEX IF EXISTS idx_settings_name;`); + + // 2. Add new unique index for name and user_id. + // Since user_id can be NULL, we need a special index or use coalesce for the index. + // In SQLite, multiple NULLs are allowed in a UNIQUE index, which is fine for our global settings (user_id IS NULL). + // But we want only one global setting for a given name. + // Actually, in SQLite, UNIQUE allows multiple NULL values. + // To have only one NULL user_id for a name, we can use a partial index or COALESCE. + + db.exec(` + CREATE UNIQUE INDEX idx_settings_name_user_id ON settings (name, IFNULL(user_id, 'GLOBAL_SETTING')); + `); +} diff --git a/lib/services/storage/settingsStorage.js b/lib/services/storage/settingsStorage.js index 42b3176..92cb506 100644 --- a/lib/services/storage/settingsStorage.js +++ b/lib/services/storage/settingsStorage.js @@ -37,12 +37,25 @@ function compileSettings(rows, configValues) { * @returns {Record} */ export async function refreshSettingsCache() { - const rows = SqliteConnection.query(`SELECT name, value FROM settings`); + const rows = SqliteConnection.query(`SELECT name, value FROM settings WHERE user_id IS NULL`); const configValues = await readConfigFromStorage(); cachedSettingsConfig = compileSettings(rows, configValues); return cachedSettingsConfig; } +/** + * Retrieves user-specific settings from the database. + * @param {string} userId + * @returns {Record} + */ +export function getUserSettings(userId) { + if (!userId || typeof userId !== 'string') { + return {}; + } + const userRows = SqliteConnection.query(`SELECT name, value FROM settings WHERE user_id = @userId`, { userId }); + return compileSettings(userRows, {}); +} + /** * Get the compiled settings config. Loads it once and caches the result. * @returns {Record} @@ -83,10 +96,12 @@ export function upsertSettings(settingsMapOrEntry, userId = null) { SqliteConnection.execute( `INSERT INTO settings (id, create_date, name, value, user_id) VALUES (@id, @create_date, @name, @value, @userId) - ON CONFLICT(name) DO UPDATE SET value = excluded.value`, + ON CONFLICT(name, IFNULL(user_id, 'GLOBAL_SETTING')) DO UPDATE SET value = excluded.value`, { id, create_date, name, value: json, userId }, ); } - // keep cache in sync - refreshSettingsCache(); + // keep cache in sync (only for global settings) + if (userId == null) { + refreshSettingsCache(); + } } diff --git a/lib/services/tracking/Tracker.js b/lib/services/tracking/Tracker.js index 861988a..2e212f2 100644 --- a/lib/services/tracking/Tracker.js +++ b/lib/services/tracking/Tracker.js @@ -47,6 +47,25 @@ export const trackMainEvent = async () => { } }; +export const trackFeature = async (feature) => { + try { + const settings = await getSettings(); + if (settings.analyticsEnabled && !inDevMode()) { + const trackingObj = await enrichTrackingObject({ + feature, + }); + + 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); + } +}; + /** * Note, this will only be used when Fredy runs in demo mode */ diff --git a/package-lock.json b/package-lock.json index 5d7281f..2d96243 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,27 @@ { "name": "fredy", - "version": "18.0.0", + "version": "18.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fredy", - "version": "18.0.0", + "version": "18.0.2", "license": "Apache-2.0", "dependencies": { "@douyinfe/semi-icons": "^2.90.13", "@douyinfe/semi-ui": "2.90.13", + "@douyinfe/semi-ui-19": "^2.90.13", "@sendgrid/mail": "8.1.6", "@vitejs/plugin-react": "5.1.2", "adm-zip": "^0.5.16", - "better-sqlite3": "^12.6.0", + "better-sqlite3": "^12.6.2", "body-parser": "2.2.2", "chart.js": "^4.5.1", "cheerio": "^1.1.2", "cookie-session": "2.1.1", "handlebars": "4.7.8", - "lodash": "4.17.21", + "lodash": "4.17.23", "maplibre-gl": "^5.16.0", "nanoid": "5.1.6", "node-cron": "^4.2.1", @@ -28,13 +29,14 @@ "node-mailjet": "6.0.11", "p-throttle": "^8.1.0", "package-up": "^5.0.0", - "puppeteer": "^24.35.0", + "puppeteer": "^24.36.0", "puppeteer-extra": "^3.3.6", "puppeteer-extra-plugin-stealth": "^2.11.2", "query-string": "9.3.1", - "react": "18.3.1", + "react": "19.2.3", "react-chartjs-2": "^5.3.1", - "react-dom": "18.3.1", + "react-dom": "19.2.3", + "react-range-slider-input": "^3.3.2", "react-router": "7.12.0", "react-router-dom": "7.12.0", "restana": "5.1.0", @@ -61,7 +63,7 @@ "lint-staged": "16.2.7", "mocha": "11.7.5", "nodemon": "^3.1.11", - "prettier": "3.8.0" + "prettier": "3.8.1" }, "engines": { "node": ">=22.0.0", @@ -1987,6 +1989,53 @@ "react-dom": ">=16.0.0" } }, + "node_modules/@douyinfe/semi-ui-19": { + "version": "2.90.13", + "resolved": "https://registry.npmjs.org/@douyinfe/semi-ui-19/-/semi-ui-19-2.90.13.tgz", + "integrity": "sha512-OdJOOKEiRBTpwSdGSdtkwzAsQxehrQtvsU37YgMR3jGXL38PGN+UhEjdVbx+p6HS3G9fMbL1n/2+LvnHg4vx8A==", + "license": "MIT", + "dependencies": { + "@dnd-kit/core": "^6.0.8", + "@dnd-kit/sortable": "^7.0.2", + "@dnd-kit/utilities": "^3.2.1", + "@douyinfe/semi-animation": "2.90.13", + "@douyinfe/semi-animation-react": "2.90.13", + "@douyinfe/semi-foundation": "2.90.13", + "@douyinfe/semi-icons": "2.90.13", + "@douyinfe/semi-illustrations": "2.90.13", + "@douyinfe/semi-theme-default": "2.90.13", + "@tiptap/core": "^3.10.7", + "@tiptap/extension-document": "^3.10.7", + "@tiptap/extension-hard-break": "^3.10.7", + "@tiptap/extension-mention": "^3.10.7", + "@tiptap/extension-paragraph": "^3.10.7", + "@tiptap/extension-text": "^3.10.7", + "@tiptap/extensions": "^3.10.7", + "@tiptap/pm": "^3.10.7", + "@tiptap/react": "^3.10.7", + "async-validator": "^3.5.0", + "classnames": "^2.2.6", + "copy-text-to-clipboard": "^2.1.1", + "date-fns": "^2.29.3", + "date-fns-tz": "^1.3.8", + "fast-copy": "^3.0.1 ", + "jsonc-parser": "^3.3.1", + "lodash": "^4.17.21", + "prop-types": "^15.7.2", + "prosemirror-state": "^1.4.3", + "react-resizable": "^3.0.5", + "react-window": "^1.8.2", + "scroll-into-view-if-needed": "^2.2.24", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.27.1", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", @@ -2707,22 +2756,22 @@ } }, "node_modules/@tiptap/core": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.15.3.tgz", - "integrity": "sha512-bmXydIHfm2rEtGju39FiQNfzkFx9CDvJe+xem1dgEZ2P6Dj7nQX9LnA1ZscW7TuzbBRkL5p3dwuBIi3f62A66A==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.16.0.tgz", + "integrity": "sha512-XegRaNuoQ/guzBQU2xHxOwFXXrtoXW9tiyXDhssSqylvZmBVSlRIPNHA6ArkHBKm6ehLf6+6Y9fF3uky1yCXYQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^3.15.3" + "@tiptap/pm": "^3.16.0" } }, "node_modules/@tiptap/extension-bubble-menu": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.11.0.tgz", - "integrity": "sha512-P3j9lQ+EZ5Zg/isJzLpCPX7bp7WUBmz8GPs/HPlyMyN2su8LqXntITBZr8IP1JNBlB/wR83k/W0XqdC57mG7cA==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.16.0.tgz", + "integrity": "sha512-nFL7FMu1LjZ5ZGf4U3tw56JLj/SpLysZvHQ1EneGB+90TEI/WReOvTY9VwH1egGWwrl7/OvQuGKclbuLIsy+BA==", "license": "MIT", "optional": true, "dependencies": { @@ -2733,8 +2782,8 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.11.0", - "@tiptap/pm": "^3.11.0" + "@tiptap/core": "^3.16.0", + "@tiptap/pm": "^3.16.0" } }, "node_modules/@tiptap/extension-document": { @@ -2751,9 +2800,9 @@ } }, "node_modules/@tiptap/extension-floating-menu": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.11.0.tgz", - "integrity": "sha512-nEHdWZHEJYX1II1oJQ4aeZ8O/Kss4BRbYFXQFGIvPelCfCYEATpUJh3aq3767ARSq40bOWyu+Dcd4SCW0We6Sw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.16.0.tgz", + "integrity": "sha512-cokYXL8EkW+CFIlke70GLL7iKetUtYEp87muMG9oflczyj0BjmGAbO7Mskm+bcQBhxZ0dIYILTqKn2bNBvCDFw==", "license": "MIT", "optional": true, "funding": { @@ -2762,8 +2811,8 @@ }, "peerDependencies": { "@floating-ui/dom": "^1.0.0", - "@tiptap/core": "^3.11.0", - "@tiptap/pm": "^3.11.0" + "@tiptap/core": "^3.16.0", + "@tiptap/pm": "^3.16.0" } }, "node_modules/@tiptap/extension-hard-break": { @@ -2835,9 +2884,9 @@ } }, "node_modules/@tiptap/pm": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.15.3.tgz", - "integrity": "sha512-Zm1BaU1TwFi3CQiisxjgnzzIus+q40bBKWLqXf6WEaus8Z6+vo1MT2pU52dBCMIRaW9XNDq3E5cmGtMc1AlveA==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.16.0.tgz", + "integrity": "sha512-FMxZ6Tc5ONKa/EByDV8lswct6YW2lF/wn11zqXmrfBZhdG7UQPTijpSwb6TCqaO5GOHmixaIaDPj+zimUREHQA==", "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.3.0", @@ -2865,13 +2914,13 @@ } }, "node_modules/@tiptap/react": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.11.0.tgz", - "integrity": "sha512-SDGei/2DjwmhzsxIQNr6dkB6NxLgXZjQ6hF36NfDm4937r5NLrWrNk5tCsoDQiKZ0DHEzuJ6yZM5C7I7LZLB6w==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.16.0.tgz", + "integrity": "sha512-r1R19Ma4zxGt8ImiNOqSArAnWO239KUI9tTVeelgTyekPj7643lO8GbtuXJfAeWGPduDIpcAgR/Dd4NKieetiA==", "license": "MIT", "dependencies": { "@types/use-sync-external-store": "^0.0.6", - "fast-deep-equal": "^3.1.3", + "fast-equals": "^5.3.3", "use-sync-external-store": "^1.4.0" }, "funding": { @@ -2879,12 +2928,12 @@ "url": "https://github.com/sponsors/ueberdosis" }, "optionalDependencies": { - "@tiptap/extension-bubble-menu": "^3.11.0", - "@tiptap/extension-floating-menu": "^3.11.0" + "@tiptap/extension-bubble-menu": "^3.16.0", + "@tiptap/extension-floating-menu": "^3.16.0" }, "peerDependencies": { - "@tiptap/core": "^3.11.0", - "@tiptap/pm": "^3.11.0", + "@tiptap/core": "^3.16.0", + "@tiptap/pm": "^3.16.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", @@ -3674,9 +3723,9 @@ } }, "node_modules/better-sqlite3": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.6.0.tgz", - "integrity": "sha512-FXI191x+D6UPWSze5IzZjhz+i9MK9nsuHsmTX9bXVl52k06AfZ2xql0lrgIUuzsMsJ7Vgl5kIptvDgBLIV3ZSQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.6.2.tgz", + "integrity": "sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -4177,9 +4226,9 @@ "license": "ISC" }, "node_modules/chromium-bidi": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-12.0.1.tgz", - "integrity": "sha512-fGg+6jr0xjQhzpy5N4ErZxQ4wF7KLEvhGZXD6EgvZKDhu7iOhZXnZhcDxPJDcwTcrD48NPzOCo84RP2lv3Z+Cg==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-13.0.1.tgz", + "integrity": "sha512-c+RLxH0Vg2x2syS9wPw378oJgiJNXtYXUvnVAldUlt5uaHekn0CCU7gPksNgHjrH1qFhmjVXQj4esvuthuC7OQ==", "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", @@ -4421,12 +4470,16 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cookie-session": { @@ -4491,6 +4544,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/core-js": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", + "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-js-compat": { "version": "3.45.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", @@ -4867,9 +4931,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1534754", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz", - "integrity": "sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ==", + "version": "0.0.1551306", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1551306.tgz", + "integrity": "sha512-CFx8QdSim8iIv+2ZcEOclBKTQY6BI1IEDa7Tm9YkwAXzEWFndTEzpTo5jAUhSnq24IC7xaDw0wvGcm96+Y3PEg==", "license": "BSD-3-Clause" }, "node_modules/diff": { @@ -5811,8 +5875,18 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, "license": "MIT" }, + "node_modules/fast-equals": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz", + "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -7721,9 +7795,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, "node_modules/lodash.debounce": { @@ -10110,9 +10184,9 @@ } }, "node_modules/prettier": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz", - "integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { @@ -10444,17 +10518,17 @@ } }, "node_modules/puppeteer": { - "version": "24.35.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.35.0.tgz", - "integrity": "sha512-sbjB5JnJ+3nwgSdRM/bqkFXqLxRz/vsz0GRIeTlCk+j+fGpqaF2dId9Qp25rXz9zfhqnN9s0krek1M/C2GDKtA==", + "version": "24.36.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.36.0.tgz", + "integrity": "sha512-BD/VCyV/Uezvd6o7Fd1DmEJSxTzofAKplzDy6T9d4WbLTQ5A+06zY7VwO91ZlNU22vYE8sidVEsTpTrKc+EEnQ==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.11.1", - "chromium-bidi": "12.0.1", + "chromium-bidi": "13.0.1", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1534754", - "puppeteer-core": "24.35.0", + "devtools-protocol": "0.0.1551306", + "puppeteer-core": "24.36.0", "typed-query-selector": "^2.12.0" }, "bin": { @@ -10465,17 +10539,17 @@ } }, "node_modules/puppeteer-core": { - "version": "24.35.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.35.0.tgz", - "integrity": "sha512-vt1zc2ME0kHBn7ZDOqLvgvrYD5bqNv5y2ZNXzYnCv8DEtZGw/zKhljlrGuImxptZ4rq+QI9dFGrUIYqG4/IQzA==", + "version": "24.36.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.36.0.tgz", + "integrity": "sha512-P3Ou0MAFDCQ0dK1d9F9+8jTrg6JvXjUacgG0YkJQP4kbEnUOGokSDEMmMId5ZhXD5HwsHM202E9VwEpEjWfwxg==", "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.11.1", - "chromium-bidi": "12.0.1", + "chromium-bidi": "13.0.1", "debug": "^4.4.3", - "devtools-protocol": "0.0.1534754", + "devtools-protocol": "0.0.1551306", "typed-query-selector": "^2.12.0", - "webdriver-bidi-protocol": "0.3.10", + "webdriver-bidi-protocol": "0.4.0", "ws": "^8.19.0" }, "engines": { @@ -10751,13 +10825,10 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, "engines": { "node": ">=0.10.0" } @@ -10773,16 +10844,15 @@ } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.2.3" } }, "node_modules/react-draggable": { @@ -10805,6 +10875,25 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/react-range-slider-input": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/react-range-slider-input/-/react-range-slider-input-3.3.2.tgz", + "integrity": "sha512-CGyD/6Vlc7qakSW+92WAKrp333Xo9W+udW62xvf6dSwqEj7LFSY75udcbNRtCQhuXW1O7o71yC4AC/CC0etqSg==", + "license": "MIT", + "dependencies": { + "clsx": "^1.1.1", + "core-js": "^3.22.4" + } + }, + "node_modules/react-range-slider-input/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/react-refresh": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", @@ -11432,13 +11521,10 @@ "optional": true }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" }, "node_modules/scroll-into-view-if-needed": { "version": "2.2.31", @@ -11513,9 +11599,9 @@ } }, "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, "node_modules/set-function-length": { @@ -13038,9 +13124,9 @@ } }, "node_modules/webdriver-bidi-protocol": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.10.tgz", - "integrity": "sha512-5LAE43jAVLOhB/QqX4bwSiv0Hg1HBfMmOuwBSXHdvg4GMGu9Y0lIq7p4R/yySu6w74WmaR4GM4H9t2IwLW7hgw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.0.tgz", + "integrity": "sha512-U9VIlNRrq94d1xxR9JrCEAx5Gv/2W7ERSv8oWRoNe/QYbfccS0V3h/H6qeNeCRJxXGMhhnkqvwNrvPAYeuP9VA==", "license": "Apache-2.0" }, "node_modules/whatwg-encoding": { diff --git a/package.json b/package.json index 544a78e..e782fea 100755 --- a/package.json +++ b/package.json @@ -61,16 +61,17 @@ "dependencies": { "@douyinfe/semi-icons": "^2.90.13", "@douyinfe/semi-ui": "2.90.13", + "@douyinfe/semi-ui-19": "^2.90.13", "@sendgrid/mail": "8.1.6", "@vitejs/plugin-react": "5.1.2", "adm-zip": "^0.5.16", - "better-sqlite3": "^12.6.0", + "better-sqlite3": "^12.6.2", "body-parser": "2.2.2", "chart.js": "^4.5.1", "cheerio": "^1.1.2", "cookie-session": "2.1.1", "handlebars": "4.7.8", - "lodash": "4.17.21", + "lodash": "4.17.23", "maplibre-gl": "^5.16.0", "nanoid": "5.1.6", "node-cron": "^4.2.1", @@ -78,13 +79,13 @@ "node-mailjet": "6.0.11", "p-throttle": "^8.1.0", "package-up": "^5.0.0", - "puppeteer": "^24.35.0", + "puppeteer": "^24.36.0", "puppeteer-extra": "^3.3.6", "puppeteer-extra-plugin-stealth": "^2.11.2", "query-string": "9.3.1", - "react": "18.3.1", + "react": "19.2.3", "react-chartjs-2": "^5.3.1", - "react-dom": "18.3.1", + "react-dom": "19.2.3", "react-range-slider-input": "^3.3.2", "react-router": "7.12.0", "react-router-dom": "7.12.0", @@ -112,6 +113,6 @@ "lint-staged": "16.2.7", "mocha": "11.7.5", "nodemon": "^3.1.11", - "prettier": "3.8.0" + "prettier": "3.8.1" } } diff --git a/test/mocks/mockStore.js b/test/mocks/mockStore.js index 5024bf4..27dc60e 100644 --- a/test/mocks/mockStore.js +++ b/test/mocks/mockStore.js @@ -3,6 +3,7 @@ * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause */ +/* eslint-disable no-unused-vars */ const db = {}; export const storeListings = (jobKey, providerId, listings) => { if (!Array.isArray(listings)) throw Error('Not a valid array'); @@ -11,3 +12,16 @@ export const storeListings = (jobKey, providerId, listings) => { export const getKnownListingHashesForJobAndProvider = (jobKey, providerId) => { return db[providerId] || []; }; + +export const getGeocoordinatesByAddress = (any) => { + return null; +}; + +export function getUserSettings(userId) { + return null; +} + +export const updateListingDistance = (id, distance) => { + // noop +}; +/* eslint-enable no-unused-vars */ diff --git a/test/utils.js b/test/utils.js index 4bb3a9d..af2d18a 100644 --- a/test/utils.js +++ b/test/utils.js @@ -15,6 +15,15 @@ export const mockFredy = async () => { '../lib/services/storage/listingsStorage.js': { ...mockStore, }, + '../lib/services/storage/settingsStorage.js': { + ...mockStore, + }, + '../lib/services/geocoding/geoCodingService.js': { + geocodeAddress: mockStore.getGeocoordinatesByAddress, + }, + '../lib/services/storage/jobStorage.js': { + getJob: (jobKey) => ({ id: jobKey, userId: 'user1' }), + }, '../lib/notification/notify.js': { send, }, diff --git a/ui/src/App.jsx b/ui/src/App.jsx index 9ce6c9d..cda8f23 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -8,6 +8,7 @@ import React, { useEffect } from 'react'; import InsufficientPermission from './components/permission/InsufficientPermission'; import PermissionAwareRoute from './components/permission/PermissionAwareRoute'; import GeneralSettings from './views/generalSettings/GeneralSettings'; +import UserSettings from './views/userSettings/UserSettings'; import JobMutation from './views/jobs/mutation/JobMutation'; import UserMutator from './views/user/mutation/UserMutator'; import { useActions, useSelector } from './services/state/store'; @@ -18,12 +19,12 @@ import Jobs from './views/jobs/Jobs'; import './App.less'; import TrackingModal from './components/tracking/TrackingModal.jsx'; -import { Banner, Divider } from '@douyinfe/semi-ui'; +import { Banner, Divider } from '@douyinfe/semi-ui-19'; import VersionBanner from './components/version/VersionBanner.jsx'; import Listings from './views/listings/Listings.jsx'; import MapView from './views/listings/Map.jsx'; import Navigation from './components/navigation/Navigation.jsx'; -import { Layout } from '@douyinfe/semi-ui'; +import { Layout } from '@douyinfe/semi-ui-19'; import FredyFooter from './components/footer/FredyFooter.jsx'; import WatchlistManagement from './views/listings/management/WatchlistManagement.jsx'; import Dashboard from './views/dashboard/Dashboard.jsx'; @@ -123,6 +124,14 @@ export default function FredyApp() { } /> + + + + } + /> {
} showClear placeholder="Search" onChange={handleFilterChange} /> -
@@ -287,7 +290,9 @@ const JobGrid = () => { 'This job has been shared with you by another user, therefor it is read-only.', )} > - +
+ +
)} @@ -343,40 +348,59 @@ const JobGrid = () => {
-
- + + + ); +}; + +export default UserSettings; diff --git a/yarn.lock b/yarn.lock index 35f401a..4753463 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,15 +2,6 @@ # yarn lockfile v1 -"0http@^4.3.0": - version "4.3.0" - resolved "https://registry.npmjs.org/0http/-/0http-4.3.0.tgz" - integrity sha512-3Z4WQ4IA7g6+4C1KCHY3JzDEVpo1npTCO7Ym0RmLqXmaNGgtWbiJ/r/QpcKnGHH0lHveJSeVMqBMce7lZNkdmw== - dependencies: - lru-cache "^11.0.2" - regexparam "^3.0.0" - trouter "^4.0.0" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.28.6": version "7.28.6" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz" @@ -25,7 +16,7 @@ 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": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.28.5", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@7.28.6": version "7.28.6" resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz" integrity sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw== @@ -880,7 +871,7 @@ dependencies: tslib "^2.0.0" -"@dnd-kit/core@^6.0.8": +"@dnd-kit/core@^6.0.7", "@dnd-kit/core@^6.0.8": version "6.3.1" resolved "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz" integrity sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ== @@ -945,7 +936,7 @@ remark-gfm "^4.0.0" scroll-into-view-if-needed "^2.2.24" -"@douyinfe/semi-icons@2.90.13", "@douyinfe/semi-icons@^2.90.13": +"@douyinfe/semi-icons@^2.90.13", "@douyinfe/semi-icons@2.90.13": version "2.90.13" resolved "https://registry.npmjs.org/@douyinfe/semi-icons/-/semi-icons-2.90.13.tgz" integrity sha512-9OiKvleOMB+t0h+Vbq/6Tz90JJPANJDvW5g3XtVWmIwIgScgy/N52fMhWXDf6Avr6wi9MDPcQZ6SYPO2S7m4sQ== @@ -969,6 +960,44 @@ resolved "https://registry.npmjs.org/@douyinfe/semi-theme-default/-/semi-theme-default-2.90.13.tgz" integrity sha512-8f4j7NVw7w1IFFTEpTe/RkK3TW4DZWrUngV6CK3XXSCQKSVVyG/cXI5xgK9jkFiuES5S+d+ZlvL2sTA4+x8HWw== +"@douyinfe/semi-ui-19@^2.90.13": + version "2.90.13" + resolved "https://registry.npmjs.org/@douyinfe/semi-ui-19/-/semi-ui-19-2.90.13.tgz" + integrity sha512-OdJOOKEiRBTpwSdGSdtkwzAsQxehrQtvsU37YgMR3jGXL38PGN+UhEjdVbx+p6HS3G9fMbL1n/2+LvnHg4vx8A== + dependencies: + "@dnd-kit/core" "^6.0.8" + "@dnd-kit/sortable" "^7.0.2" + "@dnd-kit/utilities" "^3.2.1" + "@douyinfe/semi-animation" "2.90.13" + "@douyinfe/semi-animation-react" "2.90.13" + "@douyinfe/semi-foundation" "2.90.13" + "@douyinfe/semi-icons" "2.90.13" + "@douyinfe/semi-illustrations" "2.90.13" + "@douyinfe/semi-theme-default" "2.90.13" + "@tiptap/core" "^3.10.7" + "@tiptap/extension-document" "^3.10.7" + "@tiptap/extension-hard-break" "^3.10.7" + "@tiptap/extension-mention" "^3.10.7" + "@tiptap/extension-paragraph" "^3.10.7" + "@tiptap/extension-text" "^3.10.7" + "@tiptap/extensions" "^3.10.7" + "@tiptap/pm" "^3.10.7" + "@tiptap/react" "^3.10.7" + async-validator "^3.5.0" + classnames "^2.2.6" + copy-text-to-clipboard "^2.1.1" + date-fns "^2.29.3" + date-fns-tz "^1.3.8" + fast-copy "^3.0.1 " + jsonc-parser "^3.3.1" + lodash "^4.17.21" + prop-types "^15.7.2" + prosemirror-state "^1.4.3" + react-resizable "^3.0.5" + react-window "^1.8.2" + scroll-into-view-if-needed "^2.2.24" + utility-types "^3.10.0" + "@douyinfe/semi-ui@2.90.13": version "2.90.13" resolved "https://registry.npmjs.org/@douyinfe/semi-ui/-/semi-ui-2.90.13.tgz" @@ -1007,136 +1036,11 @@ scroll-into-view-if-needed "^2.2.24" utility-types "^3.10.0" -"@esbuild/aix-ppc64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz#116edcd62c639ed8ab551e57b38251bb28384de4" - integrity sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA== - -"@esbuild/android-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz#31c00d864c80f6de1900a11de8a506dbfbb27349" - integrity sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ== - -"@esbuild/android-arm@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.1.tgz#d2b73ab0ba894923a1d1378fd4b15cc20985f436" - integrity sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg== - -"@esbuild/android-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.1.tgz#d9f74d8278191317250cfe0c15a13f410540b122" - integrity sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ== - "@esbuild/darwin-arm64@0.27.1": version "0.27.1" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz" integrity sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ== -"@esbuild/darwin-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz#64e37400795f780a76c858a118ff19681a64b4e0" - integrity sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ== - -"@esbuild/freebsd-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz#6572f2f235933eee906e070dfaae54488ee60acd" - integrity sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg== - -"@esbuild/freebsd-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz#83105dba9cf6ac4f44336799446d7f75c8c3a1e1" - integrity sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ== - -"@esbuild/linux-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz#035ff647d4498bdf16eb2d82801f73b366477dfa" - integrity sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q== - -"@esbuild/linux-arm@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz#3516c74d2afbe305582dbb546d60f7978a8ece7f" - integrity sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA== - -"@esbuild/linux-ia32@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz#788db5db8ecd3d75dd41c42de0fe8f1fd967a4a7" - integrity sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw== - -"@esbuild/linux-loong64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz#8211f08b146916a6302ec2b8f87ec0cc4b62c49e" - integrity sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg== - -"@esbuild/linux-mips64el@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz#cc58586ea83b3f171e727a624e7883a1c3eb4c04" - integrity sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA== - -"@esbuild/linux-ppc64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz#632477bbd98175cf8e53a7c9952d17fb2d6d4115" - integrity sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ== - -"@esbuild/linux-riscv64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz#35435a82435a8a750edf433b83ac0d10239ac3fe" - integrity sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ== - -"@esbuild/linux-s390x@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz#172edd7086438edacd86c0e2ea25ac9dbb62aac5" - integrity sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw== - -"@esbuild/linux-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz#09c771de9e2d8169d5969adf298ae21581f08c7f" - integrity sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA== - -"@esbuild/netbsd-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz#475ac0ce7edf109a358b1669f67759de4bcbb7c4" - integrity sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ== - -"@esbuild/netbsd-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz#3c31603d592477dc43b63df1ae100000f7fb59d7" - integrity sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg== - -"@esbuild/openbsd-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz#482067c847665b10d66431e936d4bc5fa8025abf" - integrity sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g== - -"@esbuild/openbsd-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz#687a188c2b184e5b671c5f74a6cd6247c0718c52" - integrity sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg== - -"@esbuild/openharmony-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz#9929ee7fa8c1db2f33ef4d86198018dac9c1744f" - integrity sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg== - -"@esbuild/sunos-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz#94071a146f313e7394c6424af07b2b564f1f994d" - integrity sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA== - -"@esbuild/win32-arm64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz#869fde72a3576fdf48824085d05493fceebe395d" - integrity sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg== - -"@esbuild/win32-ia32@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz#31d7585893ed7b54483d0b8d87a4bfeba0ecfff5" - integrity sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ== - -"@esbuild/win32-x64@0.27.1": - version "0.27.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz#5efe5a112938b1180e98c76685ff9185cfa4f16e" - integrity sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw== - "@eslint-community/eslint-utils@^4.8.0": version "4.9.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz" @@ -1445,106 +1349,11 @@ resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz" integrity sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ== -"@rollup/rollup-android-arm-eabi@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.49.0.tgz#ba432433f5e7b419dba2be407d1d59fea6b8de48" - integrity sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA== - -"@rollup/rollup-android-arm64@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.49.0.tgz#4e05c86e0fb9af6eaf52fc298dcdec577477e35c" - integrity sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w== - "@rollup/rollup-darwin-arm64@4.49.0": version "4.49.0" resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.49.0.tgz" integrity sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw== -"@rollup/rollup-darwin-x64@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.49.0.tgz#d44e05bee55b781d7c2cf535d9f9169787c3599d" - integrity sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg== - -"@rollup/rollup-freebsd-arm64@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.49.0.tgz#107786b4d604495224c3543bfd2cae33ddf76500" - integrity sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA== - -"@rollup/rollup-freebsd-x64@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.49.0.tgz#54e105c3da27f31084ca6913fed603627755abde" - integrity sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w== - -"@rollup/rollup-linux-arm-gnueabihf@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.49.0.tgz#725c23e0766b5d9368180bc2c427a51e31d0e147" - integrity sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w== - -"@rollup/rollup-linux-arm-musleabihf@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.49.0.tgz#6946b0d2f132f2baf5657945b81565d8abd51cc0" - integrity sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA== - -"@rollup/rollup-linux-arm64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.49.0.tgz#83510a6d03e748619241a17f5a879418a963c5ed" - integrity sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg== - -"@rollup/rollup-linux-arm64-musl@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.49.0.tgz#085b98d44c10908626dd40f26bf924433bbd8471" - integrity sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg== - -"@rollup/rollup-linux-loongarch64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.49.0.tgz#13e0a4808e9f7924f2cc8c133603f627c7a00543" - integrity sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ== - -"@rollup/rollup-linux-ppc64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.49.0.tgz#aeee4e47fc9ca5d6687e686fea4696202af6b2f4" - integrity sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g== - -"@rollup/rollup-linux-riscv64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.49.0.tgz#603e4591643f1d7851a96d096cf7fcd273f7b0e1" - integrity sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw== - -"@rollup/rollup-linux-riscv64-musl@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.49.0.tgz#f8fd9b01f1888e1816d5a398789d430511286c00" - integrity sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw== - -"@rollup/rollup-linux-s390x-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.49.0.tgz#37a1fd372d9b93d2b75b2f37c482ecf52f52849b" - integrity sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A== - -"@rollup/rollup-linux-x64-gnu@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.49.0.tgz#131e66dbf7e71cb2a389acc45319bd4c990e093a" - integrity sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA== - -"@rollup/rollup-linux-x64-musl@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.49.0.tgz#b7245a5ea57db9679e8bf3032c25a5d2c5f54056" - integrity sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg== - -"@rollup/rollup-win32-arm64-msvc@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.49.0.tgz#768a128bb5da3c5472c3c56aec77507d28bc7209" - integrity sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA== - -"@rollup/rollup-win32-ia32-msvc@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.49.0.tgz#ce3f3b2eebe585340631498666718f00983a6a62" - integrity sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA== - -"@rollup/rollup-win32-x64-msvc@4.49.0": - version "4.49.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.49.0.tgz#c2a0e3b81262a7e9dd12ce18b350a97558dd50bc" - integrity sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg== - "@sendgrid/client@^8.1.5": version "8.1.5" resolved "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.5.tgz" @@ -1568,15 +1377,15 @@ "@sendgrid/client" "^8.1.5" "@sendgrid/helpers" "^8.0.0" -"@tiptap/core@^3.10.7": - version "3.15.3" - resolved "https://registry.npmjs.org/@tiptap/core/-/core-3.15.3.tgz" - integrity sha512-bmXydIHfm2rEtGju39FiQNfzkFx9CDvJe+xem1dgEZ2P6Dj7nQX9LnA1ZscW7TuzbBRkL5p3dwuBIi3f62A66A== +"@tiptap/core@^3.10.7", "@tiptap/core@^3.11.0", "@tiptap/core@^3.15.3", "@tiptap/core@^3.16.0": + version "3.16.0" + resolved "https://registry.npmjs.org/@tiptap/core/-/core-3.16.0.tgz" + integrity sha512-XegRaNuoQ/guzBQU2xHxOwFXXrtoXW9tiyXDhssSqylvZmBVSlRIPNHA6ArkHBKm6ehLf6+6Y9fF3uky1yCXYQ== -"@tiptap/extension-bubble-menu@^3.11.0": - version "3.11.0" - resolved "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.11.0.tgz" - integrity sha512-P3j9lQ+EZ5Zg/isJzLpCPX7bp7WUBmz8GPs/HPlyMyN2su8LqXntITBZr8IP1JNBlB/wR83k/W0XqdC57mG7cA== +"@tiptap/extension-bubble-menu@^3.16.0": + version "3.16.0" + resolved "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.16.0.tgz" + integrity sha512-nFL7FMu1LjZ5ZGf4U3tw56JLj/SpLysZvHQ1EneGB+90TEI/WReOvTY9VwH1egGWwrl7/OvQuGKclbuLIsy+BA== dependencies: "@floating-ui/dom" "^1.0.0" @@ -1585,10 +1394,10 @@ resolved "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.11.0.tgz" integrity sha512-N2G3cwL2Dtur/CgD/byJmFx9T5no6fTO/U462VP3rthQYrRA1AB3TCYqtlwJkmyoxRTNd4qIg4imaPl8ej6Heg== -"@tiptap/extension-floating-menu@^3.11.0": - version "3.11.0" - resolved "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.11.0.tgz" - integrity sha512-nEHdWZHEJYX1II1oJQ4aeZ8O/Kss4BRbYFXQFGIvPelCfCYEATpUJh3aq3767ARSq40bOWyu+Dcd4SCW0We6Sw== +"@tiptap/extension-floating-menu@^3.16.0": + version "3.16.0" + resolved "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.16.0.tgz" + integrity sha512-cokYXL8EkW+CFIlke70GLL7iKetUtYEp87muMG9oflczyj0BjmGAbO7Mskm+bcQBhxZ0dIYILTqKn2bNBvCDFw== "@tiptap/extension-hard-break@^3.10.7": version "3.11.0" @@ -1615,10 +1424,10 @@ resolved "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.11.0.tgz" integrity sha512-g43beA73ZMLezez1st9LEwYrRHZ0FLzlsSlOZKk7sdmtHLmuqWHf4oyb0XAHol1HZIdGv104rYaGNgmQXr1ecQ== -"@tiptap/pm@^3.10.7": - version "3.15.3" - resolved "https://registry.npmjs.org/@tiptap/pm/-/pm-3.15.3.tgz" - integrity sha512-Zm1BaU1TwFi3CQiisxjgnzzIus+q40bBKWLqXf6WEaus8Z6+vo1MT2pU52dBCMIRaW9XNDq3E5cmGtMc1AlveA== +"@tiptap/pm@^3.10.7", "@tiptap/pm@^3.11.0", "@tiptap/pm@^3.15.3", "@tiptap/pm@^3.16.0": + version "3.16.0" + resolved "https://registry.npmjs.org/@tiptap/pm/-/pm-3.16.0.tgz" + integrity sha512-FMxZ6Tc5ONKa/EByDV8lswct6YW2lF/wn11zqXmrfBZhdG7UQPTijpSwb6TCqaO5GOHmixaIaDPj+zimUREHQA== dependencies: prosemirror-changeset "^2.3.0" prosemirror-collab "^1.3.1" @@ -1640,16 +1449,21 @@ prosemirror-view "^1.38.1" "@tiptap/react@^3.10.7": - version "3.11.0" - resolved "https://registry.npmjs.org/@tiptap/react/-/react-3.11.0.tgz" - integrity sha512-SDGei/2DjwmhzsxIQNr6dkB6NxLgXZjQ6hF36NfDm4937r5NLrWrNk5tCsoDQiKZ0DHEzuJ6yZM5C7I7LZLB6w== + version "3.16.0" + resolved "https://registry.npmjs.org/@tiptap/react/-/react-3.16.0.tgz" + integrity sha512-r1R19Ma4zxGt8ImiNOqSArAnWO239KUI9tTVeelgTyekPj7643lO8GbtuXJfAeWGPduDIpcAgR/Dd4NKieetiA== dependencies: "@types/use-sync-external-store" "^0.0.6" - fast-deep-equal "^3.1.3" + fast-equals "^5.3.3" use-sync-external-store "^1.4.0" optionalDependencies: - "@tiptap/extension-bubble-menu" "^3.11.0" - "@tiptap/extension-floating-menu" "^3.11.0" + "@tiptap/extension-bubble-menu" "^3.16.0" + "@tiptap/extension-floating-menu" "^3.16.0" + +"@tiptap/suggestion@^3.11.0": + version "3.15.3" + resolved "https://registry.npmjs.org/@tiptap/suggestion/-/suggestion-3.15.3.tgz" + integrity sha512-+CbaHhPfKUe+fNpUIQaOPhh6xI+xL5jbK1zw++U+CZIRrVAAmHRhO+D0O2HdiE1RK7596y8bRqMiB2CRHF7emA== "@tootallnate/quickjs-emscripten@^0.23.0": version "0.23.0" @@ -1703,7 +1517,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@1.0.8", "@types/estree@^1.0.0", "@types/estree@^1.0.6": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@1.0.8": version "1.0.8" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== @@ -1767,13 +1581,25 @@ resolved "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz" integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== -"@types/node@*": +"@types/node@*", "@types/node@^20.19.0 || >=22.12.0": version "24.3.0" resolved "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz" integrity sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow== dependencies: undici-types "~7.10.0" +"@types/react-dom@^17.0.0 || ^18.0.0 || ^19.0.0": + version "19.2.3" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz" + integrity sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== + +"@types/react@^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^19.2.0", "@types/react@>=18.0.0": + version "19.2.7" + resolved "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz" + integrity sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg== + dependencies: + csstype "^3.2.2" + "@types/supercluster@^7.1.3": version "7.1.3" resolved "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz" @@ -1820,12 +1646,21 @@ "@types/babel__core" "^7.20.5" react-refresh "^0.18.0" +"0http@^4.3.0": + version "4.3.0" + resolved "https://registry.npmjs.org/0http/-/0http-4.3.0.tgz" + integrity sha512-3Z4WQ4IA7g6+4C1KCHY3JzDEVpo1npTCO7Ym0RmLqXmaNGgtWbiJ/r/QpcKnGHH0lHveJSeVMqBMce7lZNkdmw== + dependencies: + lru-cache "^11.0.2" + regexparam "^3.0.0" + trouter "^4.0.0" + acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.0.0, acorn@^8.15.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.15.0: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -1874,7 +1709,12 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^6.1.0, ansi-styles@^6.2.1: +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +ansi-styles@^6.2.1: version "6.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== @@ -2066,7 +1906,7 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -bare-events@^2.5.4, bare-events@^2.7.0: +bare-events@*, bare-events@^2.5.4, bare-events@^2.7.0: version "2.8.2" resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz" integrity sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ== @@ -2118,10 +1958,10 @@ basic-ftp@^5.0.2: resolved "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz" integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg== -better-sqlite3@^12.6.0: - version "12.6.0" - resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.6.0.tgz" - integrity sha512-FXI191x+D6UPWSze5IzZjhz+i9MK9nsuHsmTX9bXVl52k06AfZ2xql0lrgIUuzsMsJ7Vgl5kIptvDgBLIV3ZSQ== +better-sqlite3@^12.6.2: + version "12.6.2" + resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.6.2.tgz" + integrity sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA== dependencies: bindings "^1.5.0" prebuild-install "^7.1.1" @@ -2204,7 +2044,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, browserslist@^4.25.3, "browserslist@>= 4.21.0": version "4.25.3" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz" integrity sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ== @@ -2311,7 +2151,7 @@ character-reference-invalid@^2.0.0: resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz" integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== -chart.js@^4.5.1: +chart.js@^4.1.1, chart.js@^4.5.1: version "4.5.1" resolved "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz" integrity sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw== @@ -2374,10 +2214,10 @@ chownr@^1.1.1: resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== -chromium-bidi@12.0.1: - version "12.0.1" - resolved "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-12.0.1.tgz" - integrity sha512-fGg+6jr0xjQhzpy5N4ErZxQ4wF7KLEvhGZXD6EgvZKDhu7iOhZXnZhcDxPJDcwTcrD48NPzOCo84RP2lv3Z+Cg== +chromium-bidi@13.0.1: + version "13.0.1" + resolved "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-13.0.1.tgz" + integrity sha512-c+RLxH0Vg2x2syS9wPw378oJgiJNXtYXUvnVAldUlt5uaHekn0CCU7gPksNgHjrH1qFhmjVXQj4esvuthuC7OQ== dependencies: mitt "^3.0.1" zod "^3.24.1" @@ -2424,7 +2264,7 @@ clone-deep@^0.2.4: clsx@^1.1.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== clsx@^2.1.1: @@ -2502,9 +2342,9 @@ cookie-session@2.1.1: safe-buffer "5.2.1" cookie@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz" - integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA== + version "1.1.1" + resolved "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz" + integrity sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ== cookies@0.9.1: version "0.9.1" @@ -2535,7 +2375,7 @@ core-js-compat@^3.43.0: core-js@^3.22.4: version "3.47.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.47.0.tgz#436ef07650e191afeb84c24481b298bd60eb4a17" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz" integrity sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg== cosmiconfig@^9.0.0: @@ -2578,6 +2418,11 @@ css-what@^6.1.0: resolved "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz" integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA== +csstype@^3.2.2: + version "3.2.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== + data-uri-to-buffer@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz" @@ -2620,13 +2465,20 @@ date-fns-tz@^1.3.8: resolved "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.8.tgz" integrity sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ== -date-fns@^2.29.3: +date-fns@^2.29.3, date-fns@>=2.0.0: version "2.30.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz" integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== dependencies: "@babel/runtime" "^7.21.0" +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: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + debug@3.2.7: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" @@ -2634,13 +2486,6 @@ 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: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - decamelize@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" @@ -2712,7 +2557,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0, depd@~2.0.0: +depd@~2.0.0, depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -2734,10 +2579,10 @@ devlop@^1.0.0, devlop@^1.1.0: dependencies: dequal "^2.0.0" -devtools-protocol@0.0.1534754: - version "0.0.1534754" - resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz" - integrity sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ== +devtools-protocol@*, devtools-protocol@0.0.1551306: + version "0.0.1551306" + resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1551306.tgz" + integrity sha512-CFx8QdSim8iIv+2ZcEOclBKTQY6BI1IEDa7Tm9YkwAXzEWFndTEzpTo5jAUhSnq24IC7xaDw0wvGcm96+Y3PEg== diff@^7.0.0: version "7.0.0" @@ -3121,14 +2966,6 @@ eslint-plugin-react@7.37.5: string.prototype.matchall "^4.0.12" string.prototype.repeat "^1.0.0" -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-scope@^8.4.0: version "8.4.0" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz" @@ -3137,6 +2974,14 @@ eslint-scope@^8.4.0: esrecurse "^4.3.0" estraverse "^5.2.0" +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" @@ -3152,7 +2997,7 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@9.39.2: +"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.5.0 || ^8.0.0 || ^9.0.0", eslint@>=7.0.0, eslint@9.39.2: version "9.39.2" resolved "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz" integrity sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw== @@ -3342,6 +3187,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-equals@^5.3.3: + version "5.4.0" + resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz" + integrity sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw== + fast-fifo@^1.2.0, fast-fifo@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz" @@ -3863,14 +3713,21 @@ husky@9.1.7: resolved "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz" integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA== -iconv-lite@0.6.3, iconv-lite@^0.6.3: +iconv-lite@^0.6.3, iconv-lite@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -iconv-lite@^0.7.0, iconv-lite@~0.7.0: +iconv-lite@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz" + integrity sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +iconv-lite@~0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz" integrity sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ== @@ -3918,7 +3775,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.4: +inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.4, inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4380,7 +4237,7 @@ lazy-cache@^1.0.3: resolved "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz" integrity sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ== -less@4.5.1: +less@^4.0.0, less@4.5.1: version "4.5.1" resolved "https://registry.npmjs.org/less/-/less-4.5.1.tgz" integrity sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw== @@ -4459,10 +4316,10 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@4.17.21, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lodash@^4.17.21, lodash@4.17.23: + version "4.17.23" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz" + integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== log-symbols@^4.1.0: version "4.1.0" @@ -4488,7 +4345,7 @@ longest-streak@^3.0.0: resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -4787,7 +4644,7 @@ media-typer@^1.1.0: resolved "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz" integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== -"memoize-one@>=3.1.1 <6", memoize-one@^5.2.1: +memoize-one@^5.2.1, "memoize-one@>=3.1.1 <6": version "5.2.1" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== @@ -5176,16 +5033,16 @@ micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - mime-db@^1.54.0: version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@^2.1.12: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" @@ -5299,16 +5156,16 @@ nano-spawn@^2.0.0: resolved "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz" integrity sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw== -nanoid@5.1.6: - version "5.1.6" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz" - integrity sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg== - nanoid@^3.3.11: version "3.3.11" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== +nanoid@5.1.6: + version "5.1.6" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz" + integrity sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg== + napi-build-utils@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz" @@ -5679,7 +5536,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.3: +"picomatch@^3 || ^4", picomatch@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== @@ -5736,10 +5593,10 @@ prelude-ls@^1.2.1: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@3.8.0: - version "3.8.0" - resolved "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz" - integrity sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA== +prettier@3.8.1: + version "3.8.1" + resolved "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz" + integrity sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg== prismjs@^1.29.0: version "1.30.0" @@ -5751,7 +5608,7 @@ progress@^2.0.3: resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prop-types@15.x, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.7.2, prop-types@^15.8.1, prop-types@15.x: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -5852,7 +5709,7 @@ prosemirror-menu@^1.2.4: prosemirror-history "^1.0.0" prosemirror-state "^1.0.0" -prosemirror-model@^1.0.0, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.24.1, prosemirror-model@^1.25.0: +prosemirror-model@^1.0.0, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.22.1, prosemirror-model@^1.24.1, prosemirror-model@^1.25.0: version "1.25.4" resolved "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz" integrity sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA== @@ -5875,7 +5732,7 @@ prosemirror-schema-list@^1.5.0: prosemirror-state "^1.0.0" prosemirror-transform "^1.7.3" -prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.4.3: +prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.4.2, prosemirror-state@^1.4.3: version "1.4.4" resolved "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz" integrity sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw== @@ -5910,7 +5767,7 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor dependencies: prosemirror-model "^1.21.0" -prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.38.1, prosemirror-view@^1.39.1: +prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.33.8, prosemirror-view@^1.38.1, prosemirror-view@^1.39.1: version "1.41.3" resolved "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.3.tgz" integrity sha512-SqMiYMUQNNBP9kfPhLO8WXEk/fon47vc52FQsUiJzTBuyjKgEcoAwMyF04eQ4WZ2ArMn7+ReypYL60aKngbACQ== @@ -5971,17 +5828,17 @@ punycode@^2.1.0: resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -puppeteer-core@24.35.0: - version "24.35.0" - resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.35.0.tgz" - integrity sha512-vt1zc2ME0kHBn7ZDOqLvgvrYD5bqNv5y2ZNXzYnCv8DEtZGw/zKhljlrGuImxptZ4rq+QI9dFGrUIYqG4/IQzA== +puppeteer-core@*, puppeteer-core@24.36.0: + version "24.36.0" + resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.36.0.tgz" + integrity sha512-P3Ou0MAFDCQ0dK1d9F9+8jTrg6JvXjUacgG0YkJQP4kbEnUOGokSDEMmMId5ZhXD5HwsHM202E9VwEpEjWfwxg== dependencies: "@puppeteer/browsers" "2.11.1" - chromium-bidi "12.0.1" + chromium-bidi "13.0.1" debug "^4.4.3" - devtools-protocol "0.0.1534754" + devtools-protocol "0.0.1551306" typed-query-selector "^2.12.0" - webdriver-bidi-protocol "0.3.10" + webdriver-bidi-protocol "0.4.0" ws "^8.19.0" puppeteer-extra-plugin-stealth@^2.11.2: @@ -6022,7 +5879,7 @@ puppeteer-extra-plugin@^3.2.3: debug "^4.1.1" merge-deep "^3.0.1" -puppeteer-extra@^3.3.6: +puppeteer-extra@*, puppeteer-extra@^3.3.6: version "3.3.6" resolved "https://registry.npmjs.org/puppeteer-extra/-/puppeteer-extra-3.3.6.tgz" integrity sha512-rsLBE/6mMxAjlLd06LuGacrukP2bqbzKCLzV1vrhHFavqQE/taQ2UXv3H5P0Ls7nsrASa+6x3bDbXHpqMwq+7A== @@ -6031,16 +5888,16 @@ puppeteer-extra@^3.3.6: debug "^4.1.1" deepmerge "^4.2.2" -puppeteer@^24.35.0: - version "24.35.0" - resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-24.35.0.tgz" - integrity sha512-sbjB5JnJ+3nwgSdRM/bqkFXqLxRz/vsz0GRIeTlCk+j+fGpqaF2dId9Qp25rXz9zfhqnN9s0krek1M/C2GDKtA== +puppeteer@*, puppeteer@^24.36.0: + version "24.36.0" + resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-24.36.0.tgz" + integrity sha512-BD/VCyV/Uezvd6o7Fd1DmEJSxTzofAKplzDy6T9d4WbLTQ5A+06zY7VwO91ZlNU22vYE8sidVEsTpTrKc+EEnQ== dependencies: "@puppeteer/browsers" "2.11.1" - chromium-bidi "12.0.1" + chromium-bidi "13.0.1" cosmiconfig "^9.0.0" - devtools-protocol "0.0.1534754" - puppeteer-core "24.35.0" + devtools-protocol "0.0.1551306" + puppeteer-core "24.36.0" typed-query-selector "^2.12.0" qs@^6.14.1: @@ -6101,13 +5958,12 @@ react-chartjs-2@^5.3.1: resolved "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.1.tgz" integrity sha512-h5IPXKg9EXpjoBzUfyWJvllMjG2mQ4EiuHQFhms/AjUm0XSZHhyRy2xVmLXHKrtcdrPO4mnGqRtYoD0vp95A0A== -react-dom@18.3.1: - version "18.3.1" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== +"react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", react-dom@^19.0.0, "react-dom@>= 16.3.0", react-dom@>=16.0.0, react-dom@>=16.8.0, react-dom@>=18, react-dom@19.2.3: + version "19.2.3" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz" + integrity sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg== dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" + scheduler "^0.27.0" react-draggable@^4.0.3: version "4.5.0" @@ -6124,7 +5980,7 @@ react-is@^16.13.1: react-range-slider-input@^3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/react-range-slider-input/-/react-range-slider-input-3.3.2.tgz#1fe03d7489fe2c664c92b0cf970b19b45257ec82" + resolved "https://registry.npmjs.org/react-range-slider-input/-/react-range-slider-input-3.3.2.tgz" integrity sha512-CGyD/6Vlc7qakSW+92WAKrp333Xo9W+udW62xvf6dSwqEj7LFSY75udcbNRtCQhuXW1O7o71yC4AC/CC0etqSg== dependencies: clsx "^1.1.1" @@ -6166,12 +6022,10 @@ react-window@^1.8.2: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@18.3.1: - version "18.3.1" - resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" +"react@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", react@^19.0.0, react@^19.2.3, "react@>= 16.3", "react@>= 16.3.0", react@>=16.0.0, react@>=16.8.0, react@>=18, react@>=18.0.0, react@19.2.3: + version "19.2.3" + resolved "https://registry.npmjs.org/react/-/react-19.2.3.tgz" + integrity sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA== readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.2" @@ -6403,9 +6257,7 @@ resolve@^2.0.0-next.5: supports-preserve-symlinks-flag "^1.0.0" restana@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/restana/-/restana-5.1.0.tgz#c6f72090b1599d864d87ce054eb5c190fa7b1c3b" - integrity sha512-LHDNXj5AmwGDrnR2DUG/+kGzfGa1KysXP2H0cCvhuVk+/peRLbLqOMuULSul/SGnW3s2+ijnvJCowBWLyniCMQ== + version "v5.1.0" dependencies: "0http" "^4.3.0" @@ -6479,7 +6331,7 @@ safe-array-concat@^1.1.3: has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -6511,12 +6363,10 @@ sax@^1.2.4: resolved "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" +scheduler@^0.27.0: + version "0.27.0" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz" + integrity sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q== scroll-into-view-if-needed@^2.2.24: version "2.2.31" @@ -6535,7 +6385,12 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.5.3: +semver@^7.3.5: + version "7.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + +semver@^7.5.3: version "7.7.2" resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== @@ -6580,9 +6435,9 @@ serve-static@2.2.1: send "^1.2.0" set-cookie-parser@^2.6.0: - version "2.7.1" - resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz" - integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== + version "2.7.2" + resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz" + integrity sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw== set-function-length@^1.2.2: version "1.2.2" @@ -6615,7 +6470,7 @@ set-proto@^1.0.0: es-errors "^1.3.0" es-object-atoms "^1.0.0" -setprototypeof@1.2.0, setprototypeof@~1.2.0: +setprototypeof@~1.2.0, setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -6779,16 +6634,16 @@ split-on-first@^3.0.0: resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz" integrity sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - statuses@^2.0.1, statuses@~2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + stop-iteration-iterator@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz" @@ -6806,6 +6661,13 @@ streamx@^2.15.0, streamx@^2.21.0: fast-fifo "^1.3.2" text-decoder "^1.1.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string-argv@^0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" @@ -6914,13 +6776,6 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - stringify-entities@^4.0.0: version "4.0.4" resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" @@ -7080,7 +6935,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1, toidentifier@~1.0.1: +toidentifier@~1.0.1, toidentifier@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -7336,7 +7191,7 @@ url-join@^4.0.0: resolved "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== -use-sync-external-store@^1.4.0: +use-sync-external-store@^1.4.0, use-sync-external-store@>=1.2.0: version "1.6.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz" integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== @@ -7367,7 +7222,7 @@ vfile@^6.0.0: "@types/unist" "^3.0.0" vfile-message "^4.0.0" -vite@7.3.1: +"vite@^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", vite@7.3.1: version "7.3.1" resolved "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz" integrity sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA== @@ -7391,10 +7246,10 @@ web-streams-polyfill@^3.0.3: resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz" integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== -webdriver-bidi-protocol@0.3.10: - version "0.3.10" - resolved "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.10.tgz" - integrity sha512-5LAE43jAVLOhB/QqX4bwSiv0Hg1HBfMmOuwBSXHdvg4GMGu9Y0lIq7p4R/yySu6w74WmaR4GM4H9t2IwLW7hgw== +webdriver-bidi-protocol@0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.0.tgz" + integrity sha512-U9VIlNRrq94d1xxR9JrCEAx5Gv/2W7ERSv8oWRoNe/QYbfccS0V3h/H6qeNeCRJxXGMhhnkqvwNrvPAYeuP9VA== whatwg-encoding@^3.1.1: version "3.1.1" @@ -7547,7 +7402,7 @@ yallist@^3.0.2: resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yaml@^2.8.1: +yaml@^2.4.2, yaml@^2.8.1: version "2.8.1" resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz" integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==