Merge branch 'anis_link_with_sdk_client' into dev
This commit is contained in:
commit
427252e4a7
440
package-lock.json
generated
440
package-lock.json
generated
@ -9,9 +9,12 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"@vitejs/plugin-vue": "^5.0.5",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"vite": "^5.3.3",
|
"html5-qrcode": "^2.3.8",
|
||||||
|
"qrcode": "^1.5.3",
|
||||||
|
"vite": "^5.4.9",
|
||||||
"vite-plugin-copy": "^0.1.6",
|
"vite-plugin-copy": "^0.1.6",
|
||||||
"vite-plugin-html": "^3.2.2",
|
"vite-plugin-html": "^3.2.2",
|
||||||
"vite-plugin-wasm": "^3.3.0"
|
"vite-plugin-wasm": "^3.3.0"
|
||||||
@ -912,192 +915,208 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
|
||||||
"integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
|
"integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz",
|
||||||
"integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
|
"integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
|
||||||
"integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
|
"integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz",
|
||||||
"integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
|
"integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz",
|
||||||
"integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
|
"integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz",
|
||||||
"integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
|
"integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz",
|
||||||
"integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
|
"integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz",
|
||||||
"integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
|
"integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz",
|
||||||
"integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
|
"integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz",
|
||||||
"integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
|
"integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz",
|
||||||
"integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
|
"integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz",
|
||||||
"integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
|
"integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz",
|
||||||
"integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
|
"integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz",
|
||||||
"integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
|
"integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz",
|
||||||
"integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
|
"integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz",
|
||||||
"integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
|
"integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@ -1211,9 +1230,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/express": {
|
"node_modules/@types/express": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
@ -1276,7 +1296,6 @@
|
|||||||
"version": "20.14.9",
|
"version": "20.14.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
|
||||||
"integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
|
"integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
|
||||||
"devOptional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
@ -1290,6 +1309,14 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/qrcode": {
|
||||||
|
"version": "1.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz",
|
||||||
|
"integrity": "sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/qs": {
|
"node_modules/@types/qs": {
|
||||||
"version": "6.9.15",
|
"version": "6.9.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
|
||||||
@ -1794,7 +1821,6 @@
|
|||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -2028,6 +2054,14 @@
|
|||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/camelcase": {
|
||||||
|
"version": "5.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||||
|
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001640",
|
"version": "1.0.30001640",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
|
||||||
@ -2116,6 +2150,77 @@
|
|||||||
"node": ">= 10.0"
|
"node": ">= 10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cliui": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"strip-ansi": "^6.0.0",
|
||||||
|
"wrap-ansi": "^6.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/wrap-ansi": {
|
||||||
|
"version": "6.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||||
|
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/clone-deep": {
|
"node_modules/clone-deep": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
||||||
@ -2358,6 +2463,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/decamelize": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/default-browser": {
|
"node_modules/default-browser": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
||||||
@ -2452,6 +2565,11 @@
|
|||||||
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/dijkstrajs": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
|
||||||
|
},
|
||||||
"node_modules/dns-packet": {
|
"node_modules/dns-packet": {
|
||||||
"version": "5.6.1",
|
"version": "5.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
||||||
@ -2589,6 +2707,11 @@
|
|||||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/encode-utf8": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
|
||||||
|
},
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
@ -3011,7 +3134,6 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"locate-path": "^5.0.0",
|
"locate-path": "^5.0.0",
|
||||||
"path-exists": "^4.0.0"
|
"path-exists": "^4.0.0"
|
||||||
@ -3138,6 +3260,14 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-caller-file": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||||
|
"engines": {
|
||||||
|
"node": "6.* || 8.* || >= 10.*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||||
@ -3459,6 +3589,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html5-qrcode": {
|
||||||
|
"version": "2.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.3.8.tgz",
|
||||||
|
"integrity": "sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ=="
|
||||||
|
},
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
|
||||||
@ -3680,7 +3815,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -4025,7 +4159,6 @@
|
|||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-locate": "^4.1.0"
|
"p-locate": "^4.1.0"
|
||||||
},
|
},
|
||||||
@ -4391,7 +4524,6 @@
|
|||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-try": "^2.0.0"
|
"p-try": "^2.0.0"
|
||||||
},
|
},
|
||||||
@ -4406,7 +4538,6 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-limit": "^2.2.0"
|
"p-limit": "^2.2.0"
|
||||||
},
|
},
|
||||||
@ -4435,7 +4566,6 @@
|
|||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@ -4477,7 +4607,6 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -4546,9 +4675,10 @@
|
|||||||
"integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw=="
|
"integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw=="
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
|
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
@ -4573,10 +4703,18 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pngjs": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.39",
|
"version": "8.4.47",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||||
"integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
|
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -4591,10 +4729,11 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.7",
|
"nanoid": "^3.3.7",
|
||||||
"picocolors": "^1.0.1",
|
"picocolors": "^1.1.0",
|
||||||
"source-map-js": "^1.2.0"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
@ -4647,6 +4786,23 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/qrcode": {
|
||||||
|
"version": "1.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
|
||||||
|
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
|
||||||
|
"dependencies": {
|
||||||
|
"dijkstrajs": "^1.0.1",
|
||||||
|
"encode-utf8": "^1.0.3",
|
||||||
|
"pngjs": "^5.0.0",
|
||||||
|
"yargs": "^15.3.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"qrcode": "bin/qrcode"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.11.0",
|
"version": "6.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||||
@ -4790,6 +4946,14 @@
|
|||||||
"strip-ansi": "^6.0.1"
|
"strip-ansi": "^6.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/require-directory": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/require-from-string": {
|
"node_modules/require-from-string": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||||
@ -4799,6 +4963,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/require-main-filename": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||||
|
},
|
||||||
"node_modules/requires-port": {
|
"node_modules/requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
@ -4880,11 +5049,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.18.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz",
|
||||||
"integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
|
"integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.5"
|
"@types/estree": "1.0.6"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
@ -4894,22 +5064,22 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.18.0",
|
"@rollup/rollup-android-arm-eabi": "4.24.0",
|
||||||
"@rollup/rollup-android-arm64": "4.18.0",
|
"@rollup/rollup-android-arm64": "4.24.0",
|
||||||
"@rollup/rollup-darwin-arm64": "4.18.0",
|
"@rollup/rollup-darwin-arm64": "4.24.0",
|
||||||
"@rollup/rollup-darwin-x64": "4.18.0",
|
"@rollup/rollup-darwin-x64": "4.24.0",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.24.0",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.18.0",
|
"@rollup/rollup-linux-arm-musleabihf": "4.24.0",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.18.0",
|
"@rollup/rollup-linux-arm64-gnu": "4.24.0",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.18.0",
|
"@rollup/rollup-linux-arm64-musl": "4.24.0",
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
|
"@rollup/rollup-linux-powerpc64le-gnu": "4.24.0",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.18.0",
|
"@rollup/rollup-linux-riscv64-gnu": "4.24.0",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.18.0",
|
"@rollup/rollup-linux-s390x-gnu": "4.24.0",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.18.0",
|
"@rollup/rollup-linux-x64-gnu": "4.24.0",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.18.0",
|
"@rollup/rollup-linux-x64-musl": "4.24.0",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.18.0",
|
"@rollup/rollup-win32-arm64-msvc": "4.24.0",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.18.0",
|
"@rollup/rollup-win32-ia32-msvc": "4.24.0",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.18.0",
|
"@rollup/rollup-win32-x64-msvc": "4.24.0",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -5166,6 +5336,11 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-blocking": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||||
|
},
|
||||||
"node_modules/set-function-length": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
@ -5287,9 +5462,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -5420,7 +5596,6 @@
|
|||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": "^5.0.1"
|
"ansi-regex": "^5.0.1"
|
||||||
},
|
},
|
||||||
@ -5794,8 +5969,7 @@
|
|||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||||
"devOptional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/unicorn-magic": {
|
"node_modules/unicorn-magic": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
@ -5904,13 +6078,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.3.3",
|
"version": "5.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz",
|
||||||
"integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==",
|
"integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.21.3",
|
"esbuild": "^0.21.3",
|
||||||
"postcss": "^8.4.39",
|
"postcss": "^8.4.43",
|
||||||
"rollup": "^4.13.0"
|
"rollup": "^4.20.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
@ -5929,6 +6104,7 @@
|
|||||||
"less": "*",
|
"less": "*",
|
||||||
"lightningcss": "^1.21.0",
|
"lightningcss": "^1.21.0",
|
||||||
"sass": "*",
|
"sass": "*",
|
||||||
|
"sass-embedded": "*",
|
||||||
"stylus": "*",
|
"stylus": "*",
|
||||||
"sugarss": "*",
|
"sugarss": "*",
|
||||||
"terser": "^5.4.0"
|
"terser": "^5.4.0"
|
||||||
@ -5946,6 +6122,9 @@
|
|||||||
"sass": {
|
"sass": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"sass-embedded": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"stylus": {
|
"stylus": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
@ -6381,6 +6560,11 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/which-module": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
|
||||||
|
},
|
||||||
"node_modules/wildcard": {
|
"node_modules/wildcard": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
||||||
@ -6535,10 +6719,66 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/y18n": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||||
|
},
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||||
|
},
|
||||||
|
"node_modules/yargs": {
|
||||||
|
"version": "15.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||||
|
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||||
|
"dependencies": {
|
||||||
|
"cliui": "^6.0.0",
|
||||||
|
"decamelize": "^1.2.0",
|
||||||
|
"find-up": "^4.1.0",
|
||||||
|
"get-caller-file": "^2.0.1",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"require-main-filename": "^2.0.0",
|
||||||
|
"set-blocking": "^2.0.0",
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"which-module": "^2.0.0",
|
||||||
|
"y18n": "^4.0.0",
|
||||||
|
"yargs-parser": "^18.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs-parser": {
|
||||||
|
"version": "18.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||||
|
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"camelcase": "^5.0.0",
|
||||||
|
"decamelize": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
package.json
11
package.json
@ -2,12 +2,12 @@
|
|||||||
"name": "sdk_client",
|
"name": "sdk_client",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"build_wasm": "wasm-pack build --out-dir ../../dist/pkg ./crates/sp_client --target bundler --dev",
|
"build_wasm": "wasm-pack build --out-dir ../ihm_client/dist/pkg ../sdk_client --target bundler --dev",
|
||||||
"start": "vite --host 0.0.0.0",
|
"start": "vite --host 0.0.0.0",
|
||||||
"build": "webpack",
|
"build": "tsc && vite build",
|
||||||
"deploy": "sudo cp -r dist/* /var/www/html/"
|
"deploy": "sudo cp -r dist/* /var/www/html/"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
@ -24,9 +24,12 @@
|
|||||||
"webpack-dev-server": "^5.0.2"
|
"webpack-dev-server": "^5.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"@vitejs/plugin-vue": "^5.0.5",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"vite": "^5.3.3",
|
"html5-qrcode": "^2.3.8",
|
||||||
|
"qrcode": "^1.5.3",
|
||||||
|
"vite": "^5.4.9",
|
||||||
"vite-plugin-copy": "^0.1.6",
|
"vite-plugin-copy": "^0.1.6",
|
||||||
"vite-plugin-html": "^3.2.2",
|
"vite-plugin-html": "^3.2.2",
|
||||||
"vite-plugin-wasm": "^3.3.0"
|
"vite-plugin-wasm": "^3.3.0"
|
||||||
|
@ -20,6 +20,10 @@ body {
|
|||||||
background-blend-mode :soft-light;
|
background-blend-mode :soft-light;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
.message {
|
||||||
|
font-size: 14px;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
/** Modal Css */
|
/** Modal Css */
|
||||||
.modal {
|
.modal {
|
||||||
@ -35,10 +39,10 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
width: 40%;
|
width: 55%;
|
||||||
height: 40%;
|
height: 30%;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 8px;
|
border-radius: 4px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -48,23 +52,21 @@ body {
|
|||||||
|
|
||||||
.modal-title {
|
.modal-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 1.5em;
|
font-size: 0.9em;
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirmation-box {
|
.confirmation-box {
|
||||||
margin-top: 20px;
|
/* margin-top: 20px; */
|
||||||
align-content: center;
|
align-content: center;
|
||||||
width: 40%;
|
width: 70%;
|
||||||
height: 20%;
|
height: 20%;
|
||||||
padding: 20px;
|
/* padding: 20px; */
|
||||||
background-color: var(--secondary-color);
|
font-size: 1.5em;
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 1.2em;
|
|
||||||
color: #333333;
|
color: #333333;
|
||||||
top: 20%;
|
top: 5%;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +108,32 @@ body {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.notification-board {
|
||||||
|
position: absolute;
|
||||||
|
width: 20rem;
|
||||||
|
min-height: 8rem;
|
||||||
|
background-color: white;
|
||||||
|
right: 0.5rem;
|
||||||
|
display: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.notification-element {
|
||||||
|
padding: .8rem 0;
|
||||||
|
width: 100%;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(26, 28, 24, .08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.notification-element:not(:last-child) {
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-logo {
|
.brand-logo {
|
||||||
@ -130,6 +158,10 @@ body {
|
|||||||
grid-column: 2 / 7;
|
grid-column: 2 / 7;
|
||||||
grid-row: 3 ;
|
grid-row: 3 ;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
padding: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-height: 50vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -219,7 +251,7 @@ body {
|
|||||||
.tab-content.active {
|
.tab-content.active {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-evenly;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 80%;
|
height: 80%;
|
||||||
}
|
}
|
||||||
@ -235,6 +267,12 @@ body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
.camera-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
/* height: 200px; */
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -258,6 +296,7 @@ body {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
box-sizing: border-box;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -265,13 +304,18 @@ body {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
min-height: 40vh;
|
min-height: 40vh;
|
||||||
max-height: 60vh;
|
max-height: 60vh;
|
||||||
justify-content: space-between;
|
justify-content: flex-start;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -282,7 +326,13 @@ body {
|
|||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
.process-element {
|
.process-element {
|
||||||
padding: .3rem 0;
|
padding: .4rem 0;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(26, 28, 24, .08);
|
||||||
|
}
|
||||||
|
&.selected {
|
||||||
|
background-color: rgba(26, 28, 24, .08);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,6 +341,11 @@ body {
|
|||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
color: #333;
|
color: #333;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -324,8 +379,22 @@ body {
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.qr-code-scanner {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* QR READER */
|
||||||
|
#qr-reader div {
|
||||||
|
position: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qr-reader div img{
|
||||||
|
top: 15px ;
|
||||||
|
right: 25px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* INPUT CSS **/
|
/* INPUT CSS **/
|
||||||
.input-container {
|
.input-container {
|
||||||
|
178
src/database.ts
178
src/database.ts
@ -1,178 +0,0 @@
|
|||||||
class Database {
|
|
||||||
private static instance: Database;
|
|
||||||
private db: IDBDatabase | null = null;
|
|
||||||
private dbName: string = '4nk';
|
|
||||||
private dbVersion: number = 1;
|
|
||||||
private storeDefinitions = {
|
|
||||||
AnkUser: {
|
|
||||||
name: "user",
|
|
||||||
options: {'keyPath': 'pre_id'},
|
|
||||||
indices: []
|
|
||||||
},
|
|
||||||
AnkSession: {
|
|
||||||
name: "session",
|
|
||||||
options: {},
|
|
||||||
indices: []
|
|
||||||
},
|
|
||||||
AnkProcess: {
|
|
||||||
name: "process",
|
|
||||||
options: {'keyPath': 'id'},
|
|
||||||
indices: [{
|
|
||||||
name: 'by_name',
|
|
||||||
keyPath: 'name',
|
|
||||||
options: {
|
|
||||||
'unique': true
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
AnkMessages: {
|
|
||||||
name: "messages",
|
|
||||||
options: {'keyPath': 'id'},
|
|
||||||
indices: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private constructor to prevent direct instantiation from outside
|
|
||||||
private constructor() {}
|
|
||||||
|
|
||||||
// Method to access the singleton instance of Database
|
|
||||||
public static async getInstance(): Promise<Database> {
|
|
||||||
if (!Database.instance) {
|
|
||||||
Database.instance = new Database();
|
|
||||||
await Database.instance.init();
|
|
||||||
}
|
|
||||||
return Database.instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the database
|
|
||||||
private async init(): Promise<void> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const request = indexedDB.open(this.dbName, this.dbVersion);
|
|
||||||
|
|
||||||
request.onupgradeneeded = () => {
|
|
||||||
const db = request.result;
|
|
||||||
|
|
||||||
Object.values(this.storeDefinitions).forEach(({name, options, indices}) => {
|
|
||||||
if (!db.objectStoreNames.contains(name)) {
|
|
||||||
let store = db.createObjectStore(name, options);
|
|
||||||
|
|
||||||
indices.forEach(({name, keyPath, options}) => {
|
|
||||||
store.createIndex(name, keyPath, options);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
request.onsuccess = () => {
|
|
||||||
this.db = request.result;
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
|
|
||||||
request.onerror = () => {
|
|
||||||
console.error("Database error:", request.error);
|
|
||||||
reject(request.error);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getDb(): Promise<IDBDatabase> {
|
|
||||||
if (!this.db) {
|
|
||||||
await this.init();
|
|
||||||
}
|
|
||||||
return this.db!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getStoreList(): {[key: string]: string} {
|
|
||||||
const objectList: {[key: string]: string} = {};
|
|
||||||
Object.keys(this.storeDefinitions).forEach(key => {
|
|
||||||
objectList[key] = this.storeDefinitions[key as keyof typeof this.storeDefinitions].name;
|
|
||||||
});
|
|
||||||
return objectList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public writeObject(db: IDBDatabase, storeName: string, obj: any, key: IDBValidKey | null): Promise<IDBRequest> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readwrite');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
let request: IDBRequest<any>;
|
|
||||||
if (key) {
|
|
||||||
request = store.add(obj, key);
|
|
||||||
} else {
|
|
||||||
request = store.add(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = () => reject(request.error);
|
|
||||||
request.onsuccess = () => resolve(request.result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public getObject<T>(db: IDBDatabase, storeName: string, key: IDBValidKey): Promise<T> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readonly');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
const request = store.get(key);
|
|
||||||
|
|
||||||
request.onerror = () => reject(request.error);
|
|
||||||
request.onsuccess = () => resolve(request.result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public rmObject(db: IDBDatabase, storeName: string, key: IDBValidKey): Promise<void> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readwrite');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
const request = store.delete(key);
|
|
||||||
|
|
||||||
request.onerror = () => reject(request.error);
|
|
||||||
request.onsuccess = () => resolve(request.result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public getFirstMatchWithIndex<T>(db: IDBDatabase, storeName: string, indexName: string, lookup: string): Promise<T | null> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readonly');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
const index = store.index(indexName);
|
|
||||||
const request = index.openCursor(IDBKeyRange.only(lookup));
|
|
||||||
|
|
||||||
request.onerror = () => reject(request.error);
|
|
||||||
request.onsuccess = () => {
|
|
||||||
const cursor = request.result;
|
|
||||||
if (cursor) {
|
|
||||||
resolve(cursor.value);
|
|
||||||
} else {
|
|
||||||
resolve(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public setObject(db: IDBDatabase, storeName: string, obj: any, key: string | null): Promise<IDBRequest> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readwrite');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
let request: IDBRequest<any>;
|
|
||||||
if (key) {
|
|
||||||
request = store.put(obj, key);
|
|
||||||
} else {
|
|
||||||
request = store.put(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = () => reject(request.error);
|
|
||||||
request.onsuccess = () => resolve(request.result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public getAll<T>(db: IDBDatabase, storeName: string): Promise<T[]> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readonly');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
const request = store.getAll();
|
|
||||||
|
|
||||||
request.onerror = () => reject(request.error);
|
|
||||||
request.onsuccess = () => resolve(request.result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Database;
|
|
16
src/html/confirmation-modal.html
Normal file
16
src/html/confirmation-modal.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<div id="modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-title">Login</div>
|
||||||
|
<div class="message">
|
||||||
|
Do you want to pair device?
|
||||||
|
<!-- Attempting to pair device with address
|
||||||
|
<strong>{{device1}}</strong>
|
||||||
|
with device with address
|
||||||
|
<strong>{{device2}}</strong> -->
|
||||||
|
</div>
|
||||||
|
<div class="confirmation-box">
|
||||||
|
<a class="btn confirmation-btn" onclick="confirm()">Confirm</a>
|
||||||
|
<a class="btn refusal-btn" onclick="closeConfirmationModal()">Refuse</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
13
src/html/confirmation-modal.js
Normal file
13
src/html/confirmation-modal.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Routing from "/src/services/routing.service.ts";
|
||||||
|
|
||||||
|
const router = await Routing.getInstance();
|
||||||
|
export async function confirm() {
|
||||||
|
router.confirmPairing()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function closeConfirmationModal() {
|
||||||
|
router.closeConirmationModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
window.confirm = confirm;
|
||||||
|
window.closeConfirmationModal = closeConfirmationModal;
|
@ -4,11 +4,14 @@
|
|||||||
<div class="brand-logo">4NK</div>
|
<div class="brand-logo">4NK</div>
|
||||||
<div class="nav-right-icons">
|
<div class="nav-right-icons">
|
||||||
<div class="notification-container">
|
<div class="notification-container">
|
||||||
<div class="bell-icon">
|
<div id="notification-bell" class="bell-icon">
|
||||||
<svg class="notification-bell" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
<svg class="notification-bell" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||||
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
|
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="notification-badge">1</div>
|
<div class="notification-badge"></div>
|
||||||
|
<div id="notification-board" class="notification-board">
|
||||||
|
<div class="no-notification">No notifications available</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="burger-menu">
|
<div class="burger-menu">
|
||||||
@ -18,7 +21,7 @@
|
|||||||
|
|
||||||
<div class="menu-content" id="menu">
|
<div class="menu-content" id="menu">
|
||||||
<a href="#">Import</a>
|
<a href="#">Import</a>
|
||||||
<button onclick="openModal()">Open Modal</button>
|
<!-- <button onclick="openModal()">Open Modal</button> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,28 +46,28 @@
|
|||||||
<div class="card-image qr-code">
|
<div class="card-image qr-code">
|
||||||
<img src="assets/qr_code.png" alt="QR Code" width="150" height="150">
|
<img src="assets/qr_code.png" alt="QR Code" width="150" height="150">
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action">
|
|
||||||
<a id="scan-this-device" class="btn">OK</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div id="tab2" class="card tab-content">
|
<div id="tab2" class="card tab-content">
|
||||||
<div class="card-description">
|
<div class="card-description">
|
||||||
Scan your other device :
|
Scan your other device :
|
||||||
</div>
|
</div>
|
||||||
<div class="card-image qr-code">
|
<div class="card-image camera-card">
|
||||||
<img src="assets/camera.jpg" alt="QR Code" width="150" height="150">
|
<img id="scanner" src="assets/camera.jpg" alt="QR Code" width="150" height="150">
|
||||||
|
<div class="qr-code-scanner">
|
||||||
|
<div id="qr-reader" style="width:200px; display: contents;"></div>
|
||||||
|
<div id="qr-reader-results"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action">
|
|
||||||
<a id="scan-device" class="btn">OK</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="modal" class="modal">
|
<!-- <div id="modal" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-title">Login</div>
|
<div class="modal-title">Login</div>
|
||||||
<div class="confirmation-box">Waiting for confirmation...</div>
|
<div class="confirmation-box">Waiting for confirmation...</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import Routing from "/src/services/routing.service.ts";
|
||||||
|
import Services from "/src/services/service.ts";
|
||||||
|
|
||||||
document.querySelectorAll('.tab').forEach(tab => {
|
document.querySelectorAll('.tab').forEach(tab => {
|
||||||
tab.addEventListener('click', () => {
|
tab.addEventListener('click', () => {
|
||||||
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
||||||
@ -7,7 +10,11 @@ document.querySelectorAll('.tab').forEach(tab => {
|
|||||||
document.getElementById(tab.getAttribute('data-tab')).classList.add('active');
|
document.getElementById(tab.getAttribute('data-tab')).classList.add('active');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
function toggleMenu() {
|
|
||||||
|
document.getElementById('notification-bell').addEventListener('click', openCloseNotifications);
|
||||||
|
|
||||||
|
|
||||||
|
export function toggleMenu() {
|
||||||
var menu = document.getElementById('menu');
|
var menu = document.getElementById('menu');
|
||||||
if (menu.style.display === 'block') {
|
if (menu.style.display === 'block') {
|
||||||
menu.style.display = 'none';
|
menu.style.display = 'none';
|
||||||
@ -16,19 +23,80 @@ document.querySelectorAll('.tab').forEach(tab => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Modal
|
//// Modal
|
||||||
function openModal() {
|
export async function openModal(myAddress, receiverAddress) {
|
||||||
document.getElementById('modal').style.display = 'flex';
|
const router = await Routing.getInstance();
|
||||||
|
router.openLoginModal(myAddress, receiverAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeModal() {
|
|
||||||
document.getElementById('modal').style.display = 'none';
|
function openCloseNotifications() {
|
||||||
|
const notifications = document.querySelector('.notification-board')
|
||||||
|
notifications.style.display = notifications?.style.display === 'none' ? 'block' : 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close modal when clicking outside of it
|
// const service = await Services.getInstance()
|
||||||
window.onclick = function(event) {
|
// service.setNotification()
|
||||||
const modal = document.getElementById('modal');
|
|
||||||
if (event.target === modal) {
|
window.toggleMenu = toggleMenu;
|
||||||
closeModal();
|
window.openModal = openModal;
|
||||||
|
|
||||||
|
/// Scan QR Code
|
||||||
|
function docReady(fn) {
|
||||||
|
// see if DOM is already available
|
||||||
|
if (document.readyState === "complete"
|
||||||
|
|| document.readyState === "interactive") {
|
||||||
|
// call on next available tick
|
||||||
|
setTimeout(fn, 1);
|
||||||
|
} else {
|
||||||
|
document.addEventListener("DOMContentLoaded", fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
docReady(function () {
|
||||||
|
scanDevice();
|
||||||
|
var resultContainer = document.getElementById('qr-reader-results');
|
||||||
|
var lastResult, countResults = 0;
|
||||||
|
async function onScanSuccess(decodedText, decodedResult) {
|
||||||
|
if (lastResult === decodedText) { return; }
|
||||||
|
lastResult = decodedText;
|
||||||
|
++countResults;
|
||||||
|
// Handle on success condition with the decoded message.
|
||||||
|
console.log(`Scan result ${decodedText}`, decodedResult);
|
||||||
|
try {
|
||||||
|
// Attempt to parse the decoded text as a URL
|
||||||
|
const scannedUrl = new URL(decodedText);
|
||||||
|
|
||||||
|
// Extract the 'sp_address' parameter
|
||||||
|
const spAddress = scannedUrl.searchParams.get('sp_address');
|
||||||
|
|
||||||
|
if (spAddress) {
|
||||||
|
html5QrcodeScanner.clear();
|
||||||
|
const service = await Services.getInstance()
|
||||||
|
// Call the sendPairingTx function with the extracted sp_address
|
||||||
|
await service.sendPairingTx(spAddress);
|
||||||
|
} else {
|
||||||
|
console.error('The scanned URL does not contain the sp_address parameter.');
|
||||||
|
alert('Invalid QR code: sp_address parameter missing.');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Handle cases where decodedText is not a valid URL
|
||||||
|
console.error('Scanned text is not a valid URL:', error);
|
||||||
|
alert('Invalid QR code: Unable to parse URL.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var html5QrcodeScanner = new Html5QrcodeScanner(
|
||||||
|
"qr-reader", { fps: 10, qrbox: 250 });
|
||||||
|
html5QrcodeScanner.render(onScanSuccess);
|
||||||
|
});
|
||||||
|
|
||||||
|
function scanDevice() {
|
||||||
|
const scannerImg = document.querySelector('#scanner')
|
||||||
|
if(scannerImg) scannerImg.style.display = 'none'
|
||||||
|
const scannerQrCode = document.querySelector('.qr-code-scanner')
|
||||||
|
if(scannerQrCode) scannerQrCode.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
window.scanDevice = scanDevice
|
16
src/html/login-modal.html
Normal file
16
src/html/login-modal.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<div id="login-modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-title">Login</div>
|
||||||
|
<div class="confirmation-box">
|
||||||
|
<div class="message">
|
||||||
|
Attempting to pair device with address
|
||||||
|
<strong>{{device1}}</strong>
|
||||||
|
with device with address
|
||||||
|
<strong>{{device2}}</strong>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Awaiting pairing validation...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
13
src/html/login-modal.js
Normal file
13
src/html/login-modal.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Routing from "/src/services/routing.service.ts";
|
||||||
|
|
||||||
|
const router = await Routing.getInstance();
|
||||||
|
export async function confirmLogin() {
|
||||||
|
router.confirmLogin()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function closeLoginModal() {
|
||||||
|
router.closeLoginModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
window.confirmLogin = confirmLogin;
|
||||||
|
window.closeLoginModal = closeLoginModal;
|
@ -17,7 +17,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<div class="menu-content" id="menu">
|
<div class="menu-content" id="menu">
|
||||||
<a href="#">Revoke</a>
|
<a href="#" onclick="unpair()">Revoke</a>
|
||||||
<a href="#">Export</a>
|
<a href="#">Export</a>
|
||||||
<a href="#">Import</a>
|
<a href="#">Import</a>
|
||||||
<a href="#">Disconnect</a>
|
<a href="#">Disconnect</a>
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-description">
|
<div class="card-description">
|
||||||
<div class="input-container">
|
<div class="input-container">
|
||||||
<select multiple data-multi-select-plugin id="autocoplete" placeholder="Filter processes..." class="select-field">
|
<select multiple data-multi-select-plugin id="autocomplete" placeholder="Filter processes..." class="select-field">
|
||||||
</select>
|
</select>
|
||||||
<label for="autocomplete" class="input-label">Filter processes :</label>
|
<label for="autocomplete" class="input-label">Filter processes :</label>
|
||||||
<div class="selected-processes"></div>
|
<div class="selected-processes"></div>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import Services from "/src/services/service.ts";
|
||||||
|
|
||||||
function toggleMenu() {
|
function toggleMenu() {
|
||||||
const menu = document.getElementById("menu");
|
const menu = document.getElementById("menu");
|
||||||
if (menu.style.display === "block") {
|
if (menu.style.display === "block") {
|
||||||
@ -7,43 +9,6 @@ function toggleMenu() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input for filtering script
|
|
||||||
// var processeList = [
|
|
||||||
// {
|
|
||||||
// id: 1,
|
|
||||||
// name: "Messaging",
|
|
||||||
// description: "Encrypted messages",
|
|
||||||
// zoneList: [
|
|
||||||
// {
|
|
||||||
// id: 1,
|
|
||||||
// name: "General",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 2,
|
|
||||||
// name: "Storage",
|
|
||||||
// description: "Distributed storage",
|
|
||||||
// zoneList: [
|
|
||||||
// {
|
|
||||||
// id: 1,
|
|
||||||
// name: "Paris",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 2,
|
|
||||||
// name: "Normandy",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 3,
|
|
||||||
// name: "New York",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 4,
|
|
||||||
// name: "Moscow",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// Initialize function, create initial tokens with itens that are already selected by the user
|
// Initialize function, create initial tokens with itens that are already selected by the user
|
||||||
function init(element) {
|
function init(element) {
|
||||||
@ -407,3 +372,11 @@ document.addEventListener("click", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export async function unpair() {
|
||||||
|
const service = await Services.getInstance()
|
||||||
|
await service.unpairDevice()
|
||||||
|
}
|
||||||
|
|
||||||
|
window.unpair = unpair;
|
@ -6,7 +6,8 @@
|
|||||||
<meta name="description" content="4NK Web5 Platform">
|
<meta name="description" content="4NK Web5 Platform">
|
||||||
<meta name="keywords" content="4NK web5 bitcoin blockchain decentralize dapps relay contract">
|
<meta name="keywords" content="4NK web5 bitcoin blockchain decentralize dapps relay contract">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="/style/4nk.css">
|
<link rel="stylesheet" href="./style/4nk.css">
|
||||||
|
<script src="https://unpkg.com/html5-qrcode"></script>
|
||||||
<title>4NK Application</title>
|
<title>4NK Application</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
29
src/index.ts
29
src/index.ts
@ -1,12 +1,31 @@
|
|||||||
import Services from './services';
|
import Services from './services/service';
|
||||||
import { WebSocketClient } from './websockets';
|
|
||||||
|
|
||||||
const wsurl = `wss://${window.location.hostname}/ws/`;
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const services = await Services.getInstance();
|
const services = await Services.getInstance();
|
||||||
await services.addWebsocketConnection(wsurl);
|
setTimeout( async () => {
|
||||||
await services.recoverInjectHtml()
|
let device = await services.getDevice()
|
||||||
|
|
||||||
|
if(!device) {
|
||||||
|
device = await services.createNewDevice();
|
||||||
|
} else {
|
||||||
|
await services.restoreDevice(device)
|
||||||
|
}
|
||||||
|
await services.restoreProcesses();
|
||||||
|
await services.restoreMessages();
|
||||||
|
|
||||||
|
if (services.isPaired()) { await services.injectProcessListPage() }
|
||||||
|
else {
|
||||||
|
const queryString = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(queryString)
|
||||||
|
const pairingAddress = urlParams.get('sp_address')
|
||||||
|
|
||||||
|
if(pairingAddress) {
|
||||||
|
setTimeout(async () => await services.sendPairingTx(pairingAddress), 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
22
src/models/notification.model.ts
Normal file
22
src/models/notification.model.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export interface INotification {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
sendToNotificationPage?: boolean;
|
||||||
|
path?: string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Quelles sont les données utiles pour le user ???
|
||||||
|
export interface IUser {
|
||||||
|
id: string;
|
||||||
|
information?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Quelles sont les données utiles pour les messages ???
|
||||||
|
export interface IMessage {
|
||||||
|
id: string;
|
||||||
|
message: any
|
||||||
|
}
|
23
src/models/process.model.ts
Normal file
23
src/models/process.model.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
export interface IProcess {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
icon?: string;
|
||||||
|
zoneList: IZone[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IZone {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
// Est-ce que la zone a besoin d'une icone ?
|
||||||
|
icon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface INotification {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
sendToNotificationPage?: boolean;
|
||||||
|
path?: string;
|
||||||
|
}
|
16
src/scanner.js
Normal file
16
src/scanner.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
function onScanSuccess(decodedText, decodedResult) {
|
||||||
|
// handle the scanned code as you like, for example:
|
||||||
|
console.log(`Code matched = ${decodedText}`, decodedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScanFailure(error) {
|
||||||
|
// handle scan failure, usually better to ignore and keep scanning.
|
||||||
|
// for example:
|
||||||
|
console.warn(`Code scan error = ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let html5QrcodeScanner = new Html5QrcodeScanner(
|
||||||
|
"reader",
|
||||||
|
{ fps: 10, qrbox: {width: 250, height: 250} },
|
||||||
|
/* verbose= */ false);
|
||||||
|
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
|
183
src/services.ts
183
src/services.ts
@ -1,183 +0,0 @@
|
|||||||
import { WebSocketClient } from './websockets';
|
|
||||||
import homePage from './html/home.html?raw';
|
|
||||||
import homeScript from './html/home.js?raw';
|
|
||||||
import processPage from './html/process.html?raw';
|
|
||||||
import processScript from './html/process.js?raw';
|
|
||||||
|
|
||||||
export default class Services {
|
|
||||||
private static instance: Services;
|
|
||||||
private current_process: string | null = null;
|
|
||||||
private websocketConnection: WebSocketClient[] = [];
|
|
||||||
private sp_address: string | null = null;
|
|
||||||
private processes = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: "Messaging",
|
|
||||||
description: "Encrypted messages",
|
|
||||||
zoneList: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: "General",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: "Storage",
|
|
||||||
description: "Distributed storage",
|
|
||||||
zoneList: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: "Paris",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: "Normandy",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: "New York",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: "Moscow",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
private subscriptions: {element: Element; event: string; eventHandler: string;}[] = [] ;
|
|
||||||
// Private constructor to prevent direct instantiation from outside
|
|
||||||
private constructor() {}
|
|
||||||
|
|
||||||
// Method to access the singleton instance of Services
|
|
||||||
public static async getInstance(): Promise<Services> {
|
|
||||||
if (!Services.instance) {
|
|
||||||
Services.instance = new Services();
|
|
||||||
// await Services.instance.init();
|
|
||||||
}
|
|
||||||
return Services.instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async addWebsocketConnection(url: string): Promise<void> {
|
|
||||||
const services = await Services.getInstance();
|
|
||||||
const newClient = new WebSocketClient(url, services);
|
|
||||||
if (!services.websocketConnection.includes(newClient)) {
|
|
||||||
services.websocketConnection.push(newClient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public async recoverInjectHtml(): Promise<void> {
|
|
||||||
const container = document.getElementById('containerId');
|
|
||||||
|
|
||||||
if (!container) {
|
|
||||||
console.error("No html container");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const services = await Services.getInstance();
|
|
||||||
container.innerHTML = homePage;
|
|
||||||
|
|
||||||
const newScript = document.createElement('script')
|
|
||||||
newScript.textContent = homeScript;
|
|
||||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
|
||||||
|
|
||||||
const btn = container.querySelector('#scan-this-device')
|
|
||||||
if(btn) {
|
|
||||||
this.addSubscription(btn, 'click', 'injectProcessListPage')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private addSubscription(element: Element, event: string, eventHandler: string): void {
|
|
||||||
this.subscriptions.push({ element, event, eventHandler });
|
|
||||||
element.addEventListener(event, (this as any)[eventHandler].bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private cleanSubsciptions(): void {
|
|
||||||
for (const sub of this.subscriptions) {
|
|
||||||
const el = sub.element;
|
|
||||||
const eventHandler = sub.eventHandler;
|
|
||||||
el.removeEventListener(sub.event, (this as any)[eventHandler].bind(this));
|
|
||||||
}
|
|
||||||
this.subscriptions = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async injectProcessListPage(): Promise<void> {
|
|
||||||
const container = document.getElementById('containerId');
|
|
||||||
if (!container) {
|
|
||||||
console.error("No html container");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cleanSubsciptions()
|
|
||||||
|
|
||||||
const services = await Services.getInstance();
|
|
||||||
|
|
||||||
container.innerHTML = processPage;
|
|
||||||
const newScript = document.createElement('script');
|
|
||||||
newScript.textContent = processScript;
|
|
||||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
|
||||||
|
|
||||||
if(this.processes) {
|
|
||||||
services.setProcessesInSelectElement(this.processes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async setProcessesInSelectElement(processList: any[]) {
|
|
||||||
const select = document.querySelector(".select-field");
|
|
||||||
if(select) {
|
|
||||||
for (const process of processList) {
|
|
||||||
const option = document.createElement("option");
|
|
||||||
option.setAttribute("value", process.name);
|
|
||||||
option.innerText = process.name;
|
|
||||||
select.appendChild(option);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const optionList = document.querySelector('.autocomplete-list');
|
|
||||||
if(optionList) {
|
|
||||||
const observer = new MutationObserver((mutations, observer) => {
|
|
||||||
console.log(mutations, observer);
|
|
||||||
const options = optionList.querySelectorAll('li')
|
|
||||||
if(options) {
|
|
||||||
for(const option of options) {
|
|
||||||
this.addSubscription(option, 'click', 'showSelectedProcess')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
observer.observe(document, {
|
|
||||||
subtree: true,
|
|
||||||
attributes: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async listenToOptionListPopulating(event: Event) {
|
|
||||||
const target = event.target as HTMLUListElement;
|
|
||||||
const options = target?.querySelectorAll('li')
|
|
||||||
console.log(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
public async showSelectedProcess(event: MouseEvent) {
|
|
||||||
const elem = event.target;
|
|
||||||
if(elem) {
|
|
||||||
|
|
||||||
const cardContent = document.querySelector(".card-content");
|
|
||||||
const processes = this.processes;
|
|
||||||
const process = processes.find((process: any) => process.name === (elem as any).dataset.value);
|
|
||||||
if (process) {
|
|
||||||
const processDiv = document.createElement("div");
|
|
||||||
processDiv.className = "process";
|
|
||||||
processDiv.id = process.name;
|
|
||||||
const titleDiv = document.createElement("div");
|
|
||||||
titleDiv.className = "process-title";
|
|
||||||
titleDiv.innerHTML = `${process.name} : ${process.description}`;
|
|
||||||
processDiv.appendChild(titleDiv);
|
|
||||||
for (const zone of process.zoneList) {
|
|
||||||
const zoneElement = document.createElement("div");
|
|
||||||
zoneElement.className = "process-element";
|
|
||||||
zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`;
|
|
||||||
processDiv.appendChild(zoneElement);
|
|
||||||
}
|
|
||||||
if(cardContent) cardContent.appendChild(processDiv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
114
src/services/routing.service.ts
Normal file
114
src/services/routing.service.ts
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import modalHtml from '../html/login-modal.html?raw';
|
||||||
|
import confirmationModalHtml from '../html/confirmation-modal.html?raw';
|
||||||
|
import modalScript from '../html/login-modal.js?raw';
|
||||||
|
import confirmationModalScript from '../html/confirmation-modal.js?raw';
|
||||||
|
import Services from './service';
|
||||||
|
import { U32_MAX } from './service';
|
||||||
|
|
||||||
|
|
||||||
|
export default class Routing {
|
||||||
|
private static instance: Routing;
|
||||||
|
private sdkClient: any;
|
||||||
|
private currentPrd: any;
|
||||||
|
private currentOutpoint?: string;
|
||||||
|
private constructor() {}
|
||||||
|
private paired_addresses: string[] = [];
|
||||||
|
|
||||||
|
// Method to access the singleton instance of Services
|
||||||
|
public static async getInstance(): Promise<Routing> {
|
||||||
|
if (!Routing.instance) {
|
||||||
|
Routing.instance = new Routing();
|
||||||
|
await Routing.instance.init();
|
||||||
|
}
|
||||||
|
return Routing.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async init(): Promise<void> {
|
||||||
|
this.sdkClient = await import("../../dist/pkg/sdk_client");
|
||||||
|
}
|
||||||
|
|
||||||
|
public openLoginModal(myAddress: string, receiverAddress: string) {
|
||||||
|
const container = document.querySelector('.page-container');
|
||||||
|
let html = modalHtml
|
||||||
|
html = html.replace('{{device1}}', myAddress)
|
||||||
|
html = html.replace('{{device2}}', receiverAddress)
|
||||||
|
if (container) container.innerHTML += html;
|
||||||
|
const modal = document.getElementById('login-modal')
|
||||||
|
if (modal) modal.style.display = 'flex';
|
||||||
|
const newScript = document.createElement('script');
|
||||||
|
|
||||||
|
|
||||||
|
newScript.setAttribute('type', 'module')
|
||||||
|
newScript.textContent = modalScript;
|
||||||
|
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openConfirmationModal(pcd: any, outpointCommitment: string) {
|
||||||
|
console.log("")
|
||||||
|
let roles = JSON.parse(pcd['roles']);// ['members'][0];
|
||||||
|
console.log(roles);
|
||||||
|
let members = roles['owner']['members'];
|
||||||
|
console.log(members);
|
||||||
|
// We take all the addresses except our own
|
||||||
|
const local_address = this.sdkClient.get_address();
|
||||||
|
console.log("🚀 ~ Routing ~ openConfirmationModal ~ pcd:", pcd)
|
||||||
|
for (const address of members[0]['sp_addresses']) {
|
||||||
|
if (address !== local_address) { this.paired_addresses.push(address) }
|
||||||
|
}
|
||||||
|
let html = confirmationModalHtml;
|
||||||
|
// html = html.replace('{{device1}}', members[0]['sp_addresses'][0]);
|
||||||
|
// html = html.replace('{{device2}}', members[0]['sp_addresses'][1]);
|
||||||
|
this.currentOutpoint = outpointCommitment as string;
|
||||||
|
const container = document.querySelector('.page-container');
|
||||||
|
|
||||||
|
if (container) container.innerHTML += html;
|
||||||
|
const modal = document.getElementById('modal')
|
||||||
|
if (modal) modal.style.display = 'flex';
|
||||||
|
const newScript = document.createElement('script');
|
||||||
|
newScript.setAttribute('type', 'module')
|
||||||
|
newScript.textContent = confirmationModalScript;
|
||||||
|
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||||
|
|
||||||
|
// Add correct text
|
||||||
|
|
||||||
|
// Close modal when clicking outside of it
|
||||||
|
window.onclick = (event) => {
|
||||||
|
const modal = document.getElementById('modal');
|
||||||
|
if (event.target === modal) {
|
||||||
|
this.confirmPairing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
confirmLogin() {
|
||||||
|
console.log('=============> Confirm Login')
|
||||||
|
const loginTx = this.sdkClient.create_login_transaction(1)
|
||||||
|
console.log("🚀 ~ Routing ~ confirmLogin ~ loginTx:", loginTx)
|
||||||
|
this.sdkClient.login('LOGIN', loginTx)
|
||||||
|
}
|
||||||
|
async closeLoginModal() {
|
||||||
|
const modal = document.getElementById('login-modal')
|
||||||
|
if (modal) modal.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
async confirmPairing() {
|
||||||
|
const service = await Services.getInstance()
|
||||||
|
const modal = document.getElementById('modal')
|
||||||
|
// console.log("🚀 ~ Routing ~ confirm ~ prd:", prd)
|
||||||
|
if (modal) modal.style.display = 'none';
|
||||||
|
// Just make an empty commitment for now
|
||||||
|
const emptyTxid = '0'.repeat(64)
|
||||||
|
const commitmentOutpoint = `${emptyTxid}:${U32_MAX}`;
|
||||||
|
|
||||||
|
// We take the paired device(s) from the contract
|
||||||
|
await this.sdkClient.pair_device(commitmentOutpoint, this.paired_addresses)
|
||||||
|
this.paired_addresses = []
|
||||||
|
const newDevice = await service.dumpDevice();
|
||||||
|
await service.saveDevice(newDevice);
|
||||||
|
service.injectProcessListPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
async closeConfirmationModal() {
|
||||||
|
const modal = document.getElementById('modal')
|
||||||
|
if (modal) modal.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
719
src/services/service.ts
Normal file
719
src/services/service.ts
Normal file
@ -0,0 +1,719 @@
|
|||||||
|
// import { WebSocketClient } from '../websockets';
|
||||||
|
import { INotification } from '~/models/notification.model';
|
||||||
|
import homePage from '../html/home.html?raw';
|
||||||
|
import homeScript from '../html/home.js?raw';
|
||||||
|
import processPage from '../html/process.html?raw';
|
||||||
|
import processScript from '../html/process.js?raw';
|
||||||
|
import { IProcess } from '~/models/process.model';
|
||||||
|
// import Database from './database';
|
||||||
|
import { WebSocketClient } from '../websockets';
|
||||||
|
import QRCode from 'qrcode'
|
||||||
|
import { servicesVersion } from 'typescript';
|
||||||
|
import { ApiReturn, CachedMessage, Member } from '../../dist/pkg/sdk_client';
|
||||||
|
import Routing from './routing.service';
|
||||||
|
|
||||||
|
type ProcessesCache = {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const U32_MAX = 4294967295;
|
||||||
|
const wsurl = `https://demo.4nkweb.com/ws/`;
|
||||||
|
|
||||||
|
export default class Services {
|
||||||
|
private static initializing: Promise<Services> | null = null;
|
||||||
|
private static instance: Services;
|
||||||
|
private current_process: string | null = null;
|
||||||
|
private sdkClient: any;
|
||||||
|
private websocketConnection: WebSocketClient | null = null;
|
||||||
|
private processes: IProcess[] | null = null;
|
||||||
|
private notifications: INotification[] | null = null;
|
||||||
|
private subscriptions: {element: Element; event: string; eventHandler: string;}[] = [] ;
|
||||||
|
private database: any
|
||||||
|
// Private constructor to prevent direct instantiation from outside
|
||||||
|
private constructor() {}
|
||||||
|
|
||||||
|
// Method to access the singleton instance of Services
|
||||||
|
public static async getInstance(): Promise<Services> {
|
||||||
|
if (Services.instance) {
|
||||||
|
return Services.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Services.initializing) {
|
||||||
|
Services.initializing = (async () => {
|
||||||
|
const instance = new Services();
|
||||||
|
await instance.init();
|
||||||
|
return instance;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('initializing services');
|
||||||
|
Services.instance = await Services.initializing;
|
||||||
|
Services.initializing = null; // Reset for potential future use
|
||||||
|
return Services.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async init(): Promise<void> {
|
||||||
|
this.notifications = this.getNotifications();
|
||||||
|
this.sdkClient = await import("../../dist/pkg/sdk_client");
|
||||||
|
this.sdkClient.setup();
|
||||||
|
await this.addWebsocketConnection(wsurl);
|
||||||
|
await this.recoverInjectHtml();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async addWebsocketConnection(url: string): Promise<void> {
|
||||||
|
// const services = await Services.getInstance();
|
||||||
|
if (!this.websocketConnection) {
|
||||||
|
console.log('Opening new websocket connection');
|
||||||
|
const newClient = new WebSocketClient(url, this);
|
||||||
|
this.websocketConnection = newClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async recoverInjectHtml(): Promise<void> {
|
||||||
|
const container = document.getElementById('containerId');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error("No html container");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.innerHTML = homePage;
|
||||||
|
|
||||||
|
const newScript = document.createElement('script')
|
||||||
|
newScript.setAttribute('type', 'module')
|
||||||
|
newScript.textContent = homeScript;
|
||||||
|
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
private generateQRCode = async (text: string) => {
|
||||||
|
console.log("🚀 ~ Services ~ generateQRCode= ~ text:", text)
|
||||||
|
try {
|
||||||
|
const container = document.getElementById('containerId');
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const url = await QRCode.toDataURL(currentUrl + "?sp_address=" + text);
|
||||||
|
const qrCode = container?.querySelector('.qr-code img');
|
||||||
|
qrCode?.setAttribute('src', url)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isPaired(): boolean | undefined {
|
||||||
|
try {
|
||||||
|
return this.sdkClient.is_linking();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("isPaired ~ Error:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async unpairDevice(): Promise<void> {
|
||||||
|
const service = await Services.getInstance()
|
||||||
|
await service.sdkClient.unpair_device()
|
||||||
|
const newDevice = await this.dumpDevice();
|
||||||
|
await this.saveDevice(newDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
private prepareProcessTx(myAddress: string, recipientAddress: string) {
|
||||||
|
const initial_session_privkey = new Uint8Array(32);
|
||||||
|
const initial_session_pubkey = new Uint8Array(32);
|
||||||
|
const pairingTemplate = {
|
||||||
|
"description": "AliceBob",
|
||||||
|
"roles": {
|
||||||
|
"owner": {
|
||||||
|
"members":
|
||||||
|
[{sp_addresses: [myAddress, recipientAddress]}],
|
||||||
|
"validation_rules":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"quorum": 1.0,
|
||||||
|
"fields": [
|
||||||
|
"description",
|
||||||
|
"roles",
|
||||||
|
"session_privkey",
|
||||||
|
"session_pubkey",
|
||||||
|
"key_parity"
|
||||||
|
],
|
||||||
|
"min_sig_member": 1.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session_privkey": initial_session_privkey,
|
||||||
|
"session_pubkey": initial_session_pubkey,
|
||||||
|
"key_parity": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const apiReturn = this.sdkClient.create_update_transaction(undefined, JSON.stringify(pairingTemplate), 1)
|
||||||
|
return apiReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
public async sendPairingTx(spAddress: string): Promise<void> {
|
||||||
|
const amount = this.sdkClient.get_available_amount();
|
||||||
|
|
||||||
|
if (amount === 0n) {
|
||||||
|
const faucetMsg = this.sdkClient.create_faucet_msg();
|
||||||
|
await this.sendFaucetMessage(faucetMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const localAddress = this.sdkClient.get_address();
|
||||||
|
const emptyTxid = '0'.repeat(64)
|
||||||
|
|
||||||
|
try {
|
||||||
|
let commitmentOutpoint = `${emptyTxid}:${U32_MAX}`;
|
||||||
|
this.sdkClient.pair_device(commitmentOutpoint, [spAddress])
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Services ~ Error:", e);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout( async () => {
|
||||||
|
const apiReturn = this.prepareProcessTx(localAddress, spAddress)
|
||||||
|
await this.handleApiReturn(apiReturn);
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
async resetDevice() {
|
||||||
|
await this.sdkClient.reset_device()
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendNewTxMessage(message: string) {
|
||||||
|
if (!this.websocketConnection) {
|
||||||
|
throw new Error('No websocket connection');
|
||||||
|
}
|
||||||
|
// console.log("🚀 ~ WebSocketClient ~ this.ws.onopen= ~ newTxMessage:", message)
|
||||||
|
await this.websocketConnection.sendMessage('NewTx', message)
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendCommitMessage(message: string) {
|
||||||
|
// console.log("🚀 ~ WebSocketClient ~ this.ws.onopen= ~ CommitMessage:", message)
|
||||||
|
await this.websocketConnection?.sendMessage('Commit', message)
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendCipherMessages(ciphers: string[]) {
|
||||||
|
for (let i = 0; i < ciphers.length; i++) {
|
||||||
|
const cipher = ciphers[i];
|
||||||
|
await this.websocketConnection?.sendMessage('Cipher', cipher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendFaucetMessage(message: string): Promise<void> {
|
||||||
|
// console.log("🚀 ~ WebSocketClient ~ this.ws.onopen= ~ faucetMessage:", message)
|
||||||
|
await this.websocketConnection?.sendMessage('Faucet', message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async parseCipher(message: string) {
|
||||||
|
// try {
|
||||||
|
// JSON.parse(message)
|
||||||
|
// const router = await Routing.getInstance();
|
||||||
|
// router.closeLoginModal()
|
||||||
|
// this.injectProcessListPage()
|
||||||
|
// } catch {
|
||||||
|
// console.log('Not proper format for cipher')
|
||||||
|
// }
|
||||||
|
try {
|
||||||
|
console.log('parsing new cipher');
|
||||||
|
const apiReturn = await this.sdkClient.parse_cipher(message, 0.00001);
|
||||||
|
console.log("🚀 ~ Services ~ parseCipher ~ apiReturn:", apiReturn);
|
||||||
|
await this.handleApiReturn(apiReturn)
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Cipher isn't for us");
|
||||||
|
}
|
||||||
|
// await this.saveCipherTxToDb(parsedTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
async parseNewTx(tx: string) {
|
||||||
|
try {
|
||||||
|
// console.log('==============> sending txxxxxxx parser', tx)
|
||||||
|
const parsedTx = await this.sdkClient.parse_new_tx(tx, 0, 0.0001)
|
||||||
|
if(parsedTx) {
|
||||||
|
console.log("🚀 ~ Services ~ parseNewTx ~ parsedTx:", parsedTx)
|
||||||
|
try {
|
||||||
|
await this.handleApiReturn(parsedTx);
|
||||||
|
const newDevice = await this.dumpDevice();
|
||||||
|
await this.saveDevice(newDevice);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to update device with new tx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
console.trace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleApiReturn(apiReturn: ApiReturn) {
|
||||||
|
if (apiReturn.ciphers_to_send && apiReturn.ciphers_to_send.length) {
|
||||||
|
await this.sendCipherMessages(apiReturn.ciphers_to_send)
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
if (apiReturn.updated_process && apiReturn.updated_process.length) {
|
||||||
|
const [processCommitment, process] = apiReturn.updated_process;
|
||||||
|
console.debug('Updated Process Commitment:', processCommitment);
|
||||||
|
console.debug('Process Details:', process);
|
||||||
|
|
||||||
|
// Save process to storage
|
||||||
|
localStorage.setItem(processCommitment, JSON.stringify(process));
|
||||||
|
// Check if the newly updated process reveals some new information
|
||||||
|
try {
|
||||||
|
const proposals: string[] = this.sdkClient.get_update_proposals(processCommitment);
|
||||||
|
if (proposals && proposals.length != 0) {
|
||||||
|
const actual_proposal = JSON.parse(proposals[0]); // We just don't acknowledge concurrent proposals for now
|
||||||
|
console.info(actual_proposal);
|
||||||
|
let router = await Routing.getInstance();
|
||||||
|
router.openConfirmationModal(actual_proposal, processCommitment);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(apiReturn.updated_cached_msg && apiReturn.updated_cached_msg.length) {
|
||||||
|
apiReturn.updated_cached_msg.forEach((msg, index) => {
|
||||||
|
// console.debug(`CachedMessage ${index}:`, msg);
|
||||||
|
// Save the message to local storage
|
||||||
|
localStorage.setItem(msg.id.toString(), JSON.stringify(msg));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiReturn.commit_to_send) {
|
||||||
|
const commit = apiReturn.commit_to_send;
|
||||||
|
await this.sendCommitMessage(JSON.stringify(commit));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) {
|
||||||
|
await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send))
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async pairDevice(prd: any, outpointCommitment: string) {
|
||||||
|
console.log("🚀 ~ Services ~ pairDevice ~ prd:", prd)
|
||||||
|
// const service = await Services.getInstance();
|
||||||
|
// const spAddress = await this.getDeviceAddress() as any;
|
||||||
|
// const sender = JSON.parse(prd?.sender)
|
||||||
|
// const senderAddress = sender?.sp_addresses?.find((address: string) => address !== spAddress)
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ senderAddress:", senderAddress)
|
||||||
|
// if(senderAddress) {
|
||||||
|
// const proposal = service.sdkClient.get_update_proposals(outpointCommitment);
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ proposal:", proposal)
|
||||||
|
// // const pairingTx = proposal.pairing_tx.replace(/^\"+|\"+$/g, '')
|
||||||
|
// const parsedProposal = JSON.parse(proposal[0])
|
||||||
|
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ parsedProposal:", parsedProposal)
|
||||||
|
// const roles = JSON.parse(parsedProposal.roles)
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ roles:", roles, Array.isArray(roles), !roles.owner)
|
||||||
|
// if(Array.isArray(roles) || !roles.owner) return
|
||||||
|
// const proposalMembers = roles?.owner?.members
|
||||||
|
// const isFirstDevice = proposalMembers.some((member: Member) => member.sp_addresses.some(address => address === spAddress))
|
||||||
|
// const isSecondDevice = proposalMembers.some((member: Member) => member.sp_addresses.some(address => address === senderAddress))
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ proposalMembers:", proposalMembers)
|
||||||
|
// if(proposalMembers?.length !== 2 || !isFirstDevice || !isSecondDevice) return
|
||||||
|
// const pairingTx = parsedProposal?.pairing_tx?.replace(/^\"+|\"+$/g, '')
|
||||||
|
|
||||||
|
// let txid = '0'.repeat(64)
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ pairingTx:", pairingTx, `${txid}:4294967295`)
|
||||||
|
|
||||||
|
// const pairing = await service.sdkClient.pair_device(`${txid}:4294967295`, [senderAddress])
|
||||||
|
// const device = this.dumpDevice()
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ device:", device)
|
||||||
|
// this.saveDevice(device)
|
||||||
|
// // await service.sdkClient.pair_device(pairingTx, [senderAddress])
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ pairing:", pairing)
|
||||||
|
// // const process = await this.prepareProcessTx(spAddress, senderAddress)
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ process:", outpointCommitment, prd, prd.payload)
|
||||||
|
// const prdString = JSON.stringify(prd).trim()
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ prdString:", prdString)
|
||||||
|
// let tx = await service.sdkClient.response_prd(outpointCommitment, prdString, true)
|
||||||
|
// console.log("🚀 ~ Services ~ pairDevice ~ tx:", tx)
|
||||||
|
// if(tx.ciphers_to_send) {
|
||||||
|
// tx.ciphers_to_send.forEach((cipher: string) => service.websocketConnection?.sendMessage('Cipher', cipher))
|
||||||
|
// }
|
||||||
|
// this.injectProcessListPage()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// async saveTxToDb(tx: CachedMessage) {
|
||||||
|
// const database = await Database.getInstance();
|
||||||
|
// const indexedDb = await database.getDb();
|
||||||
|
// await database.writeObject(indexedDb, 'messages', tx, null);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async saveCipherTxToDb(tx: string) {
|
||||||
|
// const database = await Database.getInstance();
|
||||||
|
// const indexedDb = await database.getDb();
|
||||||
|
|
||||||
|
// if(tx) {
|
||||||
|
// await database.writeObject(indexedDb, database.getStoreList().AnkCipherMessages, tx, null);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
async getAmount() {
|
||||||
|
const amount = await this.sdkClient.get_available_amount()
|
||||||
|
console.log("🚀 ~ Services ~ getAmount ~ amount:", amount)
|
||||||
|
return amount
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDeviceAddress() {
|
||||||
|
return await this.sdkClient.get_address();
|
||||||
|
}
|
||||||
|
|
||||||
|
async dumpDevice() {
|
||||||
|
const device = await this.sdkClient.dump_device()
|
||||||
|
// console.log("🚀 ~ Services ~ dumpDevice ~ device:", device)
|
||||||
|
return device
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveDevice(device: any): Promise<any> {
|
||||||
|
// console.log("🚀 ~ Services ~ saveDevice ~ device:", device)
|
||||||
|
localStorage.setItem('wallet', device);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDevice(): Promise<string | null> {
|
||||||
|
return localStorage.getItem('wallet')
|
||||||
|
}
|
||||||
|
|
||||||
|
async dumpWallet() {
|
||||||
|
const wallet = await this.sdkClient.dump_wallet()
|
||||||
|
console.log("🚀 ~ Services ~ dumpWallet ~ wallet:", wallet)
|
||||||
|
return wallet
|
||||||
|
}
|
||||||
|
|
||||||
|
async createFaucetMessage() {
|
||||||
|
const message = await this.sdkClient.create_faucet_msg()
|
||||||
|
console.log("🚀 ~ Services ~ createFaucetMessage ~ message:", message)
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private addSubscription(element: Element, event: string, eventHandler: string): void {
|
||||||
|
this.subscriptions.push({ element, event, eventHandler });
|
||||||
|
element.addEventListener(event, (this as any)[eventHandler].bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
async createNewDevice() {
|
||||||
|
let spAddress = '';
|
||||||
|
try {
|
||||||
|
spAddress = await this.sdkClient.create_new_device(0, 'regtest')
|
||||||
|
const device = await this.dumpDevice()
|
||||||
|
console.log("🚀 ~ Services ~ device:", device)
|
||||||
|
await this.saveDevice(device)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Services ~ Error:", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.generateQRCode(spAddress || '')
|
||||||
|
|
||||||
|
return spAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
async restoreDevice(device: string) {
|
||||||
|
try {
|
||||||
|
await this.sdkClient.restore_device(device)
|
||||||
|
const spAddress = this.sdkClient.get_address();
|
||||||
|
this.generateQRCode(spAddress || '')
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getProcessesCache(): ProcessesCache {
|
||||||
|
// Regular expression to match 64-character hexadecimal strings
|
||||||
|
const hexU32KeyRegex: RegExp = /^[0-9a-fA-F]{64}:\d+$/;
|
||||||
|
const hexObjects: ProcessesCache = {}
|
||||||
|
|
||||||
|
// Iterate over all keys in localStorage
|
||||||
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
|
const key = localStorage.key(i);
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
return hexObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the key matches the 32-byte hex pattern
|
||||||
|
if (hexU32KeyRegex.test(key)) {
|
||||||
|
const value = localStorage.getItem(key);
|
||||||
|
if (!value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hexObjects[key] = JSON.parse(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hexObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCachedMessages(): string[] {
|
||||||
|
const u32KeyRegex = /^\d+$/;
|
||||||
|
const U32_MAX = 4294967295;
|
||||||
|
const messages: string[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
|
const key = localStorage.key(i);
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u32KeyRegex.test(key)) {
|
||||||
|
const num = parseInt(key, 10);
|
||||||
|
if (num < 0 || num > U32_MAX) {
|
||||||
|
console.warn(`Key ${key} is outside the u32 range and will be ignored.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = localStorage.getItem(key);
|
||||||
|
if (!value) {
|
||||||
|
console.warn(`No value found for key: ${key}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
messages.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async restoreProcesses() {
|
||||||
|
const processesCache = this.getProcessesCache();
|
||||||
|
console.log("🚀 ~ Services ~ restoreProcesses ~ processesCache:", processesCache);
|
||||||
|
|
||||||
|
if (processesCache.length == 0) {
|
||||||
|
console.debug("🚀 ~ Services ~ restoreProcesses ~ no processes in local storage");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.sdkClient.set_process_cache(JSON.stringify(processesCache));
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Services ~ restoreProcesses ~ Error:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async restoreMessages() {
|
||||||
|
const cachedMessages = this.getCachedMessages();
|
||||||
|
console.log("🚀 ~ Services ~ restoreMessages ~ chachedMessages:", cachedMessages);
|
||||||
|
|
||||||
|
if (cachedMessages && cachedMessages.length != 0) {
|
||||||
|
try {
|
||||||
|
await this.sdkClient.set_message_cache(cachedMessages);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Services ~ restoreMessages ~ Error:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private cleanSubscriptions(): void {
|
||||||
|
for (const sub of this.subscriptions) {
|
||||||
|
const el = sub.element;
|
||||||
|
const eventHandler = sub.eventHandler;
|
||||||
|
el.removeEventListener(sub.event, (this as any)[eventHandler].bind(this));
|
||||||
|
}
|
||||||
|
this.subscriptions = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async injectProcessListPage(): Promise<void> {
|
||||||
|
const container = document.getElementById('containerId');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error("No html container");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cleanSubscriptions()
|
||||||
|
|
||||||
|
// const user = services.sdkClient.create_user('Test', 'test', 10, 1, 'Messaging')
|
||||||
|
// console.log("🚀 ~ Services ~ injectProcessListPage ~ user:", user)
|
||||||
|
|
||||||
|
// const database = await Database.getInstance();
|
||||||
|
// const indexedDb = await database.getDb();
|
||||||
|
// await database.writeObject(indexedDb, database.getStoreList().AnkUser, user.user, null);
|
||||||
|
container.innerHTML = processPage;
|
||||||
|
const newScript = document.createElement('script');
|
||||||
|
newScript.setAttribute('type', 'module')
|
||||||
|
newScript.textContent = processScript;
|
||||||
|
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||||
|
|
||||||
|
this.processes = await this.getProcesses();
|
||||||
|
if(this.processes) {
|
||||||
|
this.setProcessesInSelectElement(this.processes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async setProcessesInSelectElement(processList: any[]) {
|
||||||
|
const select = document.querySelector(".select-field");
|
||||||
|
if(select) {
|
||||||
|
for (const process of processList) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.setAttribute("value", process.name);
|
||||||
|
option.innerText = process.name;
|
||||||
|
select.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const optionList = document.querySelector('.autocomplete-list');
|
||||||
|
if(optionList) {
|
||||||
|
const observer = new MutationObserver((mutations, observer) => {
|
||||||
|
const options = optionList.querySelectorAll('li')
|
||||||
|
if(options) {
|
||||||
|
for(const option of options) {
|
||||||
|
this.addSubscription(option, 'click', 'showSelectedProcess')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(document, {
|
||||||
|
subtree: true,
|
||||||
|
attributes: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async listenToOptionListPopulating(event: Event) {
|
||||||
|
const target = event.target as HTMLUListElement;
|
||||||
|
const options = target?.querySelectorAll('li')
|
||||||
|
}
|
||||||
|
|
||||||
|
public async showSelectedProcess(event: MouseEvent) {
|
||||||
|
const elem = event.target;
|
||||||
|
if(elem) {
|
||||||
|
|
||||||
|
const cardContent = document.querySelector(".card-content");
|
||||||
|
|
||||||
|
const processes = await this.getProcesses();
|
||||||
|
console.log("🚀 ~ Services ~ showSelectedProcess ~ processes:", processes)
|
||||||
|
const process = processes.find((process: any) => process.name === (elem as any).dataset.value);
|
||||||
|
if (process) {
|
||||||
|
const processDiv = document.createElement("div");
|
||||||
|
processDiv.className = "process";
|
||||||
|
processDiv.id = process.name;
|
||||||
|
const titleDiv = document.createElement("div");
|
||||||
|
titleDiv.className = "process-title";
|
||||||
|
titleDiv.innerHTML = `${process.name} : ${process.description}`;
|
||||||
|
processDiv.appendChild(titleDiv);
|
||||||
|
for (const zone of process.zoneList) {
|
||||||
|
const zoneElement = document.createElement("div");
|
||||||
|
zoneElement.className = "process-element";
|
||||||
|
zoneElement.setAttribute('zone-id', zone.id.toString())
|
||||||
|
zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`;
|
||||||
|
this.addSubscription(zoneElement, 'click', 'goToProcessPage')
|
||||||
|
processDiv.appendChild(zoneElement);
|
||||||
|
}
|
||||||
|
if(cardContent) cardContent.appendChild(processDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goToProcessPage(event: MouseEvent) {
|
||||||
|
const target = event.target as HTMLDivElement;
|
||||||
|
const zoneId = target?.getAttribute('zone-id');
|
||||||
|
const processList = document.querySelectorAll('.process-element');
|
||||||
|
if(processList) {
|
||||||
|
for(const process of processList) {
|
||||||
|
process.classList.remove('selected')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target.classList.add('selected')
|
||||||
|
|
||||||
|
console.log('=======================> going to process page', zoneId)
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProcesses(): Promise<IProcess[]> {
|
||||||
|
const processes = this.sdkClient.get_processes()
|
||||||
|
console.log("🚀 ~ Services ~ getProcesses ~ processes:", processes)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Messaging",
|
||||||
|
description: "Encrypted messages",
|
||||||
|
zoneList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "General",
|
||||||
|
path: '/test'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Storage",
|
||||||
|
description: "Distributed storage",
|
||||||
|
zoneList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Paris",
|
||||||
|
path: '/test'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Normandy",
|
||||||
|
path: '/test'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "New York",
|
||||||
|
path: '/test'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Moscow",
|
||||||
|
path: '/test'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
getNotifications(): INotification[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: 'Notif 1',
|
||||||
|
description: 'A normal notification',
|
||||||
|
sendToNotificationPage: false,
|
||||||
|
path: '/notif1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: 'Notif 2',
|
||||||
|
description: 'A normal notification',
|
||||||
|
sendToNotificationPage: false,
|
||||||
|
path: '/notif2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: 'Notif 3',
|
||||||
|
description: 'A normal notification',
|
||||||
|
sendToNotificationPage: false,
|
||||||
|
path: '/notif3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async setNotification(): Promise<void> {
|
||||||
|
const badge = document.querySelector('.notification-badge') as HTMLDivElement
|
||||||
|
const notifications = this.notifications
|
||||||
|
const noNotifications = document.querySelector('.no-notification') as HTMLDivElement
|
||||||
|
if(notifications?.length) {
|
||||||
|
badge.innerText = notifications.length.toString()
|
||||||
|
const notificationBoard = document.querySelector('.notification-board') as HTMLDivElement
|
||||||
|
noNotifications.style.display = 'none'
|
||||||
|
for(const notif of notifications) {
|
||||||
|
const notifElement = document.createElement("div");
|
||||||
|
notifElement.className = "notification-element";
|
||||||
|
notifElement.setAttribute('notif-id', notif.id.toString())
|
||||||
|
notifElement.innerHTML = `
|
||||||
|
<div>${notif.title}</div>
|
||||||
|
<div>${notif.description}</div>
|
||||||
|
`;
|
||||||
|
// this.addSubscription(notifElement, 'click', 'goToProcessPage')
|
||||||
|
notificationBoard.appendChild(notifElement);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
noNotifications.style.display = 'block'
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import Services from "./services";
|
import { AnkFlag, CachedMessage } from "dist/pkg/sdk_client";
|
||||||
import { AnkFlag, AnkNetworkMsg, CachedMessage } from "../dist/pkg/sdk_client";
|
import Services from "./services/service";
|
||||||
|
// import { AnkFlag, AnkNetworkMsg, CachedMessage } from "../dist/pkg/sdk_client";
|
||||||
|
|
||||||
class WebSocketClient {
|
class WebSocketClient {
|
||||||
private ws: WebSocket;
|
private ws: WebSocket;
|
||||||
@ -8,67 +9,67 @@ class WebSocketClient {
|
|||||||
constructor(url: string, private services: Services) {
|
constructor(url: string, private services: Services) {
|
||||||
this.ws = new WebSocket(url);
|
this.ws = new WebSocket(url);
|
||||||
|
|
||||||
this.ws.addEventListener('open', (event) => {
|
if(this.ws !== null) {
|
||||||
|
this.ws.onopen = async (event) => {
|
||||||
console.log('WebSocket connection established');
|
console.log('WebSocket connection established');
|
||||||
// Once the connection is open, send all messages in the queue
|
|
||||||
while (this.messageQueue.length > 0) {
|
while (this.messageQueue.length > 0) {
|
||||||
const message = this.messageQueue.shift();
|
const message = this.messageQueue.shift();
|
||||||
if (message) {
|
if (message) {
|
||||||
this.ws.send(message);
|
this.ws.send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
// Listen for messages
|
// Listen for messages
|
||||||
this.ws.addEventListener('message', (event) => {
|
this.ws.onmessage = (event) => {
|
||||||
const msgData = event.data;
|
const msgData = event.data;
|
||||||
|
|
||||||
|
// console.log("Received text message: ", msgData);
|
||||||
(async () => {
|
(async () => {
|
||||||
if (typeof(msgData) === 'string') {
|
if (typeof msgData === 'string') {
|
||||||
console.log("Received text message: "+msgData);
|
|
||||||
try {
|
try {
|
||||||
const feeRate = 1;
|
const feeRate = 0.0001;
|
||||||
// By parsing the message, we can link it with existing cached message and return the updated version of the message
|
const parsedMessage = JSON.parse(msgData)
|
||||||
let res: CachedMessage = await services.parseNetworkMessage(msgData, feeRate);
|
// console.log("🚀 ~ WebSocketClient ~ parsedMessage:", parsedMessage)
|
||||||
console.debug(res);
|
const services = await Services.getInstance()
|
||||||
if (res.status === 'FaucetComplete') {
|
switch(parsedMessage.flag) {
|
||||||
// we received a faucet tx, there's nothing else to do
|
case 'NewTx':
|
||||||
window.alert(`New faucet output\n${res.commited_in}`);
|
await services.parseNewTx(parsedMessage.content)
|
||||||
await services.updateMessages(res);
|
break;
|
||||||
await services.updateOwnedOutputsForUser();
|
case 'Cipher':
|
||||||
} else if (res.status === 'TxWaitingCipher') {
|
await services.parseCipher(parsedMessage.content)
|
||||||
// we received a tx but we don't have the cipher
|
// device = await services.dumpWallet()
|
||||||
console.debug(`received notification in output ${res.commited_in}, waiting for cipher message`);
|
// console.log("🚀 ~ WebSocketClient ~ device:", device)
|
||||||
await services.updateMessages(res);
|
// await services.saveDevice(device)
|
||||||
await services.updateOwnedOutputsForUser();
|
break;
|
||||||
} else if (res.status === 'CipherWaitingTx') {
|
|
||||||
// we received a cipher but we don't have the key
|
|
||||||
console.debug(`received a cipher`);
|
|
||||||
await services.updateMessages(res);
|
|
||||||
} else if (res.status === 'SentWaitingConfirmation') {
|
|
||||||
// We are sender and we're waiting for the challenge that will confirm recipient got the transaction and the message
|
|
||||||
await services.updateMessages(res);
|
|
||||||
await services.updateOwnedOutputsForUser();
|
|
||||||
} else if (res.status === 'MustSpendConfirmation') {
|
|
||||||
// we received a challenge for a notification we made
|
|
||||||
// that means we can stop rebroadcasting the tx and we must spend the challenge to confirm
|
|
||||||
window.alert(`Spending ${res.confirmed_by} to prove our identity`);
|
|
||||||
console.debug(`sending confirm message to ${res.recipient}`);
|
|
||||||
await services.updateMessages(res);
|
|
||||||
await services.answer_confirmation_message(res);
|
|
||||||
} else if (res.status === 'ReceivedMustConfirm') {
|
|
||||||
// we found a notification and decrypted the cipher
|
|
||||||
window.alert(`Received message from ${res.sender}\n${res.plaintext}`);
|
|
||||||
// we must spend the commited_in output to sender
|
|
||||||
await services.updateMessages(res);
|
|
||||||
await services.confirm_sender_address(res);
|
|
||||||
} else if (res.status === 'Complete') {
|
|
||||||
window.alert(`Received confirmation that ${res.sender} is the author of message ${res.plaintext}`)
|
|
||||||
await services.updateMessages(res);
|
|
||||||
await services.updateOwnedOutputsForUser();
|
|
||||||
} else {
|
|
||||||
console.debug('Received an unimplemented valid message');
|
|
||||||
}
|
}
|
||||||
|
// By parsing the message, we can link it with existing cached message and return the updated version of the message
|
||||||
|
// if (res.status === 'FaucetComplete') {
|
||||||
|
// // we received a faucet tx, there's nothing else to do
|
||||||
|
// window.alert(`New faucet output\n${res.commited_in}`);
|
||||||
|
// } else if (res.status === 'TxWaitingCipher') {
|
||||||
|
// // we received a tx but we don't have the cipher
|
||||||
|
// console.debug(`received notification in output ${res.commited_in}, waiting for cipher message`);
|
||||||
|
// } else if (res.status === 'CipherWaitingTx') {
|
||||||
|
// // we received a cipher but we don't have the key
|
||||||
|
// console.debug(`received a cipher`);
|
||||||
|
// } else if (res.status === 'SentWaitingConfirmation') {
|
||||||
|
// // We are sender and we're waiting for the challenge that will confirm recipient got the transaction and the message
|
||||||
|
// } else if (res.status === 'MustSpendConfirmation') {
|
||||||
|
// // we received a challenge for a notification we made
|
||||||
|
// // that means we can stop rebroadcasting the tx and we must spend the challenge to confirm
|
||||||
|
// window.alert(`Spending ${res.confirmed_by} to prove our identity`);
|
||||||
|
// console.debug(`sending confirm message to ${res.recipient}`);
|
||||||
|
// } else if (res.status === 'ReceivedMustConfirm') {
|
||||||
|
// // we found a notification and decrypted the cipher
|
||||||
|
// window.alert(`Received message from ${res.sender}\n${res.plaintext}`);
|
||||||
|
// // we must spend the commited_in output to sender
|
||||||
|
// } else if (res.status === 'Complete') {
|
||||||
|
// window.alert(`Received confirmation that ${res.sender} is the author of message ${res.plaintext}`)
|
||||||
|
// } else {
|
||||||
|
// console.debug('Received an unimplemented valid message');
|
||||||
|
// }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Received an invalid message:', error);
|
console.error('Received an invalid message:', error);
|
||||||
}
|
}
|
||||||
@ -76,30 +77,36 @@ class WebSocketClient {
|
|||||||
console.error('Received a non-string message');
|
console.error('Received a non-string message');
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
});
|
};
|
||||||
|
|
||||||
// Listen for possible errors
|
// Listen for possible errors
|
||||||
this.ws.addEventListener('error', (event) => {
|
this.ws.onerror = (event) => {
|
||||||
console.error('WebSocket error:', event);
|
console.error('WebSocket error:', event);
|
||||||
});
|
};
|
||||||
|
|
||||||
// Listen for when the connection is closed
|
// Listen for when the connection is closed
|
||||||
this.ws.addEventListener('close', (event) => {
|
this.ws.onclose = (event) => {
|
||||||
console.log('WebSocket is closed now.');
|
console.log('WebSocket is closed now.');
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to send messages
|
// Method to send messages
|
||||||
public sendMessage(flag: AnkFlag, message: string): void {
|
public async sendMessage(flag: AnkFlag, message: string): Promise<void> {
|
||||||
if (this.ws.readyState === WebSocket.OPEN) {
|
if (this.ws.readyState === WebSocket.OPEN) {
|
||||||
const networkMessage: AnkNetworkMsg = {
|
const networkMessage = {
|
||||||
'flag': flag,
|
'flag': flag,
|
||||||
'content': message
|
'content': message
|
||||||
}
|
}
|
||||||
// console.debug("Sending message:", JSON.stringify(networkMessage));
|
// if(flag === 'Cipher') {
|
||||||
|
// const services = await Services.getInstance();
|
||||||
|
// services.parseCipher(JSON.stringify(networkMessage))
|
||||||
|
// }
|
||||||
|
console.log("Sending message:", JSON.stringify(networkMessage));
|
||||||
this.ws.send(JSON.stringify(networkMessage));
|
this.ws.send(JSON.stringify(networkMessage));
|
||||||
} else {
|
} else {
|
||||||
console.warn('WebSocket is not open. ReadyState:', this.ws.readyState);
|
console.error('WebSocket is not open. ReadyState:', this.ws.readyState);
|
||||||
this.messageQueue.push(message);
|
this.messageQueue.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,6 +115,12 @@ class WebSocketClient {
|
|||||||
return this.ws.url;
|
return this.ws.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sendNormalMessage(message: string) {
|
||||||
|
this.ws.send(message);
|
||||||
|
console.log("Sending message:", JSON.stringify(message));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Method to close the WebSocket connection
|
// Method to close the WebSocket connection
|
||||||
public close(): void {
|
public close(): void {
|
||||||
this.ws.close();
|
this.ws.close();
|
||||||
|
@ -2,8 +2,13 @@ import { defineConfig } from 'vite';
|
|||||||
import vue from '@vitejs/plugin-vue'; // or react from '@vitejs/plugin-react' if using React
|
import vue from '@vitejs/plugin-vue'; // or react from '@vitejs/plugin-react' if using React
|
||||||
import wasm from 'vite-plugin-wasm';
|
import wasm from 'vite-plugin-wasm';
|
||||||
import {createHtmlPlugin} from 'vite-plugin-html';
|
import {createHtmlPlugin} from 'vite-plugin-html';
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
optimizeDeps: {
|
||||||
|
include: ['qrcode']
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(), // or react() if using React
|
vue(), // or react() if using React
|
||||||
wasm(),
|
wasm(),
|
||||||
@ -14,6 +19,7 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
build: {
|
build: {
|
||||||
outDir: 'dist',
|
outDir: 'dist',
|
||||||
|
target: 'esnext',
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: './src/index.ts',
|
input: './src/index.ts',
|
||||||
output: {
|
output: {
|
||||||
@ -28,7 +34,9 @@ export default defineConfig({
|
|||||||
extensions: ['.ts', '.tsx', '.js'],
|
extensions: ['.ts', '.tsx', '.js'],
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
|
host: 'localhost',
|
||||||
open: false,
|
open: false,
|
||||||
port: 3001,
|
port: 3001,
|
||||||
|
strictPort: true, // Empêche de changer de port si le 3001 est occupé
|
||||||
},
|
},
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user