From dfbd387fae86212e31c6285014a120a0b41234e9 Mon Sep 17 00:00:00 2001 From: test Date: Thu, 19 Jun 2025 13:16:59 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20=D1=84?= =?UTF-8?q?=D1=80=D0=BE=D0=BD=D1=82=20=D1=87=D0=B0=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FRONT/BUILD/index.html | 13 + FRONT/BUILD/resources/app/.gitignore | 3 +- .../app/dist/assets/icon-4fEsvohP.png | Bin 129501 -> 0 bytes .../app/dist/assets/index-CAnb47c8.js | 913 ------------------ .../app/dist/assets/index-DWFkiel1.css | 1 - FRONT/BUILD/resources/app/dist/index.html | 13 - FRONT/BUILD/resources/app/eslint.config.js | 28 + FRONT/BUILD/resources/app/index.html | 12 + FRONT/BUILD/resources/app/index.tsx | 52 + FRONT/BUILD/resources/app/main.js | 2 +- FRONT/BUILD/resources/app/package.json | 1 + .../{dist => public}/assets/images/back1.svg | 0 .../assets/images/bigLogo.svg | 0 .../{dist => public}/assets/images/bukvi.svg | 0 .../{dist => public}/assets/images/cancel.svg | 0 .../{dist => public}/assets/images/check.svg | 0 .../{dist => public}/assets/images/edit.svg | 0 .../assets/images/ethernet.svg | 0 .../{dist => public}/assets/images/gossys.png | Bin .../{dist => public}/assets/images/logo.svg | 0 .../{dist => public}/assets/images/signal.svg | 0 .../{dist => public}/assets/images/vite.svg | 0 .../{dist => public}/assets/images/vpn.svg | 0 .../{dist => public}/assets/images/wifi.svg | 0 FRONT/BUILD/resources/app/src/api/request.ts | 160 +++ .../resources/app/src/assets/css/flow.css | 108 +++ .../resources/app/src/assets/css/index.css | 36 + .../src/components/UI/Dropdown/DeviceCard.tsx | 137 +++ .../components/UI/Dropdown/DropdownType.tsx | 130 +++ .../app/src/components/UI/animDot.tsx | 29 + .../src/components/UI/buttons/mainButton.tsx | 75 ++ .../src/components/UI/buttons/quitButton.tsx | 45 + .../src/components/UI/buttons/toggletheme.tsx | 26 + .../app/src/components/UI/inputs/input.tsx | 65 ++ .../app/src/components/UI/loader.tsx | 101 ++ .../app/src/components/UI/routerLoader.tsx | 103 ++ .../app/src/components/UI/signalSvg.tsx | 63 ++ .../src/components/UI/tables/TableScanner.tsx | 109 +++ .../nodes/baseForm/circle/circleNode.tsx | 38 + .../nodes/baseForm/circle/style.ts | 20 + .../nodes/baseForm/default/defaultNode.tsx | 37 + .../nodes/baseForm/default/style.ts | 20 + .../nodes/baseForm/diamond/diamondNode.tsx | 45 + .../nodes/baseForm/diamond/style.ts | 32 + .../customeNodes/nodes/baseForm/index.ts | 5 + .../paralelogram/paralelogramNode.tsx | 35 + .../nodes/baseForm/paralelogram/style.ts | 43 + .../nodes/baseForm/pill/pillNode.tsx | 40 + .../customeNodes/nodes/baseForm/pill/style.ts | 19 + .../nodes/networkInterface/index.ts | 5 + .../networkInterface/ipGroup/ipGroup.tsx | 18 + .../nodes/networkInterface/ipGroup/style.ts | 12 + .../nodes/networkInterface/ipNode/ipNode.tsx | 245 +++++ .../nodes/networkInterface/ipNode/style.ts | 74 ++ .../networkGroup/nodeGroup.tsx | 64 ++ .../networkInterface/networkGroup/style.ts | 47 + .../networkNode/networkNode.tsx | 110 +++ .../networkInterface/networkNode/style.ts | 93 ++ .../networkInterface/portNode/portNode.tsx | 48 + .../nodes/networkInterface/portNode/style.ts | 30 + .../components/customeNodes/types/colors.ts | 11 + .../components/customeNodes/types/types.ts | 16 + .../app/src/components/modalwindows/modal.tsx | 10 + .../modalContainers/ConnectNetwork.tsx | 84 ++ .../modalContainers/NoteDevice.tsx | 82 ++ .../modalwindows/modalContainers/NoteWifi.tsx | 82 ++ .../modalContainers/addDevice.tsx | 58 ++ .../modalContainers/connectionError.tsx | 38 + .../modalContainers/disconnectConfirm.tsx | 54 ++ .../modalwindows/modalContainers/index.ts | 4 + .../modalContainers/ipConfirm.tsx | 211 ++++ .../modalContainers/rightsConfirm.tsx | 135 +++ .../components/modalwindows/modalWindow.tsx | 81 ++ .../app/src/components/modalwindows/style.ts | 70 ++ .../components/modalwindows/windowsType.ts | 13 + .../resources/app/src/components/register.tsx | 194 ++++ .../workSpace/modules/appModules/about.tsx | 213 ++++ .../workSpace/modules/appModules/header.tsx | 46 + .../modules/appModules/helloWindow.tsx | 82 ++ .../usersScanner/modules/ListUsers.tsx | 73 ++ .../usersScanner/modules/TableUsers.tsx | 45 + .../appModules/usersScanner/userScanner.tsx | 191 ++++ .../appModules/wifiScanner/WifiScanner.tsx | 199 ++++ .../wifiScanner/modules/ModalWifiScaner.tsx | 225 +++++ .../wifiScanner/modules/WifiDot.tsx | 79 ++ .../modules/workModules/networkInterfaces.tsx | 282 ++++++ .../components/workSpace/sideBar/sideBar.tsx | 17 + .../sideBar/toolBar/toolBar-button.tsx | 32 + .../workSpace/sideBar/toolBar/toolBar.tsx | 87 ++ .../sideBar/toolSpace/devicesBar.tsx | 244 +++++ .../workSpace/sideBar/toolSpace/toolSpace.tsx | 31 + .../src/components/workSpace/workSpace.tsx | 101 ++ .../resources/app/src/const/buttons/icons.tsx | 63 ++ .../resources/app/src/const/buttons/names.ts | 20 + .../app/src/const/menus/othersMenus/data.ts | 9 + .../app/src/const/menus/othersMenus/names.ts | 5 + .../src/const/menus/sideBar/components.tsx | 20 + .../app/src/const/menus/sideBar/data.ts | 13 + .../app/src/const/menus/sideBar/icons.tsx | 32 + .../app/src/const/menus/sideBar/names.ts | 5 + .../resources/app/src/const/modals/names.ts | 8 + .../app/src/const/theme/globalStyles.ts | 55 ++ .../resources/app/src/const/theme/icons.tsx | 36 + .../resources/app/src/const/theme/names.ts | 10 + .../resources/app/src/const/theme/theme.ts | 30 + .../resources/app/src/const/types/types.ts | 213 ++++ .../app/src/const/workspace/names.ts | 10 + FRONT/BUILD/resources/app/src/electron.d.ts | 5 + .../BUILD/resources/app/src/hooks/useMenu.ts | 15 + .../resources/app/src/hooks/useToolBar.ts | 16 + FRONT/BUILD/resources/app/src/router.tsx | 43 + .../resources/app/src/store/adminStore.ts | 11 + .../resources/app/src/store/devicesStore.ts | 39 + .../resources/app/src/store/flowStore.ts | 22 + .../resources/app/src/store/groupStore.ts | 13 + FRONT/BUILD/resources/app/src/store/index.ts | 9 + .../BUILD/resources/app/src/store/ipStore.ts | 20 + .../resources/app/src/store/menusStore.ts | 28 + .../resources/app/src/store/modalContext.tsx | 63 ++ .../resources/app/src/store/pannableStore.ts | 11 + .../BUILD/resources/app/src/store/posStore.ts | 11 + .../resources/app/src/store/themeContext.tsx | 78 ++ .../resources/app/src/store/toolBarStore.ts | 50 + .../resources/app/src/store/useDeviceStore.ts | 51 + .../resources/app/src/store/workSpaceStore.ts | 26 + .../resources/app/src/utils/checkAdmin.ts | 19 + .../utils/nodeController/autosavePosition.ts | 104 ++ .../src/utils/nodeController/collapseGroup.ts | 65 ++ .../app/src/utils/nodeController/groupSort.ts | 37 + .../app/src/utils/nodeController/index.ts | 6 + .../utils/nodeController/initNetIntData.ts | 60 ++ .../nodeController/nodeCreator/deviceState.ts | 33 + .../nodeCreator/inits/initEdges.ts | 19 + .../nodeCreator/inits/initIpArray.ts | 44 + .../nodeCreator/inits/initNodes.ts | 297 ++++++ .../nodeCreator/inits/initor.ts | 15 + .../utils/nodeController/updateWifiData.ts | 21 + .../app/src/utils/nodeController/validator.ts | 35 + .../resources/app/src/utils/pageReloads.ts | 18 + FRONT/BUILD/resources/app/tsconfig.app.json | 26 + FRONT/BUILD/resources/app/tsconfig.json | 33 + FRONT/BUILD/resources/app/tsconfig.node.json | 11 + FRONT/BUILD/resources/app/vite-env.d.ts | 1 + FRONT/BUILD/resources/app/vite.config.ts | 11 + FRONT/DEV/main.js | 4 +- FRONT/DEV/package-lock.json | 10 + FRONT/DEV/package.json | 1 + FRONT/DEV/src/api/request.ts | 47 +- .../src/components/UI/Dropdown/DeviceCard.tsx | 4 +- FRONT/DEV/src/components/UI/inputs/input.tsx | 4 +- FRONT/DEV/src/components/UI/signalSvg.tsx | 18 +- .../src/components/UI/tables/TableScanner.tsx | 4 +- .../nodes/networkInterface/ipNode/ipNode.tsx | 6 +- .../networkNode/networkNode.tsx | 2 +- .../networkInterface/networkNode/style.ts | 4 +- .../modalContainers/ConnectNetwork.tsx | 84 ++ .../modalContainers/NoteDevice.tsx | 13 +- .../modalwindows/modalContainers/NoteWifi.tsx | 82 ++ .../modalContainers/addDevice.tsx | 2 +- .../modalContainers/disconnectConfirm.tsx | 54 ++ .../modalContainers/rightsConfirm.tsx | 2 +- .../components/modalwindows/modalWindow.tsx | 27 +- .../DEV/src/components/modalwindows/style.ts | 2 +- .../components/modalwindows/windowsType.ts | 3 + FRONT/DEV/src/components/register.tsx | 5 +- .../appModules/usersScanner/userScanner.tsx | 2 +- .../appModules/wifiScanner/WifiScanner.tsx | 40 +- .../wifiScanner/modules/ModalWifiScaner.tsx | 141 ++- .../wifiScanner/modules/WifiDot.tsx | 3 +- .../modules/workModules/networkInterfaces.tsx | 2 +- .../sideBar/toolSpace/devicesBar.tsx | 2 +- FRONT/DEV/src/const/buttons/icons.tsx | 2 + FRONT/DEV/src/const/buttons/names.ts | 1 + FRONT/DEV/src/store/ipStore.ts | 2 +- FRONT/DEV/src/store/useDeviceStore.ts | 1 + FRONT/DEV/yarn.lock | 7 + 176 files changed, 7839 insertions(+), 1032 deletions(-) create mode 100644 FRONT/BUILD/index.html delete mode 100644 FRONT/BUILD/resources/app/dist/assets/icon-4fEsvohP.png delete mode 100644 FRONT/BUILD/resources/app/dist/assets/index-CAnb47c8.js delete mode 100644 FRONT/BUILD/resources/app/dist/assets/index-DWFkiel1.css delete mode 100644 FRONT/BUILD/resources/app/dist/index.html create mode 100644 FRONT/BUILD/resources/app/eslint.config.js create mode 100644 FRONT/BUILD/resources/app/index.html create mode 100644 FRONT/BUILD/resources/app/index.tsx rename FRONT/BUILD/resources/app/{dist => public}/assets/images/back1.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/bigLogo.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/bukvi.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/cancel.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/check.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/edit.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/ethernet.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/gossys.png (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/logo.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/signal.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/vite.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/vpn.svg (100%) rename FRONT/BUILD/resources/app/{dist => public}/assets/images/wifi.svg (100%) create mode 100644 FRONT/BUILD/resources/app/src/api/request.ts create mode 100644 FRONT/BUILD/resources/app/src/assets/css/flow.css create mode 100644 FRONT/BUILD/resources/app/src/assets/css/index.css create mode 100644 FRONT/BUILD/resources/app/src/components/UI/Dropdown/DeviceCard.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/Dropdown/DropdownType.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/animDot.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/buttons/mainButton.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/buttons/quitButton.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/buttons/toggletheme.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/inputs/input.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/loader.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/routerLoader.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/signalSvg.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/index.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/index.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/types/colors.ts create mode 100644 FRONT/BUILD/resources/app/src/components/customeNodes/types/types.ts create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modal.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ConnectNetwork.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteDevice.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteWifi.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/addDevice.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/connectionError.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/disconnectConfirm.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/index.ts create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ipConfirm.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/rightsConfirm.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/modalWindow.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/style.ts create mode 100644 FRONT/BUILD/resources/app/src/components/modalwindows/windowsType.ts create mode 100644 FRONT/BUILD/resources/app/src/components/register.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/header.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/helloWindow.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/WifiScanner.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/modules/ModalWifiScaner.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/modules/WifiDot.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/modules/workModules/networkInterfaces.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/sideBar/sideBar.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolBar/toolBar-button.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolBar/toolBar.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolSpace/devicesBar.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolSpace/toolSpace.tsx create mode 100644 FRONT/BUILD/resources/app/src/components/workSpace/workSpace.tsx create mode 100644 FRONT/BUILD/resources/app/src/const/buttons/icons.tsx create mode 100644 FRONT/BUILD/resources/app/src/const/buttons/names.ts create mode 100644 FRONT/BUILD/resources/app/src/const/menus/othersMenus/data.ts create mode 100644 FRONT/BUILD/resources/app/src/const/menus/othersMenus/names.ts create mode 100644 FRONT/BUILD/resources/app/src/const/menus/sideBar/components.tsx create mode 100644 FRONT/BUILD/resources/app/src/const/menus/sideBar/data.ts create mode 100644 FRONT/BUILD/resources/app/src/const/menus/sideBar/icons.tsx create mode 100644 FRONT/BUILD/resources/app/src/const/menus/sideBar/names.ts create mode 100644 FRONT/BUILD/resources/app/src/const/modals/names.ts create mode 100644 FRONT/BUILD/resources/app/src/const/theme/globalStyles.ts create mode 100644 FRONT/BUILD/resources/app/src/const/theme/icons.tsx create mode 100644 FRONT/BUILD/resources/app/src/const/theme/names.ts create mode 100644 FRONT/BUILD/resources/app/src/const/theme/theme.ts create mode 100644 FRONT/BUILD/resources/app/src/const/types/types.ts create mode 100644 FRONT/BUILD/resources/app/src/const/workspace/names.ts create mode 100644 FRONT/BUILD/resources/app/src/electron.d.ts create mode 100644 FRONT/BUILD/resources/app/src/hooks/useMenu.ts create mode 100644 FRONT/BUILD/resources/app/src/hooks/useToolBar.ts create mode 100644 FRONT/BUILD/resources/app/src/router.tsx create mode 100644 FRONT/BUILD/resources/app/src/store/adminStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/devicesStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/flowStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/groupStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/index.ts create mode 100644 FRONT/BUILD/resources/app/src/store/ipStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/menusStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/modalContext.tsx create mode 100644 FRONT/BUILD/resources/app/src/store/pannableStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/posStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/themeContext.tsx create mode 100644 FRONT/BUILD/resources/app/src/store/toolBarStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/useDeviceStore.ts create mode 100644 FRONT/BUILD/resources/app/src/store/workSpaceStore.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/checkAdmin.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/autosavePosition.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/collapseGroup.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/groupSort.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/index.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/initNetIntData.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/nodeCreator/deviceState.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/nodeCreator/inits/initEdges.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/nodeCreator/inits/initIpArray.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/nodeCreator/inits/initNodes.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/nodeCreator/inits/initor.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/updateWifiData.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/nodeController/validator.ts create mode 100644 FRONT/BUILD/resources/app/src/utils/pageReloads.ts create mode 100644 FRONT/BUILD/resources/app/tsconfig.app.json create mode 100644 FRONT/BUILD/resources/app/tsconfig.json create mode 100644 FRONT/BUILD/resources/app/tsconfig.node.json create mode 100644 FRONT/BUILD/resources/app/vite-env.d.ts create mode 100644 FRONT/BUILD/resources/app/vite.config.ts create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/ConnectNetwork.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/NoteWifi.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/disconnectConfirm.tsx diff --git a/FRONT/BUILD/index.html b/FRONT/BUILD/index.html new file mode 100644 index 0000000..8f4d4d1 --- /dev/null +++ b/FRONT/BUILD/index.html @@ -0,0 +1,13 @@ + + + + + GoNets + + + + + +
+ + \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/.gitignore b/FRONT/BUILD/resources/app/.gitignore index 30bc162..b2d59d1 100644 --- a/FRONT/BUILD/resources/app/.gitignore +++ b/FRONT/BUILD/resources/app/.gitignore @@ -1 +1,2 @@ -/node_modules \ No newline at end of file +/node_modules +/dist \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/dist/assets/icon-4fEsvohP.png b/FRONT/BUILD/resources/app/dist/assets/icon-4fEsvohP.png deleted file mode 100644 index b39bc87e4e512daba45f91f3151ed3e92c77f0a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129501 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 z%0D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 diff --git a/FRONT/BUILD/resources/app/dist/assets/index-CAnb47c8.js b/FRONT/BUILD/resources/app/dist/assets/index-CAnb47c8.js deleted file mode 100644 index 2ee490f..0000000 --- a/FRONT/BUILD/resources/app/dist/assets/index-CAnb47c8.js +++ /dev/null @@ -1,913 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))i(s);new MutationObserver(s=>{for(const a of s)if(a.type==="childList")for(const u of a.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&i(u)}).observe(document,{childList:!0,subtree:!0});function r(s){const a={};return s.integrity&&(a.integrity=s.integrity),s.referrerPolicy&&(a.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?a.credentials="include":s.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function i(s){if(s.ep)return;s.ep=!0;const a=r(s);fetch(s.href,a)}})();function rt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Wf={exports:{}},ns={},qf={exports:{}},Re={};/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var mm;function KS(){if(mm)return Re;mm=1;var e=Symbol.for("react.element"),t=Symbol.for("react.portal"),r=Symbol.for("react.fragment"),i=Symbol.for("react.strict_mode"),s=Symbol.for("react.profiler"),a=Symbol.for("react.provider"),u=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),d=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),g=Symbol.for("react.lazy"),m=Symbol.iterator;function y(T){return T===null||typeof T!="object"?null:(T=m&&T[m]||T["@@iterator"],typeof T=="function"?T:null)}var v={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,E={};function k(T,H,Z){this.props=T,this.context=H,this.refs=E,this.updater=Z||v}k.prototype.isReactComponent={},k.prototype.setState=function(T,H){if(typeof T!="object"&&typeof T!="function"&&T!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,T,H,"setState")},k.prototype.forceUpdate=function(T){this.updater.enqueueForceUpdate(this,T,"forceUpdate")};function C(){}C.prototype=k.prototype;function R(T,H,Z){this.props=T,this.context=H,this.refs=E,this.updater=Z||v}var N=R.prototype=new C;N.constructor=R,S(N,k.prototype),N.isPureReactComponent=!0;var b=Array.isArray,M=Object.prototype.hasOwnProperty,L={current:null},j={key:!0,ref:!0,__self:!0,__source:!0};function G(T,H,Z){var te,ie={},le=null,de=null;if(H!=null)for(te in H.ref!==void 0&&(de=H.ref),H.key!==void 0&&(le=""+H.key),H)M.call(H,te)&&!j.hasOwnProperty(te)&&(ie[te]=H[te]);var re=arguments.length-2;if(re===1)ie.children=Z;else if(1>>1,H=A[T];if(0>>1;Ts(ie,z))les(de,ie)?(A[T]=de,A[le]=z,T=le):(A[T]=ie,A[te]=z,T=te);else if(les(de,z))A[T]=de,A[le]=z,T=le;else break e}}return O}function s(A,O){var z=A.sortIndex-O.sortIndex;return z!==0?z:A.id-O.id}if(typeof performance=="object"&&typeof performance.now=="function"){var a=performance;e.unstable_now=function(){return a.now()}}else{var u=Date,f=u.now();e.unstable_now=function(){return u.now()-f}}var d=[],h=[],g=1,m=null,y=3,v=!1,S=!1,E=!1,k=typeof setTimeout=="function"?setTimeout:null,C=typeof clearTimeout=="function"?clearTimeout:null,R=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function N(A){for(var O=r(h);O!==null;){if(O.callback===null)i(h);else if(O.startTime<=A)i(h),O.sortIndex=O.expirationTime,t(d,O);else break;O=r(h)}}function b(A){if(E=!1,N(A),!S)if(r(d)!==null)S=!0,F(M);else{var O=r(h);O!==null&&q(b,O.startTime-A)}}function M(A,O){S=!1,E&&(E=!1,C(G),G=-1),v=!0;var z=y;try{for(N(O),m=r(d);m!==null&&(!(m.expirationTime>O)||A&&!ee());){var T=m.callback;if(typeof T=="function"){m.callback=null,y=m.priorityLevel;var H=T(m.expirationTime<=O);O=e.unstable_now(),typeof H=="function"?m.callback=H:m===r(d)&&i(d),N(O)}else i(d);m=r(d)}if(m!==null)var Z=!0;else{var te=r(h);te!==null&&q(b,te.startTime-O),Z=!1}return Z}finally{m=null,y=z,v=!1}}var L=!1,j=null,G=-1,V=5,Y=-1;function ee(){return!(e.unstable_now()-YA||125T?(A.sortIndex=z,t(h,A),r(d)===null&&A===r(h)&&(E?(C(G),G=-1):E=!0,q(b,z-T))):(A.sortIndex=H,t(d,A),S||v||(S=!0,F(M))),A},e.unstable_shouldYield=ee,e.unstable_wrapCallback=function(A){var O=y;return function(){var z=y;y=O;try{return A.apply(this,arguments)}finally{y=z}}}}(Gf)),Gf}var Sm;function eE(){return Sm||(Sm=1,Xf.exports=ZS()),Xf.exports}/** - * @license React - * react-dom.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Em;function tE(){if(Em)return Nt;Em=1;var e=As(),t=eE();function r(n){for(var o="https://reactjs.org/docs/error-decoder.html?invariant="+n,l=1;l"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),d=Object.prototype.hasOwnProperty,h=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,g={},m={};function y(n){return d.call(m,n)?!0:d.call(g,n)?!1:h.test(n)?m[n]=!0:(g[n]=!0,!1)}function v(n,o,l,c){if(l!==null&&l.type===0)return!1;switch(typeof o){case"function":case"symbol":return!0;case"boolean":return c?!1:l!==null?!l.acceptsBooleans:(n=n.toLowerCase().slice(0,5),n!=="data-"&&n!=="aria-");default:return!1}}function S(n,o,l,c){if(o===null||typeof o>"u"||v(n,o,l,c))return!0;if(c)return!1;if(l!==null)switch(l.type){case 3:return!o;case 4:return o===!1;case 5:return isNaN(o);case 6:return isNaN(o)||1>o}return!1}function E(n,o,l,c,p,x,_){this.acceptsBooleans=o===2||o===3||o===4,this.attributeName=c,this.attributeNamespace=p,this.mustUseProperty=l,this.propertyName=n,this.type=o,this.sanitizeURL=x,this.removeEmptyString=_}var k={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(n){k[n]=new E(n,0,!1,n,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(n){var o=n[0];k[o]=new E(o,1,!1,n[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(n){k[n]=new E(n,2,!1,n.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(n){k[n]=new E(n,2,!1,n,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(n){k[n]=new E(n,3,!1,n.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(n){k[n]=new E(n,3,!0,n,null,!1,!1)}),["capture","download"].forEach(function(n){k[n]=new E(n,4,!1,n,null,!1,!1)}),["cols","rows","size","span"].forEach(function(n){k[n]=new E(n,6,!1,n,null,!1,!1)}),["rowSpan","start"].forEach(function(n){k[n]=new E(n,5,!1,n.toLowerCase(),null,!1,!1)});var C=/[\-:]([a-z])/g;function R(n){return n[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(n){var o=n.replace(C,R);k[o]=new E(o,1,!1,n,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(n){var o=n.replace(C,R);k[o]=new E(o,1,!1,n,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(n){var o=n.replace(C,R);k[o]=new E(o,1,!1,n,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(n){k[n]=new E(n,1,!1,n.toLowerCase(),null,!1,!1)}),k.xlinkHref=new E("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(n){k[n]=new E(n,1,!1,n.toLowerCase(),null,!0,!0)});function N(n,o,l,c){var p=k.hasOwnProperty(o)?k[o]:null;(p!==null?p.type!==0:c||!(2$||p[_]!==x[$]){var D=` -`+p[_].replace(" at new "," at ");return n.displayName&&D.includes("")&&(D=D.replace("",n.displayName)),D}while(1<=_&&0<=$);break}}}finally{Z=!1,Error.prepareStackTrace=l}return(n=n?n.displayName||n.name:"")?H(n):""}function ie(n){switch(n.tag){case 5:return H(n.type);case 16:return H("Lazy");case 13:return H("Suspense");case 19:return H("SuspenseList");case 0:case 2:case 15:return n=te(n.type,!1),n;case 11:return n=te(n.type.render,!1),n;case 1:return n=te(n.type,!0),n;default:return""}}function le(n){if(n==null)return null;if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n;switch(n){case j:return"Fragment";case L:return"Portal";case V:return"Profiler";case G:return"StrictMode";case J:return"Suspense";case I:return"SuspenseList"}if(typeof n=="object")switch(n.$$typeof){case ee:return(n.displayName||"Context")+".Consumer";case Y:return(n._context.displayName||"Context")+".Provider";case ne:var o=n.render;return n=n.displayName,n||(n=o.displayName||o.name||"",n=n!==""?"ForwardRef("+n+")":"ForwardRef"),n;case U:return o=n.displayName||null,o!==null?o:le(n.type)||"Memo";case F:o=n._payload,n=n._init;try{return le(n(o))}catch{}}return null}function de(n){var o=n.type;switch(n.tag){case 24:return"Cache";case 9:return(o.displayName||"Context")+".Consumer";case 10:return(o._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return n=o.render,n=n.displayName||n.name||"",o.displayName||(n!==""?"ForwardRef("+n+")":"ForwardRef");case 7:return"Fragment";case 5:return o;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return le(o);case 8:return o===G?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof o=="function")return o.displayName||o.name||null;if(typeof o=="string")return o}return null}function re(n){switch(typeof n){case"boolean":case"number":case"string":case"undefined":return n;case"object":return n;default:return""}}function he(n){var o=n.type;return(n=n.nodeName)&&n.toLowerCase()==="input"&&(o==="checkbox"||o==="radio")}function Se(n){var o=he(n)?"checked":"value",l=Object.getOwnPropertyDescriptor(n.constructor.prototype,o),c=""+n[o];if(!n.hasOwnProperty(o)&&typeof l<"u"&&typeof l.get=="function"&&typeof l.set=="function"){var p=l.get,x=l.set;return Object.defineProperty(n,o,{configurable:!0,get:function(){return p.call(this)},set:function(_){c=""+_,x.call(this,_)}}),Object.defineProperty(n,o,{enumerable:l.enumerable}),{getValue:function(){return c},setValue:function(_){c=""+_},stopTracking:function(){n._valueTracker=null,delete n[o]}}}}function we(n){n._valueTracker||(n._valueTracker=Se(n))}function ge(n){if(!n)return!1;var o=n._valueTracker;if(!o)return!0;var l=o.getValue(),c="";return n&&(c=he(n)?n.checked?"true":"false":n.value),n=c,n!==l?(o.setValue(n),!0):!1}function Pe(n){if(n=n||(typeof document<"u"?document:void 0),typeof n>"u")return null;try{return n.activeElement||n.body}catch{return n.body}}function $e(n,o){var l=o.checked;return z({},o,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:l??n._wrapperState.initialChecked})}function Ke(n,o){var l=o.defaultValue==null?"":o.defaultValue,c=o.checked!=null?o.checked:o.defaultChecked;l=re(o.value!=null?o.value:l),n._wrapperState={initialChecked:c,initialValue:l,controlled:o.type==="checkbox"||o.type==="radio"?o.checked!=null:o.value!=null}}function Xt(n,o){o=o.checked,o!=null&&N(n,"checked",o,!1)}function Cr(n,o){Xt(n,o);var l=re(o.value),c=o.type;if(l!=null)c==="number"?(l===0&&n.value===""||n.value!=l)&&(n.value=""+l):n.value!==""+l&&(n.value=""+l);else if(c==="submit"||c==="reset"){n.removeAttribute("value");return}o.hasOwnProperty("value")?_r(n,o.type,l):o.hasOwnProperty("defaultValue")&&_r(n,o.type,re(o.defaultValue)),o.checked==null&&o.defaultChecked!=null&&(n.defaultChecked=!!o.defaultChecked)}function lo(n,o,l){if(o.hasOwnProperty("value")||o.hasOwnProperty("defaultValue")){var c=o.type;if(!(c!=="submit"&&c!=="reset"||o.value!==void 0&&o.value!==null))return;o=""+n._wrapperState.initialValue,l||o===n.value||(n.value=o),n.defaultValue=o}l=n.name,l!==""&&(n.name=""),n.defaultChecked=!!n._wrapperState.initialChecked,l!==""&&(n.name=l)}function _r(n,o,l){(o!=="number"||Pe(n.ownerDocument)!==n)&&(l==null?n.defaultValue=""+n._wrapperState.initialValue:n.defaultValue!==""+l&&(n.defaultValue=""+l))}var Gt=Array.isArray;function fn(n,o,l,c){if(n=n.options,o){o={};for(var p=0;p"+o.valueOf().toString()+"",o=uo.firstChild;n.firstChild;)n.removeChild(n.firstChild);for(;o.firstChild;)n.appendChild(o.firstChild)}});function Nr(n,o){if(o){var l=n.firstChild;if(l&&l===n.lastChild&&l.nodeType===3){l.nodeValue=o;return}}n.textContent=o}var br={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Ju=["Webkit","ms","Moz","O"];Object.keys(br).forEach(function(n){Ju.forEach(function(o){o=o+n.charAt(0).toUpperCase()+n.substring(1),br[o]=br[n]})});function qs(n,o,l){return o==null||typeof o=="boolean"||o===""?"":l||typeof o!="number"||o===0||br.hasOwnProperty(n)&&br[n]?(""+o).trim():o+"px"}function Ys(n,o){n=n.style;for(var l in o)if(o.hasOwnProperty(l)){var c=l.indexOf("--")===0,p=qs(l,o[l],c);l==="float"&&(l="cssFloat"),c?n.setProperty(l,p):n[l]=p}}var Zu=z({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function hi(n,o){if(o){if(Zu[n]&&(o.children!=null||o.dangerouslySetInnerHTML!=null))throw Error(r(137,n));if(o.dangerouslySetInnerHTML!=null){if(o.children!=null)throw Error(r(60));if(typeof o.dangerouslySetInnerHTML!="object"||!("__html"in o.dangerouslySetInnerHTML))throw Error(r(61))}if(o.style!=null&&typeof o.style!="object")throw Error(r(62))}}function pi(n,o){if(n.indexOf("-")===-1)return typeof o.is=="string";switch(n){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var gi=null;function mi(n){return n=n.target||n.srcElement||window,n.correspondingUseElement&&(n=n.correspondingUseElement),n.nodeType===3?n.parentNode:n}var yi=null,Gn=null,Kn=null;function Xs(n){if(n=Bi(n)){if(typeof yi!="function")throw Error(r(280));var o=n.stateNode;o&&(o=kl(o),yi(n.stateNode,n.type,o))}}function xi(n){Gn?Kn?Kn.push(n):Kn=[n]:Gn=n}function Gs(){if(Gn){var n=Gn,o=Kn;if(Kn=Gn=null,Xs(n),o)for(n=0;n>>=0,n===0?32:31-(ac(n)/uc|0)|0}var mo=64,yo=4194304;function kn(n){switch(n&-n){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return n&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return n}}function xo(n,o){var l=n.pendingLanes;if(l===0)return 0;var c=0,p=n.suspendedLanes,x=n.pingedLanes,_=l&268435455;if(_!==0){var $=_&~p;$!==0?c=kn($):(x&=_,x!==0&&(c=kn(x)))}else _=l&~p,_!==0?c=kn(_):x!==0&&(c=kn(x));if(c===0)return 0;if(o!==0&&o!==c&&(o&p)===0&&(p=c&-c,x=o&-o,p>=x||p===16&&(x&4194240)!==0))return o;if((c&4)!==0&&(c|=l&16),o=n.entangledLanes,o!==0)for(n=n.entanglements,o&=c;0l;l++)o.push(n);return o}function Ci(n,o,l){n.pendingLanes|=o,o!==536870912&&(n.suspendedLanes=0,n.pingedLanes=0),n=n.eventTimes,o=31-Tt(o),n[o]=l}function yw(n,o){var l=n.pendingLanes&~o;n.pendingLanes=o,n.suspendedLanes=0,n.pingedLanes=0,n.expiredLanes&=o,n.mutableReadLanes&=o,n.entangledLanes&=o,o=n.entanglements;var c=n.eventTimes;for(n=n.expirationTimes;0=ji),up=" ",cp=!1;function fp(n,o){switch(n){case"keyup":return Ww.indexOf(o.keyCode)!==-1;case"keydown":return o.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function dp(n){return n=n.detail,typeof n=="object"&&"data"in n?n.data:null}var So=!1;function Yw(n,o){switch(n){case"compositionend":return dp(o);case"keypress":return o.which!==32?null:(cp=!0,up);case"textInput":return n=o.data,n===up&&cp?null:n;default:return null}}function Xw(n,o){if(So)return n==="compositionend"||!Cc&&fp(n,o)?(n=rp(),dl=xc=tr=null,So=!1,n):null;switch(n){case"paste":return null;case"keypress":if(!(o.ctrlKey||o.altKey||o.metaKey)||o.ctrlKey&&o.altKey){if(o.char&&1=o)return{node:l,offset:o-n};n=c}e:{for(;l;){if(l.nextSibling){l=l.nextSibling;break e}l=l.parentNode}l=void 0}l=vp(l)}}function Sp(n,o){return n&&o?n===o?!0:n&&n.nodeType===3?!1:o&&o.nodeType===3?Sp(n,o.parentNode):"contains"in n?n.contains(o):n.compareDocumentPosition?!!(n.compareDocumentPosition(o)&16):!1:!1}function Ep(){for(var n=window,o=Pe();o instanceof n.HTMLIFrameElement;){try{var l=typeof o.contentWindow.location.href=="string"}catch{l=!1}if(l)n=o.contentWindow;else break;o=Pe(n.document)}return o}function bc(n){var o=n&&n.nodeName&&n.nodeName.toLowerCase();return o&&(o==="input"&&(n.type==="text"||n.type==="search"||n.type==="tel"||n.type==="url"||n.type==="password")||o==="textarea"||n.contentEditable==="true")}function rS(n){var o=Ep(),l=n.focusedElem,c=n.selectionRange;if(o!==l&&l&&l.ownerDocument&&Sp(l.ownerDocument.documentElement,l)){if(c!==null&&bc(l)){if(o=c.start,n=c.end,n===void 0&&(n=o),"selectionStart"in l)l.selectionStart=o,l.selectionEnd=Math.min(n,l.value.length);else if(n=(o=l.ownerDocument||document)&&o.defaultView||window,n.getSelection){n=n.getSelection();var p=l.textContent.length,x=Math.min(c.start,p);c=c.end===void 0?x:Math.min(c.end,p),!n.extend&&x>c&&(p=c,c=x,x=p),p=wp(l,x);var _=wp(l,c);p&&_&&(n.rangeCount!==1||n.anchorNode!==p.node||n.anchorOffset!==p.offset||n.focusNode!==_.node||n.focusOffset!==_.offset)&&(o=o.createRange(),o.setStart(p.node,p.offset),n.removeAllRanges(),x>c?(n.addRange(o),n.extend(_.node,_.offset)):(o.setEnd(_.node,_.offset),n.addRange(o)))}}for(o=[],n=l;n=n.parentNode;)n.nodeType===1&&o.push({element:n,left:n.scrollLeft,top:n.scrollTop});for(typeof l.focus=="function"&&l.focus(),l=0;l=document.documentMode,Eo=null,Pc=null,Li=null,Rc=!1;function kp(n,o,l){var c=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;Rc||Eo==null||Eo!==Pe(c)||(c=Eo,"selectionStart"in c&&bc(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}),Li&&Mi(Li,c)||(Li=c,c=wl(Pc,"onSelect"),0bo||(n.current=Bc[bo],Bc[bo]=null,bo--)}function De(n,o){bo++,Bc[bo]=n.current,n.current=o}var ir={},dt=or(ir),St=or(!1),jr=ir;function Po(n,o){var l=n.type.contextTypes;if(!l)return ir;var c=n.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===o)return c.__reactInternalMemoizedMaskedChildContext;var p={},x;for(x in l)p[x]=o[x];return c&&(n=n.stateNode,n.__reactInternalMemoizedUnmaskedChildContext=o,n.__reactInternalMemoizedMaskedChildContext=p),p}function Et(n){return n=n.childContextTypes,n!=null}function Cl(){ze(St),ze(dt)}function Op(n,o,l){if(dt.current!==ir)throw Error(r(168));De(dt,o),De(St,l)}function zp(n,o,l){var c=n.stateNode;if(o=o.childContextTypes,typeof c.getChildContext!="function")return l;c=c.getChildContext();for(var p in c)if(!(p in o))throw Error(r(108,de(n)||"Unknown",p));return z({},l,c)}function _l(n){return n=(n=n.stateNode)&&n.__reactInternalMemoizedMergedChildContext||ir,jr=dt.current,De(dt,n),De(St,St.current),!0}function Fp(n,o,l){var c=n.stateNode;if(!c)throw Error(r(169));l?(n=zp(n,o,jr),c.__reactInternalMemoizedMergedChildContext=n,ze(St),ze(dt),De(dt,n)):ze(St),De(St,l)}var _n=null,Nl=!1,Hc=!1;function Bp(n){_n===null?_n=[n]:_n.push(n)}function gS(n){Nl=!0,Bp(n)}function sr(){if(!Hc&&_n!==null){Hc=!0;var n=0,o=Me;try{var l=_n;for(Me=1;n>=_,p-=_,Nn=1<<32-Tt(o)+p|l<Ce?(st=ke,ke=null):st=ke.sibling;var je=se(W,ke,X[Ce],fe);if(je===null){ke===null&&(ke=st);break}n&&ke&&je.alternate===null&&o(W,ke),B=x(je,B,Ce),Ee===null?ve=je:Ee.sibling=je,Ee=je,ke=st}if(Ce===X.length)return l(W,ke),Be&&Ar(W,Ce),ve;if(ke===null){for(;CeCe?(st=ke,ke=null):st=ke.sibling;var gr=se(W,ke,je.value,fe);if(gr===null){ke===null&&(ke=st);break}n&&ke&&gr.alternate===null&&o(W,ke),B=x(gr,B,Ce),Ee===null?ve=gr:Ee.sibling=gr,Ee=gr,ke=st}if(je.done)return l(W,ke),Be&&Ar(W,Ce),ve;if(ke===null){for(;!je.done;Ce++,je=X.next())je=ue(W,je.value,fe),je!==null&&(B=x(je,B,Ce),Ee===null?ve=je:Ee.sibling=je,Ee=je);return Be&&Ar(W,Ce),ve}for(ke=c(W,ke);!je.done;Ce++,je=X.next())je=pe(ke,W,Ce,je.value,fe),je!==null&&(n&&je.alternate!==null&&ke.delete(je.key===null?Ce:je.key),B=x(je,B,Ce),Ee===null?ve=je:Ee.sibling=je,Ee=je);return n&&ke.forEach(function(GS){return o(W,GS)}),Be&&Ar(W,Ce),ve}function Qe(W,B,X,fe){if(typeof X=="object"&&X!==null&&X.type===j&&X.key===null&&(X=X.props.children),typeof X=="object"&&X!==null){switch(X.$$typeof){case M:e:{for(var ve=X.key,Ee=B;Ee!==null;){if(Ee.key===ve){if(ve=X.type,ve===j){if(Ee.tag===7){l(W,Ee.sibling),B=p(Ee,X.props.children),B.return=W,W=B;break e}}else if(Ee.elementType===ve||typeof ve=="object"&&ve!==null&&ve.$$typeof===F&&Yp(ve)===Ee.type){l(W,Ee.sibling),B=p(Ee,X.props),B.ref=Hi(W,Ee,X),B.return=W,W=B;break e}l(W,Ee);break}else o(W,Ee);Ee=Ee.sibling}X.type===j?(B=Hr(X.props.children,W.mode,fe,X.key),B.return=W,W=B):(fe=ea(X.type,X.key,X.props,null,W.mode,fe),fe.ref=Hi(W,B,X),fe.return=W,W=fe)}return _(W);case L:e:{for(Ee=X.key;B!==null;){if(B.key===Ee)if(B.tag===4&&B.stateNode.containerInfo===X.containerInfo&&B.stateNode.implementation===X.implementation){l(W,B.sibling),B=p(B,X.children||[]),B.return=W,W=B;break e}else{l(W,B);break}else o(W,B);B=B.sibling}B=Ff(X,W.mode,fe),B.return=W,W=B}return _(W);case F:return Ee=X._init,Qe(W,B,Ee(X._payload),fe)}if(Gt(X))return ye(W,B,X,fe);if(O(X))return xe(W,B,X,fe);Tl(W,X)}return typeof X=="string"&&X!==""||typeof X=="number"?(X=""+X,B!==null&&B.tag===6?(l(W,B.sibling),B=p(B,X),B.return=W,W=B):(l(W,B),B=zf(X,W.mode,fe),B.return=W,W=B),_(W)):l(W,B)}return Qe}var jo=Xp(!0),Gp=Xp(!1),Il=or(null),jl=null,$o=null,Xc=null;function Gc(){Xc=$o=jl=null}function Kc(n){var o=Il.current;ze(Il),n._currentValue=o}function Qc(n,o,l){for(;n!==null;){var c=n.alternate;if((n.childLanes&o)!==o?(n.childLanes|=o,c!==null&&(c.childLanes|=o)):c!==null&&(c.childLanes&o)!==o&&(c.childLanes|=o),n===l)break;n=n.return}}function Ao(n,o){jl=n,Xc=$o=null,n=n.dependencies,n!==null&&n.firstContext!==null&&((n.lanes&o)!==0&&(kt=!0),n.firstContext=null)}function Vt(n){var o=n._currentValue;if(Xc!==n)if(n={context:n,memoizedValue:o,next:null},$o===null){if(jl===null)throw Error(r(308));$o=n,jl.dependencies={lanes:0,firstContext:n}}else $o=$o.next=n;return o}var Mr=null;function Jc(n){Mr===null?Mr=[n]:Mr.push(n)}function Kp(n,o,l,c){var p=o.interleaved;return p===null?(l.next=l,Jc(o)):(l.next=p.next,p.next=l),o.interleaved=l,Pn(n,c)}function Pn(n,o){n.lanes|=o;var l=n.alternate;for(l!==null&&(l.lanes|=o),l=n,n=n.return;n!==null;)n.childLanes|=o,l=n.alternate,l!==null&&(l.childLanes|=o),l=n,n=n.return;return l.tag===3?l.stateNode:null}var lr=!1;function Zc(n){n.updateQueue={baseState:n.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Qp(n,o){n=n.updateQueue,o.updateQueue===n&&(o.updateQueue={baseState:n.baseState,firstBaseUpdate:n.firstBaseUpdate,lastBaseUpdate:n.lastBaseUpdate,shared:n.shared,effects:n.effects})}function Rn(n,o){return{eventTime:n,lane:o,tag:0,payload:null,callback:null,next:null}}function ar(n,o,l){var c=n.updateQueue;if(c===null)return null;if(c=c.shared,(Te&2)!==0){var p=c.pending;return p===null?o.next=o:(o.next=p.next,p.next=o),c.pending=o,Pn(n,l)}return p=c.interleaved,p===null?(o.next=o,Jc(c)):(o.next=p.next,p.next=o),c.interleaved=o,Pn(n,l)}function $l(n,o,l){if(o=o.updateQueue,o!==null&&(o=o.shared,(l&4194240)!==0)){var c=o.lanes;c&=n.pendingLanes,l|=c,o.lanes=l,hc(n,l)}}function Jp(n,o){var l=n.updateQueue,c=n.alternate;if(c!==null&&(c=c.updateQueue,l===c)){var p=null,x=null;if(l=l.firstBaseUpdate,l!==null){do{var _={eventTime:l.eventTime,lane:l.lane,tag:l.tag,payload:l.payload,callback:l.callback,next:null};x===null?p=x=_:x=x.next=_,l=l.next}while(l!==null);x===null?p=x=o:x=x.next=o}else p=x=o;l={baseState:c.baseState,firstBaseUpdate:p,lastBaseUpdate:x,shared:c.shared,effects:c.effects},n.updateQueue=l;return}n=l.lastBaseUpdate,n===null?l.firstBaseUpdate=o:n.next=o,l.lastBaseUpdate=o}function Al(n,o,l,c){var p=n.updateQueue;lr=!1;var x=p.firstBaseUpdate,_=p.lastBaseUpdate,$=p.shared.pending;if($!==null){p.shared.pending=null;var D=$,K=D.next;D.next=null,_===null?x=K:_.next=K,_=D;var ae=n.alternate;ae!==null&&(ae=ae.updateQueue,$=ae.lastBaseUpdate,$!==_&&($===null?ae.firstBaseUpdate=K:$.next=K,ae.lastBaseUpdate=D))}if(x!==null){var ue=p.baseState;_=0,ae=K=D=null,$=x;do{var se=$.lane,pe=$.eventTime;if((c&se)===se){ae!==null&&(ae=ae.next={eventTime:pe,lane:0,tag:$.tag,payload:$.payload,callback:$.callback,next:null});e:{var ye=n,xe=$;switch(se=o,pe=l,xe.tag){case 1:if(ye=xe.payload,typeof ye=="function"){ue=ye.call(pe,ue,se);break e}ue=ye;break e;case 3:ye.flags=ye.flags&-65537|128;case 0:if(ye=xe.payload,se=typeof ye=="function"?ye.call(pe,ue,se):ye,se==null)break e;ue=z({},ue,se);break e;case 2:lr=!0}}$.callback!==null&&$.lane!==0&&(n.flags|=64,se=p.effects,se===null?p.effects=[$]:se.push($))}else pe={eventTime:pe,lane:se,tag:$.tag,payload:$.payload,callback:$.callback,next:null},ae===null?(K=ae=pe,D=ue):ae=ae.next=pe,_|=se;if($=$.next,$===null){if($=p.shared.pending,$===null)break;se=$,$=se.next,se.next=null,p.lastBaseUpdate=se,p.shared.pending=null}}while(!0);if(ae===null&&(D=ue),p.baseState=D,p.firstBaseUpdate=K,p.lastBaseUpdate=ae,o=p.shared.interleaved,o!==null){p=o;do _|=p.lane,p=p.next;while(p!==o)}else x===null&&(p.shared.lanes=0);Or|=_,n.lanes=_,n.memoizedState=ue}}function Zp(n,o,l){if(n=o.effects,o.effects=null,n!==null)for(o=0;ol?l:4,n(!0);var c=of.transition;of.transition={};try{n(!1),o()}finally{Me=l,of.transition=c}}function xg(){return Ut().memoizedState}function vS(n,o,l){var c=dr(n);if(l={lane:c,action:l,hasEagerState:!1,eagerState:null,next:null},vg(n))wg(o,l);else if(l=Kp(n,o,l,c),l!==null){var p=vt();tn(l,n,c,p),Sg(l,o,c)}}function wS(n,o,l){var c=dr(n),p={lane:c,action:l,hasEagerState:!1,eagerState:null,next:null};if(vg(n))wg(o,p);else{var x=n.alternate;if(n.lanes===0&&(x===null||x.lanes===0)&&(x=o.lastRenderedReducer,x!==null))try{var _=o.lastRenderedState,$=x(_,l);if(p.hasEagerState=!0,p.eagerState=$,Kt($,_)){var D=o.interleaved;D===null?(p.next=p,Jc(o)):(p.next=D.next,D.next=p),o.interleaved=p;return}}catch{}finally{}l=Kp(n,o,p,c),l!==null&&(p=vt(),tn(l,n,c,p),Sg(l,o,c))}}function vg(n){var o=n.alternate;return n===We||o!==null&&o===We}function wg(n,o){qi=Dl=!0;var l=n.pending;l===null?o.next=o:(o.next=l.next,l.next=o),n.pending=o}function Sg(n,o,l){if((l&4194240)!==0){var c=o.lanes;c&=n.pendingLanes,l|=c,o.lanes=l,hc(n,l)}}var Fl={readContext:Vt,useCallback:ht,useContext:ht,useEffect:ht,useImperativeHandle:ht,useInsertionEffect:ht,useLayoutEffect:ht,useMemo:ht,useReducer:ht,useRef:ht,useState:ht,useDebugValue:ht,useDeferredValue:ht,useTransition:ht,useMutableSource:ht,useSyncExternalStore:ht,useId:ht,unstable_isNewReconciler:!1},SS={readContext:Vt,useCallback:function(n,o){return gn().memoizedState=[n,o===void 0?null:o],n},useContext:Vt,useEffect:cg,useImperativeHandle:function(n,o,l){return l=l!=null?l.concat([n]):null,Ol(4194308,4,hg.bind(null,o,n),l)},useLayoutEffect:function(n,o){return Ol(4194308,4,n,o)},useInsertionEffect:function(n,o){return Ol(4,2,n,o)},useMemo:function(n,o){var l=gn();return o=o===void 0?null:o,n=n(),l.memoizedState=[n,o],n},useReducer:function(n,o,l){var c=gn();return o=l!==void 0?l(o):o,c.memoizedState=c.baseState=o,n={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:n,lastRenderedState:o},c.queue=n,n=n.dispatch=vS.bind(null,We,n),[c.memoizedState,n]},useRef:function(n){var o=gn();return n={current:n},o.memoizedState=n},useState:ag,useDebugValue:df,useDeferredValue:function(n){return gn().memoizedState=n},useTransition:function(){var n=ag(!1),o=n[0];return n=xS.bind(null,n[1]),gn().memoizedState=n,[o,n]},useMutableSource:function(){},useSyncExternalStore:function(n,o,l){var c=We,p=gn();if(Be){if(l===void 0)throw Error(r(407));l=l()}else{if(l=o(),it===null)throw Error(r(349));(Dr&30)!==0||rg(c,o,l)}p.memoizedState=l;var x={value:l,getSnapshot:o};return p.queue=x,cg(ig.bind(null,c,x,n),[n]),c.flags|=2048,Gi(9,og.bind(null,c,x,l,o),void 0,null),l},useId:function(){var n=gn(),o=it.identifierPrefix;if(Be){var l=bn,c=Nn;l=(c&~(1<<32-Tt(c)-1)).toString(32)+l,o=":"+o+"R"+l,l=Yi++,0<\/script>",n=n.removeChild(n.firstChild)):typeof c.is=="string"?n=_.createElement(l,{is:c.is}):(n=_.createElement(l),l==="select"&&(_=n,c.multiple?_.multiple=!0:c.size&&(_.size=c.size))):n=_.createElementNS(n,l),n[hn]=o,n[Fi]=c,Bg(n,o,!1,!1),o.stateNode=n;e:{switch(_=pi(l,c),l){case"dialog":Oe("cancel",n),Oe("close",n),p=c;break;case"iframe":case"object":case"embed":Oe("load",n),p=c;break;case"video":case"audio":for(p=0;pzo&&(o.flags|=128,c=!0,Ki(x,!1),o.lanes=4194304)}else{if(!c)if(n=Ml(_),n!==null){if(o.flags|=128,c=!0,l=n.updateQueue,l!==null&&(o.updateQueue=l,o.flags|=4),Ki(x,!0),x.tail===null&&x.tailMode==="hidden"&&!_.alternate&&!Be)return pt(o),null}else 2*Ve()-x.renderingStartTime>zo&&l!==1073741824&&(o.flags|=128,c=!0,Ki(x,!1),o.lanes=4194304);x.isBackwards?(_.sibling=o.child,o.child=_):(l=x.last,l!==null?l.sibling=_:o.child=_,x.last=_)}return x.tail!==null?(o=x.tail,x.rendering=o,x.tail=o.sibling,x.renderingStartTime=Ve(),o.sibling=null,l=Ue.current,De(Ue,c?l&1|2:l&1),o):(pt(o),null);case 22:case 23:return Lf(),c=o.memoizedState!==null,n!==null&&n.memoizedState!==null!==c&&(o.flags|=8192),c&&(o.mode&1)!==0?(At&1073741824)!==0&&(pt(o),o.subtreeFlags&6&&(o.flags|=8192)):pt(o),null;case 24:return null;case 25:return null}throw Error(r(156,o.tag))}function RS(n,o){switch(Uc(o),o.tag){case 1:return Et(o.type)&&Cl(),n=o.flags,n&65536?(o.flags=n&-65537|128,o):null;case 3:return Mo(),ze(St),ze(dt),rf(),n=o.flags,(n&65536)!==0&&(n&128)===0?(o.flags=n&-65537|128,o):null;case 5:return tf(o),null;case 13:if(ze(Ue),n=o.memoizedState,n!==null&&n.dehydrated!==null){if(o.alternate===null)throw Error(r(340));Io()}return n=o.flags,n&65536?(o.flags=n&-65537|128,o):null;case 19:return ze(Ue),null;case 4:return Mo(),null;case 10:return Kc(o.type._context),null;case 22:case 23:return Lf(),null;case 24:return null;default:return null}}var Ul=!1,gt=!1,TS=typeof WeakSet=="function"?WeakSet:Set,me=null;function Do(n,o){var l=n.ref;if(l!==null)if(typeof l=="function")try{l(null)}catch(c){Ye(n,o,c)}else l.current=null}function Cf(n,o,l){try{l()}catch(c){Ye(n,o,c)}}var Ug=!1;function IS(n,o){if(Mc=cl,n=Ep(),bc(n)){if("selectionStart"in n)var l={start:n.selectionStart,end:n.selectionEnd};else e:{l=(l=n.ownerDocument)&&l.defaultView||window;var c=l.getSelection&&l.getSelection();if(c&&c.rangeCount!==0){l=c.anchorNode;var p=c.anchorOffset,x=c.focusNode;c=c.focusOffset;try{l.nodeType,x.nodeType}catch{l=null;break e}var _=0,$=-1,D=-1,K=0,ae=0,ue=n,se=null;t:for(;;){for(var pe;ue!==l||p!==0&&ue.nodeType!==3||($=_+p),ue!==x||c!==0&&ue.nodeType!==3||(D=_+c),ue.nodeType===3&&(_+=ue.nodeValue.length),(pe=ue.firstChild)!==null;)se=ue,ue=pe;for(;;){if(ue===n)break t;if(se===l&&++K===p&&($=_),se===x&&++ae===c&&(D=_),(pe=ue.nextSibling)!==null)break;ue=se,se=ue.parentNode}ue=pe}l=$===-1||D===-1?null:{start:$,end:D}}else l=null}l=l||{start:0,end:0}}else l=null;for(Lc={focusedElem:n,selectionRange:l},cl=!1,me=o;me!==null;)if(o=me,n=o.child,(o.subtreeFlags&1028)!==0&&n!==null)n.return=o,me=n;else for(;me!==null;){o=me;try{var ye=o.alternate;if((o.flags&1024)!==0)switch(o.tag){case 0:case 11:case 15:break;case 1:if(ye!==null){var xe=ye.memoizedProps,Qe=ye.memoizedState,W=o.stateNode,B=W.getSnapshotBeforeUpdate(o.elementType===o.type?xe:Jt(o.type,xe),Qe);W.__reactInternalSnapshotBeforeUpdate=B}break;case 3:var X=o.stateNode.containerInfo;X.nodeType===1?X.textContent="":X.nodeType===9&&X.documentElement&&X.removeChild(X.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(r(163))}}catch(fe){Ye(o,o.return,fe)}if(n=o.sibling,n!==null){n.return=o.return,me=n;break}me=o.return}return ye=Ug,Ug=!1,ye}function Qi(n,o,l){var c=o.updateQueue;if(c=c!==null?c.lastEffect:null,c!==null){var p=c=c.next;do{if((p.tag&n)===n){var x=p.destroy;p.destroy=void 0,x!==void 0&&Cf(o,l,x)}p=p.next}while(p!==c)}}function Wl(n,o){if(o=o.updateQueue,o=o!==null?o.lastEffect:null,o!==null){var l=o=o.next;do{if((l.tag&n)===n){var c=l.create;l.destroy=c()}l=l.next}while(l!==o)}}function _f(n){var o=n.ref;if(o!==null){var l=n.stateNode;switch(n.tag){case 5:n=l;break;default:n=l}typeof o=="function"?o(n):o.current=n}}function Wg(n){var o=n.alternate;o!==null&&(n.alternate=null,Wg(o)),n.child=null,n.deletions=null,n.sibling=null,n.tag===5&&(o=n.stateNode,o!==null&&(delete o[hn],delete o[Fi],delete o[Fc],delete o[hS],delete o[pS])),n.stateNode=null,n.return=null,n.dependencies=null,n.memoizedProps=null,n.memoizedState=null,n.pendingProps=null,n.stateNode=null,n.updateQueue=null}function qg(n){return n.tag===5||n.tag===3||n.tag===4}function Yg(n){e:for(;;){for(;n.sibling===null;){if(n.return===null||qg(n.return))return null;n=n.return}for(n.sibling.return=n.return,n=n.sibling;n.tag!==5&&n.tag!==6&&n.tag!==18;){if(n.flags&2||n.child===null||n.tag===4)continue e;n.child.return=n,n=n.child}if(!(n.flags&2))return n.stateNode}}function Nf(n,o,l){var c=n.tag;if(c===5||c===6)n=n.stateNode,o?l.nodeType===8?l.parentNode.insertBefore(n,o):l.insertBefore(n,o):(l.nodeType===8?(o=l.parentNode,o.insertBefore(n,l)):(o=l,o.appendChild(n)),l=l._reactRootContainer,l!=null||o.onclick!==null||(o.onclick=El));else if(c!==4&&(n=n.child,n!==null))for(Nf(n,o,l),n=n.sibling;n!==null;)Nf(n,o,l),n=n.sibling}function bf(n,o,l){var c=n.tag;if(c===5||c===6)n=n.stateNode,o?l.insertBefore(n,o):l.appendChild(n);else if(c!==4&&(n=n.child,n!==null))for(bf(n,o,l),n=n.sibling;n!==null;)bf(n,o,l),n=n.sibling}var ct=null,Zt=!1;function ur(n,o,l){for(l=l.child;l!==null;)Xg(n,o,l),l=l.sibling}function Xg(n,o,l){if(Ft&&typeof Ft.onCommitFiberUnmount=="function")try{Ft.onCommitFiberUnmount(go,l)}catch{}switch(l.tag){case 5:gt||Do(l,o);case 6:var c=ct,p=Zt;ct=null,ur(n,o,l),ct=c,Zt=p,ct!==null&&(Zt?(n=ct,l=l.stateNode,n.nodeType===8?n.parentNode.removeChild(l):n.removeChild(l)):ct.removeChild(l.stateNode));break;case 18:ct!==null&&(Zt?(n=ct,l=l.stateNode,n.nodeType===8?zc(n.parentNode,l):n.nodeType===1&&zc(n,l),Ri(n)):zc(ct,l.stateNode));break;case 4:c=ct,p=Zt,ct=l.stateNode.containerInfo,Zt=!0,ur(n,o,l),ct=c,Zt=p;break;case 0:case 11:case 14:case 15:if(!gt&&(c=l.updateQueue,c!==null&&(c=c.lastEffect,c!==null))){p=c=c.next;do{var x=p,_=x.destroy;x=x.tag,_!==void 0&&((x&2)!==0||(x&4)!==0)&&Cf(l,o,_),p=p.next}while(p!==c)}ur(n,o,l);break;case 1:if(!gt&&(Do(l,o),c=l.stateNode,typeof c.componentWillUnmount=="function"))try{c.props=l.memoizedProps,c.state=l.memoizedState,c.componentWillUnmount()}catch($){Ye(l,o,$)}ur(n,o,l);break;case 21:ur(n,o,l);break;case 22:l.mode&1?(gt=(c=gt)||l.memoizedState!==null,ur(n,o,l),gt=c):ur(n,o,l);break;default:ur(n,o,l)}}function Gg(n){var o=n.updateQueue;if(o!==null){n.updateQueue=null;var l=n.stateNode;l===null&&(l=n.stateNode=new TS),o.forEach(function(c){var p=FS.bind(null,n,c);l.has(c)||(l.add(c),c.then(p,p))})}}function en(n,o){var l=o.deletions;if(l!==null)for(var c=0;cp&&(p=_),c&=~x}if(c=p,c=Ve()-c,c=(120>c?120:480>c?480:1080>c?1080:1920>c?1920:3e3>c?3e3:4320>c?4320:1960*$S(c/1960))-c,10n?16:n,fr===null)var c=!1;else{if(n=fr,fr=null,Kl=0,(Te&6)!==0)throw Error(r(331));var p=Te;for(Te|=4,me=n.current;me!==null;){var x=me,_=x.child;if((me.flags&16)!==0){var $=x.deletions;if($!==null){for(var D=0;D<$.length;D++){var K=$[D];for(me=K;me!==null;){var ae=me;switch(ae.tag){case 0:case 11:case 15:Qi(8,ae,x)}var ue=ae.child;if(ue!==null)ue.return=ae,me=ue;else for(;me!==null;){ae=me;var se=ae.sibling,pe=ae.return;if(Wg(ae),ae===K){me=null;break}if(se!==null){se.return=pe,me=se;break}me=pe}}}var ye=x.alternate;if(ye!==null){var xe=ye.child;if(xe!==null){ye.child=null;do{var Qe=xe.sibling;xe.sibling=null,xe=Qe}while(xe!==null)}}me=x}}if((x.subtreeFlags&2064)!==0&&_!==null)_.return=x,me=_;else e:for(;me!==null;){if(x=me,(x.flags&2048)!==0)switch(x.tag){case 0:case 11:case 15:Qi(9,x,x.return)}var W=x.sibling;if(W!==null){W.return=x.return,me=W;break e}me=x.return}}var B=n.current;for(me=B;me!==null;){_=me;var X=_.child;if((_.subtreeFlags&2064)!==0&&X!==null)X.return=_,me=X;else e:for(_=B;me!==null;){if($=me,($.flags&2048)!==0)try{switch($.tag){case 0:case 11:case 15:Wl(9,$)}}catch(ve){Ye($,$.return,ve)}if($===_){me=null;break e}var fe=$.sibling;if(fe!==null){fe.return=$.return,me=fe;break e}me=$.return}}if(Te=p,sr(),Ft&&typeof Ft.onPostCommitFiberRoot=="function")try{Ft.onPostCommitFiberRoot(go,n)}catch{}c=!0}return c}finally{Me=l,Wt.transition=o}}return!1}function lm(n,o,l){o=Lo(l,o),o=_g(n,o,1),n=ar(n,o,1),o=vt(),n!==null&&(Ci(n,1,o),_t(n,o))}function Ye(n,o,l){if(n.tag===3)lm(n,n,l);else for(;o!==null;){if(o.tag===3){lm(o,n,l);break}else if(o.tag===1){var c=o.stateNode;if(typeof o.type.getDerivedStateFromError=="function"||typeof c.componentDidCatch=="function"&&(cr===null||!cr.has(c))){n=Lo(l,n),n=Ng(o,n,1),o=ar(o,n,1),n=vt(),o!==null&&(Ci(o,1,n),_t(o,n));break}}o=o.return}}function OS(n,o,l){var c=n.pingCache;c!==null&&c.delete(o),o=vt(),n.pingedLanes|=n.suspendedLanes&l,it===n&&(ft&l)===l&&(nt===4||nt===3&&(ft&130023424)===ft&&500>Ve()-Tf?Fr(n,0):Rf|=l),_t(n,o)}function am(n,o){o===0&&((n.mode&1)===0?o=1:(o=yo,yo<<=1,(yo&130023424)===0&&(yo=4194304)));var l=vt();n=Pn(n,o),n!==null&&(Ci(n,o,l),_t(n,l))}function zS(n){var o=n.memoizedState,l=0;o!==null&&(l=o.retryLane),am(n,l)}function FS(n,o){var l=0;switch(n.tag){case 13:var c=n.stateNode,p=n.memoizedState;p!==null&&(l=p.retryLane);break;case 19:c=n.stateNode;break;default:throw Error(r(314))}c!==null&&c.delete(o),am(n,l)}var um;um=function(n,o,l){if(n!==null)if(n.memoizedProps!==o.pendingProps||St.current)kt=!0;else{if((n.lanes&l)===0&&(o.flags&128)===0)return kt=!1,bS(n,o,l);kt=(n.flags&131072)!==0}else kt=!1,Be&&(o.flags&1048576)!==0&&Hp(o,Pl,o.index);switch(o.lanes=0,o.tag){case 2:var c=o.type;Vl(n,o),n=o.pendingProps;var p=Po(o,dt.current);Ao(o,l),p=lf(null,o,c,n,p,l);var x=af();return o.flags|=1,typeof p=="object"&&p!==null&&typeof p.render=="function"&&p.$$typeof===void 0?(o.tag=1,o.memoizedState=null,o.updateQueue=null,Et(c)?(x=!0,_l(o)):x=!1,o.memoizedState=p.state!==null&&p.state!==void 0?p.state:null,Zc(o),p.updater=Bl,o.stateNode=p,p._reactInternals=o,pf(o,c,n,l),o=xf(null,o,c,!0,x,l)):(o.tag=0,Be&&x&&Vc(o),xt(null,o,p,l),o=o.child),o;case 16:c=o.elementType;e:{switch(Vl(n,o),n=o.pendingProps,p=c._init,c=p(c._payload),o.type=c,p=o.tag=HS(c),n=Jt(c,n),p){case 0:o=yf(null,o,c,n,l);break e;case 1:o=Mg(null,o,c,n,l);break e;case 11:o=Tg(null,o,c,n,l);break e;case 14:o=Ig(null,o,c,Jt(c.type,n),l);break e}throw Error(r(306,c,""))}return o;case 0:return c=o.type,p=o.pendingProps,p=o.elementType===c?p:Jt(c,p),yf(n,o,c,p,l);case 1:return c=o.type,p=o.pendingProps,p=o.elementType===c?p:Jt(c,p),Mg(n,o,c,p,l);case 3:e:{if(Lg(o),n===null)throw Error(r(387));c=o.pendingProps,x=o.memoizedState,p=x.element,Qp(n,o),Al(o,c,null,l);var _=o.memoizedState;if(c=_.element,x.isDehydrated)if(x={element:c,isDehydrated:!1,cache:_.cache,pendingSuspenseBoundaries:_.pendingSuspenseBoundaries,transitions:_.transitions},o.updateQueue.baseState=x,o.memoizedState=x,o.flags&256){p=Lo(Error(r(423)),o),o=Dg(n,o,c,l,p);break e}else if(c!==p){p=Lo(Error(r(424)),o),o=Dg(n,o,c,l,p);break e}else for($t=rr(o.stateNode.containerInfo.firstChild),jt=o,Be=!0,Qt=null,l=Gp(o,null,c,l),o.child=l;l;)l.flags=l.flags&-3|4096,l=l.sibling;else{if(Io(),c===p){o=Tn(n,o,l);break e}xt(n,o,c,l)}o=o.child}return o;case 5:return eg(o),n===null&&qc(o),c=o.type,p=o.pendingProps,x=n!==null?n.memoizedProps:null,_=p.children,Dc(c,p)?_=null:x!==null&&Dc(c,x)&&(o.flags|=32),Ag(n,o),xt(n,o,_,l),o.child;case 6:return n===null&&qc(o),null;case 13:return Og(n,o,l);case 4:return ef(o,o.stateNode.containerInfo),c=o.pendingProps,n===null?o.child=jo(o,null,c,l):xt(n,o,c,l),o.child;case 11:return c=o.type,p=o.pendingProps,p=o.elementType===c?p:Jt(c,p),Tg(n,o,c,p,l);case 7:return xt(n,o,o.pendingProps,l),o.child;case 8:return xt(n,o,o.pendingProps.children,l),o.child;case 12:return xt(n,o,o.pendingProps.children,l),o.child;case 10:e:{if(c=o.type._context,p=o.pendingProps,x=o.memoizedProps,_=p.value,De(Il,c._currentValue),c._currentValue=_,x!==null)if(Kt(x.value,_)){if(x.children===p.children&&!St.current){o=Tn(n,o,l);break e}}else for(x=o.child,x!==null&&(x.return=o);x!==null;){var $=x.dependencies;if($!==null){_=x.child;for(var D=$.firstContext;D!==null;){if(D.context===c){if(x.tag===1){D=Rn(-1,l&-l),D.tag=2;var K=x.updateQueue;if(K!==null){K=K.shared;var ae=K.pending;ae===null?D.next=D:(D.next=ae.next,ae.next=D),K.pending=D}}x.lanes|=l,D=x.alternate,D!==null&&(D.lanes|=l),Qc(x.return,l,o),$.lanes|=l;break}D=D.next}}else if(x.tag===10)_=x.type===o.type?null:x.child;else if(x.tag===18){if(_=x.return,_===null)throw Error(r(341));_.lanes|=l,$=_.alternate,$!==null&&($.lanes|=l),Qc(_,l,o),_=x.sibling}else _=x.child;if(_!==null)_.return=x;else for(_=x;_!==null;){if(_===o){_=null;break}if(x=_.sibling,x!==null){x.return=_.return,_=x;break}_=_.return}x=_}xt(n,o,p.children,l),o=o.child}return o;case 9:return p=o.type,c=o.pendingProps.children,Ao(o,l),p=Vt(p),c=c(p),o.flags|=1,xt(n,o,c,l),o.child;case 14:return c=o.type,p=Jt(c,o.pendingProps),p=Jt(c.type,p),Ig(n,o,c,p,l);case 15:return jg(n,o,o.type,o.pendingProps,l);case 17:return c=o.type,p=o.pendingProps,p=o.elementType===c?p:Jt(c,p),Vl(n,o),o.tag=1,Et(c)?(n=!0,_l(o)):n=!1,Ao(o,l),kg(o,c,p),pf(o,c,p,l),xf(null,o,c,!0,n,l);case 19:return Fg(n,o,l);case 22:return $g(n,o,l)}throw Error(r(156,o.tag))};function cm(n,o){return ol(n,o)}function BS(n,o,l,c){this.tag=n,this.key=l,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=o,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=c,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function qt(n,o,l,c){return new BS(n,o,l,c)}function Of(n){return n=n.prototype,!(!n||!n.isReactComponent)}function HS(n){if(typeof n=="function")return Of(n)?1:0;if(n!=null){if(n=n.$$typeof,n===ne)return 11;if(n===U)return 14}return 2}function pr(n,o){var l=n.alternate;return l===null?(l=qt(n.tag,o,n.key,n.mode),l.elementType=n.elementType,l.type=n.type,l.stateNode=n.stateNode,l.alternate=n,n.alternate=l):(l.pendingProps=o,l.type=n.type,l.flags=0,l.subtreeFlags=0,l.deletions=null),l.flags=n.flags&14680064,l.childLanes=n.childLanes,l.lanes=n.lanes,l.child=n.child,l.memoizedProps=n.memoizedProps,l.memoizedState=n.memoizedState,l.updateQueue=n.updateQueue,o=n.dependencies,l.dependencies=o===null?null:{lanes:o.lanes,firstContext:o.firstContext},l.sibling=n.sibling,l.index=n.index,l.ref=n.ref,l}function ea(n,o,l,c,p,x){var _=2;if(c=n,typeof n=="function")Of(n)&&(_=1);else if(typeof n=="string")_=5;else e:switch(n){case j:return Hr(l.children,p,x,o);case G:_=8,p|=8;break;case V:return n=qt(12,l,o,p|2),n.elementType=V,n.lanes=x,n;case J:return n=qt(13,l,o,p),n.elementType=J,n.lanes=x,n;case I:return n=qt(19,l,o,p),n.elementType=I,n.lanes=x,n;case q:return ta(l,p,x,o);default:if(typeof n=="object"&&n!==null)switch(n.$$typeof){case Y:_=10;break e;case ee:_=9;break e;case ne:_=11;break e;case U:_=14;break e;case F:_=16,c=null;break e}throw Error(r(130,n==null?n:typeof n,""))}return o=qt(_,l,o,p),o.elementType=n,o.type=c,o.lanes=x,o}function Hr(n,o,l,c){return n=qt(7,n,c,o),n.lanes=l,n}function ta(n,o,l,c){return n=qt(22,n,c,o),n.elementType=q,n.lanes=l,n.stateNode={isHidden:!1},n}function zf(n,o,l){return n=qt(6,n,null,o),n.lanes=l,n}function Ff(n,o,l){return o=qt(4,n.children!==null?n.children:[],n.key,o),o.lanes=l,o.stateNode={containerInfo:n.containerInfo,pendingChildren:null,implementation:n.implementation},o}function VS(n,o,l,c,p){this.tag=o,this.containerInfo=n,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=dc(0),this.expirationTimes=dc(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=dc(0),this.identifierPrefix=c,this.onRecoverableError=p,this.mutableSourceEagerHydrationData=null}function Bf(n,o,l,c,p,x,_,$,D){return n=new VS(n,o,l,$,D),o===1?(o=1,x===!0&&(o|=8)):o=0,x=qt(3,null,null,o),n.current=x,x.stateNode=n,x.memoizedState={element:c,isDehydrated:l,cache:null,transitions:null,pendingSuspenseBoundaries:null},Zc(x),n}function US(n,o,l){var c=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),Yf.exports=tE(),Yf.exports}var Cm;function nE(){if(Cm)return aa;Cm=1;var e=Uy();return aa.createRoot=e.createRoot,aa.hydrateRoot=e.hydrateRoot,aa}var rE=nE(),P=As();const yt=rt(P);var rs={},_m;function oE(){if(_m)return rs;_m=1,Object.defineProperty(rs,"__esModule",{value:!0}),rs.parse=u,rs.serialize=h;const e=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,t=/^[\u0021-\u003A\u003C-\u007E]*$/,r=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,i=/^[\u0020-\u003A\u003D-\u007E]*$/,s=Object.prototype.toString,a=(()=>{const y=function(){};return y.prototype=Object.create(null),y})();function u(y,v){const S=new a,E=y.length;if(E<2)return S;const k=(v==null?void 0:v.decode)||g;let C=0;do{const R=y.indexOf("=",C);if(R===-1)break;const N=y.indexOf(";",C),b=N===-1?E:N;if(R>b){C=y.lastIndexOf(";",R-1)+1;continue}const M=f(y,C,R),L=d(y,R,M),j=y.slice(M,L);if(S[j]===void 0){let G=f(y,R+1,b),V=d(y,b,G);const Y=k(y.slice(G,V));S[j]=Y}C=b+1}while(CS;){const E=y.charCodeAt(--v);if(E!==32&&E!==9)return v+1}return S}function h(y,v,S){const E=(S==null?void 0:S.encode)||encodeURIComponent;if(!e.test(y))throw new TypeError(`argument name is invalid: ${y}`);const k=E(v);if(!t.test(k))throw new TypeError(`argument val is invalid: ${v}`);let C=y+"="+k;if(!S)return C;if(S.maxAge!==void 0){if(!Number.isInteger(S.maxAge))throw new TypeError(`option maxAge is invalid: ${S.maxAge}`);C+="; Max-Age="+S.maxAge}if(S.domain){if(!r.test(S.domain))throw new TypeError(`option domain is invalid: ${S.domain}`);C+="; Domain="+S.domain}if(S.path){if(!i.test(S.path))throw new TypeError(`option path is invalid: ${S.path}`);C+="; Path="+S.path}if(S.expires){if(!m(S.expires)||!Number.isFinite(S.expires.valueOf()))throw new TypeError(`option expires is invalid: ${S.expires}`);C+="; Expires="+S.expires.toUTCString()}if(S.httpOnly&&(C+="; HttpOnly"),S.secure&&(C+="; Secure"),S.partitioned&&(C+="; Partitioned"),S.priority)switch(typeof S.priority=="string"?S.priority.toLowerCase():void 0){case"low":C+="; Priority=Low";break;case"medium":C+="; Priority=Medium";break;case"high":C+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${S.priority}`)}if(S.sameSite)switch(typeof S.sameSite=="string"?S.sameSite.toLowerCase():S.sameSite){case!0:case"strict":C+="; SameSite=Strict";break;case"lax":C+="; SameSite=Lax";break;case"none":C+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${S.sameSite}`)}return C}function g(y){if(y.indexOf("%")===-1)return y;try{return decodeURIComponent(y)}catch{return y}}function m(y){return s.call(y)==="[object Date]"}return rs}oE();var Nm="popstate";function iE(e={}){function t(s,a){let{pathname:u="/",search:f="",hash:d=""}=ro(s.location.hash.substring(1));return!u.startsWith("/")&&!u.startsWith(".")&&(u="/"+u),Ed("",{pathname:u,search:f,hash:d},a.state&&a.state.usr||null,a.state&&a.state.key||"default")}function r(s,a){let u=s.document.querySelector("base"),f="";if(u&&u.getAttribute("href")){let d=s.location.href,h=d.indexOf("#");f=h===-1?d:d.slice(0,h)}return f+"#"+(typeof a=="string"?a:xs(a))}function i(s,a){an(s.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(a)})`)}return lE(t,r,i,e)}function qe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function an(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function sE(){return Math.random().toString(36).substring(2,10)}function bm(e,t){return{usr:e.state,key:e.key,idx:t}}function Ed(e,t,r=null,i){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?ro(t):t,state:r,key:t&&t.key||i||sE()}}function xs({pathname:e="/",search:t="",hash:r=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),r&&r!=="#"&&(e+=r.charAt(0)==="#"?r:"#"+r),e}function ro(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substring(r),e=e.substring(0,r));let i=e.indexOf("?");i>=0&&(t.search=e.substring(i),e=e.substring(0,i)),e&&(t.pathname=e)}return t}function lE(e,t,r,i={}){let{window:s=document.defaultView,v5Compat:a=!1}=i,u=s.history,f="POP",d=null,h=g();h==null&&(h=0,u.replaceState({...u.state,idx:h},""));function g(){return(u.state||{idx:null}).idx}function m(){f="POP";let k=g(),C=k==null?null:k-h;h=k,d&&d({action:f,location:E.location,delta:C})}function y(k,C){f="PUSH";let R=Ed(E.location,k,C);r&&r(R,k),h=g()+1;let N=bm(R,h),b=E.createHref(R);try{u.pushState(N,"",b)}catch(M){if(M instanceof DOMException&&M.name==="DataCloneError")throw M;s.location.assign(b)}a&&d&&d({action:f,location:E.location,delta:1})}function v(k,C){f="REPLACE";let R=Ed(E.location,k,C);r&&r(R,k),h=g();let N=bm(R,h),b=E.createHref(R);u.replaceState(N,"",b),a&&d&&d({action:f,location:E.location,delta:0})}function S(k){let C=s.location.origin!=="null"?s.location.origin:s.location.href,R=typeof k=="string"?k:xs(k);return R=R.replace(/ $/,"%20"),qe(C,`No window.location.(origin|href) available to create URL for href: ${R}`),new URL(R,C)}let E={get action(){return f},get location(){return e(s,u)},listen(k){if(d)throw new Error("A history only accepts one active listener");return s.addEventListener(Nm,m),d=k,()=>{s.removeEventListener(Nm,m),d=null}},createHref(k){return t(s,k)},createURL:S,encodeLocation(k){let C=S(k);return{pathname:C.pathname,search:C.search,hash:C.hash}},push:y,replace:v,go(k){return u.go(k)}};return E}function Wy(e,t,r="/"){return aE(e,t,r,!1)}function aE(e,t,r,i){let s=typeof t=="string"?ro(t):t,a=On(s.pathname||"/",r);if(a==null)return null;let u=qy(e);uE(u);let f=null;for(let d=0;f==null&&d{let d={relativePath:f===void 0?a.path||"":f,caseSensitive:a.caseSensitive===!0,childrenIndex:u,route:a};d.relativePath.startsWith("/")&&(qe(d.relativePath.startsWith(i),`Absolute route path "${d.relativePath}" nested under path "${i}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),d.relativePath=d.relativePath.slice(i.length));let h=Mn([i,d.relativePath]),g=r.concat(d);a.children&&a.children.length>0&&(qe(a.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${h}".`),qy(a.children,t,g,h)),!(a.path==null&&!a.index)&&t.push({path:h,score:mE(h,a.index),routesMeta:g})};return e.forEach((a,u)=>{var f;if(a.path===""||!((f=a.path)!=null&&f.includes("?")))s(a,u);else for(let d of Yy(a.path))s(a,u,d)}),t}function Yy(e){let t=e.split("/");if(t.length===0)return[];let[r,...i]=t,s=r.endsWith("?"),a=r.replace(/\?$/,"");if(i.length===0)return s?[a,""]:[a];let u=Yy(i.join("/")),f=[];return f.push(...u.map(d=>d===""?a:[a,d].join("/"))),s&&f.push(...u),f.map(d=>e.startsWith("/")&&d===""?"/":d)}function uE(e){e.sort((t,r)=>t.score!==r.score?r.score-t.score:yE(t.routesMeta.map(i=>i.childrenIndex),r.routesMeta.map(i=>i.childrenIndex)))}var cE=/^:[\w-]+$/,fE=3,dE=2,hE=1,pE=10,gE=-2,Pm=e=>e==="*";function mE(e,t){let r=e.split("/"),i=r.length;return r.some(Pm)&&(i+=gE),t&&(i+=dE),r.filter(s=>!Pm(s)).reduce((s,a)=>s+(cE.test(a)?fE:a===""?hE:pE),i)}function yE(e,t){return e.length===t.length&&e.slice(0,-1).every((i,s)=>i===t[s])?e[e.length-1]-t[t.length-1]:0}function xE(e,t,r=!1){let{routesMeta:i}=e,s={},a="/",u=[];for(let f=0;f{if(g==="*"){let S=f[y]||"";u=a.slice(0,a.length-S.length).replace(/(.)\/+$/,"$1")}const v=f[y];return m&&!v?h[g]=void 0:h[g]=(v||"").replace(/%2F/g,"/"),h},{}),pathname:a,pathnameBase:u,pattern:e}}function vE(e,t=!1,r=!0){an(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let i=[],s="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(u,f,d)=>(i.push({paramName:f,isOptional:d!=null}),d?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(i.push({paramName:"*"}),s+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?s+="\\/*$":e!==""&&e!=="/"&&(s+="(?:(?=\\/|$))"),[new RegExp(s,t?void 0:"i"),i]}function wE(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return an(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function On(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,i=e.charAt(r);return i&&i!=="/"?null:e.slice(r)||"/"}function SE(e,t="/"){let{pathname:r,search:i="",hash:s=""}=typeof e=="string"?ro(e):e;return{pathname:r?r.startsWith("/")?r:EE(r,t):t,search:_E(i),hash:NE(s)}}function EE(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(s=>{s===".."?r.length>1&&r.pop():s!=="."&&r.push(s)}),r.length>1?r.join("/"):"/"}function Kf(e,t,r,i){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(i)}]. Please separate it out to the \`to.${r}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function kE(e){return e.filter((t,r)=>r===0||t.route.path&&t.route.path.length>0)}function Xy(e){let t=kE(e);return t.map((r,i)=>i===t.length-1?r.pathname:r.pathnameBase)}function Gy(e,t,r,i=!1){let s;typeof e=="string"?s=ro(e):(s={...e},qe(!s.pathname||!s.pathname.includes("?"),Kf("?","pathname","search",s)),qe(!s.pathname||!s.pathname.includes("#"),Kf("#","pathname","hash",s)),qe(!s.search||!s.search.includes("#"),Kf("#","search","hash",s)));let a=e===""||s.pathname==="",u=a?"/":s.pathname,f;if(u==null)f=r;else{let m=t.length-1;if(!i&&u.startsWith("..")){let y=u.split("/");for(;y[0]==="..";)y.shift(),m-=1;s.pathname=y.join("/")}f=m>=0?t[m]:"/"}let d=SE(s,f),h=u&&u!=="/"&&u.endsWith("/"),g=(a||u===".")&&r.endsWith("/");return!d.pathname.endsWith("/")&&(h||g)&&(d.pathname+="/"),d}var Mn=e=>e.join("/").replace(/\/\/+/g,"/"),CE=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),_E=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,NE=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function bE(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}var Ky=["POST","PUT","PATCH","DELETE"];new Set(Ky);var PE=["GET",...Ky];new Set(PE);var ai=P.createContext(null);ai.displayName="DataRouter";var Eu=P.createContext(null);Eu.displayName="DataRouterState";var Qy=P.createContext({isTransitioning:!1});Qy.displayName="ViewTransition";var RE=P.createContext(new Map);RE.displayName="Fetchers";var TE=P.createContext(null);TE.displayName="Await";var wn=P.createContext(null);wn.displayName="Navigation";var Ms=P.createContext(null);Ms.displayName="Location";var Fn=P.createContext({outlet:null,matches:[],isDataRoute:!1});Fn.displayName="Route";var ah=P.createContext(null);ah.displayName="RouteError";function IE(e,{relative:t}={}){qe(Ls(),"useHref() may be used only in the context of a component.");let{basename:r,navigator:i}=P.useContext(wn),{hash:s,pathname:a,search:u}=Ds(e,{relative:t}),f=a;return r!=="/"&&(f=a==="/"?r:Mn([r,a])),i.createHref({pathname:f,search:u,hash:s})}function Ls(){return P.useContext(Ms)!=null}function oo(){return qe(Ls(),"useLocation() may be used only in the context of a component."),P.useContext(Ms).location}var Jy="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Zy(e){P.useContext(wn).static||P.useLayoutEffect(e)}function jE(){let{isDataRoute:e}=P.useContext(Fn);return e?WE():$E()}function $E(){qe(Ls(),"useNavigate() may be used only in the context of a component.");let e=P.useContext(ai),{basename:t,navigator:r}=P.useContext(wn),{matches:i}=P.useContext(Fn),{pathname:s}=oo(),a=JSON.stringify(Xy(i)),u=P.useRef(!1);return Zy(()=>{u.current=!0}),P.useCallback((d,h={})=>{if(an(u.current,Jy),!u.current)return;if(typeof d=="number"){r.go(d);return}let g=Gy(d,JSON.parse(a),s,h.relative==="path");e==null&&t!=="/"&&(g.pathname=g.pathname==="/"?t:Mn([t,g.pathname])),(h.replace?r.replace:r.push)(g,h.state,h)},[t,r,a,s,e])}P.createContext(null);function Ds(e,{relative:t}={}){let{matches:r}=P.useContext(Fn),{pathname:i}=oo(),s=JSON.stringify(Xy(r));return P.useMemo(()=>Gy(e,JSON.parse(s),i,t==="path"),[e,s,i,t])}function AE(e,t){return ex(e,t)}function ex(e,t,r,i){var R;qe(Ls(),"useRoutes() may be used only in the context of a component.");let{navigator:s,static:a}=P.useContext(wn),{matches:u}=P.useContext(Fn),f=u[u.length-1],d=f?f.params:{},h=f?f.pathname:"/",g=f?f.pathnameBase:"/",m=f&&f.route;{let N=m&&m.path||"";tx(h,!m||N.endsWith("*")||N.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${h}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. - -Please change the parent to .`)}let y=oo(),v;if(t){let N=typeof t=="string"?ro(t):t;qe(g==="/"||((R=N.pathname)==null?void 0:R.startsWith(g)),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${g}" but pathname "${N.pathname}" was given in the \`location\` prop.`),v=N}else v=y;let S=v.pathname||"/",E=S;if(g!=="/"){let N=g.replace(/^\//,"").split("/");E="/"+S.replace(/^\//,"").split("/").slice(N.length).join("/")}let k=!a&&r&&r.matches&&r.matches.length>0?r.matches:Wy(e,{pathname:E});an(m||k!=null,`No routes matched location "${v.pathname}${v.search}${v.hash}" `),an(k==null||k[k.length-1].route.element!==void 0||k[k.length-1].route.Component!==void 0||k[k.length-1].route.lazy!==void 0,`Matched leaf route at location "${v.pathname}${v.search}${v.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let C=zE(k&&k.map(N=>Object.assign({},N,{params:Object.assign({},d,N.params),pathname:Mn([g,s.encodeLocation?s.encodeLocation(N.pathname).pathname:N.pathname]),pathnameBase:N.pathnameBase==="/"?g:Mn([g,s.encodeLocation?s.encodeLocation(N.pathnameBase).pathname:N.pathnameBase])})),u,r,i);return t&&C?P.createElement(Ms.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...v},navigationType:"POP"}},C):C}function ME(){let e=UE(),t=bE(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),r=e instanceof Error?e.stack:null,i="rgba(200,200,200, 0.5)",s={padding:"0.5rem",backgroundColor:i},a={padding:"2px 4px",backgroundColor:i},u=null;return console.error("Error handled by React Router default ErrorBoundary:",e),u=P.createElement(P.Fragment,null,P.createElement("p",null,"💿 Hey developer 👋"),P.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",P.createElement("code",{style:a},"ErrorBoundary")," or"," ",P.createElement("code",{style:a},"errorElement")," prop on your route.")),P.createElement(P.Fragment,null,P.createElement("h2",null,"Unexpected Application Error!"),P.createElement("h3",{style:{fontStyle:"italic"}},t),r?P.createElement("pre",{style:s},r):null,u)}var LE=P.createElement(ME,null),DE=class extends P.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){console.error("React Router caught the following error during render",e,t)}render(){return this.state.error!==void 0?P.createElement(Fn.Provider,{value:this.props.routeContext},P.createElement(ah.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};function OE({routeContext:e,match:t,children:r}){let i=P.useContext(ai);return i&&i.static&&i.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=t.route.id),P.createElement(Fn.Provider,{value:e},r)}function zE(e,t=[],r=null,i=null){if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let s=e,a=r==null?void 0:r.errors;if(a!=null){let d=s.findIndex(h=>h.route.id&&(a==null?void 0:a[h.route.id])!==void 0);qe(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(a).join(",")}`),s=s.slice(0,Math.min(s.length,d+1))}let u=!1,f=-1;if(r)for(let d=0;d=0?s=s.slice(0,f+1):s=[s[0]];break}}}return s.reduceRight((d,h,g)=>{let m,y=!1,v=null,S=null;r&&(m=a&&h.route.id?a[h.route.id]:void 0,v=h.route.errorElement||LE,u&&(f<0&&g===0?(tx("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),y=!0,S=null):f===g&&(y=!0,S=h.route.hydrateFallbackElement||null)));let E=t.concat(s.slice(0,g+1)),k=()=>{let C;return m?C=v:y?C=S:h.route.Component?C=P.createElement(h.route.Component,null):h.route.element?C=h.route.element:C=d,P.createElement(OE,{match:h,routeContext:{outlet:d,matches:E,isDataRoute:r!=null},children:C})};return r&&(h.route.ErrorBoundary||h.route.errorElement||g===0)?P.createElement(DE,{location:r.location,revalidation:r.revalidation,component:v,error:m,children:k(),routeContext:{outlet:null,matches:E,isDataRoute:!0}}):k()},null)}function uh(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function FE(e){let t=P.useContext(ai);return qe(t,uh(e)),t}function BE(e){let t=P.useContext(Eu);return qe(t,uh(e)),t}function HE(e){let t=P.useContext(Fn);return qe(t,uh(e)),t}function ch(e){let t=HE(e),r=t.matches[t.matches.length-1];return qe(r.route.id,`${e} can only be used on routes that contain a unique "id"`),r.route.id}function VE(){return ch("useRouteId")}function UE(){var i;let e=P.useContext(ah),t=BE("useRouteError"),r=ch("useRouteError");return e!==void 0?e:(i=t.errors)==null?void 0:i[r]}function WE(){let{router:e}=FE("useNavigate"),t=ch("useNavigate"),r=P.useRef(!1);return Zy(()=>{r.current=!0}),P.useCallback(async(s,a={})=>{an(r.current,Jy),r.current&&(typeof s=="number"?e.navigate(s):await e.navigate(s,{fromRouteId:t,...a}))},[e,t])}var Rm={};function tx(e,t,r){!t&&!Rm[e]&&(Rm[e]=!0,an(!1,r))}P.memo(qE);function qE({routes:e,future:t,state:r}){return ex(e,void 0,r,t)}function nx(e){qe(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function YE({basename:e="/",children:t=null,location:r,navigationType:i="POP",navigator:s,static:a=!1}){qe(!Ls(),"You cannot render a inside another . You should never have more than one in your app.");let u=e.replace(/^\/*/,"/"),f=P.useMemo(()=>({basename:u,navigator:s,static:a,future:{}}),[u,s,a]);typeof r=="string"&&(r=ro(r));let{pathname:d="/",search:h="",hash:g="",state:m=null,key:y="default"}=r,v=P.useMemo(()=>{let S=On(d,u);return S==null?null:{location:{pathname:S,search:h,hash:g,state:m,key:y},navigationType:i}},[u,d,h,g,m,y,i]);return an(v!=null,` is not able to match the URL "${d}${h}${g}" because it does not start with the basename, so the won't render anything.`),v==null?null:P.createElement(wn.Provider,{value:f},P.createElement(Ms.Provider,{children:t,value:v}))}function XE({children:e,location:t}){return AE(kd(e),t)}function kd(e,t=[]){let r=[];return P.Children.forEach(e,(i,s)=>{if(!P.isValidElement(i))return;let a=[...t,s];if(i.type===P.Fragment){r.push.apply(r,kd(i.props.children,a));return}qe(i.type===nx,`[${typeof i.type=="string"?i.type:i.type.name}] is not a component. All component children of must be a or `),qe(!i.props.index||!i.props.children,"An index route cannot have child routes.");let u={id:i.props.id||a.join("-"),caseSensitive:i.props.caseSensitive,element:i.props.element,Component:i.props.Component,index:i.props.index,path:i.props.path,loader:i.props.loader,action:i.props.action,hydrateFallbackElement:i.props.hydrateFallbackElement,HydrateFallback:i.props.HydrateFallback,errorElement:i.props.errorElement,ErrorBoundary:i.props.ErrorBoundary,hasErrorBoundary:i.props.hasErrorBoundary===!0||i.props.ErrorBoundary!=null||i.props.errorElement!=null,shouldRevalidate:i.props.shouldRevalidate,handle:i.props.handle,lazy:i.props.lazy};i.props.children&&(u.children=kd(i.props.children,a)),r.push(u)}),r}var za="get",Fa="application/x-www-form-urlencoded";function ku(e){return e!=null&&typeof e.tagName=="string"}function GE(e){return ku(e)&&e.tagName.toLowerCase()==="button"}function KE(e){return ku(e)&&e.tagName.toLowerCase()==="form"}function QE(e){return ku(e)&&e.tagName.toLowerCase()==="input"}function JE(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function ZE(e,t){return e.button===0&&(!t||t==="_self")&&!JE(e)}var ua=null;function ek(){if(ua===null)try{new FormData(document.createElement("form"),0),ua=!1}catch{ua=!0}return ua}var tk=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Qf(e){return e!=null&&!tk.has(e)?(an(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Fa}"`),null):e}function nk(e,t){let r,i,s,a,u;if(KE(e)){let f=e.getAttribute("action");i=f?On(f,t):null,r=e.getAttribute("method")||za,s=Qf(e.getAttribute("enctype"))||Fa,a=new FormData(e)}else if(GE(e)||QE(e)&&(e.type==="submit"||e.type==="image")){let f=e.form;if(f==null)throw new Error('Cannot submit a + ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/buttons/quitButton.tsx b/FRONT/BUILD/resources/app/src/components/UI/buttons/quitButton.tsx new file mode 100644 index 0000000..373655f --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/buttons/quitButton.tsx @@ -0,0 +1,45 @@ +import { MainButton } from "./mainButton"; +import styled from "styled-components"; +import { buttonNames } from "../../../const/buttons/names"; +import { IconComponent as Icon } from '../../../const/buttons/icons'; +import { useWorkSpaceStore } from "../../../store"; + +type Props = { + size: "small" | "big"; +}; + +const Container = styled.div<{ size: "small" | "big" }>` + ${(props) => props.size === "small" && "width: 100%;"} +`; + +const Button = styled.div` + width: 100%; + cursor: pointer; + color: ${(props) => props.theme.textColor}; +`; + +const IconContainer = styled.div` + padding: 10px; +`; + +export const QuitButton = ({ size }: Props) => { + const handleExit = () => { + window.electron.quitApp(); + }; + + const { setWorkModule } = useWorkSpaceStore() + + return ( + setWorkModule('helloWindow')}> + {size === "big" ? ( + + ) : ( + + )} + + ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/buttons/toggletheme.tsx b/FRONT/BUILD/resources/app/src/components/UI/buttons/toggletheme.tsx new file mode 100644 index 0000000..f1ca231 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/buttons/toggletheme.tsx @@ -0,0 +1,26 @@ +import styled, { useTheme } from "styled-components"; +import { IconComponent as Icon } from '../../../const/theme/icons'; +import { ThemName } from "../../../const/theme/names"; + +const Button = styled.div` + width: 100%; + cursor: pointer; +` + +const IconContainer = styled.div` + padding: 10px; + color: ${props => props.theme.text}; +` + +export default function ThemeButton() { + const theme = useTheme(); + const name = localStorage.getItem('theme') as ThemName + + return ( + + ); +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/inputs/input.tsx b/FRONT/BUILD/resources/app/src/components/UI/inputs/input.tsx new file mode 100644 index 0000000..dd2b9c9 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/inputs/input.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import styled from 'styled-components'; + +type Props = { + placeholderText: string; + id: string; + value?: string; + onChange?: (value: string) => void; + onFileChange?: (event: React.ChangeEvent) => void; + type?: string; + multiple?: boolean; + style?: React.CSSProperties; + search?: boolean; + onFocus?: any + onBlur?: any + $size?: string +} + +const InputContainer = styled.div` + width: 100%; + display: flex; + flex: 3; + +`; + +const StyledInput = styled.input` + padding: 8px 10px; + color: black; + border-radius: 8px; + border: 1px solid #A1A1A1; + background-color: transparent; + &:focus{ + border: 1px solid #adadad; + } + width: 100%; + font-size: 18px; + color: ${props=>props.theme.textColor} +`; + +const Input = React.forwardRef(({ placeholderText, id, value, onChange, onFileChange, type = "text", multiple, style, onFocus, onBlur }, ref) => { + const handleInputChange = (e: React.ChangeEvent) => { + const { value } = e.target; + if (onChange) { + onChange(value); + } + }; + + return ( + + + + ); +}); + +export default Input; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/loader.tsx b/FRONT/BUILD/resources/app/src/components/UI/loader.tsx new file mode 100644 index 0000000..c13bd3f --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/loader.tsx @@ -0,0 +1,101 @@ +type Props = { + loaderText: string; //Тип передаваемых данных loaderText - string +} + +import styled, { keyframes } from 'styled-components' +import { AnimDot } from './animDot'; + + +//Константа которая устанавливает кейфвреймы для вращения +const spinAnimation = keyframes` + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +` + +//Стиль экрана загрузки +export const LoaderContainer = styled.div` + top: 0px; + z-index:998; + background-color: rgba(0,0,0, 0.7); + position: fixed; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + overflow-y: hidden; +` + + +//Стиль блока с элементами загрузки +export const Loaderblock = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + + p{ + font-size: 24px; + color: white; + } +` +//Стиль для блока с кольцом загрузки +export const LoadingSpinner = styled.div` + position: relative; + width: 65px; + height: 65px; +` + +//Стиль для кольца загрузки +export const LoadingRing = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid white; +` +//Стиль для части кольца загрузки, которая будет вращаться +export const LoadingPart = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid transparent; + border-top: 12px solid ${props => props.theme.accent}; + + // Добавление аниманции и использование кейфремов + animation: ${spinAnimation} 1s linear infinite; +` + +const Text = styled.div` + display: flex; + gap: 3px; + font-size: 24px; + color: white; + margin-top: 30px; + margin-left: 25px; +` + +export default function Loader({ loaderText }: Props) { + return ( + + + + + + + + + {/* Текст экрана загрузки устанавливается с помощью передаваемых данных loaderText */} + {loaderText} + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/routerLoader.tsx b/FRONT/BUILD/resources/app/src/components/UI/routerLoader.tsx new file mode 100644 index 0000000..9a788f4 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/routerLoader.tsx @@ -0,0 +1,103 @@ +type Props = { + loaderText: string; //Тип передаваемых данных loaderText - string +} + +import styled, { keyframes } from 'styled-components' +import { AnimDot } from './animDot'; +import { ModalWindow } from '../modalwindows/style'; + + +//Константа которая устанавливает кейфвреймы для вращения +const spinAnimation = keyframes` + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +` + +//Стиль экрана загрузки +export const LoaderContainer = styled.div` + top: 0px; + z-index:998; + background-color: rgba(0,0,0, 0.7); + position: fixed; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + overflow-y: hidden; +` + + +//Стиль блока с элементами загрузки +export const Loaderblock = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + + p{ + font-size: 24px; + color: white; + } +` +//Стиль для блока с кольцом загрузки +export const LoadingSpinner = styled.div` + position: relative; + width: 65px; + height: 65px; +` + +//Стиль для кольца загрузки +export const LoadingRing = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid white; +` +//Стиль для части кольца загрузки, которая будет вращаться +export const LoadingPart = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid transparent; + border-top: 12px solid ${props => props.theme.accent}; + + // Добавление аниманции и использование кейфремов + animation: ${spinAnimation} 1s linear infinite; +` + +const Text = styled.div` + display: flex; + gap: 3px; + font-size: 24px; + color: white; + margin-top: 30px; + margin-left: 25px; +` + +export default function RouterLoader({ loaderText }: Props) { + return ( + + + + + + + + {/* Текст экрана загрузки устанавливается с помощью передаваемых данных loaderText */} + {loaderText} + + + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/signalSvg.tsx b/FRONT/BUILD/resources/app/src/components/UI/signalSvg.tsx new file mode 100644 index 0000000..9590433 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/signalSvg.tsx @@ -0,0 +1,63 @@ +import React, { useEffect, useRef } from 'react'; + +interface SignalSVGProps { + signal: number; // Принимаем signal как пропс + color: string; + size: string; +} + +const SignalSVG: React.FC = ({ signal, color, size }) => { + const svgRef = useRef(null); + + useEffect(() => { + // Устанавливаем цвета в зависимости от signal + const colors = { + '--st1-color': signal >= 1 ? color : 'black', + '--st2-color': signal >= 2 ? color : 'black', + '--st3-color': signal >= 3 ? color : 'black', + '--st4-color': signal >= 4 ? color : 'black', + '--st5-color': signal === 5 ? color : 'black', + }; + + // Применяем стили к SVG + if (svgRef.current) { + Object.entries(colors).forEach(([key, value]) => { + svgRef.current?.style.setProperty(key, value); + }); + } + }, [signal]); + + return ( + + + + + + + + + + + ); +}; + +export default SignalSVG; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx b/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx new file mode 100644 index 0000000..e1b8c6f --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx @@ -0,0 +1,109 @@ +import React from 'react'; +import { DeviceUser } from '../../../store/useDeviceStore'; + +interface TableScannerProps { + devices: DeviceUser[]; +} +import styled from 'styled-components'; +import {IconComponent} from "../../../const/buttons/icons"; +import {buttonNames} from "../../../const/buttons/names"; +import {ModalMap} from "../../modalwindows/windowsType"; +import {useModalContext} from "../../../store"; + +const TableContainer = styled.div` + width: 100%; + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08); + background: ${({ theme }) => theme.primary}; + margin: 24px 0; +`; + +const StyledTable = styled.table` + width: 100%; + border-collapse: separate; + border-spacing: 0; +`; + +const TableHeaderCell = styled.th<{ sortable?: boolean }>` + padding: 16px 24px; + text-align: left; + font-weight: 600; + font-size: 14px; + color: ${({ theme }) => theme.textSecondary}; + background: ${({ theme }) => theme.primary}; + border-bottom: 1px solid ${({ theme }) => theme.borderColor}; + transition: all 0.2s ease; +`; + +const TableRow = styled.tr<{ clickable?: boolean }>` + transition: all 0.2s ease; + &:hover { + background-color: ${({ theme }) => theme.background}; + } +`; + +const TableCell = styled.td` + padding: 16px 24px; + font-size: 14px; + color: ${({ theme }) => theme.text}; + border-bottom: 1px solid ${({ theme }) => theme.borderColor}; + transition: all 0.2s ease; +`; + +const StatusBadge = styled.span<{ status:string }>` + width: 10px; + height: 30px; + background-color: ${({theme, status}) => (status==='online' ? theme.successColor : theme.offlineColor)}; + display: inline-block; + border-radius:4px; +` + +const TableScanner = ({devices}:TableScannerProps) => { + const { openModal } = useModalContext(); + + const openModalNote = (e: React.MouseEvent, device:DeviceUser ) => { + e.stopPropagation(); + openModal(ModalMap['6'], { + address: device.mac, + currentNote: device.note || '' + }); + }; + + return ( + + + + + + Имя + Производитель + IP адрес + Открытые порты + Последняя активность + Заметка + + + + + {devices.map((item, i) => ( + + + {item.hostname || 'Неизвестен'} + {item.vendor} + {item.ip} + {item.open_ports.join(', ') || '-'} + {item.last_seen} + {item.note || '-'} + + openModalNote(e, item)}> + + + + + ))} + + + + ); +}; + +export default TableScanner; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx new file mode 100644 index 0000000..94eb76c --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Circle } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const CircleNode = ({ data }: CustomNodeProps) => { + return ( + {/* */} + {/*
*/} + {data.label} + + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + + {/*
*/} + +
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/style.ts new file mode 100644 index 0000000..df61ace --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/circle/style.ts @@ -0,0 +1,20 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + + +export const Circle = styled.div` + background-color: white; + border-radius: 100%; + display: flex; + align-items: center; + justify-content: center; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx new file mode 100644 index 0000000..388e9fb --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Default } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const DefaultNode = ({ data }: CustomNodeProps) => { + return ( + + {data.label} + + {/* Узлы для подключения */} + {/* + + + */} + + {/* Для входящих подключений */} + {/* */} + + {/* + */} + {/* */} + + + ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/style.ts new file mode 100644 index 0000000..62595bc --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/default/style.ts @@ -0,0 +1,20 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + +export const Default = styled.div` + background-color: white; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + visibility: visible; +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx new file mode 100644 index 0000000..49ab61c --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Diamond, InnerDiamond, Border } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const DiamondNode = ({ data }: CustomNodeProps) => { + + const baseSize = Math.max(data.style.width, data.style.height); + + return ( + {/* */} + + + {data.label} + + + +
+ {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + +
+ +
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/style.ts new file mode 100644 index 0000000..5eb0ba0 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/diamond/style.ts @@ -0,0 +1,32 @@ +import styled from "styled-components"; + +interface StyledDefaultProps { + width: any; + height: any; +} + +export const Diamond = styled.div` + position: relative; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; +`; + +export const InnerDiamond = styled.div` + clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); + width: ${(props) => props.width - 6}px; + height: ${(props) => props.height - 4}px; + background-color: white; + display: flex; + align-items: center; + justify-content: center; +` + +export const Border = styled.div<{ width: number; height: number, bordercolor: any }>` + clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; + background-color: ${(props) => props.bordercolor}; + display: flex; + align-items: center; + justify-content: center; +`; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/index.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/index.ts new file mode 100644 index 0000000..9827eef --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/index.ts @@ -0,0 +1,5 @@ +export {DefaultNode} from './default/defaultNode' +export {PillNode} from './pill/pillNode' +export {ParalelorgamNode} from './paralelogram/paralelogramNode' +export {CircleNode} from './circle/circleNode' +export {DiamondNode} from './diamond/diamondNode' \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx new file mode 100644 index 0000000..699f00c --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Paralelorgam } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const ParalelorgamNode = ({ data }: CustomNodeProps) => { + return ( + + {data.label} + + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + + + ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts new file mode 100644 index 0000000..46791e4 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts @@ -0,0 +1,43 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + + +export const Paralelorgam = styled.div` + transform: skewX(-20deg); + background-color: white; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; + + .react-flow__handle-top{ + transform: skewX(20deg); + top: -5px; + } + + .react-flow__handle-bottom{ + transform: skewX(20deg); + bottom: -5px; + } + + .react-flow__handle-right{ + transform: skewX(20deg); + right: -5px; + top: 25px; + } + + .react-flow__handle-left{ + transform: skewX(20deg); + left: -5px; + top: 25px; + } +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx new file mode 100644 index 0000000..7adf271 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Pill } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const PillNode = ({ data }: CustomNodeProps) => { + return ( + {/* */} + {/*
*/} + {data.label} + + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + + {/*
*/} + +
+ ); +}; + +export default PillNode; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/style.ts new file mode 100644 index 0000000..d08fe21 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/baseForm/pill/style.ts @@ -0,0 +1,19 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + +export const Pill = styled.div` + background-color: white; + border-radius: 50px; + display: flex; + align-items: center; + justify-content: center; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/index.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/index.ts new file mode 100644 index 0000000..64b1036 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/index.ts @@ -0,0 +1,5 @@ +export {NodeGroupNode} from './networkGroup/nodeGroup' +export {NetWorkNode} from './networkNode/networkNode' +export {IpGroupeNode} from './ipGroup/ipGroup' +export {IpNode} from './ipNode/ipNode' +export {PortNode} from './portNode/portNode' \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx new file mode 100644 index 0000000..750e612 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx @@ -0,0 +1,18 @@ + +import { IpGroup } from "./style"; + +interface CustomNodeProps { + data: { + style: { + width: any, + height: any, + } + }; +} + +export const IpGroupeNode = ({ data }: CustomNodeProps) => { + return ( + + ); +}; + diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts new file mode 100644 index 0000000..606ce1a --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts @@ -0,0 +1,12 @@ +import styled from "styled-components" + +type Props={ + $width: string, + $height?: any +} + + +export const IpGroup = styled.div` + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx new file mode 100644 index 0000000..d04af92 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx @@ -0,0 +1,245 @@ +import { useState } from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Ip } from './style'; +import { Row, IpTitle, IpContent } from './style'; +import Input from '../../../../UI/inputs/input'; +import { useModalContext, usePannableStore } from '../../../../../store'; +import { ModalMap } from '../../../../modalwindows/windowsType'; +import { validateIPAddress, validateSameSubnet } from '../../../../../utils/nodeController/validator'; +import {changeIp} from '../../../../../const/types/types' +import { IconComponent } from "../../../../../const/buttons/icons"; +import { buttonNames } from "../../../../../const/buttons/names"; + +interface IIp { + ipType: string + ipAdress: string, + ipGate: string, + ipDns: string[] + ipVersion: string +} + +type StateType = Record; +const typeMap: StateType = { + 'auto': "DHCP", + 'manual': "Static" +} + +interface CustomNodeProps { + data: { + ipData: IIp, + interfaceData: { + device: string, + connection: string + }, + style: { + width: any, + height: any, + borderType: string, + borderColor: string, + } + route: boolean + } +} + +export const IpNode = ({ data }: CustomNodeProps) => { + const { toggleEditingMode } = usePannableStore(); + const [isInput, setIsInput] = useState(false) + const { openModal } = useModalContext(); + + const [ipData, setIpData] = useState( + { + currentIp: data.ipData.ipAdress, + newIp: data.ipData.ipAdress, + currentGate: data.ipData.ipGate, + newGate: data.ipData.ipGate, + currentDns: data.ipData.ipDns, + newDns: data.ipData.ipDns, + device: data.interfaceData.device, + connection: data.interfaceData.connection, + version: data.ipData.ipVersion, + prefix: 0 + } + ) + + const handleFocus = () => { + toggleEditingMode(); + }; + + const handleBlur = () => { + toggleEditingMode(); + }; + + const handleClick = () => { + if (isInput) { + setIsInput(false) + setIpData(prevData => ({ + ...prevData, + newIp: data.ipData.ipAdress, + newGate: data.ipData.ipGate, + newDns: data.ipData.ipDns + })); + } + else { + setIsInput(true) + } + } + + const handleChange = (id: string, value: string) => { + if (id === 'newDns') { + const dnsArray = value.split(',').map(dns => dns.trim()); + setIpData(prevData => ({ + ...prevData, + [id]: dnsArray + })); + } else { + setIpData(prevData => ({ + ...prevData, + [id]: value + })); + } + }; + + function getSubnetMask(ipAddress: string, ipVersion: string): number { + if (ipVersion === "6") { + return 64; + } + + const firstOctet = parseInt(ipAddress.split(".")[0], 10); + if (firstOctet >= 0 && firstOctet <= 127) { + return 8; + } else if (firstOctet >= 128 && firstOctet <= 191) { + return 16; + } else if (firstOctet >= 192 && firstOctet <= 223) { + return 24; + } else { + return 24; + } + } + + + const handleConfirm = () => { + if ( + !validateIPAddress(ipData.newIp) || + !validateIPAddress(ipData.newGate) || + !ipData.newDns.every(dns => validateIPAddress(dns)) + ) { + alert('Один или несколько IP-адресов некорректны.'); + return; + } + + if (!validateSameSubnet(ipData.newIp, ipData.newGate, ipData.newDns)) { + alert('Адрес, шлюз и хотя бы один DNS должны находиться в одной подсети.'); + return; + } + + const calculatedPrefix = getSubnetMask(ipData.newIp, data.ipData.ipVersion); + + setIpData(prevData => ({ + ...prevData, + prefix: calculatedPrefix, + })); + + openModal(ModalMap['1'], { + ...ipData, + prefix: calculatedPrefix, + }); + + setIsInput(false) + }; + + + return ( + <> + + + + {/* +

Версия IP:

+

v{data.ipData.ipVersion}

+
*/} + + +

Метод:

+

{typeMap[data.ipData.ipType]}

+
+ + {isInput ? ( + + + + + + ) : ( + + )} + +
+ + + +

IPv{data.ipData.ipVersion}-Addr:

+ {isInput ? ( + handleChange('newIp', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +

{data.ipData.ipAdress}

+ )} + +
+ + +

IPv{data.ipData.ipVersion}-GW:

+ {isInput ? ( + handleChange('newGate', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +

{data.ipData.ipGate}

+ )} +
+ + +

IPv{data.ipData.ipVersion}-DNS:

+ {isInput ? ( + handleChange('newDns', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +

{data.ipData.ipDns.join(', ')}

+ )} +
+ + {data.route && + <> + + + + } +
+
+ + + ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts new file mode 100644 index 0000000..3355417 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts @@ -0,0 +1,74 @@ +import styled from "styled-components"; + +type Props={ + $width: string, + $height?: any + $bordertype: string, + $bordercolor: string +} + +export const Ip = styled.div` + background-color: ${(props)=>props.theme.secondary}; + display: flex; + flex-direction: column; + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + // box-shadow: 0px 0px 15px 2px rgba(0, 0, 0, 0.1); + border-radius: 8px; + + p{ + margin: 0; + } + + img{ + width: 15px; + height: 15px; + } +` + +export const IpTitle = styled.div` + background: ${(props)=>props.theme.accent}; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + color: white; + display: flex; + justify-content: space-between; + padding: 10px; + +` + +export const IpContent = styled.div` + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + padding: 10px; + + .row{ + height: 24px; + + .row-label{ + flex: 1; + } + + .row-text{ + flex: 3; + } + + p{ + + text-wrap: nowrap; + text-align: left; + } + } +` + +export const Row = styled.div` + display: flex; + align-items: center; + gap: 5px; + + p{ + margin: 0; + } +` diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx new file mode 100644 index 0000000..e7b3f66 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx @@ -0,0 +1,64 @@ +import { useState } from "react"; +import { NodeGroup, Row, CollapseButton } from "./style"; +import { useGroupStore } from "../../../../../store"; +import { MainButton } from "../../../../UI/buttons/mainButton"; +import { IconComponent } from "../../../../../const/buttons/icons"; +import { buttonNames } from "../../../../../const/buttons/names"; + +interface CustomNodeProps { + data: { + id: string; + label: string; + height: any + style: { + width: any; + height: any; + borderType: any; + borderColor: any; + }; + }; +} + +export const NodeGroupNode = ({ data }: CustomNodeProps) => { + const [click, setClick] = useState(false); + const { groups, setGroups } = useGroupStore(); + + const handleClick = () => { + const newClickState = !click; + setClick(newClickState); + + const updatedNodes = groups.map((groups) => + groups.id === data.id ? { ...groups, click: newClickState } : groups + ); + + if (!groups.some((groups) => groups.id === data.id)) { + updatedNodes.push({ id: data.id, click: newClickState }); + } + + setGroups(updatedNodes); + }; + + return ( + + +

{data.label}

+ + {/* */} + + {click ?( + 'Развернуть' + ):( + 'Свернуть' + )} + + {/* */} + +
+
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts new file mode 100644 index 0000000..9311bd5 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts @@ -0,0 +1,47 @@ +import styled from "styled-components" + +type Props={ + $width?: string, + $height?: any + $bordertype?: string, + $bordercolor?: string + $backgroundcolor?: string +} + + +export const NodeGroup = styled.div` + border: 2px ${(props) => props.$bordertype} ${(props) => props.$bordercolor}; + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + visibility: visible; +` + +export const Row = styled.div` + position: absolute; + top: -25px; + left: 10px; + display: flex; + justify-content: space-between; + align-items: center; + width: ${props=>props.$width}px; + gap: 5px; + padding-right: 10px; + + p{ + margin: 0; + } +` + +export const CollapseButton = styled.p` + padding: unset; + background: none; + color: ${(props)=>props.theme.textColor}; + margin-right: 15px !important; + &:hover{ + background: none; + } +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx new file mode 100644 index 0000000..0c0bfa4 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Network, TitleContainer, Device, Status, Content, Row, MAC, LabelColumn } from './style'; +import SignalSVG from '../../../../UI/signalSvg'; + +interface CustomNodeProps { + data: { + networkData: { + device: string + type: string + mac: string + mtu: number + state: string + connection: string + id: string, + strength: string + } + style: { + width: any, + height: any, + borderType: string, + borderColor: string, + backgroundColor: string + } + height: string + visible: true + }; +} + +export const NetWorkNode = ({ data }: CustomNodeProps) => { + const [signal, setSignal] = useState(1); + + useEffect(() => { + const perc = Number(data.networkData.strength); + + switch (true) { + case perc < 20: + setSignal(1); + break; + case perc < 40: + setSignal(2); + break; + case perc < 60: + setSignal(3); + break; + case perc < 80: + setSignal(4); + break; + default: + setSignal(5); + break; + } + + }, [data.networkData.strength]) + + return ( + + + + {data.networkData.type == "WIFI" && + + } + + {data.networkData.type == "ETHERNET" && + + } + + {data.networkData.type == "TUN" && + + } + + {data.networkData.device} + + {data.networkData.type == 'WIFI' && data.networkData.state === "Подключено" ? ( + + + + ) : ( +
+ ) + } + +
+ + {data.visible && + + +

Конфигурация

+ + +

MAC:

+

{data.networkData.mac}

+
+ +

MTU:

+

{data.networkData.mtu}

+
+
+
+
+ } + + {data.networkData.connection !== 'unknown' && + + } +
+ ); +}; + +export default NetWorkNode \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts new file mode 100644 index 0000000..f73753f --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts @@ -0,0 +1,93 @@ +import styled from "styled-components"; + +type Props = { + $width?: string, + $height?: any + $bordertype?: string, + $bordercolor?: string + $backgroundcolor?: string +} + +export const Network = styled.div` + background-color: ${(props) => props.theme.primary}; + border: 2px ${(props) => props.$bordertype} ${(props) => props.$bordercolor}; + min-width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + border-radius: 8px; + display: flex; + flex-direction: column; + gap: 10px; + visibility: visible; + overflow: hidden; + p{ + margin: 0; + } +` + +export const TitleContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + background: ${(props) => props.$backgroundcolor}; + color: white; + padding: 15px; + height: ${(props) => props.$height ? props.$height : 'unset'}; + + img{ + width: 20px + } +` + +export const Device = styled.p` + font-size: 18px; +` + +export const Status = styled.p` + font-size: 14px; + + + img{ + width: 20px; + height: 20px; + } +` + +export const Content = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + padding: 15px; +` + +export const Row = styled.div` + display: flex; + gap: 5px; +` + +export const MAC = styled.div` + display: flex; + justify-content: space-between; + background: ${(props) => props.theme.secondary}; + border-radius: 8px; + // box-shadow: 0px 0px 15px 2px rgba(0, 0, 0, 0.1); + width: 100%; + + .networkNode-row{ + padding: 10px; + } +` + +export const LabelColumn = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; + width: 100%; + + .networkNode-label{ + font-size: 10px; + width: 100%; + text-align: left; + margin-left: 15px; + } +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx new file mode 100644 index 0000000..68939f7 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx @@ -0,0 +1,48 @@ +import { Handle, Position } from '@xyflow/react'; +import { Port, Column } from './style'; + +interface CustomNodeProps { + data: { + label: string; + port: string + id: string; + style: { + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const PortNode = ({ data }: CustomNodeProps) => { + return ( + + + +

{data.label}

+ + + {data.port && +

{data.port}

+ } +
+ + + {data.port ? ( + <> + + + + + ) : ( + <> + + + + + )} + +
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/style.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/style.ts new file mode 100644 index 0000000..17a1b0f --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/nodes/networkInterface/portNode/style.ts @@ -0,0 +1,30 @@ +import styled from "styled-components" + +type Props={ + $width: string, + $height?: any + $bordertype: string, + $bordercolor: string +} + +export const Port = styled.div` + background-color: ${(props)=>props.theme.primary}; + border: 2px ${(props) => props.$bordertype} ${(props) => props.$bordercolor}; + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + visibility: visible; +` + +export const Column = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + + p{ + margin: 0; + } +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/types/colors.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/types/colors.ts new file mode 100644 index 0000000..342c6f7 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/types/colors.ts @@ -0,0 +1,11 @@ +type ColorType = Record; + +export const NodeColors: ColorType = { + '0': '#c0c0c0', + '1': '#ef6e7d', + '2': '#f19e4c', + '3': '#e9c44c', + '4': '#51ce82', + '5': '#4cd2d0', + '6': '#a085f3', +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/customeNodes/types/types.ts b/FRONT/BUILD/resources/app/src/components/customeNodes/types/types.ts new file mode 100644 index 0000000..5b7ce87 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/customeNodes/types/types.ts @@ -0,0 +1,16 @@ + +import { DefaultNode, PillNode, ParalelorgamNode, DiamondNode, CircleNode } from '../nodes/baseForm' +import { NodeGroupNode, NetWorkNode, IpGroupeNode, IpNode, PortNode } from '../nodes/networkInterface'; + +export const nodeTypes = { + custom: DefaultNode, + pill: PillNode, + parallelogram: ParalelorgamNode, + diamond: DiamondNode, + circle: CircleNode, + nodegroup: NodeGroupNode, + portNode: PortNode, + network: NetWorkNode, + ipgroup: IpGroupeNode, + ip: IpNode, +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modal.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modal.tsx new file mode 100644 index 0000000..b030ace --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modal.tsx @@ -0,0 +1,10 @@ +import { ModalWindow, ModalContainer } from "./style" +import { modalNames } from "../../const/modals/names" + +export const WindowComponent = ()=>{ + return( + + + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ConnectNetwork.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ConnectNetwork.tsx new file mode 100644 index 0000000..ff3532f --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ConnectNetwork.tsx @@ -0,0 +1,84 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import Input from "../../UI/inputs/input"; +import { useState } from "react"; +import {NetworkService} from "../../../api/request"; +import useNetworkStore from "../../../store/useDeviceStore"; +import RouterLoader from "../../UI/routerLoader"; +import {useTheme} from "styled-components"; +import {useIpStore} from "../../../store"; + +interface Props { + address: string; + onClose: () => void; +} + + + +export const ConnectNetwork = ({address, onClose}: Props) => { + const [password, setPassword] = useState(''); + const theme = useTheme(); + const { ipAddress } = useIpStore(); + const [error, setError] = useState(''); + const [isLoading, setIsLoading] = useState(false); + + const handleSave = async () => { + try { + setIsLoading(true); + setError('') + const res = await NetworkService.connectNetwork(ipAddress, password, address); + if(res.status === 200) { + onClose() + }else{ + setError(res.data.detail) + } + } catch (error) { + console.error('Error connection:', error); + setError('Ошибка подключения к сети') + }finally { + setIsLoading(false); + } + }; + + + return ( + + +

Подключение к сети

+
+ + + setPassword(value)} + /> +

+ {error} +

+
+ + + + + + + {isLoading && } +
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteDevice.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteDevice.tsx new file mode 100644 index 0000000..6d0b666 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteDevice.tsx @@ -0,0 +1,82 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import Input from "../../UI/inputs/input"; +import { useState } from "react"; +import {useIpStore} from "../../../store"; +import {NetworkService} from "../../../api/request"; +import useNetworkStore from "../../../store/useDeviceStore"; + +interface Props { + address: string; + onClose: () => void; + currentNote?: string; + type: string +} + + + +export const NoteDevice = ({ address, onClose, currentNote, type}: Props) => { + const [note, setNote] = useState(currentNote || ''); + const { ipAddress } = useIpStore(); + const { devices, setDevices } = useNetworkStore(); + + const handleSave = async () => { + try { + if (!currentNote && note.trim() !== '') { + await NetworkService.addNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() !== '' && note !== currentNote) { + await NetworkService.editNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() === '') { + await NetworkService.deleteNote(ipAddress, address, type); + }else { + onClose(); + return; + } + + const updatedDevices = devices.map(device => + device.mac === address + ? { ...device, note: note.trim() } + : device + ); + setDevices(updatedDevices); + onClose(); + + } catch (error) { + console.error('Error saving note:', error); + } + }; + + return ( + + +

{currentNote ? 'Редактирование заметки' : 'Добавление заметки'}

+
+ + + setNote(value)} + /> + + + + + + +
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteWifi.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteWifi.tsx new file mode 100644 index 0000000..c03a48a --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/NoteWifi.tsx @@ -0,0 +1,82 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import Input from "../../UI/inputs/input"; +import { useState } from "react"; +import {NetworkService} from "../../../api/request"; +import useNetworkStore from "../../../store/useDeviceStore"; +import {useIpStore} from "../../../store"; + +interface Props { + address: string; + onClose: () => void; + currentNote?: string; + type: string +} + + + +export const NoteWifi = ({ address, onClose, currentNote, type}: Props) => { + const [note, setNote] = useState(currentNote || ''); + const { ipAddress } = useIpStore(); + const { wifiNetworks, setWifiNetworks } = useNetworkStore(); + + const handleSave = async () => { + try { + if (!currentNote && note.trim() !== '') { + await NetworkService.addNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() !== '' && note !== currentNote) { + await NetworkService.editNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() === '') { + await NetworkService.deleteNote(ipAddress, address, type); + }else { + onClose(); + return; + } + const updatedNetworks = wifiNetworks.map(network => + network.ssid === address + ? { ...network, note: note.trim() } + : { ...network } + ); + setWifiNetworks(updatedNetworks); + onClose(); + + } catch (error) { + console.error('Error saving note:', error); + } + }; + + + return ( + + +

{currentNote ? 'Редактирование заметки' : 'Добавление заметки'}

+
+ + + setNote(value)} + /> + + + + + + +
+ ); +}; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/addDevice.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/addDevice.tsx new file mode 100644 index 0000000..5611792 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/addDevice.tsx @@ -0,0 +1,58 @@ +import Input from "../../UI/inputs/input" +import { MainButton } from "../../UI/buttons/mainButton"; +import { useState } from "react"; +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import { validateIPAddress } from "../../../utils/nodeController/validator"; + +interface Props { + onSave?: (data: string) => void; + onClose: () => void; +} + +export const AddDevice = ({ onSave, onClose }: Props) => { + const [ipAddress, setIpAddress] = useState('') + const [error, setError] = useState(false) + + const handleSubmit = () => { + if (!validateIPAddress(ipAddress)) { + setError(true) + return; + } + // e.preventDefault(); // Предотвращаем перезагрузку страницы + if (onSave && ipAddress) { + setError(false) + onSave(ipAddress); + onClose(); + } + }; + + return ( + + {/* */} + +

Добавление узла

+
+ + + setIpAddress(value)} + /> + {error && ( +

+ Некорректный адрес узла +

+ )} +
+ + + + + + {/* */} +
+ ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/connectionError.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/connectionError.tsx new file mode 100644 index 0000000..224ba6e --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/connectionError.tsx @@ -0,0 +1,38 @@ +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import { useModalContext } from "../../../store" +import { useIpStore } from "../../../store" +import { MainButton } from "../../UI/buttons/mainButton" + +type Props={ + message: string +} + +export const ConnectionError = ({message}: Props)=>{ + const {closeModal} = useModalContext() + const { setIpAddress } = useIpStore(); + + const close = ()=>{ + setIpAddress('localhost') + closeModal() + } + + return( + + +

Соединение прервано

+
+ + + +

Произошёл разрыв с сервером

+

Пожалуйста, проверьте доступ к адресу и попробуйте снова.

+
+
+ + + + + +
+ ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/disconnectConfirm.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/disconnectConfirm.tsx new file mode 100644 index 0000000..148d657 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/disconnectConfirm.tsx @@ -0,0 +1,54 @@ +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import { useModalContext } from "../../../store" +import { useIpStore } from "../../../store" +import { MainButton } from "../../UI/buttons/mainButton" +import {useState} from "react"; +import {NetworkService} from "../../../api/request"; +import RouterLoader from "../../UI/routerLoader"; +import {useTheme} from "styled-components"; + +type Props={ + address: string, + onClose: () => void +} + +export const DisconnectConfirm = ({address, onClose}: Props)=>{ + const { ipAddress } = useIpStore(); + const theme = useTheme() + const [isLoading, setIsLoading] = useState(false); + + const handleDisconnect = async () => { + try { + setIsLoading(true); + const res = await NetworkService.disconnectNetwork(ipAddress, address); + if(res.status === 200) { + onClose() + } + } catch (error) { + console.error('Error connection:', error); + }finally { + setIsLoading(false); + } + }; + + return( + + +

Отключение от Wi-Fi сети

+
+ + + +

Подтверждение отключения

+

Вы собираетесь отключиться от сети "{address}". Все активные подключения будут прерваны.

+
+
+ + + + + + {isLoading && } +
+ ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/index.ts b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/index.ts new file mode 100644 index 0000000..ed95168 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/index.ts @@ -0,0 +1,4 @@ +export {IpConfirm} from './ipConfirm' +export {ConnectionError} from './connectionError' +export {AddDevice} from './addDevice' +export {RightsConfirm} from './rightsConfirm' \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ipConfirm.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ipConfirm.tsx new file mode 100644 index 0000000..2e2b998 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/ipConfirm.tsx @@ -0,0 +1,211 @@ +import styled from "styled-components"; +import Loader from "../../UI/loader"; +import { useEffect, useState } from "react"; +import { changeIp } from '../../../const/types/types' +import { NetworkService } from '../../../api/request' +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer, ErrorMessage } from "../style" +import { useIpStore } from "../../../store"; +import { MainButton } from "../../UI/buttons/mainButton"; +import { useAdminStore } from "../../../store/adminStore"; +import { useDevicesStore } from "../../../store"; + +type Props = { + ipData: changeIp + onClose: () => void; + smoothClose: () => void; +} + +const Information = styled.div` + display: flex; + flex-direction: column; + gap: 15px; +` + +const Info = styled.div` + display: flex; + gap: 10px; +` + +const DataContainer = styled.div` + display: flex; + gap: 35px; +` + +const CurrentData = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +` + +const NewData = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +` + +export const IpConfirm = ({ ipData, onClose, smoothClose }: Props) => { + const [loader, setLoader] = useState(true) + const [newIP, setNewIp] = useState(null) + const [currentIp, setCurrentIP] = useState({}) + const [checkStatus, setcheckStatus] = useState(false) + const [message, setMessgae] = useState('') + const { ipAddress, setIpAddress } = useIpStore(); + const {isAdmin} = useAdminStore() + const { devices, addDevice, deleteDevice } = useDevicesStore(); + + useEffect(() => { + if (ipData && isAdmin) { + const data = { + "connection_id": ipData.connection, + "ipv4_updates": { + "ipv4.method": "manual", + "ipv4.address-data": [ + { + "address": ipData.newIp, + "prefix": ipData.prefix + } + ], + "ipv4.gateway": ipData.newGate, + "ipv4.dns-data": ipData.newDns + } + }; + + const oldData = { + "connection_id": ipData.connection, + "ipv4_updates": { + "ipv4.method": "manual", + "ipv4.address-data": [ + { + "address": ipData.currentIp, + "prefix": ipData.prefix + } + ], + "ipv4.gateway": ipData.currentGate, + "ipv4.dns-data": ipData.currentDns + } + } + + setCurrentIP(oldData) + + checkIp(data); + } + }, [ipData, isAdmin]); + + const checkIp = async (data: any) => { + try { + const result = await NetworkService.checkIp(ipAddress, data); + setcheckStatus(result.data.available) + setMessgae(result.data.message) + if (result.data.available) { + setNewIp(data) + } + } catch (err) { + console.error('Error:', err); + } finally { + setLoader(false); + } + }; + + const saveIp = async (data: any) => { + try { + const result = await NetworkService.saveIp(ipAddress, data); + if (result.status === 200) { + if(ipAddress!=='localhost'){ + setIpAddress(ipData.newIp) + + const updatedDevices = devices.map(device => + device.address === ipData.currentIp + ? { ...device, address: ipData.newIp } + : device + ); + useDevicesStore.setState({ devices: updatedDevices }); + } + + onClose() + } + } catch (err) { + console.error('Error:', err); + } finally { + setLoader(false); + } + }; + + const cancelIp = async (data: any) => { + try { + const result = await NetworkService.saveIp(ipAddress, data); + if (result.status === 200) { + onClose() + } + } catch (err) { + console.error('Error:', err); + } finally { + setLoader(false); + } + }; + + return ( + <> + {loader && isAdmin ? ( + + ) : ( + + +

Изменение IP-Адреса

+
+ {checkStatus ? ( + + +

Общие сведения

+ +

Интерфейс: {ipData.device}

+

--{'>'}

+

{ipData.connection}

+
+

Сведения об IP

+ + +

Текущий ip: {ipData.currentIp}

+

Текущий шлюз: {ipData.currentGate}

+

Текущий DNS: {ipData.currentDns}

+
+ + +

Новый ip: {ipData.newIp}

+

Новый шлюз: {ipData.newGate}

+

Новый DNS: {ipData.newDns}

+
+
+
+ + + cancelIp(currentIp)}/> + saveIp(newIP)}/> + +
+ ) : ( + <> + + + {isAdmin ? ( + <> +

Произошла ошибка проверки корректности

+ {message} + + + ):( +

Для изменения сетевых настроек необходимо авторизироваться под администратором

+ )} + +
+
+ + + + + + )} +
+ )} + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/rightsConfirm.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/rightsConfirm.tsx new file mode 100644 index 0000000..24351dd --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalContainers/rightsConfirm.tsx @@ -0,0 +1,135 @@ +import { useEffect, useState } from "react" +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import Input from "../../UI/inputs/input" +import { MainButton } from "../../UI/buttons/mainButton" +import { NetworkService } from "../../../api/request" +import { useIpStore } from "../../../store" +import { useAdminStore } from "../../../store/adminStore" +import { useCheckAdmin } from "../../../utils/checkAdmin" + +import { buttonNames } from "../../../const/buttons/names" +import { IconComponent } from "../../../const/buttons/icons" + +interface Props { + onClose: () => void; +} + +export const RightsConfirm = ({ onClose }: Props) => { + + const { ipAddress } = useIpStore(); + const { isAdmin, setAdmin } = useAdminStore() + const checkAdmin = useCheckAdmin(); + const [error, setError] = useState(false) + const [success, setSuccess] = useState({ + message: '', + status: false + }) + + const [user, setUser] = useState({ + username: 'operator', + password: "" + }) + + const handleChange = (id: string, value: string) => { + setUser(prevData => ({ + ...prevData, + [id]: value + })); + } + + const login = async (user: object) => { + try { + const response = await NetworkService.login(ipAddress, user); + if(response.status === 200){ + await checkAdmin(); + setError(false) + setSuccess(prevData => ({ + ...prevData, + message: 'Успешный вход', + status: true + })); + await new Promise(resolve => setTimeout(resolve, 3000)); + onClose(); + }else{ + setError(true) + } + } catch (err) { + console.error('Error:', err); + } + } + + const logout = async () => { + await NetworkService.logout(ipAddress); + await checkAdmin(); + setSuccess(prevData => ({ + ...prevData, + message: 'Успешный выход', + status: true + })); + await new Promise(resolve => setTimeout(resolve, 3000)); + onClose(); + } + + return ( + + {!success.status ? ( + !isAdmin ? ( + <> + +

Получение прав доступа

+
+ + + +

Включить административный доступ

+ handleChange('password', value)} + /> + + {error && ( +

+ Неверный пароль оператора +

+ )} + +
+ + + + login(user)} /> + + + ) : ( + <> + +

Переключиться на ограниченный доступ

+
+ + +

В данном режиме доступа ограничиваются полномочия администратора.

+
+ + + + + + + + ) + ):( + + +

{success.message}

+

Это окно можно закрыть, либо оно пропадёт само

+ +
+ )} + + +
+ ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/modalWindow.tsx b/FRONT/BUILD/resources/app/src/components/modalwindows/modalWindow.tsx new file mode 100644 index 0000000..7edf179 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/modalWindow.tsx @@ -0,0 +1,81 @@ +import { useModalContext } from "../../store"; +import { IpConfirm, ConnectionError, AddDevice, RightsConfirm } from "./modalContainers"; +import { ModalMap } from "./windowsType"; +import Loader from "../UI/loader"; +import { ModalWindow } from "./style"; +import {NoteDevice} from "./modalContainers/NoteDevice"; +import { NoteWifi } from "./modalContainers/NoteWifi"; +import {ConnectNetwork} from "./modalContainers/ConnectNetwork"; +import {DisconnectConfirm} from "./modalContainers/disconnectConfirm"; + +type Props = { + isOpen: boolean, + type: string + data: any; +} + +export default function WindowComponent({ isOpen, type, data }: Props) { + + const { closeModal, closeLoader } = useModalContext() + + return ( + <> + {isOpen && + + {type == ModalMap['1'] && data && + + } + + {type == ModalMap['2'] && + + } + + {type === ModalMap['3'] && + + } + {type === ModalMap['6'] && ( + + )} + {type === ModalMap['7'] && ( + + )} + {type === ModalMap['8'] && ( + + )} + {type === ModalMap['9'] && ( + + )} + {type === ModalMap['4'] && ( + + )} + + {type === ModalMap['5'] && ( + + )} + + } + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/style.ts b/FRONT/BUILD/resources/app/src/components/modalwindows/style.ts new file mode 100644 index 0000000..2b75bd3 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/style.ts @@ -0,0 +1,70 @@ +import styled from "styled-components"; + +export const ModalWindow = styled.div` + width: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 9999; + background-color: rgba(0, 0, 0, 0.8); + display: flex; + align-items: center; + justify-content: center; + height: 100%; +` + +export const ModalContainer = styled.div<{height?: string}>` + border-radius: 12px; + background: ${(props)=>props.theme.secondary}; + color: ${(props=>props.theme.textColor)}; + position: relative; + max-height: 100%; + overflow: auto; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 15px; + height: ${(props) => props.height ? props.height : '230px'}; + width: 520px; +` + +export const ModalTitle = styled.div` + padding: 20px; + border-bottom: 1px solid #9D9D9D; + display: flex; + justify-content: space-between; + + h3{ + font-size: 18px; + } +` + +export const ModalContent = styled.div` + padding: 0 20px; + + h3{ + font-size: 14px; + } + + p{ + font-size: 12px; + } +` + +export const ModalText = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px; +` + +export const ErrorMessage = styled.p` + color: #d95454; +` + +export const ButtonContainer = styled.div` + justify-content: flex-end; + display: flex; + gap: 10px; + padding: 10px 20px 20px; +` \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/modalwindows/windowsType.ts b/FRONT/BUILD/resources/app/src/components/modalwindows/windowsType.ts new file mode 100644 index 0000000..ae6d760 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/modalwindows/windowsType.ts @@ -0,0 +1,13 @@ +export type ModalType = Record; + +export const ModalMap: ModalType = { + '1': 'ipConfirm', + '2': 'loader', + '3': 'connectionError', + '4': 'addDevice', + '5': 'sudo', + '6': 'noteDevice', + '7': 'noteWifi', + '8': 'connectNetwork', + '9': 'disconnectConfirm', +} diff --git a/FRONT/BUILD/resources/app/src/components/register.tsx b/FRONT/BUILD/resources/app/src/components/register.tsx new file mode 100644 index 0000000..a043285 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/register.tsx @@ -0,0 +1,194 @@ +import { ModalContainer, ModalTitle, ModalContent, ModalText } from "./modalwindows/style" +import Input from "./UI/inputs/input" +import { MainButton } from "./UI/buttons/mainButton" +import styled from "styled-components" +import { useEffect, useState } from "react" +import { useIpStore } from "../store" +import { NetworkService } from "../api/request" +import { IconComponent } from "../const/buttons/icons" +import { buttonNames } from "../const/buttons/names" +import ThemeButton from "./UI/buttons/toggletheme" +import About from "./workSpace/modules/appModules/about" + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + background: ${(props) => props.theme.background}; +` + +const Container = styled.form` + display: flex; + flex-direction: column; + gap: 25px; + align-items: center; + background: ${(props) => props.theme.primary}; + padding: 25px; + border-radius: 18px; + width: 350px; +` + +const Title = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + align-items: center; + text-align: center; + font-size: 20px; +` + +const Content = styled.div` + display: flex; + flex-direction: column; + gap: 25px; + text-align: center; +` + +const ButtonContainer = styled.div` + width: 100%; + display: flex; + justify-content: center; +` + +const Menu = styled.div` + display: flex; + align-items: center; +` + +const Button = styled.div` + width: 100%; + cursor: pointer; +` + +const IconContainer = styled.div` + padding: 10px; + color: ${props => props.theme.text}; +` + +export const CreateUser = () => { + + const { ipAddress, setIpAddress } = useIpStore(); + const [repeatPassword, setRepeatPassword] = useState(''); + const [passwordsMatch, setPasswordsMatch] = useState(true); + const [about, setAbout] = useState(false) + + const [user, setUser] = useState({ + username: 'operator', + password: '', + is_admin: true + }) + + const handleChange = (id: string, value: string) => { + if (id === 'repeatPassword') { + setRepeatPassword(value); + setPasswordsMatch(user.password === value); + } else { + setUser(prevData => ({ + ...prevData, + [id]: value + })); + if (id === 'password') { + setPasswordsMatch(value === repeatPassword); + } + } + } + + const handleSave = async (user: object) => { + try { + const result = await NetworkService.createUser(ipAddress, user); + if (result.status === 200) { window.location.reload() } + } catch (err) { + console.error('Error:', err); + } + } + + const handleSubmit = () => { + if (passwordsMatch) { + handleSave(user); + } + }; + + const back = ()=>{ + setIpAddress('localhost') + } + + const toAbout = ()=>{ + setAbout(true) + } + return ( + + <> + {!about ? ( + + + + + <IconComponent name={buttonNames[3]} width="52" height="52"></IconComponent> + <h3>Настройка оператора узла</h3> + {ipAddress != 'localhost' && + <p>{ipAddress}</p> + } + + + + + +
+

Перед началом работы необходимо создать пароль оператора приложения

+
+ +
+ handleChange('password', value)} + /> + + handleChange('repeatPassword', value)} + style={{ marginTop: '10px' }} + /> + {!passwordsMatch && ( +

+ Пароли не совпадают! +

+ )} +
+ +
+ + + + + + +
+ + + + {ipAddress != 'localhost' && + + } + + + +
+ ): ( + setAbout(false)} /> + )} + + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx new file mode 100644 index 0000000..57207b9 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx @@ -0,0 +1,213 @@ + +import { MainButton } from "../../../UI/buttons/mainButton" +import { workSpaceNames } from "../../../../const/workspace/names" +import { useWorkSpaceStore } from "../../../../store" +import styled from "styled-components" +import ThemeButton from "../../../UI/buttons/toggletheme" + +type Props = { + from: 'reg' | 'helloWindow' | 'workSpace' + onBack?: () => void +} + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + background: ${(props => props.theme.background)}; + padding: 50px; + box-sizing: border-box; +` + +const Content = styled.div` + max-width: 1200px; + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + box-sizing: border-box; + padding: 25px 50px; + background: ${(props => props.theme.secondary)}; + border-radius: 18px; +` + +const Listing = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + +` + +const List = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + margin-left: 10px; +` + +const Title = styled.div` + font-size: 20px; +` + +const SubTitle = styled.div` + display: flex; + flex-direction: column; + gap: 10px; + + p{ + font-size: 18px; + } + +` + +const Links = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +` + +const LinkColumn = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +` + + +const LinkBlock = styled.div` + display: flex; + gap: 5px; +` + +const Copyright = styled.div` + width: 100%; + text-align: center; + margin-top: 50px; +` + +const ButtonContainer = styled.div` + width: 100%; + display: flex; + justifi-content: flex-start; + align-items: center; +` + +const MainTitle = styled.div` + width: 100%; + display: flex; + gap: 15px; + align-items: center; + justify-content: center; + padding-top: 50px; + box-sizing: border-box; + + img{ + width: 40px; + height: 40px; + } +` +const Text = styled.div` + display: flex; + flex-direction: column; + gap: 30px; +` + +export default function About({ from, onBack }: Props) { + const { setWorkModule } = useWorkSpaceStore() + + const getBackHandler = () => { + switch (from) { + case 'reg': + return onBack + case 'helloWindow': + return () => setWorkModule(workSpaceNames[1]) + case 'workSpace': + return () => setWorkModule(workSpaceNames[3]) + default: + return undefined + } + } + + const backHandler = getBackHandler() + const showBackButton = from !== 'reg' || (from === 'reg' && onBack) + + return ( + + + + + +

О приложении

+ +
+ + + + + + <p>Приложение ГоNets является минимально работоспособным кроссплатформенным продуктом (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.</p> + + + + +

Данное приложение умеет:

+ +

- Отображать в графическом виде активные сетевые ресурсы

+

- Настраивать сетевые параметры локального и удаленных сетевых ресурсов

+

- Отображать и изменять взаимодействие сетевых ресурсов с установленным Клиентом ГоNets

+
+
+ + +

Программное обеспечение исключительно для ознакомления и домашнего использования.

+

Для коммерческого использования приобретите версию ГоNets-PRO (Подробная информация на странице продукта)

+
+ + + +

Ссылка на домашнюю страницу:

+ https://gossys.dev/pages/projects/gonets +
+ + +

Инструкции и информация:

+ https://wiki.gossys.dev/ru/gonets +
+ + +

Распространяется под лицензией GosysPUB текущей версии.

+ +

Полный текст актуальной лицензии:

+ https://wiki.gossys.dev/ru/lic/GosysPUB +
+
+ +
+ + +

Разработано и поддерживается ООО «Гибридные Офисные Системы» 2024-2025 г. Все права защищены.

+
+ +
+ + + + {showBackButton && backHandler && ( + + )} + + {from == 'reg' && + + } + +
+ +
+ ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/header.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/header.tsx new file mode 100644 index 0000000..356764b --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/header.tsx @@ -0,0 +1,46 @@ +import styled from "styled-components" +import { IconComponent } from "../../../../const/buttons/icons" +import { buttonNames } from "../../../../const/buttons/names" +import { useWorkSpaceStore } from "../../../../store" +import { useModalContext } from "../../../../store" +import { useAdminStore } from "../../../../store/adminStore" +import { ModalMap } from "../../../modalwindows/windowsType" +import { QuitButton } from "../../../UI/buttons/quitButton" +import { usePosStore } from "../../../../store/posStore" + +const Container = styled.div` + display: flex; + align-items: center; + justify-content: flex-end; + background-color: ${(props) => props.theme.primary}; + padding: 0 5px; +` + +const ButtonContainer = styled.div` + display: flex; + align-items: center; +` + +const IconContainer = styled.div` + padding: 10px; + + svg{ + cursor: pointer; + } +` + +export const Header = () => { + const {setNullPos} = usePosStore() + + return ( + + + + setNullPos(true)}/> + + + + + + ) +} \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/helloWindow.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/helloWindow.tsx new file mode 100644 index 0000000..0a09826 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/helloWindow.tsx @@ -0,0 +1,82 @@ + import styled from "styled-components" + import { MainButton } from "../../../UI/buttons/mainButton" + import { useWorkSpaceStore } from "../../../../store" + import { workSpaceNames } from "../../../../const/workspace/names" + import { buttonNames } from "../../../../const/buttons/names" + + const Wrapper = styled.div` + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: ${(props => props.theme.background)}; + background-image: url('./assets/images/back1.svg'); + background-size: 100%; + background-repeat: no-repeat; + background-position: bottom; + ` + + const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 52px; + margin-bottom: 100px; + ` + + const ButtonWrapper = styled.div` + display: flex; + gap: 75px; + flex-direction: column; + ` + + const ButtonContainer = styled.div` + display: flex; + gap: 15px; + flex-direction: column; + ` + + const Title = styled.div` + display: flex; + align-items: flex-end; + gap: 10px; + + h1{ + font-size: 52px; + } + ` + + export const HelloWindow = () => { + + const { setWorkModule } = useWorkSpaceStore() + + return ( + + + + <img src="./assets/images/logo.svg" alt="" style={{width: '152px'}}/> + + + + + + setWorkModule(workSpaceNames[3])} + /> + setWorkModule(workSpaceNames[4])} + /> + + + + + ) + } \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx new file mode 100644 index 0000000..1075a09 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import styled from 'styled-components'; +import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; +import {DeviceUser} from "../../../../../../store/useDeviceStore"; + +const ScanBtn = styled.button` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; + transition: .4s ease; + &:hover{ + transform: scale(1.03); + } +` + +interface ListUsersProps { + loading: boolean; + handleScan: ()=>void; + devices: DeviceUser[]; + scanInitiated: boolean; +} + +const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps) => { + const activeDevices = devices.filter(device => device.status === 'online'); + const inactiveDevices = devices.filter(device => device.status !== 'online'); + + return ( + <> + + {devices.length > 0 ? 'Обновить список' : 'Сканировать сеть'} + + + {devices.length > 0 ? ( +
+ {/* Колонка активных устройств */} +
+

Активные устройства ({activeDevices.length})

+ {activeDevices.map((device, index) => ( + + ))} +
+ {/* Колонка неактивных устройств */} +
+

Неактивные устройства ({inactiveDevices.length})

+ {inactiveDevices.map((device, index) => ( + + ))} +
+
+ ) : scanInitiated ? ( +

Устройства не найдены

+ ) : null} + + ); +}; + +export default ListUsers; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx new file mode 100644 index 0000000..ebe71a9 --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import styled from 'styled-components'; +import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; +import {DeviceUser} from "../../../../../../store/useDeviceStore"; +import TableScanner from "../../../../../UI/tables/TableScanner"; + +const ScanBtn = styled.button` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; + transition: .4s ease; + &:hover{ + transform: scale(1.03); + } +` + +interface ListUsersProps { + loading: boolean; + handleScan: ()=>void; + devices: DeviceUser[]; + scanInitiated: boolean; +} + +const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps) => { + + return ( + <> + + {devices.length > 0 ? 'Обновить список' : 'Сканировать сеть'} + + + {devices.length > 0 ? ( + + ) : scanInitiated ? ( +

Устройства не найдены

+ ) : null} + + ); +}; + +export default ListUsers; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx new file mode 100644 index 0000000..cb816ca --- /dev/null +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx @@ -0,0 +1,191 @@ +import { useIpStore } from "../../../../../store"; +import styled, { keyframes } from "styled-components"; +import { useState } from "react"; +import { NetworkService } from "../../../../../api/request"; +import ListUsers from "./modules/ListUsers"; +import TableUsers from "./modules/TableUsers"; +import DropdownType from "../../../../UI/Dropdown/DropdownType"; +import useNetworkStore from "../../../../../store/useDeviceStore"; + +type Option ={ + value: number, + label: string, +} + +// Анимации +const ring1 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.12; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.2; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.12; } +`; + +const ring2 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.08; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.15; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.08; } +`; + +const ring3 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.04; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.1; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.04; } +`; +const dotAnimation = keyframes` + 0% { content: '.'; } + 33% { content: '..'; } + 66% { content: '...'; } + 100% { content: '.'; } +`; +const pulse = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); } + 50% { transform: translate(-50%, -50%) scale(1.1); } + 100% { transform: translate(-50%, -50%) scale(1); } +`; + +// Стили +const Wrapper = styled.div<{ scanInitiated: boolean, loading: boolean}>` + display: flex; + flex-direction: column; + align-items: center; + justify-content:${({scanInitiated, loading})=>(scanInitiated && !loading ? 'start' : 'center')}; + height: 100%; + width: 100%; + background: ${(props) => props.theme.background}; + padding: 50px; + box-sizing: border-box; + gap: 24px; + transition: justify-content .4s ease; + overflow-y: auto; + overflow-x: hidden; + position: relative; +`; +const TitleWrapper = styled.h2` + position: absolute; + top: 20px; + left: 50%; + transform: translateX(-50%); + font-size: 32px; + width: max-content; +` +const UserLocate = styled.div<{ loading: boolean, scanInitiated: boolean }>` + width: 60px; + height: 60px; + border-radius: 50%; + position: relative; + transition: .4s ease; + transform: ${({scanInitiated,loading})=>(scanInitiated && !loading ? 'scale(0)' : 'scale(1)')}; + span { + position: absolute; + display: inline-block; + background: ${(props) => props.theme.accent}; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border-radius: 50%; + &.center { + width: 60px; + height: 60px; + animation: ${({ loading }) => (loading ? pulse : "none")} 2s ease infinite; + } + &.ring1 { + opacity: 0.12; + width: 250px; + height: 250px; + animation: ${({ loading }) => (loading ? ring1 : "none")} 4s linear infinite; + } + + &.ring2 { + opacity: 0.08; + width: 400px; + height: 400px; + animation: ${({ loading }) => (loading ? ring2 : "none")} 4s linear infinite; + animation-delay: ${({ loading }) => (loading ? "0.1s" : "0")}; + } + + &.ring3 { + opacity: 0.04; + width: 550px; + height: 550px; + animation: ${({ loading }) => (loading ? ring3 : "none")} 4s linear infinite; + animation-delay: ${({ loading }) => (loading ? "0.2s" : "0")}; + } + } +`; + +const LoadingText = styled.div` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; +`; +const ScanningText = styled.span` + &::after { + content: '.'; + animation: ${dotAnimation} 1.5s infinite; + } +`; + + +export default function UserScanner() { + const { ipAddress } = useIpStore(); + const [loading, setLoading] = useState(false); + const { devices, setDevices } = useNetworkStore(); + const [scanInitiated, setScanInitiated] = useState(devices.length > 0); + + // Сканирование + const handleScan = async () => { + try { + setLoading(true); + setScanInitiated(true); + const res = await NetworkService.scanUser(ipAddress); + console.log(res); + setDevices(res.data.devices || []); + } catch (err) { + console.error("Ошибка сканирования сети:", err); + setDevices([]) + } finally { + setLoading(false); + } + }; + + // Способ отображения + const viewOptions: Option[] = [ + { value: 1, label: 'Таблица' }, + { value: 2, label: 'Список' }, + ]; + const [selectedView, setSelectedView] = useState