diff --git a/electron/analytics.ts b/electron/analytics.ts new file mode 100644 index 0000000..fc5606e --- /dev/null +++ b/electron/analytics.ts @@ -0,0 +1,30 @@ +import { trackEvent, initialize } from '@aptabase/electron/main' + +/** + * Initialize Aptabase analytics + * Set the APTABASE_APP_KEY environment variable or replace the placeholder + */ +export function initAnalytics() { + const appKey = process.env.APTABASE_APP_KEY || 'YOUR_APTABASE_APP_KEY' + + // Only initialize if a valid key is provided + if (appKey && appKey !== 'YOUR_APTABASE_APP_KEY') { + try { + initialize(appKey) + console.log('Analytics initialized') + } catch (error) { + console.error('Failed to initialize analytics:', error) + } + } +} + +/** + * Track an analytics event + */ +export function track(eventName: string, properties?: Record) { + try { + trackEvent(eventName, properties) + } catch (error) { + // Silently fail if analytics is not initialized + } +} diff --git a/electron/main.ts b/electron/main.ts index aa0bbc4..123d78d 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -27,6 +27,7 @@ import { GetVectorsPaginatedParams, } from './types' import { initAutoUpdater, checkForUpdates } from './auto-updater' +import { initAnalytics, track } from './analytics' // Inject stored API keys into process.env at startup settingsStore.injectIntoProcessEnv() @@ -99,6 +100,7 @@ process.env.VITE_PUBLIC = app.isPackaged ipcMain.handle('pinecone:connect', async (_event, profileId: string, profile: ConnectionProfile) => { try { await pineconeConnectionPool.connect(profileId, profile) + track('pinecone_connected') return { success: true } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to connect to Pinecone' @@ -232,6 +234,7 @@ ipcMain.handle('pinecone:createVector', async (_event, profileId: string, params const embeddingOverride = connectionStore.getEmbeddingOverride(profileId, params.indexName) const hybridOverride = connectionStore.getHybridEmbeddingOverride(profileId, params.indexName) await service.createVector(params, embeddingOverride || undefined, hybridOverride || undefined) + track('vector_created') return { success: true } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to create vector' @@ -249,6 +252,7 @@ ipcMain.handle('pinecone:updateVector', async (_event, profileId: string, params const embeddingOverride = connectionStore.getEmbeddingOverride(profileId, params.indexName) const hybridOverride = connectionStore.getHybridEmbeddingOverride(profileId, params.indexName) await service.updateVector(params, embeddingOverride || undefined, hybridOverride || undefined) + track('vector_updated') return { success: true } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to update vector' @@ -263,6 +267,13 @@ ipcMain.handle('pinecone:deleteVectors', async (_event, profileId: string, param return { success: false, error: 'Not connected to Pinecone' } } await service.deleteVectors(params) + // Track vector deletion with count if specific IDs provided + const count = params.ids?.length + if (count !== undefined) { + track('vectors_deleted', { count }) + } else { + track('vectors_deleted') + } return { success: true } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to delete vectors' @@ -280,6 +291,9 @@ ipcMain.handle('pinecone:batchImport', async (_event, profileId: string, params: const embeddingOverride = connectionStore.getEmbeddingOverride(profileId, params.indexName) const hybridOverride = connectionStore.getHybridEmbeddingOverride(profileId, params.indexName) const result = await service.batchImport(params, embeddingOverride || undefined, undefined, hybridOverride || undefined) + track('vectors_imported', { + count: result.upsertedCount, + }) return { success: true, data: result } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to import vectors' @@ -294,6 +308,14 @@ ipcMain.handle('pinecone:createIndex', async (_event, profileId: string, params: return { success: false, error: 'Not connected to Pinecone' } } await service.createIndex(params) + // Track index creation with generic metadata + const spec = params.spec as { serverless?: { cloud?: string; region?: string } } + track('index_created', { + cloud: spec.serverless?.cloud, + region: spec.serverless?.region, + metric: params.metric, + dimension: params.dimension, + }) return { success: true } } catch (error) { // Extract cloud/region from serverless spec for better error messages @@ -313,6 +335,7 @@ ipcMain.handle('pinecone:deleteIndex', async (_event, profileId: string, indexNa return { success: false, error: 'Not connected to Pinecone' } } await service.deleteIndex(indexName) + track('index_deleted') return { success: true } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to delete index' @@ -351,6 +374,13 @@ ipcMain.handle('pinecone:cloneIndex', async (event, profileId: string, params: C // Clean up abort controller activeCloneOperations.delete(profileId) + // Track successful index duplication + if (result.success) { + track('index_duplicated', { + vectorsCopied: result.copiedVectors + }) + } + return { success: result.success, data: result, error: result.error } } catch (error) { activeCloneOperations.delete(profileId) @@ -418,6 +448,9 @@ ipcMain.handle('pinecone:cloneNamespace', async (event, profileId: string, param activeNamespaceCloneOperations.delete(operationKey) if (result.success) { + track('namespace_duplicated', { + vectorsCopied: result.copiedVectors, + }) event.sender.send('pinecone:cloneNamespaceProgress', { phase: 'complete', totalVectors, @@ -916,6 +949,10 @@ ipcMain.handle('shell:openExternal', async (_event, url: string) => { // ============================================================================ app.whenReady().then(() => { + // Initialize analytics + initAnalytics() + track('app_started') + // Create application menu createApplicationMenu() @@ -935,10 +972,15 @@ app.whenReady().then(() => { app.on('window-all-closed', () => { if (process.platform !== 'darwin') { + track('app_closed') app.quit() } }) +app.on('before-quit', () => { + track('app_closed') +}) + app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { windowManager.createSetupWindow() diff --git a/electron/pinecone-service.ts b/electron/pinecone-service.ts index 58eb742..860f38d 100644 --- a/electron/pinecone-service.ts +++ b/electron/pinecone-service.ts @@ -32,7 +32,7 @@ import { withRetry } from './retry-utils' * Main Pinecone service class */ class PineconeService { - private static readonly BATCH_SIZE = 100 + private static readonly BATCH_SIZE = 50 private client: Pinecone | null = null private embeddingService: EmbeddingService | null = null diff --git a/package.json b/package.json index 71ac1f3..63df443 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "vite-plugin-electron-renderer": "^0.14.6" }, "dependencies": { + "@aptabase/electron": "^0.3.1", "@pinecone-database/pinecone": "^6.1.3", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-dialog": "^1.1.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4439544..a1f41d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@aptabase/electron': + specifier: ^0.3.1 + version: 0.3.1(electron@39.2.7) '@pinecone-database/pinecone': specifier: ^6.1.3 version: 6.1.3 @@ -136,6 +139,14 @@ packages: engines: {node: '>=10'} dev: true + /@aptabase/electron@0.3.1(electron@39.2.7): + resolution: {integrity: sha512-FECaGsjuoQu70F+M6V1evdgLP7yaq/sne9fC60AZZ6B9RsCDlxFBnJzdq3+xevHlUx6AB5o9ygUhQ+ONT9EqiA==} + peerDependencies: + electron: '>= 3.x' + dependencies: + electron: 39.2.7 + dev: false + /@develar/schema-utils@2.6.5: resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} engines: {node: '>= 8.9.0'} @@ -178,7 +189,6 @@ packages: global-agent: 3.0.0 transitivePeerDependencies: - supports-color - dev: true /@electron/notarize@2.5.0: resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} @@ -1667,14 +1677,12 @@ packages: /@sindresorhus/is@4.6.0: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} - dev: true /@szmarczak/http-timer@4.0.6: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} dependencies: defer-to-connect: 2.0.1 - dev: true /@tailwindcss/node@4.1.18: resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} @@ -1882,7 +1890,6 @@ packages: '@types/keyv': 3.1.4 '@types/node': 25.0.9 '@types/responselike': 1.0.3 - dev: true /@types/debug@4.1.12: resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -1902,13 +1909,11 @@ packages: /@types/http-cache-semantics@4.0.4: resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - dev: true /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: '@types/node': 25.0.9 - dev: true /@types/ms@2.1.0: resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -1931,7 +1936,6 @@ packages: resolution: {integrity: sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==} dependencies: undici-types: 6.21.0 - dev: true /@types/node@25.0.9: resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} @@ -1963,7 +1967,6 @@ packages: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: '@types/node': 25.0.9 - dev: true /@types/verror@1.10.11: resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==} @@ -1976,7 +1979,6 @@ packages: requiresBuild: true dependencies: '@types/node': 25.0.9 - dev: true optional: true /@xmldom/xmldom@0.8.11: @@ -2206,7 +2208,6 @@ packages: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. requiresBuild: true - dev: true optional: true /brace-expansion@1.1.12: @@ -2236,7 +2237,6 @@ packages: /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: true /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -2310,7 +2310,6 @@ packages: /cacheable-lookup@5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} - dev: true /cacheable-request@7.0.4: resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} @@ -2323,7 +2322,6 @@ packages: lowercase-keys: 2.0.0 normalize-url: 6.1.0 responselike: 2.0.1 - dev: true /call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} @@ -2404,7 +2402,6 @@ packages: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} dependencies: mimic-response: 1.0.1 - dev: true /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} @@ -2524,7 +2521,6 @@ packages: engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 - dev: true /defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -2535,7 +2531,6 @@ packages: /defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} - dev: true /define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} @@ -2545,7 +2540,6 @@ packages: es-define-property: 1.0.1 es-errors: 1.3.0 gopd: 1.2.0 - dev: true optional: true /define-properties@1.2.1: @@ -2556,7 +2550,6 @@ packages: define-data-property: 1.1.4 has-property-descriptors: 1.0.2 object-keys: 1.1.1 - dev: true optional: true /delayed-stream@1.0.0: @@ -2574,7 +2567,6 @@ packages: /detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} requiresBuild: true - dev: true optional: true /dir-compare@4.2.0: @@ -2766,7 +2758,6 @@ packages: extract-zip: 2.0.1 transitivePeerDependencies: - supports-color - dev: true /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2788,7 +2779,6 @@ packages: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} dependencies: once: 1.4.0 - dev: true /enhanced-resolve@5.18.4: resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} @@ -2801,7 +2791,6 @@ packages: /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - dev: true /env-paths@3.0.0: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} @@ -2838,7 +2827,6 @@ packages: /es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} requiresBuild: true - dev: true optional: true /esbuild@0.27.2: @@ -2884,7 +2872,6 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} requiresBuild: true - dev: true optional: true /event-target-shim@5.0.1: @@ -2908,7 +2895,6 @@ packages: '@types/yauzl': 2.10.3 transitivePeerDependencies: - supports-color - dev: true /extsprintf@1.4.1: resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} @@ -2933,7 +2919,6 @@ packages: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} dependencies: pend: 1.2.0 - dev: true /fdir@6.5.0(picomatch@4.0.3): resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -3020,7 +3005,6 @@ packages: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - dev: true /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} @@ -3098,7 +3082,6 @@ packages: engines: {node: '>=8'} dependencies: pump: 3.0.3 - dev: true /glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} @@ -3135,7 +3118,6 @@ packages: roarr: 2.15.4 semver: 7.7.3 serialize-error: 7.0.1 - dev: true optional: true /globalthis@1.0.4: @@ -3145,7 +3127,6 @@ packages: dependencies: define-properties: 1.2.1 gopd: 1.2.0 - dev: true optional: true /gopd@1.2.0: @@ -3167,7 +3148,6 @@ packages: lowercase-keys: 2.0.0 p-cancelable: 2.1.1 responselike: 2.0.1 - dev: true /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -3182,7 +3162,6 @@ packages: requiresBuild: true dependencies: es-define-property: 1.0.1 - dev: true optional: true /has-symbols@1.1.0: @@ -3210,7 +3189,6 @@ packages: /http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - dev: true /http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} @@ -3228,7 +3206,6 @@ packages: dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - dev: true /https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} @@ -3356,7 +3333,6 @@ packages: /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -3374,7 +3350,6 @@ packages: /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} requiresBuild: true - dev: true optional: true /json5@2.2.3: @@ -3387,7 +3362,6 @@ packages: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: graceful-fs: 4.2.11 - dev: true /jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} @@ -3400,7 +3374,6 @@ packages: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: json-buffer: 3.0.1 - dev: true /lazy-val@1.0.5: resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} @@ -3547,7 +3520,6 @@ packages: /lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} - dev: true /lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -3599,7 +3571,6 @@ packages: requiresBuild: true dependencies: escape-string-regexp: 4.0.0 - dev: true optional: true /math-intrinsics@1.1.0: @@ -3635,12 +3606,10 @@ packages: /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} - dev: true /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - dev: true /minimatch@10.1.1: resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} @@ -3847,20 +3816,17 @@ packages: /normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - dev: true /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} requiresBuild: true - dev: true optional: true /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 - dev: true /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} @@ -3910,7 +3876,6 @@ packages: /p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} - dev: true /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -3953,7 +3918,6 @@ packages: /pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - dev: true /picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -4004,7 +3968,6 @@ packages: /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - dev: true /promise-retry@2.0.1: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} @@ -4019,7 +3982,6 @@ packages: dependencies: end-of-stream: 1.4.5 once: 1.4.0 - dev: true /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -4030,7 +3992,6 @@ packages: /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - dev: true /react-dom@19.2.3(react@19.2.3): resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} @@ -4144,13 +4105,11 @@ packages: /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - dev: true /responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} dependencies: lowercase-keys: 2.0.0 - dev: true /restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} @@ -4184,7 +4143,6 @@ packages: json-stringify-safe: 5.0.1 semver-compare: 1.0.0 sprintf-js: 1.1.3 - dev: true optional: true /rollup@4.55.2: @@ -4247,7 +4205,6 @@ packages: /semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} requiresBuild: true - dev: true optional: true /semver@5.7.2: @@ -4258,7 +4215,6 @@ packages: /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - dev: true /semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} @@ -4271,7 +4227,6 @@ packages: requiresBuild: true dependencies: type-fest: 0.13.1 - dev: true optional: true /sharp@0.34.5: @@ -4392,7 +4347,6 @@ packages: /sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} requiresBuild: true - dev: true optional: true /ssri@12.0.0: @@ -4462,7 +4416,6 @@ packages: debug: 4.4.3 transitivePeerDependencies: - supports-color - dev: true /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} @@ -4583,7 +4536,6 @@ packages: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} requiresBuild: true - dev: true optional: true /type-fest@5.4.1: @@ -4610,7 +4562,6 @@ packages: /undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - dev: true /undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} @@ -4632,7 +4583,6 @@ packages: /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - dev: true /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} @@ -4842,7 +4792,6 @@ packages: /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true /xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} @@ -4886,7 +4835,6 @@ packages: dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}