diff --git a/admin-server1/logs/admin.log b/admin-server1/logs/admin.log index d3bfb44..9af4dff 100644 --- a/admin-server1/logs/admin.log +++ b/admin-server1/logs/admin.log @@ -1638,3 +1638,23 @@ [2026-08-09T19:34:39.791Z] [INFO] Card logs initialized successfully [2026-08-09T19:36:51.312Z] [INFO] Server running on http://localhost:3005 [2026-08-09T19:36:51.318Z] [INFO] Card logs initialized successfully +[2026-08-10T07:16:29.299Z] [INFO] Server running on http://localhost:3005 +[2026-08-10T07:16:29.302Z] [INFO] Card log file created at: D:\rasch_git\electron\backend\logs\cards.log +[2026-08-10T07:16:29.303Z] [INFO] Card log file created at: D:\rasch_git\electron\backend\logs\cards.log +[2026-08-10T07:16:29.303Z] [INFO] Card logs initialized successfully +[2026-08-10T07:16:37.113Z] [ERROR] Error: ENOENT: no such file or directory, stat 'D:\rasch_git\electron\admin-frontend\build\index.html' +[2026-08-10T07:17:35.578Z] [INFO] Server running on http://localhost:3005 +[2026-08-10T07:17:35.581Z] [INFO] Card logs initialized successfully +[2026-08-10T07:17:43.099Z] [INFO] Login successful +[2026-08-10T07:17:43.218Z] [INFO] [DB CHECK] Проверка подключения к MySQL: localhost:3306/rasch_content +[2026-08-10T07:17:43.250Z] [INFO] [DB CHECK] ✅ Успешное подключение к MySQL +[2026-08-10T07:17:44.412Z] [WARN] Log file not found: D:\rasch_git\electron\backend\logs\app.log +[2026-08-10T07:18:02.846Z] [INFO] [LOGIN] Попытка входа: grivova +[2026-08-10T07:18:02.846Z] [INFO] [LOGIN] Проверка подключения к базе... +[2026-08-10T07:18:02.852Z] [INFO] [LOGIN] Результат поиска пользователя: найден +[2026-08-10T07:18:02.853Z] [INFO] [LOGIN] Сравнение пароля через bcrypt... +[2026-08-10T07:18:02.943Z] [INFO] [LOGIN] Результат сравнения пароля: true +[2026-08-10T07:18:02.944Z] [INFO] [LOGIN] Сессия установлена: {"isModerator":true,"userId":3,"username":"grivova"} +[2026-08-10T07:18:02.945Z] [INFO] [LOGIN] Ответ отправлен +[2026-08-10T07:22:25.057Z] [INFO] Server running on http://localhost:3005 +[2026-08-10T07:22:25.060Z] [INFO] Card logs initialized successfully diff --git a/admin-server1/package-lock.json b/admin-server1/package-lock.json index 93bdda8..f9c6c04 100644 --- a/admin-server1/package-lock.json +++ b/admin-server1/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "admin-server", "version": "1.0.0", - "hasInstallScript": true, "license": "ISC", "dependencies": { "axios": "^1.10.0", diff --git a/admin-server1/package.json b/admin-server1/package.json index 62d2aef..d8e06b1 100644 --- a/admin-server1/package.json +++ b/admin-server1/package.json @@ -6,7 +6,6 @@ "start": "node server.js", "electron": "electron .", "electron-dev": "set NODE_ENV=development&& electron .", - "postinstall": "electron-builder install-app-deps", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], diff --git a/backend/config.json b/backend/config.json index d105e6c..bbc3d97 100644 --- a/backend/config.json +++ b/backend/config.json @@ -1,5 +1,5 @@ { - "payslipsPath": "\\\\PC-20010\\payslips", + "payslipsPath": "\\\\PC-20010\\payslips2", "server": { "host": "localhost", "port": "3001" diff --git a/frontend/package-lock.json b/frontend/package-lock.json index aa4dd37..bf2f6fa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,13 +13,17 @@ "@testing-library/user-event": "^13.5.0", "@types/react": "^19.2.0", "@types/react-dom": "^19.2.0", + "axios": "^1.6.0", + "date-fns": "^2.30.0", "dotenv": "^17.4.2", "electron-is-dev": "^2.0.0", - "pdfjs-dist": "^4.10.38", + "framer-motion": "^13.0.0", + "pdfjs-dist": "^3.11.174", "react": "^19.2.0", "react-dom": "^19.2.0", - "react-pdf": "^10.0.0", - "serialport": "^13.0.0", + "react-icons": "^4.11.0", + "react-pdf": "^8.0.0", + "react-zoom-pan-pinch": "^3.3.0", "typescript": "^5.8.0", "web-vitals": "^2.1.4" }, @@ -669,254 +673,208 @@ "node": ">= 10.0.0" } }, - "node_modules/@napi-rs/canvas": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.100.tgz", - "integrity": "sha512-xglYA6q3XO5P3BNJYxVZ1IV7DLVjp1Py6nwag88YntrS+3vKHyYcMqXVS4ZztJmwz2uGvz1FWhI/4LgbR5uQDA==", - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "license": "BSD-3-Clause", "optional": true, - "workspaces": [ - "e2e/*" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@napi-rs/canvas-android-arm64": "0.1.100", - "@napi-rs/canvas-darwin-arm64": "0.1.100", - "@napi-rs/canvas-darwin-x64": "0.1.100", - "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.100", - "@napi-rs/canvas-linux-arm64-gnu": "0.1.100", - "@napi-rs/canvas-linux-arm64-musl": "0.1.100", - "@napi-rs/canvas-linux-riscv64-gnu": "0.1.100", - "@napi-rs/canvas-linux-x64-gnu": "0.1.100", - "@napi-rs/canvas-linux-x64-musl": "0.1.100", - "@napi-rs/canvas-win32-arm64-msvc": "0.1.100", - "@napi-rs/canvas-win32-x64-msvc": "0.1.100" + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@napi-rs/canvas-android-arm64": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.100.tgz", - "integrity": "sha512-hjhCKhntPv9+t4ckHymdx0phYNcVW+GKQR6Lzw2zE+pOVjOplSmtx9nNNknTjbEDLcuLZqA1y8ufKg1XfgftzQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "license": "ISC", + "optional": true + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=10" } }, - "node_modules/@napi-rs/canvas-darwin-arm64": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.100.tgz", - "integrity": "sha512-2PcswRaC7Ly645DGt88///zuFDhJxJYdKAs1uU3mfk1atYkXufgcgLfBpk6Tm12nCQBaNt1wpybuPZ4qOhTo8A==", - "cpu": [ - "arm64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "node": ">=10" } }, - "node_modules/@napi-rs/canvas-darwin-x64": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.100.tgz", - "integrity": "sha512-ePNZtj7pNIva/siZMg+HmbeozkIjqUIYdoymH8HaA3qK7LfzFN4WMBM8G6HQ9ZC+H3+Dnn5pqtiXpgLykaPOhw==", - "cpu": [ - "x64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=10" } }, - "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.100.tgz", - "integrity": "sha512-d5cDB48oWFGU8/XPhUOFAlySgb/VAu7D+s8fi55K1Pcfg8aPplHWqMgibhVLU8ky7Pyg/fuiVLz4Nf3JrSTuUA==", - "cpu": [ - "arm" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "node": ">=8" } }, - "node_modules/@napi-rs/canvas-linux-arm64-gnu": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.100.tgz", - "integrity": "sha512-rDxgxRu69RvDlX/bh9o22DxLsGr8EqsNgotL9+RwQE1S0b0cqeatqsw6aW45mukm0B42DIAaAacKaYQ8cqS1nw==", - "cpu": [ - "arm64" - ], + "node_modules/@mapbox/node-pre-gyp/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "license": "MIT", "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">= 8" } }, - "node_modules/@napi-rs/canvas-linux-arm64-musl": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.100.tgz", - "integrity": "sha512-K3mDW66N+xT2/V439u1alFANiBUjdEx2gLiNYnCmUsva5jZMxWTjafBYwTzYK+EMFMHrUoabuU+T1BIP5CgbYQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "yallist": "^4.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=8" } }, - "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.100.tgz", - "integrity": "sha512-mooqUBTIsccZpnoQC4NgrC1v6C1vof39etLNMnBwCY+p0gajWJvAHLGQ6g/gGyS5YrpDW+GefSN4+Cvcr08UWw==", - "cpu": [ - "riscv64" - ], + "node_modules/@mapbox/node-pre-gyp/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "license": "MIT", "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "bin": { + "mkdirp": "bin/cmd.js" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=10" } }, - "node_modules/@napi-rs/canvas-linux-x64-gnu": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.100.tgz", - "integrity": "sha512-1eCvkDCazm7FFhsT7DfGOdSaHgZVK3bt/dSBl5EWHOWmnz+I7j8tPseJqqD81NF+MH21jKUK4wQSDjN0mdhnTg==", - "cpu": [ - "x64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "abbrev": "1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" } }, - "node_modules/@napi-rs/canvas-linux-x64-musl": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.100.tgz", - "integrity": "sha512-20arT6lnI19S68qNlii73TSEDbECNgzMz2EpldC1V3mZFuRkeujXkcebRk0LRJe9SEUAooYiLokfMViY8IX7yA==", - "cpu": [ - "x64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" } }, - "node_modules/@napi-rs/canvas-win32-arm64-msvc": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.100.tgz", - "integrity": "sha512-DZFFT1wIAg37LJw37yhMRFfjATd3vTQzjZ1Yki8u2vhO6Hi5VE6BVaGQ1aaDu7xb4iMErz+9EOwjpS7xcxFeBw==", - "cpu": [ - "arm64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@napi-rs/canvas-win32-x64-msvc": { - "version": "0.1.100", - "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.100.tgz", - "integrity": "sha512-MyT1j3mHC2+Lu4pBi9mKyMJhtP6U7k7EldY7sj/uS5gJA65gTXt8MefJQXLJo5d/vZbuWmfxzkEUNc/urV3pHA==", - "cpu": [ - "x64" - ], - "license": "MIT", + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/@napi-rs/lzma-linux-x64-gnu": { @@ -927,6 +885,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1176,6 +1137,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1193,6 +1157,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1210,6 +1177,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1227,6 +1197,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1244,6 +1217,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1261,6 +1237,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1420,6 +1399,9 @@ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1434,6 +1416,9 @@ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1448,6 +1433,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1462,6 +1450,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1476,6 +1467,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1490,6 +1484,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1504,6 +1501,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1518,6 +1518,9 @@ "ppc64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1532,6 +1535,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1546,6 +1552,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1560,6 +1569,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1574,6 +1586,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1588,6 +1603,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1678,254 +1696,6 @@ "win32" ] }, - "node_modules/@serialport/binding-mock": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", - "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", - "license": "MIT", - "dependencies": { - "@serialport/bindings-interface": "^1.2.1", - "debug": "^4.3.3" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@serialport/bindings-cpp": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-13.0.0.tgz", - "integrity": "sha512-r25o4Bk/vaO1LyUfY/ulR6hCg/aWiN6Wo2ljVlb4Pj5bqWGcSRC4Vse4a9AcapuAu/FeBzHCbKMvRQeCuKjzIQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@serialport/bindings-interface": "1.2.2", - "@serialport/parser-readline": "12.0.0", - "debug": "4.4.0", - "node-addon-api": "8.3.0", - "node-gyp-build": "4.8.4" - }, - "engines": { - "node": ">=18.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", - "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", - "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", - "license": "MIT", - "dependencies": { - "@serialport/parser-delimiter": "12.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@serialport/bindings-cpp/node_modules/node-addon-api": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz", - "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==", - "license": "MIT", - "engines": { - "node": "^18 || ^20 || >= 21" - } - }, - "node_modules/@serialport/bindings-interface": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", - "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", - "license": "MIT", - "engines": { - "node": "^12.22 || ^14.13 || >=16" - } - }, - "node_modules/@serialport/parser-byte-length": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-13.0.0.tgz", - "integrity": "sha512-32yvqeTAqJzAEtX5zCrN1Mej56GJ5h/cVFsCDPbF9S1ZSC9FWjOqNAgtByseHfFTSTs/4ZBQZZcZBpolt8sUng==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-cctalk": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-13.0.0.tgz", - "integrity": "sha512-RErAe57g9gvnlieVYGIn1xymb1bzNXb2QtUQd14FpmbQQYlcrmuRnJwKa1BgTCujoCkhtaTtgHlbBWOxm8U2uA==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-delimiter": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-13.0.0.tgz", - "integrity": "sha512-Qqyb0FX1avs3XabQqNaZSivyVbl/yl0jywImp7ePvfZKLwx7jBZjvL+Hawt9wIG6tfq6zbFM24vzCCK7REMUig==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-inter-byte-timeout": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-13.0.0.tgz", - "integrity": "sha512-a0w0WecTW7bD2YHWrpTz1uyiWA2fDNym0kjmPeNSwZ2XCP+JbirZt31l43m2ey6qXItTYVuQBthm75sPVeHnGA==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-packet-length": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-13.0.0.tgz", - "integrity": "sha512-60ZDDIqYRi0Xs2SPZUo4Jr5LLIjtb+rvzPKMJCohrO6tAqSDponcNpcB1O4W21mKTxYjqInSz+eMrtk0LLfZIg==", - "license": "MIT", - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@serialport/parser-readline": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-13.0.0.tgz", - "integrity": "sha512-dov3zYoyf0dt1Sudd1q42VVYQ4WlliF0MYvAMA3MOyiU1IeG4hl0J6buBA2w4gl3DOCC05tGgLDN/3yIL81gsA==", - "license": "MIT", - "dependencies": { - "@serialport/parser-delimiter": "13.0.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-ready": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-13.0.0.tgz", - "integrity": "sha512-JNUQA+y2Rfs4bU+cGYNqOPnNMAcayhhW+XJZihSLQXOHcZsFnOa2F9YtMg9VXRWIcnHldHYtisp62Etjlw24bw==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-regex": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-13.0.0.tgz", - "integrity": "sha512-m7HpIf56G5XcuDdA3DB34Z0pJiwxNRakThEHjSa4mG05OnWYv0IG8l2oUyYfuGMowQWaVnQ+8r+brlPxGVH+eA==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-slip-encoder": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-13.0.0.tgz", - "integrity": "sha512-fUHZEExm6izJ7rg0A1yjXwu4sOzeBkPAjDZPfb+XQoqgtKAk+s+HfICiYn7N2QU9gyaeCO8VKgWwi+b/DowYOg==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-spacepacket": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-13.0.0.tgz", - "integrity": "sha512-DoXJ3mFYmyD8X/8931agJvrBPxqTaYDsPoly9/cwQSeh/q4EjQND9ySXBxpWz5WcpyCU4jOuusqCSAPsbB30Eg==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/stream": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-13.0.0.tgz", - "integrity": "sha512-F7xLJKsjGo2WuEWMSEO1SimRcOA+WtWICsY13r0ahx8s2SecPQH06338g28OT7cW7uRXI7oEQAk62qh5gHJW3g==", - "license": "MIT", - "dependencies": { - "@serialport/bindings-interface": "1.2.2", - "debug": "4.4.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/stream/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -2697,7 +2467,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/are-we-there-yet": { @@ -2777,7 +2547,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, "license": "MIT" }, "node_modules/at-least-node": { @@ -2798,13 +2567,15 @@ "license": "MIT" }, "node_modules/axios": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", - "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", - "dev": true, + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.19.0.tgz", + "integrity": "sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.14.7" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.6", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" } }, "node_modules/balanced-match": { @@ -2989,6 +2760,20 @@ "node": ">=12" } }, + "node_modules/builder-util/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/builder-util/node_modules/jsonfile": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", @@ -3265,13 +3050,6 @@ "node": ">=8" } }, - "node_modules/cacache/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -3305,7 +3083,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3315,6 +3092,22 @@ "node": ">= 0.4" } }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/chai": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", @@ -3512,7 +3305,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "color-support": "bin.js" @@ -3522,7 +3315,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -3555,7 +3347,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/concurrently": { @@ -3590,7 +3382,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/core-util-is": { @@ -3663,7 +3455,6 @@ "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.21.0" @@ -3797,7 +3588,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -3807,7 +3597,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/dequal": { @@ -3823,7 +3613,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -3992,7 +3782,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -4495,13 +4284,6 @@ "node": ">= 8" } }, - "node_modules/electron-rebuild/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/electron-winstaller": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", @@ -4561,14 +4343,13 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4606,7 +4387,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4616,7 +4396,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4633,7 +4412,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -4646,7 +4424,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4846,7 +4623,6 @@ "version": "1.16.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", - "dev": true, "funding": [ { "type": "individual", @@ -4867,7 +4643,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", - "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -4880,6 +4655,29 @@ "node": ">= 6" } }, + "node_modules/framer-motion": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-13.0.0.tgz", + "integrity": "sha512-nQGZXlsiigN48nzvE7AL1GLekql+etcphp8v+PQ0X04oxO20yVmV9rU9XQ25c136RdeIYoaWlKT9oAwvJza3mg==", + "license": "MIT", + "dependencies": { + "motion-dom": "^13.0.0", + "motion-utils": "^13.0.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -4899,7 +4697,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -4912,7 +4710,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -4921,18 +4719,11 @@ "node": ">=8" } }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/fsevents": { @@ -4954,7 +4745,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4995,7 +4785,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -5020,7 +4809,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -5051,7 +4839,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -5072,14 +4860,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/glob/node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -5090,7 +4878,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -5154,7 +4942,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5224,7 +5011,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5237,7 +5023,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -5253,14 +5038,13 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/hasown": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -5282,26 +5066,6 @@ "node": ">=10" } }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", @@ -5338,17 +5102,28 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" } }, "node_modules/humanize-ms": { @@ -5365,7 +5140,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -5427,7 +5201,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -5438,13 +5212,13 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/ip-address": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.4.0.tgz", - "integrity": "sha512-oSK96Grm3aP6OrS263xVxbNDGVL7rzBtYdpGqlDG8iQdoenDoTs/nkki+DflYbAEE8Xl6o5YxhxlrKvI3nqKXQ==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz", + "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==", "dev": true, "license": "MIT", "engines": { @@ -5455,7 +5229,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -6009,6 +5783,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -6030,6 +5807,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -6051,6 +5831,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -6072,6 +5855,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -6180,6 +5966,19 @@ "node": ">=8" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/lz-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", @@ -6220,18 +6019,34 @@ } }, "node_modules/make-cancellable-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/make-cancellable-promise/-/make-cancellable-promise-2.0.0.tgz", - "integrity": "sha512-3SEQqTpV9oqVsIWqAcmDuaNeo7yBO3tqPtqGRcKkEo0lrzD3wqbKG9mkxO65KoOgXqj+zH2phJ2LiAsdzlogSw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/make-cancellable-promise/-/make-cancellable-promise-1.3.2.tgz", + "integrity": "sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww==", "license": "MIT", "funding": { "url": "https://github.com/wojtekmaj/make-cancellable-promise?sponsor=1" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-event-props": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-2.0.0.tgz", - "integrity": "sha512-G/hncXrl4Qt7mauJEXSg3AcdYzmpkIITTNl5I+rH9sog5Yw0kK6vseJjCaPfOXqOqQuPUP89Rkhfz5kPS8ijtw==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.6.2.tgz", + "integrity": "sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA==", "license": "MIT", "funding": { "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" @@ -6293,20 +6108,6 @@ "node": ">= 6" } }, - "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/make-fetch-happen/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -6330,13 +6131,6 @@ "node": ">=8" } }, - "node_modules/make-fetch-happen/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -6355,16 +6149,15 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/merge-refs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-2.0.0.tgz", - "integrity": "sha512-3+B21mYK2IqUWnd2EivABLT7ueDhb0b8/dGK8LoFQPrU61YITeCMn14F7y7qZafWNZhUEKb24cJdiT5Wxs3prg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.3.0.tgz", + "integrity": "sha512-nqXPXbso+1dcKDpPCXvwZyJILz+vSLqGGOnDrYHQYE+B8n9JTCekVLC65AfCpR4ggVyA/45Y0iR9LDyS2iI+zA==", "license": "MIT", "funding": { "url": "https://github.com/wojtekmaj/merge-refs?sponsor=1" @@ -6409,7 +6202,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -6419,7 +6211,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -6519,13 +6310,6 @@ "node": ">=8" } }, - "node_modules/minipass-collect/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/minipass-fetch": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", @@ -6571,13 +6355,6 @@ "node": ">= 8" } }, - "node_modules/minipass-fetch/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/minipass-flush": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", @@ -6604,13 +6381,6 @@ "node": ">=8" } }, - "node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -6637,13 +6407,6 @@ "node": ">=8" } }, - "node_modules/minipass-pipeline/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/minipass-sized": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", @@ -6670,13 +6433,6 @@ "node": ">=8" } }, - "node_modules/minipass-sized/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/minizlib": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", @@ -6704,12 +6460,34 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/motion-dom": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-13.0.0.tgz", + "integrity": "sha512-Xk+SJas70uMAUIApg+m3lZDShxI3LBFHq7mFGbBKoRXc2PVPDyAKmzN64Bbzt4CZdP/CItTiJxWtn4TA0v53Ng==", + "license": "MIT", + "dependencies": { + "motion-utils": "^13.0.0" + } + }, + "node_modules/motion-utils": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-13.0.0.tgz", + "integrity": "sha512-7DnN7TmbLcYXcG4RVadXIihWlyuM9afoUww8Y5Agg431kGKiuL2/OMyP4mJ5wLz+pvN3t5ySClLOaVXJ+wekRQ==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/nan": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz", + "integrity": "sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==", + "license": "MIT", + "optional": true + }, "node_modules/nanoid": { "version": "3.3.18", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", @@ -6795,6 +6573,27 @@ "node": ">=10" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-gyp": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", @@ -6824,6 +6623,7 @@ "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, "license": "MIT", "bin": { "node-gyp-build": "bin.js", @@ -6923,6 +6723,16 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -6938,7 +6748,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -7030,7 +6840,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7046,6 +6856,16 @@ "node": ">=8" } }, + "node_modules/path2d-polyfill": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", + "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -7064,15 +6884,16 @@ } }, "node_modules/pdfjs-dist": { - "version": "4.10.38", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.10.38.tgz", - "integrity": "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ==", + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", "license": "Apache-2.0", "engines": { - "node": ">=20" + "node": ">=18" }, "optionalDependencies": { - "@napi-rs/canvas": "^0.1.65" + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" } }, "node_modules/pe-library": { @@ -7309,6 +7130,15 @@ "signal-exit": "^3.0.2" } }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/pump": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", @@ -7374,6 +7204,15 @@ "react": "^19.2.8" } }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -7382,17 +7221,17 @@ "peer": true }, "node_modules/react-pdf": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-10.4.1.tgz", - "integrity": "sha512-kS/35staVCBqS29verTQJQZXw7RfsRCPO3fdJoW1KXylcv7A9dw6DZ3vJXC2w+bIBgLw5FN4pOFvKSQtkQhPfA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-8.0.0.tgz", + "integrity": "sha512-0aAQjdXeiAFTCGa607reLwPCrjpwH3MM2t0Lpq5Eju6ss17tNDIdhYiyvw/sZg9/ZrmL9aC0I4ztGiFeWz3zOQ==", "license": "MIT", "dependencies": { "clsx": "^2.0.0", "dequal": "^2.0.3", - "make-cancellable-promise": "^2.0.0", - "make-event-props": "^2.0.0", - "merge-refs": "^2.0.0", - "pdfjs-dist": "5.4.296", + "make-cancellable-promise": "^1.3.1", + "make-event-props": "^1.6.0", + "merge-refs": "^1.2.1", + "pdfjs-dist": "3.11.174", "tiny-invariant": "^1.0.0", "warning": "^4.0.0" }, @@ -7410,16 +7249,18 @@ } } }, - "node_modules/react-pdf/node_modules/pdfjs-dist": { - "version": "5.4.296", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.4.296.tgz", - "integrity": "sha512-DlOzet0HO7OEnmUmB6wWGJrrdvbyJKftI1bhMitK7O2N8W2gc757yyYBbINy9IDafXAV9wmKr9t7xsTaNKRG5Q==", - "license": "Apache-2.0", + "node_modules/react-zoom-pan-pinch": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.7.0.tgz", + "integrity": "sha512-UmReVZ0TxlKzxSbYiAj+LeGRW8s8LraAFTXRAxzMYnNRgGPsxCudwZKVkjvGmjtx7SW/hZamt69NUmGf4xrkXA==", + "license": "MIT", "engines": { - "node": ">=20.16.0 || >=22.3.0" + "node": ">=8", + "npm": ">=5" }, - "optionalDependencies": { - "@napi-rs/canvas": "^0.1.80" + "peerDependencies": { + "react": "*", + "react-dom": "*" } }, "node_modules/read-binary-file-arch": { @@ -7439,7 +7280,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -7672,7 +7513,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -7693,7 +7534,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT", "optional": true }, @@ -7727,7 +7567,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -7758,56 +7598,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serialport": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/serialport/-/serialport-13.0.0.tgz", - "integrity": "sha512-PHpnTd8isMGPfFTZNCzOZp9m4mAJSNWle9Jxu6BPTcWq7YXl5qN7tp8Sgn0h+WIGcD6JFz5QDgixC2s4VW7vzg==", - "license": "MIT", - "dependencies": { - "@serialport/binding-mock": "10.2.2", - "@serialport/bindings-cpp": "13.0.0", - "@serialport/parser-byte-length": "13.0.0", - "@serialport/parser-cctalk": "13.0.0", - "@serialport/parser-delimiter": "13.0.0", - "@serialport/parser-inter-byte-timeout": "13.0.0", - "@serialport/parser-packet-length": "13.0.0", - "@serialport/parser-readline": "13.0.0", - "@serialport/parser-ready": "13.0.0", - "@serialport/parser-regex": "13.0.0", - "@serialport/parser-slip-encoder": "13.0.0", - "@serialport/parser-spacepacket": "13.0.0", - "@serialport/stream": "13.0.0", - "debug": "4.4.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/serialport/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/shebang-command": { @@ -7857,9 +7652,68 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-get/node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -8021,13 +7875,6 @@ "node": ">=8" } }, - "node_modules/ssri/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -8079,7 +7926,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -8089,7 +7936,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -8104,7 +7951,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -8396,6 +8243,13 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT", + "optional": true + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -8420,7 +8274,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/type-fest": { @@ -8566,7 +8419,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/vite": { @@ -9776,6 +9629,16 @@ "node": ">=10.0.0" } }, + "node_modules/wait-on/node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", @@ -9815,6 +9678,24 @@ "tslib": "^2.8.1" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause", + "optional": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", @@ -9852,7 +9733,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" @@ -9880,7 +9761,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/xmlbuilder": { @@ -9903,6 +9784,13 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "devOptional": true, + "license": "ISC" + }, "node_modules/yargs": { "version": "17.7.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index 28bf88a..9773877 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,13 +9,17 @@ "@testing-library/user-event": "^13.5.0", "@types/react": "^19.2.0", "@types/react-dom": "^19.2.0", + "axios": "^1.6.0", + "date-fns": "^2.30.0", "dotenv": "^17.4.2", "electron-is-dev": "^2.0.0", - "pdfjs-dist": "^4.10.38", + "framer-motion": "^13.0.0", + "pdfjs-dist": "^3.11.174", "react": "^19.2.0", "react-dom": "^19.2.0", - "react-pdf": "^10.0.0", - "serialport": "^13.0.0", + "react-icons": "^4.11.0", + "react-pdf": "^8.0.0", + "react-zoom-pan-pinch": "^3.3.0", "typescript": "^5.8.0", "web-vitals": "^2.1.4" }, @@ -40,7 +44,7 @@ }, "extraResources": [ { - "from": "node_modules/pdfjs-dist/build/pdf.worker.min.mjs", + "from": "node_modules/pdfjs-dist/build/pdf.worker.min.js", "to": "pdf.worker.mjs", "filter": [ "**/*" @@ -69,13 +73,13 @@ "devDependencies": { "@types/jest": "^29.5.14", "@types/node": "^26.2.0", -"@vitejs/plugin-react":"^6.0.5", - "concurrently":"^7.5.0", - "electron":"^37.0.0", - "electron-builder":"^26.15.3", - "electron-rebuild":"^3.2.9", - "vite":"^8.2.1", - "vitest":"^2.1.8", - "wait-on":"^6.0.1" + "@vitejs/plugin-react": "^6.0.5", + "concurrently": "^7.5.0", + "electron": "^37.0.0", + "electron-builder": "^26.15.3", + "electron-rebuild": "^3.2.9", + "vite": "^8.2.1", + "vitest": "^2.1.8", + "wait-on": "^6.0.1" } } diff --git a/frontend/public/assets/maps/enterprise-map.tiff b/frontend/public/assets/maps/enterprise-map.tiff new file mode 100644 index 0000000..d3199c1 Binary files /dev/null and b/frontend/public/assets/maps/enterprise-map.tiff differ diff --git a/frontend/public/assets/videos/flag.mp4 b/frontend/public/assets/videos/flag.mp4 new file mode 100644 index 0000000..3e428eb Binary files /dev/null and b/frontend/public/assets/videos/flag.mp4 differ diff --git a/frontend/public/electron.js b/frontend/public/electron.js index 856fc4d..abb12bc 100644 --- a/frontend/public/electron.js +++ b/frontend/public/electron.js @@ -5,7 +5,6 @@ const isDev = require('electron-is-dev'); const fs = require('fs'); const COM_PORT = process.env.COM_PORT; const COM_SPEED = process.env.COM_SPEED; -const { SerialPort } = require('serialport'); const axios = require('axios'); const { logger } = require('../../backend/src/config/logger'); const config = require('../src/config.json') @@ -140,57 +139,6 @@ app.on('will-quit', () => { }); //считыватель -SerialPort.list().then(ports => { - logger.info('Доступные порты:', ports.map(p => p.path)); -}).catch(err => { - logger.error('Ошибка при получении списка портов:', err); -}); -try { - const port = new SerialPort({ path: COM_PORT, baudRate: parseInt(COM_SPEED, 10)}); - let buffer = ''; - port.on('open', () => { - logger.info(' Serial port открыт'); - }); - port.on('data', (data) => { - logger.info('RAW DATA:', data); - buffer += data.toString('utf8'); - if (buffer.includes('\n')) { - const lines = buffer.split('\n'); - lines.forEach((line, idx) => { - if (idx < lines.length - 1) { - const uid = line.trim().replace(/\D/g, ''); - if (uid) { - console.log(`UID карты: ${uid}`); - console.log('[DEBUG] Отправляю событие на admin-server:', { - event: 'CARD_PLACED', - uid: uid, - timestamp: Date.now() - }); - axios.post(`${config.adminUrl}}/api/card-event`, { - event: 'CARD_PLACED', - uid: uid, - timestamp: Date.now() - }).catch(err => { - console.error('[ADMIN][CARD_LOG] Ошибка отправки:', err.message); - }); - if (mainWindow && mainWindow.webContents) { - mainWindow.webContents.send('card-detected', uid); - console.log(` Отправка события 'card-detected' в рендерер с UID: ${uid}`); - } else { - console.warn('mainWindow или webContents не определены, событие не отправлено'); - } - } - } - }); - buffer = lines[lines.length - 1]; - } - }); - port.on('error', (err) => { - console.error('Ошибка serialport:', err); - }); -} catch (err) { - console.error('!!! FATAL: FAILED TO INITIALIZE SERIALPORT !!!', err); -} ipcMain.handle('get-app-config', async (event) => { console.log('[IPC] Renderer requested app config. Sending:', appConfig); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 1ac0916..a9e90f3 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,30 +1,111 @@ -import React, { useState } from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import './styles/main.css'; +import './styles/animations.css'; import LoginWindow from './components/LoginWindow'; -import EmployeeInfo from './components/EmployeeInfo'; import GuestMode from './components/GuestMode'; +import MainMenu from './components/MenuComponent'; +import VideoBackground from './components/VideoBackground'; +import BottomBar from './components/BottomBar'; import PayslipViewer from './components/PayslipViewer'; +import EmployeeInfo from './components/EmployeeInfo'; +import { useActivityTimer } from './components/useActivityTimer' import config from './config.json'; +// Импорты разделов +import Finance from './components/Finance'; +import Medicine from './components/Medicine'; +import TradeUnion from './components/TradeUnion'; +import LaborSafety from './components/LaborSafety'; +import Contacts from './components/Contacts'; +import News from './components/News'; +import Profile from './components/Profile'; + interface Employee { id: string; tnom: string; famaly: string; ima: string; otch: string; - category: string; + category?: string; organization: string; - identNumber: string; + identNumber?: string; + departmentName?: string; + profession?: string; + cardNumber?: string; } function App() { + // 📊 Состояния приложения const [isLoggedIn, setIsLoggedIn] = useState(false); const [isGuestMode, setIsGuestMode] = useState(false); const [employee, setEmployee] = useState(null); + const [loginError, setLoginError] = useState(''); + const [showVideo, setShowVideo] = useState(true); + const [currentSection, setCurrentSection] = useState(null); const [showPayslip, setShowPayslip] = useState(false); const [selectedPeriod, setSelectedPeriod] = useState(''); - const [loginError, setLoginError] = useState(''); + + // 📊 Состояния для таймера + const [showInactiveWarning, setShowInactiveWarning] = useState(false); + + // 📌 Реф для поля ввода логина (исправленный тип) + const loginInputRef = useRef(null!); // ✅ Исправлено + // ============================================ + // 🛑 Функция ПОЛНОГО сброса приложения (как при запуске) + // ============================================ + const resetToInitialState = () => { + console.log('🔄 ПОЛНЫЙ СБРОС ПРИЛОЖЕНИЯ — как при запуске'); + + // ✅ Сбрасываем ВСЕ состояния + setIsLoggedIn(false); + setIsGuestMode(false); + setEmployee(null); + setCurrentSection(null); + setShowPayslip(false); + setSelectedPeriod(''); + setShowInactiveWarning(false); + setLoginError(''); + + // ✅ ПОКАЗЫВАЕМ ВИДЕО-ЗАСТАВКУ СНАЧАЛА + setShowVideo(true); + + // ✅ Через 200ms ставим фокус на поле ввода (после видео) + setTimeout(() => { + if (loginInputRef.current) { + loginInputRef.current.focus(); + console.log('✅ Фокус на поле ввода логина'); + } + }, 200); + }; + + // ============================================ + // 🕐 Таймер неактивности (работает ВСЕГДА) + // ============================================ + const { isWarning, timeLeft, resetTimer } = useActivityTimer({ + timeout: 30000, // 30 секунд до предупреждения + warningTimeout: 10000, // 10 секунд до сброса + onInactive: () => { + console.log('🛑 Пользователь неактивен! ПОЛНЫЙ СБРОС ПРИЛОЖЕНИЯ'); + resetToInitialState(); + }, + onWarning: () => { + console.log('⚠️ Предупреждение о неактивности!'); + setShowInactiveWarning(true); + } + }); + + // 📌 Функция для сброса таймера при любом действии + const handleUserActivity = () => { + if (showInactiveWarning) { + setShowInactiveWarning(false); + } + resetTimer(); + }; + + // ============================================ + // 🔐 Вход в систему + // ============================================ const handleLogin = async (id: string) => { try { const isCardUid = /^\d{7}$/.test(id); @@ -37,6 +118,7 @@ function App() { setEmployee(data); setIsLoggedIn(true); setLoginError(''); + handleUserActivity(); } else { setLoginError('Сотрудник не найден'); } @@ -46,54 +128,224 @@ function App() { } }; + // 👤 Режим гостя const handleGuestMode = () => { setIsGuestMode(true); + handleUserActivity(); }; + // ↩️ Выход из системы const handleBack = () => { - setIsLoggedIn(false); - setEmployee(null); - setIsGuestMode(false); + resetToInitialState(); + }; + + // ↩️ Возврат в главное меню + const handleBackToMenu = () => { + setCurrentSection(null); setShowPayslip(false); setSelectedPeriod(''); + handleUserActivity(); }; + // 📂 Выбор раздела + const handleSectionSelect = (section: string) => { + setCurrentSection(section); + handleUserActivity(); + }; + + // 📄 Просмотр расчетного листка const handleViewPayslip = (period: string) => { setSelectedPeriod(period); setShowPayslip(true); + handleUserActivity(); }; + // ↩️ Назад из расчетного листка const handlePayslipBack = () => { setShowPayslip(false); setSelectedPeriod(''); + handleUserActivity(); }; + // 🔗 URL для расчетного листка const getPayslipUrl = (employee: Employee, period: string) => { const fileName = `${employee.tnom}.pdf`; - return `${config.backendUrl}/api/payslip/${period}/${fileName}`; }; - return ( -
- {!isLoggedIn && !isGuestMode ? ( - - ) : isGuestMode ? ( - - ) : showPayslip ? ( + // ============================================ + // ⚠️ Предупреждение о неактивности + // ============================================ + const renderWarning = () => { + if (!showInactiveWarning) return null; + + return ( +
+
+
⚠️
+

+ Сессия истекает! +

+

+ Вы были неактивны. Приложение будет сброшено через: +

+

+ {Math.ceil(timeLeft / 1000)}с +

+

+ 👆 Нажмите или начните двигать мышью для отмены +

+ +
+
+ ); + }; + + // ============================================ + // 📄 Рендер контента + // ============================================ + const renderContent = () => { + // 🎬 Если showVideo = true — показываем видео + if (showVideo) { + return setShowVideo(false)} />; + } + + // ✅ Если не залогинен и не гость — показываем окно входа + if (!isLoggedIn && !isGuestMode) { + return ( + + ); + } + + // 👤 Режим гостя + if (isGuestMode) { + return ; + } + + // 📄 Просмотр расчетного листка + if (showPayslip) { + return ( - ) : employee ? ( - - ) : null} + ); + } + + // 📂 Разделы приложения + if (currentSection) { + switch (currentSection) { + case 'employee-info': + return ; + case 'finance': + return ; + case 'medicine': + return ; + case 'trade-union': + return ; + case 'labor-safety': + return ; + case 'contacts': + return ; + case 'news': + return ; + case 'profile': + return ; + default: + return ; + } + } + + // 📋 Главное меню + return ; + }; + + // ============================================ + // 🚀 Рендер приложения + // ============================================ + return ( +
+ {/* ⚠️ Предупреждение о неактивности */} + {renderWarning()} + + {/* 📄 Основной контент */} + {renderContent()} + + {/* 📱 Нижняя панель (только для авторизованных) */} + {isLoggedIn && !showPayslip && }
); } -export default App; +export default App; \ No newline at end of file diff --git a/frontend/src/components/BottomBar.tsx b/frontend/src/components/BottomBar.tsx new file mode 100644 index 0000000..1098a3f --- /dev/null +++ b/frontend/src/components/BottomBar.tsx @@ -0,0 +1,311 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { motion } from 'framer-motion'; + +interface CurrencyRate { + currency: string; + rate: number; + change: number; +} + +interface MetalRate { + metal: string; + price: number; + change: number; +} + +const BottomBar: React.FC = () => { + const [currencyRates, setCurrencyRates] = useState([ + { currency: 'USD', rate: 3.22, change: 0.5 }, + { currency: 'EUR', rate: 3.45, change: -0.2 }, + { currency: 'CNY', rate: 0.44, change: 0.1 }, + { currency: 'RUB', rate: 0.035, change: -0.3 }, + ]); + + const [metalRates, setMetalRates] = useState([ + { metal: 'Золото', price: 1950, change: 0.8 }, + { metal: 'Серебро', price: 23.5, change: -0.5 }, + { metal: 'Платина', price: 920, change: 0.3 }, + { metal: 'Палладий', price: 1450, change: -0.7 }, + ]); + + const [isOnline, setIsOnline] = useState(navigator.onLine); + const [isPaused, setIsPaused] = useState(false); + const [currentTime, setCurrentTime] = useState(new Date()); // ✅ Добавлено + const scrollRef = useRef(null); + + const getAllItems = () => { + const currencyItems = currencyRates.map(item => ({ + id: `currency-${item.currency}`, + type: 'currency' as const, + label: item.currency, + value: item.rate, + change: item.change, + displayValue: item.rate.toFixed(item.rate < 1 ? 3 : 2), + })); + + const metalItems = metalRates.map(item => ({ + id: `metal-${item.metal}`, + type: 'metal' as const, + label: item.metal, + value: item.price, + change: item.change, + displayValue: `$${item.price.toFixed(item.price < 10 ? 2 : 0)}`, + })); + + return [...currencyItems, ...metalItems]; + }; + + const items = getAllItems(); + const doubledItems = [...items, ...items, ...items]; + + // ✅ Обновление времени каждую секунду + useEffect(() => { + const interval = setInterval(() => { + setCurrentTime(new Date()); + }, 1000); + + return () => clearInterval(interval); + }, []); + + useEffect(() => { + const handleOnline = () => setIsOnline(true); + const handleOffline = () => setIsOnline(false); + + window.addEventListener('online', handleOnline); + window.addEventListener('offline', handleOffline); + + return () => { + window.removeEventListener('online', handleOnline); + window.removeEventListener('offline', handleOffline); + }; + }, []); + + useEffect(() => { + const loadRates = async () => { + try { + if (isOnline) { + const response = await fetch('http://localhost:3001/api/rates'); + if (response.ok) { + const data = await response.json(); + setCurrencyRates(data.currency || currencyRates); + setMetalRates(data.metals || metalRates); + } + } else { + const stored = localStorage.getItem('currencyRates'); + if (stored) { + const data = JSON.parse(stored); + setCurrencyRates(data.currency || currencyRates); + setMetalRates(data.metals || metalRates); + } + } + } catch (error) { + console.warn('Ошибка загрузки курсов:', error); + } + }; + + loadRates(); + const interval = setInterval(loadRates, 60000); + + return () => clearInterval(interval); + }, [isOnline]); + + const handleMouseEnter = () => setIsPaused(true); + const handleMouseLeave = () => setIsPaused(false); + const handleTouchStart = () => setIsPaused(true); + const handleTouchEnd = () => setIsPaused(false); + + return ( + + {/* Статус */} +
+ + {isOnline ? '●' : '○'} + + КУРСЫ +
+
+ + {/* Бегущая строка */} +
+ + {doubledItems.map((item, index) => ( +
+ + {item.label} + + + {item.displayValue} + + = 0 ? '#2ecc71' : '#e74c3c', + fontSize: '11px', + fontWeight: 500, + display: 'flex', + alignItems: 'center', + gap: '2px', + letterSpacing: '0.2px', + }}> + {item.change >= 0 ? '▲' : '▼'} + {Math.abs(item.change).toFixed(1)}% + + {item.type === 'metal' && ( + + $ + + )} +
+ ))} +
+
+ + {/* ✅ Время с СЕКУНДАМИ и обновлением */} +
+ {currentTime.toLocaleString('ru-RU', { + timeZone: 'Europe/Minsk', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false, + })} +
+ + {/* Пауза */} + {isPaused && ( +
+ ⏸ Пауза +
+ )} + + ); +}; + +export default BottomBar; \ No newline at end of file diff --git a/frontend/src/components/Contacts.tsx b/frontend/src/components/Contacts.tsx new file mode 100644 index 0000000..92b92c4 --- /dev/null +++ b/frontend/src/components/Contacts.tsx @@ -0,0 +1,390 @@ +import React, { useState } from 'react'; +import { motion } from 'framer-motion'; +import { FaArrowLeft } from 'react-icons/fa'; +import MapViewer from './MapViewer'; + +interface ContactsProps { + onBack: () => void; +} + +const Contacts: React.FC = ({ onBack }) => { + const [searchTerm, setSearchTerm] = useState(''); + const [activeTab, setActiveTab] = useState<'map' | 'directory'>('directory'); + const [showMapViewer, setShowMapViewer] = useState(false); + + // ✅ Путь к TIFF-файлу (вместо PDF) + const MAP_FILE_URL = '/assets/maps/enterprise-map.tiff'; + + const directoryData = [ + { name: 'Иванов Иван Иванович', position: 'Директор', phone: '123-45-67', department: 'Руководство' }, + { name: 'Петров Петр Петрович', position: 'Главный инженер', phone: '123-45-68', department: 'Руководство' }, + { name: 'Сидорова Мария Сергеевна', position: 'Бухгалтер', phone: '123-45-69', department: 'Бухгалтерия' }, + { name: 'Козлов Андрей Владимирович', position: 'Начальник цеха', phone: '123-45-70', department: 'Производство' }, + ]; + + const emergencyNumbers = [ + { name: 'Пожарная служба', phone: '101', icon: '🧯' }, + { name: 'Милиция', phone: '102', icon: '🛡️' }, + { name: 'Скорая помощь', phone: '103', icon: '🚑' }, + { name: 'Газовая служба', phone: '104', icon: '📞' }, + ]; + + const filteredData = directoryData.filter(item => + item.name.toLowerCase().includes(searchTerm.toLowerCase()) || + item.position.toLowerCase().includes(searchTerm.toLowerCase()) || + item.department.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + const handleOpenMap = () => { + setShowMapViewer(true); + }; + + const handleMapBack = () => { + setShowMapViewer(false); + }; + + if (showMapViewer) { + return ( + + ); + } + + return ( + + {/* Верхняя панель */} +
+ +

+ 📘 Контакты +

+
+
+ + {/* Карточка карты */} + +
+
+ 🗺️ +
+
+

+ Карта предприятия +

+

+ Схема проезда, план здания, расположение корпусов +

+
+
+
+ → +
+
+ + {/* Вкладки */} +
+ + +
+ + {/* Контент вкладок */} + {activeTab === 'directory' && ( + + {/* Экстренные номера */} +
+ {emergencyNumbers.map((item, index) => ( + +
{item.icon}
+
{item.name}
+
{item.phone}
+
+ ))} +
+ + {/* Поиск */} +
+
+ 🔍 + setSearchTerm(e.target.value)} + style={{ + flex: 1, + border: 'none', + background: 'transparent', + padding: '10px 0', + fontSize: '15px', + outline: 'none', + }} + /> +
+
+ + {/* Таблица */} +
+ + + + + + + + + + {filteredData.map((item, index) => ( + { e.currentTarget.style.background = '#f8f9fa'; }} + onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }} + > + + + + + ))} + +
ФИОДолжностьТелефон
{item.name}{item.position} + 📞 {item.phone} +
+ {filteredData.length === 0 && ( +
+ Ничего не найдено +
+ )} +
+
+ )} + + {activeTab === 'map' && ( + { + e.currentTarget.style.borderColor = '#2ecc71'; + e.currentTarget.style.boxShadow = '0 8px 30px rgba(46, 204, 113, 0.15)'; + e.currentTarget.style.transform = 'translateY(-3px)'; + }} + onMouseLeave={(e) => { + e.currentTarget.style.borderColor = '#dfe6e9'; + e.currentTarget.style.boxShadow = '0 4px 20px rgba(0,0,0,0.06)'; + e.currentTarget.style.transform = 'translateY(0)'; + }} + > +
🗺️
+

+ Карта предприятия +

+

+ Нажмите для просмотра карты в полноэкранном режиме +

+
+ Открыть карту → +
+
+ )} + + ); +}; + +export default Contacts; \ No newline at end of file diff --git a/frontend/src/components/Finance.tsx b/frontend/src/components/Finance.tsx new file mode 100644 index 0000000..1c96bc6 --- /dev/null +++ b/frontend/src/components/Finance.tsx @@ -0,0 +1,162 @@ +import React, { useState } from 'react'; +import { motion } from 'framer-motion'; + +interface FinanceProps { + onBack: () => void; + onViewPayslip: (period: string) => void; + employee: any; +} + +interface FinancialIndicator { + title: string; + value: string; + change?: number; + unit?: string; +} + +const Finance: React.FC = ({ onBack, onViewPayslip, employee }) => { + const [selectedPeriod, setSelectedPeriod] = useState(() => { + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${month}${year}`; + }); + + const [indicators] = useState([ + { title: 'Средняя ЗП по предприятию', value: '1 850', unit: 'руб.' }, + { title: 'Премия по итогам месяца', value: '15', unit: '%' }, + { title: 'Материальная помощь к отпуску', value: '500', unit: 'руб.' }, + { title: 'Выплаты к Новому году', value: '300', unit: 'руб.' }, + ]); + + const generatePeriods = () => { + const periods = []; + const now = new Date(); + for (let i = 0; i < 12; i++) { + const date = new Date(now.getFullYear(), now.getMonth() - i, 1); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + periods.push(`${month}${year}`); + } + return periods; + }; + + const periods = generatePeriods(); + const monthNames = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', + 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']; + + const formatPeriod = (period: string) => { + const month = parseInt(period.substring(0, 2)) - 1; + const year = period.substring(2); + return `${monthNames[month]} ${year}`; + }; + + return ( + +
+ +

+ 💰 Финансы +

+
+
+ + +
+
+
{employee.organization}
+
{employee.famaly} {employee.ima} {employee.otch}
+
Табельный номер: {employee.tnom}
+
+
+
Доступно
+
0.00
+
руб.
+
+
+
+ + +

+ 📊 Финансово-экономические показатели +

+
+ {indicators.map((item, index) => ( + +
{item.title}
+
+ {item.value} + {item.unit && {item.unit}} +
+ {item.change !== undefined && ( +
= 0 ? '#2ecc71' : '#e74c3c', marginTop: '4px' }}> + {item.change >= 0 ? '↑' : '↓'} {Math.abs(item.change)}% +
+ )} +
+ ))} +
+
+ + +

+ 📄 Расчётный лист +

+
+
+ + +
+ +
+
+
💡 Информация о премии
+
+ Премия по итогам работы за {formatPeriod(selectedPeriod)} составляет 15% от оклада. +
+
+
+ + ); +}; + +export default Finance; \ No newline at end of file diff --git a/frontend/src/components/GuestMode.tsx b/frontend/src/components/GuestMode.tsx index 00d854c..f02036c 100644 --- a/frontend/src/components/GuestMode.tsx +++ b/frontend/src/components/GuestMode.tsx @@ -1,5 +1,7 @@ import React, { useState, useEffect } from 'react'; -import config from "../../src/config.json"; +import { motion } from 'framer-motion'; +import config from '../config.json'; + interface GuestModeProps { onBack: () => void; } @@ -176,39 +178,136 @@ const GuestMode: React.FC = ({ onBack }) => { }; return ( -
-
-
-

Гостевой режим

-
+

+ Гостевой режим +

+
-
+
{activeTab === 'handbook' && (
{loading ? ( -
Загрузка справочника...
+
+
+

Загрузка справочника...

+
) : ( )} @@ -217,7 +316,22 @@ const GuestMode: React.FC = ({ onBack }) => { {activeTab === 'union' && (
{loading ? ( -
Загрузка...
+
+
+

Загрузка...

+
) : ( unionBlocks.length ? renderContentBlocks(unionBlocks) :

Нет информации о профсоюзе.

)} @@ -226,7 +340,22 @@ const GuestMode: React.FC = ({ onBack }) => { {activeTab === 'info' && (
{loading ? ( -
Загрузка...
+
+
+

Загрузка...

+
) : ( infoBlocks.length ? renderContentBlocks(infoBlocks) :

Нет общей информации.

)} @@ -234,8 +363,16 @@ const GuestMode: React.FC = ({ onBack }) => { )}
-
+ + ); }; -export default GuestMode; \ No newline at end of file +export default GuestMode; \ No newline at end of file diff --git a/frontend/src/components/LaborSafety.tsx b/frontend/src/components/LaborSafety.tsx new file mode 100644 index 0000000..d8be076 --- /dev/null +++ b/frontend/src/components/LaborSafety.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import { motion } from 'framer-motion'; + +interface LaborSafetyProps { + onBack: () => void; + employee: any; +} + +const LaborSafety: React.FC = ({ onBack, employee }) => { + return ( + +
+ +
+ +

+ ⛑️ Охрана труда +

+ +
+ +
⚠️
+

Изменения в документации

+

Информирование о внесённых изменениях в ОЗИ и СТП

+
+ + +
📋
+

Средства индивидуальной защиты (СИЗ)

+

График выдачи, напоминания, информация по СИЗ

+
+ + +
📅
+

График экзаменов

+

Просмотр графика сдачи экзаменов по охране труда

+
+ + +
🔔
+

Уведомления

+

Напоминания о своевременном получении СИЗ

+
+
+ +
+

ℹ️ Раздел в разработке. Функционал будет доступен в ближайшее время.

+
+
+ ); +}; + +export default LaborSafety; \ No newline at end of file diff --git a/frontend/src/components/LoginWindow.tsx b/frontend/src/components/LoginWindow.tsx index 0e00134..2bbd214 100644 --- a/frontend/src/components/LoginWindow.tsx +++ b/frontend/src/components/LoginWindow.tsx @@ -1,49 +1,88 @@ import React, { useEffect, useRef, useState } from 'react'; +import { motion } from 'framer-motion'; + interface LoginWindowProps { onLogin: (id: string) => void; onGuestMode: () => void; loginError?: string; + inputRef?: React.RefObject; // ✅ Реф для управления фокусом } -const LoginWindow: React.FC = ({ onLogin, onGuestMode, loginError }) => { + +const LoginWindow: React.FC = ({ + onLogin, + onGuestMode, + loginError, + inputRef +}) => { const [id, setId] = useState(''); - const inputRef = useRef(null); + const [isCardDetected, setIsCardDetected] = useState(false); + + // ✅ Используем переданный реф или внутренний + const internalInputRef = useRef(null); + const activeInputRef = inputRef || internalInputRef; + + // ✅ При монтировании — фокус на поле ввода + useEffect(() => { + if (activeInputRef.current) { + setTimeout(() => { + activeInputRef.current?.focus(); + }, 100); + } + }, [activeInputRef]); + + // ✅ При ошибке — фокус на поле ввода + useEffect(() => { + if (loginError) { + setId(''); + if (activeInputRef.current) { + setTimeout(() => { + activeInputRef.current?.focus(); + }, 100); + } + } + }, [loginError, activeInputRef]); useEffect(() => { const testConnection = async () => { - try { - const response = await fetch('http://localhost:3001/api/test', { - mode: 'cors', // Явно указываем режим CORS - headers: { - 'Content-Type': 'application/json' + try { + const response = await fetch('http://localhost:3001/api/test', { + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + } + }); + + if (response.ok) { + const data = await response.json(); + console.log('Backend response:', data); + } else { + console.error('Backend returned error status:', response.status); + } + } catch (err) { + console.error('Connection test failed:', err); } - }); - - if (response.ok) { - const data = await response.json(); - console.log('Backend response:', data); - } else { - console.error('Backend returned error status:', response.status); - } - } catch (err) { - console.error('Connection test failed:', err); - } }; testConnection(); + const setupCardListener = () => { console.log('[LoginWindow] Setting up card listener...'); const handleCardDetected = (uid: string) => { console.log('Card detected in renderer via preload:', uid); + setIsCardDetected(true); onLogin(uid); + setTimeout(() => setIsCardDetected(false), 2000); }; - window.electronAPI.onCardDetected(handleCardDetected); + if (window.electronAPI) { + window.electronAPI.onCardDetected(handleCardDetected); + } else { + console.log('[LoginWindow] electronAPI not ready, waiting for event...'); + window.addEventListener('electronApiReady', setupCardListener, { once: true }); + } }; - if (window.electronAPI) { - setupCardListener(); - } else { - console.log('[LoginWindow] electronAPI not ready, waiting for event...'); - window.addEventListener('electronApiReady', setupCardListener, { once: true }); - } + + setupCardListener(); + return () => { console.log('[LoginWindow] Cleaning up listeners.'); window.removeEventListener('electronApiReady', setupCardListener); @@ -53,13 +92,6 @@ const LoginWindow: React.FC = ({ onLogin, onGuestMode, loginEr }; }, [onLogin]); - useEffect(() => { - if (loginError) { - setId(''); - inputRef.current?.focus(); - } - }, [loginError]); - const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (id.trim()) { @@ -68,38 +100,217 @@ const LoginWindow: React.FC = ({ onLogin, onGuestMode, loginEr }; return ( -
-

Вход в систему

-
-

Пожалуйста, приложите вашу карту пропуска к считывателю

-
💳
+ + {/* Индикатор считывания карты */} + {isCardDetected && ( + + ✅ Карта считана + + )} + +

+ Инфокиоск +

+ +

+ Приложите карту пропуска +

+ +
+
+ 💳 +
-
- +
+ setId(e.target.value)} - placeholder=" " + placeholder="Введите табельный номер..." autoFocus + style={{ + width: '100%', + padding: '14px 16px', + border: `2px solid ${loginError ? '#e74c3c' : '#dfe6e9'}`, + borderRadius: '12px', + fontSize: '16px', + transition: 'all 0.3s ease', + background: '#f8f9fa', + outline: 'none', + }} + onFocus={(e) => { + e.target.style.borderColor = '#6c5ce7'; + e.target.style.boxShadow = '0 0 0 4px rgba(108, 92, 231, 0.1)'; + }} + onBlur={(e) => { + e.target.style.borderColor = loginError ? '#e74c3c' : '#dfe6e9'; + e.target.style.boxShadow = 'none'; + }} />
- {loginError &&
{loginError}
} -
- -
-
+ +
+ Для автоматического входа приложите карту к считывателю +
+
); }; -export default LoginWindow; \ No newline at end of file +export default LoginWindow; \ No newline at end of file diff --git a/frontend/src/components/MapViewer.tsx b/frontend/src/components/MapViewer.tsx new file mode 100644 index 0000000..5ac5a1a --- /dev/null +++ b/frontend/src/components/MapViewer.tsx @@ -0,0 +1,863 @@ +import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { + FaArrowLeft, + FaSpinner, + FaPlus, + FaMinus, + FaHome, + FaArrowUp, + FaArrowDown, + FaArrowLeft as FaArrowLeftIcon, + FaArrowRight, + FaSearch, + FaTimes, + FaMapMarkerAlt +} from 'react-icons/fa'; + +interface MapViewerProps { + fileUrl: string; + onBack: () => void; + title?: string; +} + +interface MapMarker { + id: string; + name: string; + x: number; + y: number; + description?: string; +} + +const MapViewer: React.FC = ({ + fileUrl, + onBack, + title = 'Карта предприятия' +}) => { + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [zoom, setZoom] = useState(1); + const [minZoom, setMinZoom] = useState(1); + const [showControls, setShowControls] = useState(true); + const [searchQuery, setSearchQuery] = useState(''); + const [showSearch, setShowSearch] = useState(false); + const [searchResults, setSearchResults] = useState([]); + + // 📐 Реальные размеры изображения + const [imgWidth, setImgWidth] = useState(0); + const [imgHeight, setImgHeight] = useState(0); + const [imageLoaded, setImageLoaded] = useState(false); + + // 📍 Панорамирование + const [offsetX, setOffsetX] = useState(0); + const [offsetY, setOffsetY] = useState(0); + const [isDragging, setIsDragging] = useState(false); + const [dragStartX, setDragStartX] = useState(0); + const [dragStartY, setDragStartY] = useState(0); + const [startOffsetX, setStartOffsetX] = useState(0); + const [startOffsetY, setStartOffsetY] = useState(0); + + const containerRef = useRef(null); + const imageRef = useRef(null); + + // 📍 Тестовые метки + const markers: MapMarker[] = [ + { id: '1', name: 'Главный вход', x: 50, y: 20, description: 'Вход для посетителей' }, + { id: '2', name: 'Проходная', x: 30, y: 50, description: 'КПП №1' }, + { id: '3', name: 'Склад', x: 70, y: 70, description: 'Склад готовой продукции' }, + { id: '4', name: 'Столовая', x: 45, y: 80, description: 'Столовая №2' }, + { id: '5', name: 'Администрация', x: 20, y: 30, description: 'Главный офис' }, + ]; + + // 📄 Загрузка изображения + useEffect(() => { + const loadImage = () => { + const img = new Image(); + img.onload = () => { + setImgWidth(img.width); + setImgHeight(img.height); + setImageLoaded(true); + setLoading(false); + }; + img.onerror = () => { + setError('Не удалось загрузить изображение'); + setLoading(false); + }; + img.src = fileUrl; + }; + + loadImage(); + }, [fileUrl]); + + // ✅ Расчет минимального масштаба ПОСЛЕ загрузки изображения и рендера контейнера + useEffect(() => { + if (!imageLoaded || !containerRef.current) return; + + const calculateMinZoom = () => { + const container = containerRef.current; + if (!container || imgHeight === 0) return; + + const rect = container.getBoundingClientRect(); + const newMinZoom = rect.height / imgHeight; + setMinZoom(newMinZoom); + setZoom(newMinZoom); + }; + + // Ждем один кадр, чтобы DOM обновился + requestAnimationFrame(() => { + calculateMinZoom(); + }); + + // Также пересчитываем при ресайзе + const handleResize = () => { + if (imgHeight > 0 && containerRef.current) { + const rect = containerRef.current.getBoundingClientRect(); + const newMinZoom = rect.height / imgHeight; + setMinZoom(newMinZoom); + setZoom(prev => Math.max(prev, newMinZoom)); + } + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, [imageLoaded, imgHeight]); + + // 🔄 Масштабирование + const handleZoomIn = () => { + setZoom(prev => Math.min(prev + 0.2, 3)); + }; + + const handleZoomOut = () => { + setZoom(prev => Math.max(prev - 0.2, minZoom)); + }; + + const handleZoomReset = () => { + setZoom(minZoom); + setOffsetX(0); + setOffsetY(0); + }; + + // 📍 Получение границ + const getBounds = useCallback(() => { + const container = containerRef.current; + if (!container || imgWidth === 0 || imgHeight === 0) { + return { maxX: 0, maxY: 0 }; + } + const rect = container.getBoundingClientRect(); + const displayWidth = imgWidth * zoom; + const displayHeight = imgHeight * zoom; + const maxX = Math.max(0, (displayWidth - rect.width) / 2); + const maxY = Math.max(0, (displayHeight - rect.height) / 2); + return { maxX, maxY }; + }, [imgWidth, imgHeight, zoom]); + + // 📍 Ограничение смещения + const clampOffset = useCallback((x: number, y: number) => { + const { maxX, maxY } = getBounds(); + return { + x: Math.max(-maxX, Math.min(maxX, x)), + y: Math.max(-maxY, Math.min(maxY, y)) + }; + }, [getBounds]); + + // 📍 Панорамирование + const handlePan = useCallback((dx: number, dy: number) => { + const step = 80 / zoom; + const newX = offsetX + dx * step; + const newY = offsetY + dy * step; + const clamped = clampOffset(newX, newY); + setOffsetX(clamped.x); + setOffsetY(clamped.y); + }, [offsetX, offsetY, zoom, clampOffset]); + + // 🖱️ Drag + const handleMouseDown = (e: React.MouseEvent) => { + setIsDragging(true); + setDragStartX(e.clientX); + setDragStartY(e.clientY); + setStartOffsetX(offsetX); + setStartOffsetY(offsetY); + }; + + const handleMouseMove = (e: React.MouseEvent) => { + if (!isDragging) return; + const dx = e.clientX - dragStartX; + const dy = e.clientY - dragStartY; + const newX = startOffsetX + dx; + const newY = startOffsetY + dy; + const clamped = clampOffset(newX, newY); + setOffsetX(clamped.x); + setOffsetY(clamped.y); + }; + + const handleMouseUp = () => { + setIsDragging(false); + }; + + const handleTouchStart = (e: React.TouchEvent) => { + const touch = e.touches[0]; + setIsDragging(true); + setDragStartX(touch.clientX); + setDragStartY(touch.clientY); + setStartOffsetX(offsetX); + setStartOffsetY(offsetY); + }; + + const handleTouchMove = (e: React.TouchEvent) => { + if (!isDragging) return; + const touch = e.touches[0]; + const dx = touch.clientX - dragStartX; + const dy = touch.clientY - dragStartY; + const newX = startOffsetX + dx; + const newY = startOffsetY + dy; + const clamped = clampOffset(newX, newY); + setOffsetX(clamped.x); + setOffsetY(clamped.y); + }; + + const handleTouchEnd = () => { + setIsDragging(false); + }; + + // 🔍 Поиск + const handleSearch = (query: string) => { + setSearchQuery(query); + if (query.trim().length > 0) { + const results = markers.filter(marker => + marker.name.toLowerCase().includes(query.toLowerCase()) || + (marker.description && marker.description.toLowerCase().includes(query.toLowerCase())) + ); + setSearchResults(results); + + if (results.length > 0) { + const marker = results[0]; + const container = containerRef.current; + if (container) { + const rect = container.getBoundingClientRect(); + const displayWidth = imgWidth * zoom; + const displayHeight = imgHeight * zoom; + const targetX = (marker.x / 100) * displayWidth - rect.width / 2; + const targetY = (marker.y / 100) * displayHeight - rect.height / 2; + const clamped = clampOffset(-targetX, -targetY); + setOffsetX(clamped.x); + setOffsetY(clamped.y); + } + } + } else { + setSearchResults([]); + } + }; + + const clearSearch = () => { + setSearchQuery(''); + setSearchResults([]); + setShowSearch(false); + }; + + // ⏱️ Авто-скрытие + useEffect(() => { + let timeout: NodeJS.Timeout; + const handleActivity = () => { + setShowControls(true); + clearTimeout(timeout); + timeout = setTimeout(() => { + setShowControls(false); + }, 4000); + }; + document.addEventListener('mousemove', handleActivity); + document.addEventListener('touchstart', handleActivity); + document.addEventListener('keydown', handleActivity); + return () => { + document.removeEventListener('mousemove', handleActivity); + document.removeEventListener('touchstart', handleActivity); + document.removeEventListener('keydown', handleActivity); + clearTimeout(timeout); + }; + }, []); + + // ⌨️ ESC + useEffect(() => { + const handleEscape = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + if (showSearch) { + clearSearch(); + } else { + onBack(); + } + } + }; + document.addEventListener('keydown', handleEscape); + return () => document.removeEventListener('keydown', handleEscape); + }, [showSearch, onBack]); + + // 🎨 Рендер + if (loading) { + return ( + + + + Загрузка карты... + + + ); + } + + if (error) { + return ( + +
🗺️
+

+ Карта не найдена +

+

+ {error} +

+ +
+ ); + } + + return ( + + {/* ⬅️ Кнопка Назад */} + + + {/* 🔍 Поле поиска — сверху справа */} +
+ + + {showSearch && ( + + handleSearch(e.target.value)} + placeholder="Поиск по карте..." + autoFocus + style={{ + padding: '8px 0', + background: 'transparent', + color: '#202124', + border: 'none', + outline: 'none', + fontSize: '15px', + minWidth: '180px', + width: '100%', + fontFamily: 'inherit', + }} + /> + {searchQuery && ( + + )} + + )} +
+ + {/* 📍 Результаты поиска */} + {searchResults.length > 0 && showSearch && ( +
+ {searchResults.map((marker) => ( + + ))} +
+ )} + + {/* 🗺️ Контейнер с картой */} +
+ {/* ✅ TIFF изображение */} + Карта предприятия + + {/* 👆 Подсказка */} + {!isDragging && showControls && ( +
+ 👆 Перетащите для перемещения +
+ )} +
+ + {/* 🎮 Нижняя панель управления */} + + {showControls && ( + + {/* Кнопки панорамирования */} +
+ + + + + +
+ + {/* Кнопки масштабирования */} +
+ + + + {Math.round(zoom * 100)}% + + + +
+
+ )} +
+
+ ); +}; + +export default MapViewer; \ No newline at end of file diff --git a/frontend/src/components/Medicine.tsx b/frontend/src/components/Medicine.tsx new file mode 100644 index 0000000..7beaa98 --- /dev/null +++ b/frontend/src/components/Medicine.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { motion } from 'framer-motion'; + +interface MedicineProps { + onBack: () => void; + employee: any; +} + +const Medicine: React.FC = ({ onBack, employee }) => { + return ( + +
+ +
+ +

+ 🏥 Медицина +

+ +
+ +
📋
+

Медицинская карта

+

Просмотр информации из медицинской карты

+
+ + +
🏥
+

Запись в поликлинику

+

Онлайн запись к врачу

+
+ + +
🛡️
+

Страховая компания

+

Оформление заявок на медицинские услуги

+
+
+ +
+

ℹ️ Раздел в разработке. Функционал будет доступен в ближайшее время.

+
+
+ ); +}; + +export default Medicine; \ No newline at end of file diff --git a/frontend/src/components/MenuComponent.tsx b/frontend/src/components/MenuComponent.tsx new file mode 100644 index 0000000..f4be671 --- /dev/null +++ b/frontend/src/components/MenuComponent.tsx @@ -0,0 +1,105 @@ +import React from 'react'; + +interface MainMenuProps { + onSectionSelect: (section: string) => void; + employee: any; +} + +const MainMenu: React.FC = ({ onSectionSelect, employee }) => { + console.log('🔵 MainMenu компонент рендерится!'); + + const menuItems = [ + { id: 'employee-info', title: 'Моя информация', emoji: '📋' }, + { id: 'finance', title: 'Финансы', emoji: '💰' }, + { id: 'medicine', title: 'Медицина', emoji: '🏥' }, + { id: 'trade-union', title: 'Профсоюз', emoji: '🤝' }, + { id: 'labor-safety', title: 'Охрана труда', emoji: '⛑️' }, + { id: 'contacts', title: 'Контакты', emoji: '📞' }, + { id: 'news', title: 'Новости', emoji: '📰' }, + { id: 'profile', title: 'Обо мне', emoji: '👤' }, + ]; + + return ( +
+ {employee && ( +
+ Здравствуйте, {employee.ima} {employee.famaly} +
+ )} +

+ Выберите раздел +

+ +
+ {menuItems.map((item) => ( + + ))} +
+
+ ); +}; + +console.log('🟢 MainMenu.tsx экспорт готов'); + +export default MainMenu; \ No newline at end of file diff --git a/frontend/src/components/News.tsx b/frontend/src/components/News.tsx new file mode 100644 index 0000000..9abbe08 --- /dev/null +++ b/frontend/src/components/News.tsx @@ -0,0 +1,232 @@ +import React, { useState, type ComponentType, type SVGAttributes } from 'react'; +import { motion } from 'framer-motion'; +import { FaNewspaper, FaCalendarAlt, FaUser, FaTag } from 'react-icons/fa'; + +interface NewsProps { + onBack: () => void; +} + +interface NewsItem { + id: number; + title: string; + date: string; + content: string; + category: string; + author: string; +} + +const IconWrapper = ({ icon: Icon, style }: { icon: any; style?: React.CSSProperties }) => ( + +); + +const News: React.FC = ({ onBack }) => { + const [news, setNews] = useState([ + { + id: 1, + title: 'День химика - поздравления коллективу!', + date: '2024-05-27', + content: 'Уважаемые сотрудники! Поздравляем вас с профессиональным праздником - Днем химика! Желаем успехов в работе, крепкого здоровья и благополучия.', + category: 'Праздники', + author: 'Администрация', + }, + { + id: 2, + title: 'Новые правила охраны труда', + date: '2024-05-25', + content: 'С 1 июня вводятся новые правила по охране труда. Просим ознакомиться с изменениями в разделе "Охрана труда".', + category: 'Охрана труда', + author: 'Отдел ОТ', + }, + { + id: 3, + title: 'Спортивные соревнования среди цехов', + date: '2024-05-20', + content: 'Приглашаем принять участие в ежегодных спортивных соревнованиях. Заявки принимаются до 10 июня.', + category: 'Спорт', + author: 'Профсоюз', + }, + ]); + + const [selectedCategory, setSelectedCategory] = useState('Все'); + const categories = ['Все', ...Array.from(new Set(news.map(item => item.category)))]; + + const filteredNews = selectedCategory === 'Все' + ? news + : news.filter(item => item.category === selectedCategory); + + return ( + +
+ +
+ +

+ + Новости +

+ + {/* Фильтр по категориям */} +
+ {categories.map(category => ( + setSelectedCategory(category)} + style={{ + padding: '8px 20px', + border: 'none', + borderRadius: '20px', + cursor: 'pointer', + fontSize: '14px', + fontWeight: selectedCategory === category ? 600 : 400, + background: selectedCategory === category ? '#1abc9c' : '#f8f9fa', + color: selectedCategory === category ? 'white' : '#636e72', + transition: 'all 0.3s ease', + }} + > + {category} + + ))} +
+ + {/* Список новостей */} +
+ {filteredNews.map((item, index) => ( + +
+

+ {item.title} +

+ + + {item.category} + +
+ +

+ {item.content} +

+ +
+ + + {new Date(item.date).toLocaleDateString('ru-RU')} + + + + {item.author} + +
+
+ ))} +
+ + {filteredNews.length === 0 && ( +
+ Новостей в этой категории пока нет +
+ )} +
+ ); +}; + +export default News; \ No newline at end of file diff --git a/frontend/src/components/PayslipViewer.tsx b/frontend/src/components/PayslipViewer.tsx index 575db15..9b7ee8d 100644 --- a/frontend/src/components/PayslipViewer.tsx +++ b/frontend/src/components/PayslipViewer.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { Document, Page, pdfjs } from 'react-pdf'; -pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.mjs'; +// ИСПОЛЬЗОВАТЬ CDN - ЭТО РАБОТАЕТ +pdfjs.GlobalWorkerOptions.workerSrc = + 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js'; interface PayslipViewerProps { fileUrl: string; @@ -18,28 +20,28 @@ const PayslipViewer: React.FC = ({ fileUrl, onBack }) => { }; return ( -
-
- - -
-
- -
- -
-
-
+
+
+ +
- ); +
+ +
+ +
+
+
+
+ ); }; export default PayslipViewer; \ No newline at end of file diff --git a/frontend/src/components/Profile.tsx b/frontend/src/components/Profile.tsx new file mode 100644 index 0000000..e57890f --- /dev/null +++ b/frontend/src/components/Profile.tsx @@ -0,0 +1,642 @@ +import React, { useState } from 'react'; +import { motion } from 'framer-motion'; +import { + FaUserCircle, FaClock, FaBriefcase, FaAward, + FaExclamationTriangle, FaCalendarCheck, FaUtensils, + FaFileAlt, FaEdit, FaSave, FaTimes +} from 'react-icons/fa'; + +interface ProfileProps { + onBack: () => void; + employee: any; +} + +interface Tab { + id: string; + label: string; + icon: any; +} + +// Функция-обертка для рендеринга иконок +const renderIcon = (Icon: any, style?: React.CSSProperties) => { + return React.createElement(Icon, { style }); +}; + +const Profile: React.FC = ({ onBack, employee }) => { + const [activeTab, setActiveTab] = useState('about'); + const [isEditing, setIsEditing] = useState(false); + const [formData, setFormData] = useState({ + fullName: employee?.fullName || 'Иванов Иван Иванович', + position: employee?.position || 'Инженер-технолог', + department: employee?.department || 'Цех №5', + phone: employee?.phone || '+7 (999) 123-45-67', + email: employee?.email || 'ivanov@company.ru', + address: employee?.address || 'г. Москва, ул. Ленина, д. 1, кв. 10', + birthDate: employee?.birthDate || '1985-06-15', + education: employee?.education || 'Высшее, МГУ им. Ломоносова, химический факультет', + }); + + const tabs: Tab[] = [ + { id: 'about', label: 'Обо мне', icon: FaUserCircle }, + { id: 'achievements', label: 'Достижения', icon: FaAward }, + { id: 'vacation', label: 'Отпуск', icon: FaCalendarCheck }, + { id: 'meal', label: 'Питание', icon: FaUtensils }, + { id: 'certificates', label: 'Справки', icon: FaFileAlt }, + ]; + + const achievements = [ + { type: 'Поощрение', name: 'Благодарность за успешный проект', date: '2024-01-15' }, + { type: 'Поощрение', name: 'Премия по итогам года', date: '2023-12-20' }, + { type: 'Взыскание', name: 'Замечание за опоздание', date: '2023-10-01' }, + ]; + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ ...prev, [name]: value })); + }; + + const handleSave = () => { + setIsEditing(false); + }; + + const renderTabContent = () => { + switch (activeTab) { + case 'about': + return ( +
+
+
+ {renderIcon(FaUserCircle)} +
+
+ {isEditing ? ( + + ) : ( +
+ {formData.fullName} +
+ )} +
+ {formData.position} • {formData.department} +
+
+
+ +
+
+
Телефон
+ {isEditing ? ( + + ) : ( +
{formData.phone}
+ )} +
+
+
Email
+ {isEditing ? ( + + ) : ( +
{formData.email}
+ )} +
+
+
Адрес
+ {isEditing ? ( + + ) : ( +
{formData.address}
+ )} +
+
+
Дата рождения
+ {isEditing ? ( + + ) : ( +
+ {new Date(formData.birthDate).toLocaleDateString('ru-RU')} +
+ )} +
+
+
Образование
+ {isEditing ? ( +