From 390ea680a602b891cc2683f972b8b8f2855c3cc3 Mon Sep 17 00:00:00 2001 From: cepds <215045801+cepds@users.noreply.github.com> Date: Wed, 8 Apr 2026 23:00:10 -0300 Subject: [PATCH] refresh desktop tool library and cleanup legacy shell --- README.md | 79 +- backend/db/repositories/toolsRepo.ts | 12 +- backend/db/repositories/workspacesRepo.ts | 12 +- capacitor.config.ts | 12 - electron/preload.ts | 1 + electron/services/ipc.ts | 2 + electron/services/toolService.ts | 74 +- package-lock.json | 1123 +---------------- package.json | 15 - scripts/build-apk.ps1 | 38 - scripts/prepare-photos.mjs | 68 - shared/toolCatalog.ts | 17 +- shared/types.ts | 2 +- src/app/App.module.css | 3 +- src/app/legacy/AppAmorLegacy.module.css | 123 -- src/app/legacy/AppAmorLegacy.tsx | 137 -- src/app/routes.tsx | 11 - .../AudioPlayer/AudioPlayer.module.css | 44 - src/components/AudioPlayer/AudioPlayer.tsx | 28 - .../GalleryHighlight.module.css | 50 - .../GalleryHighlight/GalleryHighlight.tsx | 36 - src/components/Hero/Hero.module.css | 135 -- src/components/Hero/Hero.tsx | 76 -- .../MemoryCard/MemoryCard.module.css | 72 -- src/components/MemoryCard/MemoryCard.tsx | 44 - src/components/Modal/Modal.module.css | 47 - src/components/Modal/Modal.tsx | 45 - .../PremiumButton/PremiumButton.module.css | 43 - .../PremiumButton/PremiumButton.tsx | 32 - .../SectionHeader/SectionHeader.module.css | 28 - .../SectionHeader/SectionHeader.tsx | 24 - .../TimelineItem/TimelineItem.module.css | 78 -- src/components/TimelineItem/TimelineItem.tsx | 31 - src/data/content.ts | 376 ------ src/features/apps/ToolCard.module.css | 33 + src/features/apps/ToolCard.tsx | 35 +- src/hooks/useAudio.ts | 34 - src/hooks/useLocalStorage.ts | 16 - src/hooks/useReveal.ts | 33 - src/sections/Finale/Finale.module.css | 45 - src/sections/Finale/Finale.tsx | 42 - src/sections/Gallery/Gallery.module.css | 63 - src/sections/Gallery/Gallery.tsx | 47 - src/sections/LoveLetter/LoveLetter.module.css | 62 - src/sections/LoveLetter/LoveLetter.tsx | 78 -- src/sections/Memories/Memories.module.css | 116 -- src/sections/Memories/Memories.tsx | 237 ---- src/sections/Opening/Opening.module.css | 35 - src/sections/Opening/Opening.tsx | 63 - src/sections/Promises/Promises.module.css | 46 - src/sections/Promises/Promises.tsx | 38 - src/sections/QuizGate/QuizGate.module.css | 83 -- src/sections/QuizGate/QuizGate.tsx | 85 -- src/sections/Timeline/Timeline.module.css | 9 - src/sections/Timeline/Timeline.tsx | 27 - src/services/audio.ts | 75 -- src/services/countdown.ts | 70 - src/services/desktopClient.ts | 1 + src/services/device.ts | 35 - src/services/storage.ts | 38 - src/styles/globals.css | 4 +- 61 files changed, 246 insertions(+), 4122 deletions(-) delete mode 100644 capacitor.config.ts delete mode 100644 scripts/build-apk.ps1 delete mode 100644 scripts/prepare-photos.mjs delete mode 100644 src/app/legacy/AppAmorLegacy.module.css delete mode 100644 src/app/legacy/AppAmorLegacy.tsx delete mode 100644 src/app/routes.tsx delete mode 100644 src/components/AudioPlayer/AudioPlayer.module.css delete mode 100644 src/components/AudioPlayer/AudioPlayer.tsx delete mode 100644 src/components/GalleryHighlight/GalleryHighlight.module.css delete mode 100644 src/components/GalleryHighlight/GalleryHighlight.tsx delete mode 100644 src/components/Hero/Hero.module.css delete mode 100644 src/components/Hero/Hero.tsx delete mode 100644 src/components/MemoryCard/MemoryCard.module.css delete mode 100644 src/components/MemoryCard/MemoryCard.tsx delete mode 100644 src/components/Modal/Modal.module.css delete mode 100644 src/components/Modal/Modal.tsx delete mode 100644 src/components/PremiumButton/PremiumButton.module.css delete mode 100644 src/components/PremiumButton/PremiumButton.tsx delete mode 100644 src/components/SectionHeader/SectionHeader.module.css delete mode 100644 src/components/SectionHeader/SectionHeader.tsx delete mode 100644 src/components/TimelineItem/TimelineItem.module.css delete mode 100644 src/components/TimelineItem/TimelineItem.tsx delete mode 100644 src/data/content.ts delete mode 100644 src/hooks/useAudio.ts delete mode 100644 src/hooks/useLocalStorage.ts delete mode 100644 src/hooks/useReveal.ts delete mode 100644 src/sections/Finale/Finale.module.css delete mode 100644 src/sections/Finale/Finale.tsx delete mode 100644 src/sections/Gallery/Gallery.module.css delete mode 100644 src/sections/Gallery/Gallery.tsx delete mode 100644 src/sections/LoveLetter/LoveLetter.module.css delete mode 100644 src/sections/LoveLetter/LoveLetter.tsx delete mode 100644 src/sections/Memories/Memories.module.css delete mode 100644 src/sections/Memories/Memories.tsx delete mode 100644 src/sections/Opening/Opening.module.css delete mode 100644 src/sections/Opening/Opening.tsx delete mode 100644 src/sections/Promises/Promises.module.css delete mode 100644 src/sections/Promises/Promises.tsx delete mode 100644 src/sections/QuizGate/QuizGate.module.css delete mode 100644 src/sections/QuizGate/QuizGate.tsx delete mode 100644 src/sections/Timeline/Timeline.module.css delete mode 100644 src/sections/Timeline/Timeline.tsx delete mode 100644 src/services/audio.ts delete mode 100644 src/services/countdown.ts delete mode 100644 src/services/device.ts delete mode 100644 src/services/storage.ts diff --git a/README.md b/README.md index 17fb400..bcf4540 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,54 @@ -# APP AMOR +# SECCURITY -APP AMOR em stack premium com React, Vite, TypeScript, Framer Motion e Capacitor, mantendo pipeline de APK. +SECCURITY e uma shell desktop para operacoes locais de seguranca em Windows. O app combina uma interface React + Electron com persistencia em SQLite para organizar inventario de ferramentas, workspaces operacionais, sessoes, eventos, alertas e um console PowerShell integrado. + +## Stack + +- Electron + Vite + React + TypeScript +- `better-sqlite3` para persistencia local +- IPC entre renderer e main process para launchers, terminal e leitura do runtime +- `electron-builder` para empacotamento Windows ## Estrutura -- `src/app/`: bootstrap da aplicacao e navegacao por capitulos -- `src/components/`: blocos visuais reutilizaveis -- `src/sections/`: capitulos da experiencia -- `src/data/content.ts`: hero, quiz, galeria, timeline, memorias, promessas e textos finais -- `src/services/`: acesso isolado a storage, audio, countdown e browser APIs -- `src/styles/`: tokens, globals, layout e componentes base -- `public/assets/`: fotos finais tratadas por categoria (`hero`, `highlights`, `timeline`, `gallery`, `memories`) -- `scripts/prepare-photos.mjs`: prepara as fotos do ZIP em WebP -- `android/`: projeto Android do Capacitor -- `ios/`: projeto iOS do Capacitor -- `www/`: build web pronto para sync do Capacitor - -## Comandos - -- `npm run dev`: ambiente local com Vite -- `npm run lint`: verificacao com ESLint -- `npm run typecheck`: verificacao TypeScript strict -- `npm run build`: gera a pasta `www` -- `npm run photos:prepare`: converte e organiza as fotos em WebP -- `npm run cap:sync`: build web + sync do Capacitor -- `npm run android:open`: abre o projeto Android -- `npm run ios:open`: abre o projeto iOS -- `npm run apk:debug`: gera APK debug em `android/app/build/outputs/apk/debug/` -- `npm run apk:release`: gera APK release em `android/app/build/outputs/apk/release/` +- `src/app/`: shell do renderer, navegacao lateral e bootstrap da UI +- `src/features/`: telas de overview, apps, workspaces, sessions, alerts, events, console e logs +- `src/hooks/`: estado do desktop e sincronizacao do renderer com a API local +- `src/services/`: cliente IPC/browser preview usado pelo renderer +- `electron/`: main process, IPC, terminal, scans, launchers e servicos de runtime +- `backend/`: schema SQLite, paths e repositorios locais +- `shared/`: contratos de tipos e catalogo de ferramentas +- `build/`: assets de packaging + +## Scripts + +- `npm run dev`: sobe o renderer Vite, compila o processo Electron e abre o app desktop +- `npm run build`: gera `dist/` e `dist-electron/` +- `npm run dist`: empacota a aplicacao com `electron-builder` +- `npm run dist:win`: gera artefatos Windows +- `npm run lint`: executa ESLint +- `npm run typecheck`: executa o TypeScript no renderer +- `npm run typecheck:electron`: executa o TypeScript do main process +- `npm run rebuild:native`: recompila modulos nativos para a versao local do Electron +- `npm run sign:local`: aplica assinatura local para builds Windows ## Fluxo recomendado 1. `npm install` -2. `npm run photos:prepare` -3. `npm run lint` -4. `npm run typecheck` -5. `npm run build` -6. `npm run cap:sync` -7. `npm run apk:debug` +2. `npm run lint` +3. `npm run typecheck` +4. `npm run build` +5. `npm run dist:win` + +## Estado atual + +- A shell principal do SECCURITY esta em producao no renderer atual. +- O bootstrap oferece modo `browser-preview` quando o preload do Electron nao esta disponivel. +- O backend local persiste logs, eventos, sessoes, workspaces e alertas em SQLite. +- O modulo de updates ainda usa resposta mockada. ## Observacoes -- Execute tudo a partir de `apps/nossa-historia`. -- O countdown atual considera a data alvo em `src/data/content.ts`. -- O app valida memorias, datas e imagens antes de persistir no storage. -- Como o projeto esta no OneDrive, builds Android ainda podem sofrer lock de arquivos. Se isso acontecer, limpe `android/app/build` e `android/build` antes de rodar de novo. +- No PowerShell do Windows, se `npm` estiver bloqueado pela execution policy, use `npm.cmd`. +- O banco local e criado em `app.getPath("userData")/seccurity.db`. +- O repositorio ainda pode conter alguns artefatos historicos fora da shell principal; a aplicacao ativa descrita aqui e a desktop shell do SECCURITY. diff --git a/backend/db/repositories/toolsRepo.ts b/backend/db/repositories/toolsRepo.ts index f305556..6d804aa 100644 --- a/backend/db/repositories/toolsRepo.ts +++ b/backend/db/repositories/toolsRepo.ts @@ -1,5 +1,6 @@ import type { DetectedTool, ToolId, ToolPathSource } from "../../../shared/types"; import { getDatabase } from "../db"; +import { toolCatalog } from "../../../shared/toolCatalog"; export interface ToolRow { tool_id: ToolId; @@ -39,6 +40,7 @@ function mapRow(row: ToolRow): ToolRow { export function listToolRows(): ToolRow[] { const database = getDatabase(); + const activeToolIds = new Set(toolCatalog.map((tool) => tool.id)); const rows = database .prepare( ` @@ -63,7 +65,7 @@ export function listToolRows(): ToolRow[] { ) .all() as ToolRow[]; - return rows.map(mapRow); + return rows.map(mapRow).filter((row) => activeToolIds.has(row.tool_id)); } export function getToolRowMap(): Map { @@ -170,6 +172,14 @@ export function upsertTool(tool: DetectedTool): void { export function persistTools(tools: DetectedTool[]): void { const database = getDatabase(); const transaction = database.transaction((entries: DetectedTool[]) => { + const activeToolIds = entries.map((entry) => entry.id); + if (activeToolIds.length > 0) { + const placeholders = activeToolIds.map(() => "?").join(", "); + database + .prepare(`DELETE FROM tools WHERE tool_id NOT IN (${placeholders})`) + .run(...activeToolIds); + } + entries.forEach(upsertTool); }); diff --git a/backend/db/repositories/workspacesRepo.ts b/backend/db/repositories/workspacesRepo.ts index 153a9f9..e625ee0 100644 --- a/backend/db/repositories/workspacesRepo.ts +++ b/backend/db/repositories/workspacesRepo.ts @@ -30,6 +30,7 @@ interface WorkspaceAssignmentRow { } const defaultWorkspaceId = "primary-workspace"; +const activeToolIds = new Set(toolCatalog.map((tool) => tool.id)); function mapAssignmentRow(row: WorkspaceAssignmentRow): WorkspaceAppAssignment { return { @@ -54,7 +55,7 @@ export function getAssignmentsForWorkspace(workspaceId: string): WorkspaceAppAss ) .all(workspaceId) as WorkspaceAssignmentRow[]; - return rows.map(mapAssignmentRow); + return rows.map(mapAssignmentRow).filter((assignment) => activeToolIds.has(assignment.toolId)); } export function ensureDefaultWorkspace(): void { @@ -98,6 +99,15 @@ export function ensureDefaultWorkspace(): void { `); const transaction = database.transaction(() => { + database + .prepare( + ` + DELETE FROM workspace_apps + WHERE workspace_id = ? AND tool_id NOT IN (${toolCatalog.map(() => "?").join(", ")}) + ` + ) + .run(defaultWorkspaceId, ...toolCatalog.map((tool) => tool.id)); + toolCatalog.forEach((tool, index) => { upsertAssignment.run( defaultWorkspaceId, diff --git a/capacitor.config.ts b/capacitor.config.ts deleted file mode 100644 index 346730f..0000000 --- a/capacitor.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { CapacitorConfig } from "@capacitor/cli"; - -const config: CapacitorConfig = { - appId: "com.nossahistoria.celebracao", - appName: "Carlos & Sandra", - webDir: "dist", - server: { - androidScheme: "https", - }, -}; - -export default config; diff --git a/electron/preload.ts b/electron/preload.ts index 7684873..4185084 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -17,6 +17,7 @@ import { terminalChannels } from "./services/ipcChannels"; const desktopApi: DesktopApi = { bootstrap: () => ipcRenderer.invoke("seccurity:bootstrap"), listTools: () => ipcRenderer.invoke("tools:list"), + getToolIcon: (executablePath: string | null) => ipcRenderer.invoke("tools:get-icon", executablePath), saveTool: (input: ToolSaveInput) => ipcRenderer.invoke("tools:save", input), browseToolExecutablePath: (toolId: ToolId) => ipcRenderer.invoke("tools:browse-executable", toolId), listWorkspaces: () => ipcRenderer.invoke("workspaces:list"), diff --git a/electron/services/ipc.ts b/electron/services/ipc.ts index 51b8cc0..623025f 100644 --- a/electron/services/ipc.ts +++ b/electron/services/ipc.ts @@ -6,6 +6,7 @@ import { listProviders } from "./providerService"; import { listSessions } from "./sessionService"; import { getCachedTools, + getToolIcon, scanInstalledTools, setManualToolExecutablePath, launchTool, @@ -89,6 +90,7 @@ function buildBootstrap(): DesktopBootstrap { export function registerIpcHandlers(): void { ipcMain.handle("tools:list", () => getCachedTools()); + ipcMain.handle("tools:get-icon", (_event, executablePath: string | null) => getToolIcon(executablePath)); ipcMain.handle("tools:save", (_event, input: ToolSaveInput) => setManualToolExecutablePath(input.toolId, input.executablePath) diff --git a/electron/services/toolService.ts b/electron/services/toolService.ts index 198c3b2..4f99331 100644 --- a/electron/services/toolService.ts +++ b/electron/services/toolService.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; import { spawnSync } from "node:child_process"; -import { shell } from "electron"; +import { app, shell } from "electron"; import { clearRegistryCache, findRegistryInstallPaths } from "../../backend/registry"; import { getToolRowMap, @@ -56,6 +56,61 @@ function expandTemplate(template: string): string { return template.replace(/\{([^}]+)\}/g, (_, token: keyof typeof pathTokens) => pathTokens[token] ?? ""); } +function wildcardSegmentToRegex(segment: string): RegExp { + const escaped = segment.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*"); + return new RegExp(`^${escaped}$`, "i"); +} + +function expandWildcardPath(templatePath: string): string[] { + const normalized = path.normalize(templatePath); + if (!normalized.includes("*")) { + return [normalized]; + } + + const parsed = path.parse(normalized); + const root = parsed.root || path.sep; + const remainder = normalized.slice(root.length); + const segments = remainder.split(path.sep).filter(Boolean); + + let currentRoots = [root]; + + for (const segment of segments) { + const hasWildcard = segment.includes("*"); + const nextRoots: string[] = []; + + for (const currentRoot of currentRoots) { + if (!hasWildcard) { + nextRoots.push(path.join(currentRoot, segment)); + continue; + } + + try { + const entries = fs.readdirSync(currentRoot, { withFileTypes: true }); + const matcher = wildcardSegmentToRegex(segment); + for (const entry of entries) { + if (!entry.isDirectory() && segment !== segments.at(-1)) { + continue; + } + + if (matcher.test(entry.name)) { + nextRoots.push(path.join(currentRoot, entry.name)); + } + } + } catch { + continue; + } + } + + currentRoots = unique(nextRoots); + + if (currentRoots.length === 0) { + break; + } + } + + return currentRoots; +} + function findOnPath(executableNames: string[]): string[] { const matches: string[] = []; @@ -191,7 +246,9 @@ function resolveAutomaticPath(definition: ToolDefinition): AutomaticDetectionRes }; } - const commonPath = definition.commonPathTemplates.map(expandTemplate).find(fileExists); + const commonPath = definition.commonPathTemplates + .flatMap((template) => expandWildcardPath(expandTemplate(template))) + .find(fileExists); if (commonPath) { return { source: "common", @@ -305,6 +362,19 @@ export function setManualToolExecutablePath( }; } +export async function getToolIcon(executablePath: string | null): Promise { + if (!executablePath || !fileExists(executablePath)) { + return null; + } + + try { + const icon = await app.getFileIcon(executablePath, { size: "small" }); + return icon.isEmpty() ? null : icon.toDataURL(); + } catch { + return null; + } +} + export async function launchTool( toolId: ToolId, launchSource = "launcher", diff --git a/package-lock.json b/package-lock.json index e1b1a65..6907b0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,10 +15,6 @@ "react-dom": "^19.2.4" }, "devDependencies": { - "@capacitor/android": "^8.2.0", - "@capacitor/cli": "^8.2.0", - "@capacitor/core": "^8.2.0", - "@capacitor/ios": "^8.2.0", "@electron/rebuild": "^4.0.3", "@eslint/js": "^9.39.4", "@types/better-sqlite3": "^7.6.13", @@ -39,9 +35,6 @@ "typescript-eslint": "^8.58.0", "vite": "^8.0.3", "wait-on": "^9.0.4" - }, - "optionalDependencies": { - "sharp": "^0.34.5" } }, "node_modules/@babel/code-frame": { @@ -321,69 +314,6 @@ "node": ">=6.9.0" } }, - "node_modules/@capacitor/android": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.3.0.tgz", - "integrity": "sha512-EQy6ByUuKayQBJmMm/e0byJiHavqsQHrvW23BuT2GNVQvenAvipqwaePiJHzrv2PZr7A0T0+se4kgDCeROj0mQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@capacitor/core": "^8.3.0" - } - }, - "node_modules/@capacitor/cli": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.3.0.tgz", - "integrity": "sha512-n3QDUimtFNbagoo8kLdjvTz3i3Y4jX1fOjvo6ptUKLzErmuqeamL8kECASoyQvg/OzJisZToGZrgLphBsptJcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ionic/cli-framework-output": "^2.2.8", - "@ionic/utils-subprocess": "^3.0.1", - "@ionic/utils-terminal": "^2.3.5", - "commander": "^12.1.0", - "debug": "^4.4.0", - "env-paths": "^2.2.0", - "fs-extra": "^11.2.0", - "kleur": "^4.1.5", - "native-run": "^2.0.3", - "open": "^8.4.0", - "plist": "^3.1.0", - "prompts": "^2.4.2", - "rimraf": "^6.0.1", - "semver": "^7.6.3", - "tar": "^7.5.3", - "tslib": "^2.8.1", - "xml2js": "^0.6.2" - }, - "bin": { - "cap": "bin/capacitor", - "capacitor": "bin/capacitor" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@capacitor/core": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.3.0.tgz", - "integrity": "sha512-S4ajn4G/fS3VJj8salxqH/3LO5PPWv1VxGKQ27OCajnDcLJjEg9VXwgMPnlypgkIOqCJ2fmQLtk8GT+BlI9/rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@capacitor/ios": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-8.3.0.tgz", - "integrity": "sha512-5Rtwv8SITKlYTt8lAZG+khnVIdzPtqbocH3eP+JkEmX1vpSMwx4TOKtT8OBz8gpQ+pUJDRp7DBYOv3U6l/obCw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@capacitor/core": "^8.3.0" - } - }, "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -741,8 +671,10 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1057,652 +989,38 @@ "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@ionic/cli-framework-output": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", - "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ionic/utils-terminal": "2.3.5", - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-array": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz", - "integrity": "sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-fs": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", - "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/fs-extra": "^8.0.0", - "debug": "^4.0.0", - "fs-extra": "^9.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-fs/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@ionic/utils-object": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", - "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-process": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", - "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ionic/utils-object": "2.1.6", - "@ionic/utils-terminal": "2.3.5", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "tree-kill": "^1.2.2", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.7.tgz", - "integrity": "sha512-eSELBE7NWNFIHTbTC2jiMvh1ABKGIpGdUIvARsNPMNQhxJB3wpwdiVnoBoTYp+5a6UUIww4Kpg7v6S7iTctH1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-subprocess": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-3.0.1.tgz", - "integrity": "sha512-cT4te3AQQPeIM9WCwIg8ohroJ8TjsYaMb2G4ZEgv9YzeDqHZ4JpeIKqG2SoaA3GmVQ3sOfhPM6Ox9sxphV/d1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ionic/utils-array": "2.1.6", - "@ionic/utils-fs": "3.1.7", - "@ionic/utils-process": "2.1.12", - "@ionic/utils-stream": "3.1.7", - "@ionic/utils-terminal": "2.3.5", - "cross-spawn": "^7.0.3", - "debug": "^4.0.0", - "tslib": "^2.0.1" + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.18.0" } }, - "node_modules/@ionic/utils-terminal": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", - "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/slice-ansi": "^4.0.0", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "tslib": "^2.0.1", - "untildify": "^4.0.0", - "wrap-ansi": "^7.0.0" + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=16.0.0" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@isaacs/cliui": { @@ -2444,16 +1762,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/fs-extra": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", - "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", @@ -2537,13 +1845,6 @@ "@types/node": "*" } }, - "node_modules/@types/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/verror": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", @@ -3747,6 +3048,7 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -3854,16 +3156,6 @@ "node": "20.x || 22.x || 23.x || 24.x || 25.x" } }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "dev": true, - "license": "Unlicense", - "engines": { - "node": ">=0.6" - } - }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -3910,19 +3202,6 @@ "license": "MIT", "optional": true }, - "node_modules/bplist-parser": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", - "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "big-integer": "1.6.x" - }, - "engines": { - "node": ">= 5.10.0" - } - }, "node_modules/brace-expansion": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", @@ -4463,16 +3742,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/compare-version": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", @@ -4826,16 +4095,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -5213,19 +4472,6 @@ "dev": true, "license": "MIT" }, - "node_modules/elementtree": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", - "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "sax": "1.1.4" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -6038,24 +5284,6 @@ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "license": "MIT" }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -6478,16 +5706,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", @@ -6511,22 +5729,6 @@ "is-ci": "bin.js" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6590,19 +5792,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -6782,16 +5971,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", @@ -7221,16 +6400,6 @@ "node": ">=8" } }, - "node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/make-fetch-happen": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", @@ -7580,32 +6749,6 @@ "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "license": "MIT" }, - "node_modules/native-run": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.3.tgz", - "integrity": "sha512-U1PllBuzW5d1gfan+88L+Hky2eZx+9gv3Pf6rNBxKbORxi7boHzqiA6QFGSnqMem4j0A9tZ08NMIs5+0m/VS1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ionic/utils-fs": "^3.1.7", - "@ionic/utils-terminal": "^2.3.4", - "bplist-parser": "^0.3.2", - "debug": "^4.3.4", - "elementtree": "^0.1.7", - "ini": "^4.1.1", - "plist": "^3.1.0", - "split2": "^4.2.0", - "through2": "^4.0.2", - "tslib": "^2.6.2", - "yauzl": "^2.10.0" - }, - "bin": { - "native-run": "bin/native-run" - }, - "engines": { - "node": ">=16.0.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7796,24 +6939,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -7961,23 +7086,6 @@ "node": ">=8" } }, - "node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/pe-library": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", @@ -8166,30 +7274,6 @@ "node": ">=10" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prompts/node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", @@ -8437,26 +7521,6 @@ "node": ">= 4" } }, - "node_modules/rimraf": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", - "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "glob": "^13.0.3", - "package-json-from-dist": "^1.0.1" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -8564,13 +7628,6 @@ "truncate-utf8-bytes": "^1.0.0" } }, - "node_modules/sax": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", - "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", - "dev": true, - "license": "ISC" - }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -8621,51 +7678,6 @@ "dev": true, "license": "ISC" }, - "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/colour": "^1.0.0", - "detect-libc": "^2.1.2", - "semver": "^7.7.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8767,31 +7779,6 @@ "node": ">=10" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -8864,16 +7851,6 @@ "source-map": "^0.6.0" } }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -9088,16 +8065,6 @@ "node": ">=12" } }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "3" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -9294,16 +8261,6 @@ "node": ">= 10.0.0" } }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -9561,30 +8518,6 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, - "node_modules/xml2js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", - "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", - "dev": true, - "license": "MIT", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", diff --git a/package.json b/package.json index a2af531..9701733 100644 --- a/package.json +++ b/package.json @@ -27,21 +27,9 @@ "typecheck": "tsc --noEmit", "typecheck:electron": "tsc -p tsconfig.electron.json --noEmit", "rebuild:native": "electron-rebuild -f -w better-sqlite3", - "photos:prepare": "node scripts/prepare-photos.mjs", - "cap:sync": "npm run build:web && npx cap sync", - "cap:add:android": "npm run build:web && npx cap add android", - "cap:add:ios": "npm run build:web && npx cap add ios", - "android:open": "npm run cap:sync && npx cap open android", - "ios:open": "npm run cap:sync && npx cap open ios", - "apk:debug": "npm run cap:sync && powershell -ExecutionPolicy Bypass -File scripts/build-apk.ps1 Debug", - "apk:release": "npm run cap:sync && powershell -ExecutionPolicy Bypass -File scripts/build-apk.ps1 Release", "postinstall": "npm run rebuild:native" }, "devDependencies": { - "@capacitor/android": "^8.2.0", - "@capacitor/cli": "^8.2.0", - "@capacitor/core": "^8.2.0", - "@capacitor/ios": "^8.2.0", "@electron/rebuild": "^4.0.3", "@eslint/js": "^9.39.4", "@types/better-sqlite3": "^7.6.13", @@ -69,9 +57,6 @@ "react": "^19.2.4", "react-dom": "^19.2.4" }, - "optionalDependencies": { - "sharp": "^0.34.5" - }, "build": { "appId": "com.seccurity.desktop", "productName": "SECCURITY", diff --git a/scripts/build-apk.ps1 b/scripts/build-apk.ps1 deleted file mode 100644 index 238d2b5..0000000 --- a/scripts/build-apk.ps1 +++ /dev/null @@ -1,38 +0,0 @@ -param( - [ValidateSet("Debug", "Release")] - [string]$BuildType = "Debug" -) - -$ErrorActionPreference = "Stop" - -$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -$appDir = Split-Path -Parent $scriptDir -$androidDir = Join-Path $appDir "android" - -if (-not $env:JAVA_HOME) { - $androidStudioJbr = "C:\Program Files\Android\Android Studio\jbr" - if (Test-Path $androidStudioJbr) { - $env:JAVA_HOME = $androidStudioJbr - } -} - -if (-not $env:JAVA_HOME) { - throw "JAVA_HOME nao esta configurado e nenhum JDK do Android Studio foi encontrado." -} - -$javaBin = Join-Path $env:JAVA_HOME "bin" -if (-not (Test-Path (Join-Path $javaBin "java.exe"))) { - throw "JAVA_HOME aponta para '$env:JAVA_HOME', mas java.exe nao foi encontrado em '$javaBin'." -} - -$env:Path = "$javaBin;$env:Path" - -Push-Location $androidDir -try { - & .\gradlew.bat "assemble$BuildType" - if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE - } -} finally { - Pop-Location -} diff --git a/scripts/prepare-photos.mjs b/scripts/prepare-photos.mjs deleted file mode 100644 index 1bec5fe..0000000 --- a/scripts/prepare-photos.mjs +++ /dev/null @@ -1,68 +0,0 @@ -import { mkdirSync, rmSync } from "node:fs"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import sharp from "sharp"; - -const appDir = path.resolve(fileURLToPath(new URL("..", import.meta.url))); -const sourceDir = path.join(appDir, ".photo-import", "casamento-carlos-3-001", "Casamento Carlos"); -const outputRoot = path.join(appDir, "public", "assets"); - -const collections = { - hero: [ - { source: "IMG_7997.jpg", output: "main.webp", width: 1920 }, - { source: "IMG_8076.jpg", output: "portrait.webp", width: 1600 }, - ], - highlights: [ - { source: "IMG_7914.jpg", output: "hands.webp", width: 1440 }, - { source: "IMG_7921.jpg", output: "embrace.webp", width: 1440 }, - { source: "IMG_7997.jpg", output: "kiss.webp", width: 1440 }, - { source: "IMG_8019.jpg", output: "gesture.webp", width: 1440 }, - ], - timeline: [ - { source: "IMG_7917.jpg", output: "chapter-01.webp", width: 1440 }, - { source: "IMG_7943.jpg", output: "chapter-02.webp", width: 1440 }, - { source: "IMG_8062.jpg", output: "chapter-03.webp", width: 1440 }, - { source: "IMG_8076.jpg", output: "chapter-04.webp", width: 1440 }, - ], - gallery: [ - { source: "IMG_7917.jpg", output: "frame-01.webp", width: 1280 }, - { source: "IMG_7921.jpg", output: "frame-02.webp", width: 1280 }, - { source: "IMG_7997.jpg", output: "frame-03.webp", width: 1280 }, - { source: "IMG_8019.jpg", output: "frame-04.webp", width: 1280 }, - { source: "IMG_8076.jpg", output: "frame-05.webp", width: 1280 }, - { source: "IMG_8087.jpg", output: "frame-06.webp", width: 1280 }, - ], - memories: [ - { source: "IMG_7914.jpg", output: "memory-01.webp", width: 1280 }, - { source: "IMG_8019.jpg", output: "memory-02.webp", width: 1280 }, - { source: "IMG_8076.jpg", output: "memory-03.webp", width: 1280 }, - ], -}; - -mkdirSync(outputRoot, { recursive: true }); - -for (const collectionName of Object.keys(collections)) { - const collectionDir = path.join(outputRoot, collectionName); - rmSync(collectionDir, { recursive: true, force: true }); - mkdirSync(collectionDir, { recursive: true }); - - for (const entry of collections[collectionName]) { - const input = path.join(sourceDir, entry.source); - const output = path.join(collectionDir, entry.output); - - await sharp(input) - .rotate() - .resize({ - width: entry.width, - withoutEnlargement: true, - }) - .webp({ - quality: 82, - effort: 5, - }) - .toFile(output); - } -} - -rmSync(path.join(outputRoot, "photos"), { recursive: true, force: true }); -rmSync(path.join(outputRoot, "assets"), { recursive: true, force: true }); diff --git a/shared/toolCatalog.ts b/shared/toolCatalog.ts index 2b7c53e..d944a78 100644 --- a/shared/toolCatalog.ts +++ b/shared/toolCatalog.ts @@ -56,19 +56,6 @@ export const toolCatalog: ToolDefinition[] = [ "{programFilesX86}\\Process Hacker\\ProcessHacker.exe", ], }, - { - id: "forensix-studio", - name: "ForensiX Studio", - description: "Coleta e triagem local para fluxos de forense digital.", - category: "forensics", - executableNames: ["ForensiX Studio.exe", "ForensiXStudio.exe"], - registryDisplayNames: ["forensix"], - commonPathTemplates: [ - "{programFiles}\\ForensiX Studio\\ForensiX Studio.exe", - "{programFiles}\\ForensiX Studio\\ForensiXStudio.exe", - "{programFilesX86}\\ForensiX Studio\\ForensiX Studio.exe", - ], - }, { id: "hashcat", name: "Hashcat", @@ -80,6 +67,8 @@ export const toolCatalog: ToolDefinition[] = [ "{tools}\\hashcat\\hashcat.exe", "{userProfile}\\tools\\hashcat\\hashcat.exe", "{downloads}\\hashcat\\hashcat.exe", + "{downloads}\\hashcat-*\\hashcat.exe", + "{downloads}\\hashcat-*\\hashcat-*\\hashcat.exe", ], versionCommand: ["--version"], }, @@ -95,6 +84,8 @@ export const toolCatalog: ToolDefinition[] = [ "{userProfile}\\tools\\john\\run\\john.exe", "{downloads}\\john\\run\\john.exe", "{downloads}\\john-the-ripper\\run\\john.exe", + "{downloads}\\john-*\\run\\john.exe", + "{downloads}\\john-*\\john-*\\run\\john.exe", ], versionCommand: ["--version"], }, diff --git a/shared/types.ts b/shared/types.ts index 6134c96..21b6393 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -13,7 +13,6 @@ export type ToolId = | "wireshark" | "owasp-zap" | "process-hacker" - | "forensix-studio" | "hashcat" | "john-the-ripper"; @@ -288,6 +287,7 @@ export interface TerminalExitEvent { export interface DesktopApi { bootstrap: () => Promise; listTools: () => Promise; + getToolIcon: (executablePath: string | null) => Promise; saveTool: (input: ToolSaveInput) => Promise; browseToolExecutablePath: (toolId: ToolId) => Promise; listWorkspaces: () => Promise; diff --git a/src/app/App.module.css b/src/app/App.module.css index c4b7593..72418a6 100644 --- a/src/app/App.module.css +++ b/src/app/App.module.css @@ -1,7 +1,7 @@ .shell { position: relative; min-height: 100vh; - overflow: hidden; + overflow-x: clip; } .chrome { @@ -28,6 +28,7 @@ display: grid; align-content: start; gap: 20px; + min-width: 0; padding: 30px 28px 28px; } diff --git a/src/app/legacy/AppAmorLegacy.module.css b/src/app/legacy/AppAmorLegacy.module.css deleted file mode 100644 index dfe351a..0000000 --- a/src/app/legacy/AppAmorLegacy.module.css +++ /dev/null @@ -1,123 +0,0 @@ -.appShell { - position: relative; - overflow-x: clip; - min-height: 100vh; -} - -.ambient { - position: fixed; - inset: 0; - pointer-events: none; - z-index: 0; -} - -.ambient::before, -.ambient::after { - content: ""; - position: absolute; - border-radius: 999px; - filter: blur(80px); - opacity: 0.4; -} - -.ambient::before { - top: 4%; - left: -8%; - width: min(40vw, 520px); - height: min(40vw, 520px); - background: rgba(140, 39, 79, 0.34); -} - -.ambient::after { - right: -6%; - bottom: 12%; - width: min(38vw, 480px); - height: min(38vw, 480px); - background: rgba(216, 178, 125, 0.18); -} - -.contentLayer { - position: relative; - z-index: 1; - width: min(calc(100% - 28px), var(--max-width)); - margin: 0 auto; - padding: 20px 0 88px; - transition: filter 280ms ease, transform 280ms ease; -} - -.isLocked .contentLayer { - filter: blur(18px); - transform: scale(0.992); - pointer-events: none; - user-select: none; -} - -.chapterRail { - position: sticky; - top: 18px; - z-index: 5; - display: flex; - justify-content: center; - margin-bottom: 28px; -} - -.chapterRailInner { - display: flex; - gap: 8px; - padding: 8px; - border: 1px solid var(--color-line); - border-radius: var(--radius-pill); - background: rgba(15, 10, 15, 0.6); - backdrop-filter: blur(18px); - box-shadow: var(--color-shadow); - overflow-x: auto; -} - -.chapterButton { - padding: 11px 16px; - border: 1px solid transparent; - border-radius: var(--radius-pill); - background: transparent; - color: var(--color-text-soft); - cursor: pointer; - white-space: nowrap; - transition: background 180ms ease, color 180ms ease, border-color 180ms ease; -} - -.chapterButton:hover { - color: var(--color-text); -} - -.chapterButtonActive { - color: var(--color-ivory); - background: rgba(248, 239, 232, 0.08); - border-color: var(--color-line-strong); -} - -.sectionStack { - display: grid; - gap: 22px; -} - -.footerNote { - margin-top: 28px; - text-align: center; - color: var(--color-text-soft); - font-size: 0.92rem; -} - -@media (max-width: 720px) { - .contentLayer { - width: min(calc(100% - 18px), var(--max-width)); - padding-top: 14px; - } - - .chapterRail { - margin-bottom: 18px; - } - - .chapterRailInner { - width: 100%; - justify-content: flex-start; - } -} diff --git a/src/app/legacy/AppAmorLegacy.tsx b/src/app/legacy/AppAmorLegacy.tsx deleted file mode 100644 index 65c9148..0000000 --- a/src/app/legacy/AppAmorLegacy.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { useEffect, useState } from "react"; -import { appContent, sanitizeMemoryEntries, type MemoryEntry } from "../../data/content"; -import { useAudio } from "../../hooks/useAudio"; -import { useLocalStorage } from "../../hooks/useLocalStorage"; -import { AudioPlayer } from "../../components/AudioPlayer/AudioPlayer"; -import { Modal } from "../../components/Modal/Modal"; -import { Opening } from "../../sections/Opening/Opening"; -import { QuizGate } from "../../sections/QuizGate/QuizGate"; -import { LoveLetter } from "../../sections/LoveLetter/LoveLetter"; -import { Gallery } from "../../sections/Gallery/Gallery"; -import { Timeline } from "../../sections/Timeline/Timeline"; -import { Memories } from "../../sections/Memories/Memories"; -import { Promises } from "../../sections/Promises/Promises"; -import { Finale } from "../../sections/Finale/Finale"; -import { appChapters, type ChapterId } from "../routes"; -import { storageKeys } from "../../services/storage"; -import { - observeElements, - registerServiceWorker, - scrollToElement, -} from "../../services/device"; -import styles from "./AppAmorLegacy.module.css"; - -export default function AppAmorLegacy() { - const audio = useAudio(); - const [quizUnlocked, setQuizUnlocked] = useLocalStorage(storageKeys.quizUnlocked, false); - const [memories, setMemories] = useLocalStorage( - storageKeys.memories, - appContent.fallbackMemories, - (value) => sanitizeMemoryEntries(value, appContent.fallbackMemories) - ); - const [surpriseOpen, setSurpriseOpen] = useState(false); - const [activeChapter, setActiveChapter] = useState("opening"); - - useEffect(() => { - void registerServiceWorker(); - }, []); - - useEffect(() => { - return observeElements( - "[data-chapter]", - (element) => { - const chapterId = element.getAttribute("data-chapter") as ChapterId | null; - if (chapterId) { - setActiveChapter(chapterId); - } - }, - { - threshold: 0.45, - rootMargin: "-10% 0px -20% 0px", - } - ); - }, []); - - function scrollToChapter(id: ChapterId) { - scrollToElement(id); - } - - function handleUnlock() { - setQuizUnlocked(true); - setSurpriseOpen(true); - window.setTimeout(() => scrollToChapter("opening"), 180); - } - - return ( -
- - ); -} diff --git a/src/app/routes.tsx b/src/app/routes.tsx deleted file mode 100644 index 17fa1dc..0000000 --- a/src/app/routes.tsx +++ /dev/null @@ -1,11 +0,0 @@ -export const appChapters = [ - { id: "opening", label: "Abertura" }, - { id: "love-letter", label: "Carta" }, - { id: "gallery", label: "Galeria" }, - { id: "timeline", label: "Linha do tempo" }, - { id: "memories", label: "Memorias" }, - { id: "promises", label: "Promessas" }, - { id: "finale", label: "Finale" }, -] as const; - -export type ChapterId = (typeof appChapters)[number]["id"]; diff --git a/src/components/AudioPlayer/AudioPlayer.module.css b/src/components/AudioPlayer/AudioPlayer.module.css deleted file mode 100644 index 8d0391e..0000000 --- a/src/components/AudioPlayer/AudioPlayer.module.css +++ /dev/null @@ -1,44 +0,0 @@ -.player { - position: fixed; - right: 18px; - bottom: 18px; - z-index: 16; - display: grid; - gap: 12px; - width: min(100% - 36px, 360px); - padding: 16px; - border: 1px solid var(--color-line-strong); - border-radius: 26px; - background: rgba(13, 9, 13, 0.82); - box-shadow: var(--color-shadow); - backdrop-filter: blur(24px); -} - -.labelBlock { - display: grid; - gap: 6px; -} - -.kicker { - margin: 0; - color: var(--color-gold); - font-size: 0.76rem; - letter-spacing: 0.18em; - text-transform: uppercase; -} - -.status { - margin: 0; - color: var(--color-text-muted); - font-size: 0.92rem; - line-height: 1.5; -} - -@media (max-width: 720px) { - .player { - left: 12px; - right: 12px; - bottom: 12px; - width: auto; - } -} diff --git a/src/components/AudioPlayer/AudioPlayer.tsx b/src/components/AudioPlayer/AudioPlayer.tsx deleted file mode 100644 index c7cc068..0000000 --- a/src/components/AudioPlayer/AudioPlayer.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { motion } from "framer-motion"; -import { PremiumButton } from "../PremiumButton/PremiumButton"; -import styles from "./AudioPlayer.module.css"; - -type AudioPlayerProps = { - isPlaying: boolean; - status: string; - onToggle: () => void | Promise; -}; - -export function AudioPlayer({ isPlaying, status, onToggle }: AudioPlayerProps) { - return ( - -
-

Trilha do momento

-

{status}

-
- - {isPlaying ? "Pausar trilha" : "Tocar trilha"} - -
- ); -} diff --git a/src/components/GalleryHighlight/GalleryHighlight.module.css b/src/components/GalleryHighlight/GalleryHighlight.module.css deleted file mode 100644 index a5b7496..0000000 --- a/src/components/GalleryHighlight/GalleryHighlight.module.css +++ /dev/null @@ -1,50 +0,0 @@ -.card { - display: grid; - gap: 14px; -} - -.mediaWrap { - overflow: hidden; - border-radius: 30px; - background: rgba(255, 248, 244, 0.04); -} - -.media { - width: 100%; - height: min(52vw, 420px); - object-fit: cover; - transition: transform 520ms ease; -} - -.card:hover .media { - transform: scale(1.03); -} - -.large .media { - height: min(62vw, 560px); -} - -.copy { - display: grid; - gap: 8px; -} - -.badge { - color: var(--color-gold); - font-size: 0.78rem; - letter-spacing: 0.18em; - text-transform: uppercase; -} - -.title { - margin: 0; - font-family: var(--font-display); - font-size: clamp(1.9rem, 3vw, 2.8rem); - color: var(--color-ivory); -} - -.text { - margin: 0; - color: var(--color-text-muted); - line-height: 1.65; -} diff --git a/src/components/GalleryHighlight/GalleryHighlight.tsx b/src/components/GalleryHighlight/GalleryHighlight.tsx deleted file mode 100644 index 75c3bf8..0000000 --- a/src/components/GalleryHighlight/GalleryHighlight.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { motion } from "framer-motion"; -import type { GalleryEntry } from "../../data/content"; -import styles from "./GalleryHighlight.module.css"; - -type GalleryHighlightProps = { - item: GalleryEntry; - large?: boolean; - eager?: boolean; -}; - -export function GalleryHighlight({ item, large = false, eager = false }: GalleryHighlightProps) { - return ( - -
- {item.alt} -
-
- {item.badge} -

{item.title}

-

{item.copy}

-
-
- ); -} diff --git a/src/components/Hero/Hero.module.css b/src/components/Hero/Hero.module.css deleted file mode 100644 index 0e56411..0000000 --- a/src/components/Hero/Hero.module.css +++ /dev/null @@ -1,135 +0,0 @@ -.hero { - position: relative; - overflow: hidden; - min-height: min(100svh, 920px); - padding: clamp(28px, 5vw, 56px); - border: 1px solid rgba(255, 240, 228, 0.12); - border-radius: 42px; - background: #120d12; - box-shadow: var(--color-shadow-strong); -} - -.backdrop { - position: absolute; - inset: 0; -} - -.backdropImage { - width: 100%; - height: 100%; - object-fit: cover; - object-position: center 30%; - transform: scale(1.03); - filter: saturate(0.95); -} - -.overlay { - position: absolute; - inset: 0; - background: - linear-gradient(90deg, rgba(9, 6, 9, 0.78) 0%, rgba(9, 6, 9, 0.52) 40%, rgba(9, 6, 9, 0.18) 100%), - linear-gradient(180deg, rgba(14, 10, 14, 0.12) 0%, rgba(10, 8, 10, 0.82) 100%); -} - -.grid { - position: relative; - z-index: 1; - display: grid; - grid-template-columns: minmax(0, 1.1fr) minmax(280px, 0.74fr); - align-items: end; - gap: 28px; - min-height: calc(min(100svh, 920px) - clamp(56px, 10vw, 112px)); -} - -.copyBlock { - max-width: 620px; -} - -.eyebrow { - margin: 0 0 12px; - color: var(--color-gold); - font-size: 0.84rem; - letter-spacing: 0.22em; - text-transform: uppercase; -} - -.title { - margin: 0; - font-family: var(--font-display); - font-size: clamp(3.2rem, 10vw, 7rem); - line-height: 0.88; - color: var(--color-ivory); -} - -.headline { - margin: 20px 0 12px; - max-width: 14ch; - font-family: var(--font-display); - font-size: clamp(2rem, 5vw, 3.6rem); - line-height: 0.98; -} - -.description { - margin: 0; - max-width: 58ch; - color: var(--color-text-muted); - line-height: 1.75; -} - -.actions { - display: flex; - flex-wrap: wrap; - gap: 12px; - margin-top: 24px; -} - -.detail { - margin: 18px 0 0; - color: var(--color-text-soft); - max-width: 42ch; -} - -.portraitWrap { - justify-self: end; - width: min(100%, 360px); - padding: 16px; - border-radius: 32px; - background: rgba(255, 247, 240, 0.06); - border: 1px solid rgba(255, 235, 214, 0.14); - backdrop-filter: blur(14px); -} - -.portrait { - width: 100%; - aspect-ratio: 0.82; - object-fit: cover; - border-radius: 24px; -} - -@media (max-width: 960px) { - .grid { - grid-template-columns: 1fr; - align-items: end; - } - - .portraitWrap { - justify-self: stretch; - width: min(100%, 420px); - } -} - -@media (max-width: 640px) { - .hero { - min-height: auto; - padding: 24px 18px; - border-radius: 28px; - } - - .title { - font-size: clamp(2.8rem, 16vw, 4.2rem); - } - - .headline { - max-width: none; - } -} diff --git a/src/components/Hero/Hero.tsx b/src/components/Hero/Hero.tsx deleted file mode 100644 index d55c68a..0000000 --- a/src/components/Hero/Hero.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { motion } from "framer-motion"; -import { PremiumButton } from "../PremiumButton/PremiumButton"; -import styles from "./Hero.module.css"; - -type HeroProps = { - eyebrow: string; - title: string; - headline: string; - description: string; - image: string; - portrait: string; - primaryCta: string; - secondaryCta: string; - detail: string; - onPrimaryClick: () => void; - onSecondaryClick: () => void; -}; - -export function Hero({ - eyebrow, - title, - headline, - description, - image, - portrait, - primaryCta, - secondaryCta, - detail, - onPrimaryClick, - onSecondaryClick, -}: HeroProps) { - return ( -
-
- Carlos e Sandra em um retrato de abertura - - -
- -

{eyebrow}

-

{title}

-

{headline}

-

{description}

-
- {primaryCta} - - {secondaryCta} - -
-

{detail}

-
- - - Retrato vertical de Carlos e Sandra - -
-
- ); -} diff --git a/src/components/MemoryCard/MemoryCard.module.css b/src/components/MemoryCard/MemoryCard.module.css deleted file mode 100644 index 6c09a6d..0000000 --- a/src/components/MemoryCard/MemoryCard.module.css +++ /dev/null @@ -1,72 +0,0 @@ -.card { - overflow: hidden; - border: 1px solid var(--color-line); - border-radius: 28px; - background: rgba(248, 239, 232, 0.04); - box-shadow: var(--color-shadow); -} - -.image { - width: 100%; - height: 240px; - object-fit: cover; -} - -.body { - display: grid; - gap: 10px; - padding: 18px 18px 14px; -} - -.meta { - display: flex; - justify-content: space-between; - gap: 12px; - color: var(--color-text-soft); - font-size: 0.84rem; -} - -.mood { - color: var(--color-gold); - letter-spacing: 0.1em; - text-transform: uppercase; -} - -.title { - margin: 0; - font-family: var(--font-display); - font-size: 2rem; - color: var(--color-ivory); -} - -.headline { - margin: 0; - color: var(--color-text); - font-weight: 700; -} - -.description { - margin: 0; - color: var(--color-text-muted); - line-height: 1.7; -} - -.actions { - display: flex; - gap: 10px; - padding: 0 18px 18px; -} - -.actionButton { - flex: 1; - min-height: 42px; - border: 1px solid var(--color-line-strong); - border-radius: var(--radius-pill); - background: transparent; - color: var(--color-text); - cursor: pointer; -} - -.deleteButton { - color: #f6b2b2; -} diff --git a/src/components/MemoryCard/MemoryCard.tsx b/src/components/MemoryCard/MemoryCard.tsx deleted file mode 100644 index 548b3ee..0000000 --- a/src/components/MemoryCard/MemoryCard.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { motion } from "framer-motion"; -import type { MemoryEntry } from "../../data/content"; -import styles from "./MemoryCard.module.css"; - -type MemoryCardProps = { - memory: MemoryEntry; - onEdit: (memory: MemoryEntry) => void; - onDelete: (id: string) => void; -}; - -export function MemoryCard({ memory, onEdit, onDelete }: MemoryCardProps) { - return ( - - {memory.title} -
-
- {memory.mood} - {memory.date} -
-

{memory.title}

-

{memory.headline}

-

{memory.description}

-
-
- - -
-
- ); -} diff --git a/src/components/Modal/Modal.module.css b/src/components/Modal/Modal.module.css deleted file mode 100644 index 84e21ae..0000000 --- a/src/components/Modal/Modal.module.css +++ /dev/null @@ -1,47 +0,0 @@ -.overlay { - position: fixed; - inset: 0; - z-index: 40; - display: grid; - place-items: center; - padding: 20px; - background: rgba(6, 4, 6, 0.7); - backdrop-filter: blur(14px); -} - -.dialog { - position: relative; - overflow: hidden; - width: min(100%, 560px); - padding: 28px; - border: 1px solid var(--color-line-strong); - border-radius: var(--radius-md); - background: linear-gradient(180deg, rgba(25, 17, 24, 0.96), rgba(16, 11, 16, 0.96)); - box-shadow: var(--color-shadow-strong); -} - -.glow { - position: absolute; - inset: auto -10% -18% auto; - width: 220px; - height: 220px; - border-radius: 50%; - background: radial-gradient(circle, rgba(216, 178, 125, 0.22), transparent 66%); -} - -.title { - position: relative; - margin: 0 0 16px; - font-family: var(--font-display); - font-size: clamp(2rem, 4vw, 2.8rem); - color: var(--color-ivory); -} - -.body { - position: relative; - display: grid; - gap: 12px; - margin-bottom: 22px; - color: var(--color-text-muted); - line-height: 1.75; -} diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx deleted file mode 100644 index 1543d4c..0000000 --- a/src/components/Modal/Modal.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { AnimatePresence, motion } from "framer-motion"; -import type { PropsWithChildren } from "react"; -import { PremiumButton } from "../PremiumButton/PremiumButton"; -import styles from "./Modal.module.css"; - -type ModalProps = PropsWithChildren<{ - open: boolean; - title: string; - onClose: () => void; -}>; - -export function Modal({ open, title, children, onClose }: ModalProps) { - return ( - - {open ? ( - - event.stopPropagation()} - role="dialog" - aria-modal="true" - aria-labelledby="modal-title" - > -