gaialive commited on
Commit
d591eb1
·
verified ·
1 Parent(s): 757ca25

Upload 20 files

Browse files
frontend/Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-alpine
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+
7
+ RUN npm install
8
+
9
+ COPY . .
10
+
11
+ EXPOSE 5173
12
+
13
+ CMD ["npm", "run", "dev"]
frontend/Dockerfile.prod ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the official Node.js image as base
2
+ FROM node:18-alpine as build
3
+
4
+ # Set the working directory
5
+ WORKDIR /app
6
+
7
+ # Copy package files
8
+ COPY package*.json ./
9
+
10
+ # Install dependencies
11
+ RUN npm install
12
+
13
+ # Copy the rest of the application code
14
+ COPY . .
15
+
16
+ # Build the application
17
+ RUN npm run build
18
+
19
+ # Use nginx to serve the static files
20
+ FROM nginx:alpine
21
+
22
+ # Copy the build output to the nginx html directory
23
+ COPY --from=build /app/dist /usr/share/nginx/html
24
+
25
+ # Copy nginx configuration
26
+ COPY nginx.conf /etc/nginx/nginx.conf
27
+
28
+ # Expose port 80
29
+ EXPOSE 80
30
+
31
+ # Start nginx
32
+ CMD ["nginx", "-g", "daemon off;"]
frontend/index.html ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>N4SM - NextGen SDG Platform</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.jsx"></script>
12
+ </body>
13
+ </html>
frontend/nginx.conf ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ events {
2
+ worker_connections 1024;
3
+ }
4
+
5
+ http {
6
+ include /etc/nginx/mime.types;
7
+ server {
8
+ listen 80;
9
+ server_name localhost;
10
+ root /usr/share/nginx/html;
11
+ index index.html;
12
+
13
+ location / {
14
+ try_files $uri $uri/ /index.html;
15
+ }
16
+
17
+ location /api {
18
+ proxy_pass http://backend:3000;
19
+ proxy_set_header Host $host;
20
+ proxy_set_header X-Real-IP $remote_addr;
21
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
22
+ proxy_set_header X-Forwarded-Proto $scheme;
23
+ }
24
+ }
25
+ }
frontend/package-lock.json ADDED
@@ -0,0 +1,2767 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "n4sm-frontend",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "n4sm-frontend",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "react": "^18.2.0",
12
+ "react-dom": "^18.2.0",
13
+ "react-router-dom": "^6.14.2"
14
+ },
15
+ "devDependencies": {
16
+ "@types/react": "^18.2.15",
17
+ "@types/react-dom": "^18.2.7",
18
+ "@vitejs/plugin-react": "^4.0.3",
19
+ "autoprefixer": "^10.4.14",
20
+ "postcss": "^8.4.27",
21
+ "tailwindcss": "^3.3.3",
22
+ "vite": "^4.4.5"
23
+ }
24
+ },
25
+ "node_modules/@alloc/quick-lru": {
26
+ "version": "5.2.0",
27
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
28
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
29
+ "dev": true,
30
+ "license": "MIT",
31
+ "engines": {
32
+ "node": ">=10"
33
+ },
34
+ "funding": {
35
+ "url": "https://github.com/sponsors/sindresorhus"
36
+ }
37
+ },
38
+ "node_modules/@babel/code-frame": {
39
+ "version": "7.27.1",
40
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
41
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
42
+ "dev": true,
43
+ "license": "MIT",
44
+ "dependencies": {
45
+ "@babel/helper-validator-identifier": "^7.27.1",
46
+ "js-tokens": "^4.0.0",
47
+ "picocolors": "^1.1.1"
48
+ },
49
+ "engines": {
50
+ "node": ">=6.9.0"
51
+ }
52
+ },
53
+ "node_modules/@babel/compat-data": {
54
+ "version": "7.28.4",
55
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz",
56
+ "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==",
57
+ "dev": true,
58
+ "license": "MIT",
59
+ "engines": {
60
+ "node": ">=6.9.0"
61
+ }
62
+ },
63
+ "node_modules/@babel/core": {
64
+ "version": "7.28.4",
65
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz",
66
+ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
67
+ "dev": true,
68
+ "license": "MIT",
69
+ "peer": true,
70
+ "dependencies": {
71
+ "@babel/code-frame": "^7.27.1",
72
+ "@babel/generator": "^7.28.3",
73
+ "@babel/helper-compilation-targets": "^7.27.2",
74
+ "@babel/helper-module-transforms": "^7.28.3",
75
+ "@babel/helpers": "^7.28.4",
76
+ "@babel/parser": "^7.28.4",
77
+ "@babel/template": "^7.27.2",
78
+ "@babel/traverse": "^7.28.4",
79
+ "@babel/types": "^7.28.4",
80
+ "@jridgewell/remapping": "^2.3.5",
81
+ "convert-source-map": "^2.0.0",
82
+ "debug": "^4.1.0",
83
+ "gensync": "^1.0.0-beta.2",
84
+ "json5": "^2.2.3",
85
+ "semver": "^6.3.1"
86
+ },
87
+ "engines": {
88
+ "node": ">=6.9.0"
89
+ },
90
+ "funding": {
91
+ "type": "opencollective",
92
+ "url": "https://opencollective.com/babel"
93
+ }
94
+ },
95
+ "node_modules/@babel/generator": {
96
+ "version": "7.28.3",
97
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
98
+ "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
99
+ "dev": true,
100
+ "license": "MIT",
101
+ "dependencies": {
102
+ "@babel/parser": "^7.28.3",
103
+ "@babel/types": "^7.28.2",
104
+ "@jridgewell/gen-mapping": "^0.3.12",
105
+ "@jridgewell/trace-mapping": "^0.3.28",
106
+ "jsesc": "^3.0.2"
107
+ },
108
+ "engines": {
109
+ "node": ">=6.9.0"
110
+ }
111
+ },
112
+ "node_modules/@babel/helper-compilation-targets": {
113
+ "version": "7.27.2",
114
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
115
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
116
+ "dev": true,
117
+ "license": "MIT",
118
+ "dependencies": {
119
+ "@babel/compat-data": "^7.27.2",
120
+ "@babel/helper-validator-option": "^7.27.1",
121
+ "browserslist": "^4.24.0",
122
+ "lru-cache": "^5.1.1",
123
+ "semver": "^6.3.1"
124
+ },
125
+ "engines": {
126
+ "node": ">=6.9.0"
127
+ }
128
+ },
129
+ "node_modules/@babel/helper-globals": {
130
+ "version": "7.28.0",
131
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
132
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
133
+ "dev": true,
134
+ "license": "MIT",
135
+ "engines": {
136
+ "node": ">=6.9.0"
137
+ }
138
+ },
139
+ "node_modules/@babel/helper-module-imports": {
140
+ "version": "7.27.1",
141
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
142
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
143
+ "dev": true,
144
+ "license": "MIT",
145
+ "dependencies": {
146
+ "@babel/traverse": "^7.27.1",
147
+ "@babel/types": "^7.27.1"
148
+ },
149
+ "engines": {
150
+ "node": ">=6.9.0"
151
+ }
152
+ },
153
+ "node_modules/@babel/helper-module-transforms": {
154
+ "version": "7.28.3",
155
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
156
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
157
+ "dev": true,
158
+ "license": "MIT",
159
+ "dependencies": {
160
+ "@babel/helper-module-imports": "^7.27.1",
161
+ "@babel/helper-validator-identifier": "^7.27.1",
162
+ "@babel/traverse": "^7.28.3"
163
+ },
164
+ "engines": {
165
+ "node": ">=6.9.0"
166
+ },
167
+ "peerDependencies": {
168
+ "@babel/core": "^7.0.0"
169
+ }
170
+ },
171
+ "node_modules/@babel/helper-plugin-utils": {
172
+ "version": "7.27.1",
173
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
174
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
175
+ "dev": true,
176
+ "license": "MIT",
177
+ "engines": {
178
+ "node": ">=6.9.0"
179
+ }
180
+ },
181
+ "node_modules/@babel/helper-string-parser": {
182
+ "version": "7.27.1",
183
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
184
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
185
+ "dev": true,
186
+ "license": "MIT",
187
+ "engines": {
188
+ "node": ">=6.9.0"
189
+ }
190
+ },
191
+ "node_modules/@babel/helper-validator-identifier": {
192
+ "version": "7.27.1",
193
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
194
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
195
+ "dev": true,
196
+ "license": "MIT",
197
+ "engines": {
198
+ "node": ">=6.9.0"
199
+ }
200
+ },
201
+ "node_modules/@babel/helper-validator-option": {
202
+ "version": "7.27.1",
203
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
204
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
205
+ "dev": true,
206
+ "license": "MIT",
207
+ "engines": {
208
+ "node": ">=6.9.0"
209
+ }
210
+ },
211
+ "node_modules/@babel/helpers": {
212
+ "version": "7.28.4",
213
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
214
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
215
+ "dev": true,
216
+ "license": "MIT",
217
+ "dependencies": {
218
+ "@babel/template": "^7.27.2",
219
+ "@babel/types": "^7.28.4"
220
+ },
221
+ "engines": {
222
+ "node": ">=6.9.0"
223
+ }
224
+ },
225
+ "node_modules/@babel/parser": {
226
+ "version": "7.28.4",
227
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
228
+ "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
229
+ "dev": true,
230
+ "license": "MIT",
231
+ "dependencies": {
232
+ "@babel/types": "^7.28.4"
233
+ },
234
+ "bin": {
235
+ "parser": "bin/babel-parser.js"
236
+ },
237
+ "engines": {
238
+ "node": ">=6.0.0"
239
+ }
240
+ },
241
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
242
+ "version": "7.27.1",
243
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
244
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
245
+ "dev": true,
246
+ "license": "MIT",
247
+ "dependencies": {
248
+ "@babel/helper-plugin-utils": "^7.27.1"
249
+ },
250
+ "engines": {
251
+ "node": ">=6.9.0"
252
+ },
253
+ "peerDependencies": {
254
+ "@babel/core": "^7.0.0-0"
255
+ }
256
+ },
257
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
258
+ "version": "7.27.1",
259
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
260
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
261
+ "dev": true,
262
+ "license": "MIT",
263
+ "dependencies": {
264
+ "@babel/helper-plugin-utils": "^7.27.1"
265
+ },
266
+ "engines": {
267
+ "node": ">=6.9.0"
268
+ },
269
+ "peerDependencies": {
270
+ "@babel/core": "^7.0.0-0"
271
+ }
272
+ },
273
+ "node_modules/@babel/template": {
274
+ "version": "7.27.2",
275
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
276
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
277
+ "dev": true,
278
+ "license": "MIT",
279
+ "dependencies": {
280
+ "@babel/code-frame": "^7.27.1",
281
+ "@babel/parser": "^7.27.2",
282
+ "@babel/types": "^7.27.1"
283
+ },
284
+ "engines": {
285
+ "node": ">=6.9.0"
286
+ }
287
+ },
288
+ "node_modules/@babel/traverse": {
289
+ "version": "7.28.4",
290
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz",
291
+ "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==",
292
+ "dev": true,
293
+ "license": "MIT",
294
+ "dependencies": {
295
+ "@babel/code-frame": "^7.27.1",
296
+ "@babel/generator": "^7.28.3",
297
+ "@babel/helper-globals": "^7.28.0",
298
+ "@babel/parser": "^7.28.4",
299
+ "@babel/template": "^7.27.2",
300
+ "@babel/types": "^7.28.4",
301
+ "debug": "^4.3.1"
302
+ },
303
+ "engines": {
304
+ "node": ">=6.9.0"
305
+ }
306
+ },
307
+ "node_modules/@babel/types": {
308
+ "version": "7.28.4",
309
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
310
+ "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
311
+ "dev": true,
312
+ "license": "MIT",
313
+ "dependencies": {
314
+ "@babel/helper-string-parser": "^7.27.1",
315
+ "@babel/helper-validator-identifier": "^7.27.1"
316
+ },
317
+ "engines": {
318
+ "node": ">=6.9.0"
319
+ }
320
+ },
321
+ "node_modules/@esbuild/android-arm": {
322
+ "version": "0.18.20",
323
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
324
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
325
+ "cpu": [
326
+ "arm"
327
+ ],
328
+ "dev": true,
329
+ "license": "MIT",
330
+ "optional": true,
331
+ "os": [
332
+ "android"
333
+ ],
334
+ "engines": {
335
+ "node": ">=12"
336
+ }
337
+ },
338
+ "node_modules/@esbuild/android-arm64": {
339
+ "version": "0.18.20",
340
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
341
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
342
+ "cpu": [
343
+ "arm64"
344
+ ],
345
+ "dev": true,
346
+ "license": "MIT",
347
+ "optional": true,
348
+ "os": [
349
+ "android"
350
+ ],
351
+ "engines": {
352
+ "node": ">=12"
353
+ }
354
+ },
355
+ "node_modules/@esbuild/android-x64": {
356
+ "version": "0.18.20",
357
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
358
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
359
+ "cpu": [
360
+ "x64"
361
+ ],
362
+ "dev": true,
363
+ "license": "MIT",
364
+ "optional": true,
365
+ "os": [
366
+ "android"
367
+ ],
368
+ "engines": {
369
+ "node": ">=12"
370
+ }
371
+ },
372
+ "node_modules/@esbuild/darwin-arm64": {
373
+ "version": "0.18.20",
374
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
375
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
376
+ "cpu": [
377
+ "arm64"
378
+ ],
379
+ "dev": true,
380
+ "license": "MIT",
381
+ "optional": true,
382
+ "os": [
383
+ "darwin"
384
+ ],
385
+ "engines": {
386
+ "node": ">=12"
387
+ }
388
+ },
389
+ "node_modules/@esbuild/darwin-x64": {
390
+ "version": "0.18.20",
391
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
392
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
393
+ "cpu": [
394
+ "x64"
395
+ ],
396
+ "dev": true,
397
+ "license": "MIT",
398
+ "optional": true,
399
+ "os": [
400
+ "darwin"
401
+ ],
402
+ "engines": {
403
+ "node": ">=12"
404
+ }
405
+ },
406
+ "node_modules/@esbuild/freebsd-arm64": {
407
+ "version": "0.18.20",
408
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
409
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
410
+ "cpu": [
411
+ "arm64"
412
+ ],
413
+ "dev": true,
414
+ "license": "MIT",
415
+ "optional": true,
416
+ "os": [
417
+ "freebsd"
418
+ ],
419
+ "engines": {
420
+ "node": ">=12"
421
+ }
422
+ },
423
+ "node_modules/@esbuild/freebsd-x64": {
424
+ "version": "0.18.20",
425
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
426
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
427
+ "cpu": [
428
+ "x64"
429
+ ],
430
+ "dev": true,
431
+ "license": "MIT",
432
+ "optional": true,
433
+ "os": [
434
+ "freebsd"
435
+ ],
436
+ "engines": {
437
+ "node": ">=12"
438
+ }
439
+ },
440
+ "node_modules/@esbuild/linux-arm": {
441
+ "version": "0.18.20",
442
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
443
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
444
+ "cpu": [
445
+ "arm"
446
+ ],
447
+ "dev": true,
448
+ "license": "MIT",
449
+ "optional": true,
450
+ "os": [
451
+ "linux"
452
+ ],
453
+ "engines": {
454
+ "node": ">=12"
455
+ }
456
+ },
457
+ "node_modules/@esbuild/linux-arm64": {
458
+ "version": "0.18.20",
459
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
460
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
461
+ "cpu": [
462
+ "arm64"
463
+ ],
464
+ "dev": true,
465
+ "license": "MIT",
466
+ "optional": true,
467
+ "os": [
468
+ "linux"
469
+ ],
470
+ "engines": {
471
+ "node": ">=12"
472
+ }
473
+ },
474
+ "node_modules/@esbuild/linux-ia32": {
475
+ "version": "0.18.20",
476
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
477
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
478
+ "cpu": [
479
+ "ia32"
480
+ ],
481
+ "dev": true,
482
+ "license": "MIT",
483
+ "optional": true,
484
+ "os": [
485
+ "linux"
486
+ ],
487
+ "engines": {
488
+ "node": ">=12"
489
+ }
490
+ },
491
+ "node_modules/@esbuild/linux-loong64": {
492
+ "version": "0.18.20",
493
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
494
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
495
+ "cpu": [
496
+ "loong64"
497
+ ],
498
+ "dev": true,
499
+ "license": "MIT",
500
+ "optional": true,
501
+ "os": [
502
+ "linux"
503
+ ],
504
+ "engines": {
505
+ "node": ">=12"
506
+ }
507
+ },
508
+ "node_modules/@esbuild/linux-mips64el": {
509
+ "version": "0.18.20",
510
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
511
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
512
+ "cpu": [
513
+ "mips64el"
514
+ ],
515
+ "dev": true,
516
+ "license": "MIT",
517
+ "optional": true,
518
+ "os": [
519
+ "linux"
520
+ ],
521
+ "engines": {
522
+ "node": ">=12"
523
+ }
524
+ },
525
+ "node_modules/@esbuild/linux-ppc64": {
526
+ "version": "0.18.20",
527
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
528
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
529
+ "cpu": [
530
+ "ppc64"
531
+ ],
532
+ "dev": true,
533
+ "license": "MIT",
534
+ "optional": true,
535
+ "os": [
536
+ "linux"
537
+ ],
538
+ "engines": {
539
+ "node": ">=12"
540
+ }
541
+ },
542
+ "node_modules/@esbuild/linux-riscv64": {
543
+ "version": "0.18.20",
544
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
545
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
546
+ "cpu": [
547
+ "riscv64"
548
+ ],
549
+ "dev": true,
550
+ "license": "MIT",
551
+ "optional": true,
552
+ "os": [
553
+ "linux"
554
+ ],
555
+ "engines": {
556
+ "node": ">=12"
557
+ }
558
+ },
559
+ "node_modules/@esbuild/linux-s390x": {
560
+ "version": "0.18.20",
561
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
562
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
563
+ "cpu": [
564
+ "s390x"
565
+ ],
566
+ "dev": true,
567
+ "license": "MIT",
568
+ "optional": true,
569
+ "os": [
570
+ "linux"
571
+ ],
572
+ "engines": {
573
+ "node": ">=12"
574
+ }
575
+ },
576
+ "node_modules/@esbuild/linux-x64": {
577
+ "version": "0.18.20",
578
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
579
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
580
+ "cpu": [
581
+ "x64"
582
+ ],
583
+ "dev": true,
584
+ "license": "MIT",
585
+ "optional": true,
586
+ "os": [
587
+ "linux"
588
+ ],
589
+ "engines": {
590
+ "node": ">=12"
591
+ }
592
+ },
593
+ "node_modules/@esbuild/netbsd-x64": {
594
+ "version": "0.18.20",
595
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
596
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
597
+ "cpu": [
598
+ "x64"
599
+ ],
600
+ "dev": true,
601
+ "license": "MIT",
602
+ "optional": true,
603
+ "os": [
604
+ "netbsd"
605
+ ],
606
+ "engines": {
607
+ "node": ">=12"
608
+ }
609
+ },
610
+ "node_modules/@esbuild/openbsd-x64": {
611
+ "version": "0.18.20",
612
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
613
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
614
+ "cpu": [
615
+ "x64"
616
+ ],
617
+ "dev": true,
618
+ "license": "MIT",
619
+ "optional": true,
620
+ "os": [
621
+ "openbsd"
622
+ ],
623
+ "engines": {
624
+ "node": ">=12"
625
+ }
626
+ },
627
+ "node_modules/@esbuild/sunos-x64": {
628
+ "version": "0.18.20",
629
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
630
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
631
+ "cpu": [
632
+ "x64"
633
+ ],
634
+ "dev": true,
635
+ "license": "MIT",
636
+ "optional": true,
637
+ "os": [
638
+ "sunos"
639
+ ],
640
+ "engines": {
641
+ "node": ">=12"
642
+ }
643
+ },
644
+ "node_modules/@esbuild/win32-arm64": {
645
+ "version": "0.18.20",
646
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
647
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
648
+ "cpu": [
649
+ "arm64"
650
+ ],
651
+ "dev": true,
652
+ "license": "MIT",
653
+ "optional": true,
654
+ "os": [
655
+ "win32"
656
+ ],
657
+ "engines": {
658
+ "node": ">=12"
659
+ }
660
+ },
661
+ "node_modules/@esbuild/win32-ia32": {
662
+ "version": "0.18.20",
663
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
664
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
665
+ "cpu": [
666
+ "ia32"
667
+ ],
668
+ "dev": true,
669
+ "license": "MIT",
670
+ "optional": true,
671
+ "os": [
672
+ "win32"
673
+ ],
674
+ "engines": {
675
+ "node": ">=12"
676
+ }
677
+ },
678
+ "node_modules/@esbuild/win32-x64": {
679
+ "version": "0.18.20",
680
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
681
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
682
+ "cpu": [
683
+ "x64"
684
+ ],
685
+ "dev": true,
686
+ "license": "MIT",
687
+ "optional": true,
688
+ "os": [
689
+ "win32"
690
+ ],
691
+ "engines": {
692
+ "node": ">=12"
693
+ }
694
+ },
695
+ "node_modules/@isaacs/cliui": {
696
+ "version": "8.0.2",
697
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
698
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
699
+ "dev": true,
700
+ "license": "ISC",
701
+ "dependencies": {
702
+ "string-width": "^5.1.2",
703
+ "string-width-cjs": "npm:string-width@^4.2.0",
704
+ "strip-ansi": "^7.0.1",
705
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
706
+ "wrap-ansi": "^8.1.0",
707
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
708
+ },
709
+ "engines": {
710
+ "node": ">=12"
711
+ }
712
+ },
713
+ "node_modules/@jridgewell/gen-mapping": {
714
+ "version": "0.3.13",
715
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
716
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
717
+ "dev": true,
718
+ "license": "MIT",
719
+ "dependencies": {
720
+ "@jridgewell/sourcemap-codec": "^1.5.0",
721
+ "@jridgewell/trace-mapping": "^0.3.24"
722
+ }
723
+ },
724
+ "node_modules/@jridgewell/remapping": {
725
+ "version": "2.3.5",
726
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
727
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
728
+ "dev": true,
729
+ "license": "MIT",
730
+ "dependencies": {
731
+ "@jridgewell/gen-mapping": "^0.3.5",
732
+ "@jridgewell/trace-mapping": "^0.3.24"
733
+ }
734
+ },
735
+ "node_modules/@jridgewell/resolve-uri": {
736
+ "version": "3.1.2",
737
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
738
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
739
+ "dev": true,
740
+ "license": "MIT",
741
+ "engines": {
742
+ "node": ">=6.0.0"
743
+ }
744
+ },
745
+ "node_modules/@jridgewell/sourcemap-codec": {
746
+ "version": "1.5.5",
747
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
748
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
749
+ "dev": true,
750
+ "license": "MIT"
751
+ },
752
+ "node_modules/@jridgewell/trace-mapping": {
753
+ "version": "0.3.31",
754
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
755
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
756
+ "dev": true,
757
+ "license": "MIT",
758
+ "dependencies": {
759
+ "@jridgewell/resolve-uri": "^3.1.0",
760
+ "@jridgewell/sourcemap-codec": "^1.4.14"
761
+ }
762
+ },
763
+ "node_modules/@nodelib/fs.scandir": {
764
+ "version": "2.1.5",
765
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
766
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
767
+ "dev": true,
768
+ "license": "MIT",
769
+ "dependencies": {
770
+ "@nodelib/fs.stat": "2.0.5",
771
+ "run-parallel": "^1.1.9"
772
+ },
773
+ "engines": {
774
+ "node": ">= 8"
775
+ }
776
+ },
777
+ "node_modules/@nodelib/fs.stat": {
778
+ "version": "2.0.5",
779
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
780
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
781
+ "dev": true,
782
+ "license": "MIT",
783
+ "engines": {
784
+ "node": ">= 8"
785
+ }
786
+ },
787
+ "node_modules/@nodelib/fs.walk": {
788
+ "version": "1.2.8",
789
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
790
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
791
+ "dev": true,
792
+ "license": "MIT",
793
+ "dependencies": {
794
+ "@nodelib/fs.scandir": "2.1.5",
795
+ "fastq": "^1.6.0"
796
+ },
797
+ "engines": {
798
+ "node": ">= 8"
799
+ }
800
+ },
801
+ "node_modules/@pkgjs/parseargs": {
802
+ "version": "0.11.0",
803
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
804
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
805
+ "dev": true,
806
+ "license": "MIT",
807
+ "optional": true,
808
+ "engines": {
809
+ "node": ">=14"
810
+ }
811
+ },
812
+ "node_modules/@remix-run/router": {
813
+ "version": "1.23.0",
814
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
815
+ "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
816
+ "license": "MIT",
817
+ "engines": {
818
+ "node": ">=14.0.0"
819
+ }
820
+ },
821
+ "node_modules/@rolldown/pluginutils": {
822
+ "version": "1.0.0-beta.27",
823
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
824
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
825
+ "dev": true,
826
+ "license": "MIT"
827
+ },
828
+ "node_modules/@types/babel__core": {
829
+ "version": "7.20.5",
830
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
831
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
832
+ "dev": true,
833
+ "license": "MIT",
834
+ "dependencies": {
835
+ "@babel/parser": "^7.20.7",
836
+ "@babel/types": "^7.20.7",
837
+ "@types/babel__generator": "*",
838
+ "@types/babel__template": "*",
839
+ "@types/babel__traverse": "*"
840
+ }
841
+ },
842
+ "node_modules/@types/babel__generator": {
843
+ "version": "7.27.0",
844
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
845
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
846
+ "dev": true,
847
+ "license": "MIT",
848
+ "dependencies": {
849
+ "@babel/types": "^7.0.0"
850
+ }
851
+ },
852
+ "node_modules/@types/babel__template": {
853
+ "version": "7.4.4",
854
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
855
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
856
+ "dev": true,
857
+ "license": "MIT",
858
+ "dependencies": {
859
+ "@babel/parser": "^7.1.0",
860
+ "@babel/types": "^7.0.0"
861
+ }
862
+ },
863
+ "node_modules/@types/babel__traverse": {
864
+ "version": "7.28.0",
865
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
866
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
867
+ "dev": true,
868
+ "license": "MIT",
869
+ "dependencies": {
870
+ "@babel/types": "^7.28.2"
871
+ }
872
+ },
873
+ "node_modules/@types/prop-types": {
874
+ "version": "15.7.15",
875
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
876
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
877
+ "dev": true,
878
+ "license": "MIT"
879
+ },
880
+ "node_modules/@types/react": {
881
+ "version": "18.3.26",
882
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.26.tgz",
883
+ "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==",
884
+ "dev": true,
885
+ "license": "MIT",
886
+ "peer": true,
887
+ "dependencies": {
888
+ "@types/prop-types": "*",
889
+ "csstype": "^3.0.2"
890
+ }
891
+ },
892
+ "node_modules/@types/react-dom": {
893
+ "version": "18.3.7",
894
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
895
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
896
+ "dev": true,
897
+ "license": "MIT",
898
+ "peerDependencies": {
899
+ "@types/react": "^18.0.0"
900
+ }
901
+ },
902
+ "node_modules/@vitejs/plugin-react": {
903
+ "version": "4.7.0",
904
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
905
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
906
+ "dev": true,
907
+ "license": "MIT",
908
+ "dependencies": {
909
+ "@babel/core": "^7.28.0",
910
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
911
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
912
+ "@rolldown/pluginutils": "1.0.0-beta.27",
913
+ "@types/babel__core": "^7.20.5",
914
+ "react-refresh": "^0.17.0"
915
+ },
916
+ "engines": {
917
+ "node": "^14.18.0 || >=16.0.0"
918
+ },
919
+ "peerDependencies": {
920
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
921
+ }
922
+ },
923
+ "node_modules/ansi-regex": {
924
+ "version": "6.2.2",
925
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
926
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
927
+ "dev": true,
928
+ "license": "MIT",
929
+ "engines": {
930
+ "node": ">=12"
931
+ },
932
+ "funding": {
933
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
934
+ }
935
+ },
936
+ "node_modules/ansi-styles": {
937
+ "version": "6.2.3",
938
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
939
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
940
+ "dev": true,
941
+ "license": "MIT",
942
+ "engines": {
943
+ "node": ">=12"
944
+ },
945
+ "funding": {
946
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
947
+ }
948
+ },
949
+ "node_modules/any-promise": {
950
+ "version": "1.3.0",
951
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
952
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
953
+ "dev": true,
954
+ "license": "MIT"
955
+ },
956
+ "node_modules/anymatch": {
957
+ "version": "3.1.3",
958
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
959
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
960
+ "dev": true,
961
+ "license": "ISC",
962
+ "dependencies": {
963
+ "normalize-path": "^3.0.0",
964
+ "picomatch": "^2.0.4"
965
+ },
966
+ "engines": {
967
+ "node": ">= 8"
968
+ }
969
+ },
970
+ "node_modules/arg": {
971
+ "version": "5.0.2",
972
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
973
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
974
+ "dev": true,
975
+ "license": "MIT"
976
+ },
977
+ "node_modules/autoprefixer": {
978
+ "version": "10.4.21",
979
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
980
+ "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
981
+ "dev": true,
982
+ "funding": [
983
+ {
984
+ "type": "opencollective",
985
+ "url": "https://opencollective.com/postcss/"
986
+ },
987
+ {
988
+ "type": "tidelift",
989
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
990
+ },
991
+ {
992
+ "type": "github",
993
+ "url": "https://github.com/sponsors/ai"
994
+ }
995
+ ],
996
+ "license": "MIT",
997
+ "dependencies": {
998
+ "browserslist": "^4.24.4",
999
+ "caniuse-lite": "^1.0.30001702",
1000
+ "fraction.js": "^4.3.7",
1001
+ "normalize-range": "^0.1.2",
1002
+ "picocolors": "^1.1.1",
1003
+ "postcss-value-parser": "^4.2.0"
1004
+ },
1005
+ "bin": {
1006
+ "autoprefixer": "bin/autoprefixer"
1007
+ },
1008
+ "engines": {
1009
+ "node": "^10 || ^12 || >=14"
1010
+ },
1011
+ "peerDependencies": {
1012
+ "postcss": "^8.1.0"
1013
+ }
1014
+ },
1015
+ "node_modules/balanced-match": {
1016
+ "version": "1.0.2",
1017
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1018
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1019
+ "dev": true,
1020
+ "license": "MIT"
1021
+ },
1022
+ "node_modules/baseline-browser-mapping": {
1023
+ "version": "2.8.16",
1024
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz",
1025
+ "integrity": "sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==",
1026
+ "dev": true,
1027
+ "license": "Apache-2.0",
1028
+ "bin": {
1029
+ "baseline-browser-mapping": "dist/cli.js"
1030
+ }
1031
+ },
1032
+ "node_modules/binary-extensions": {
1033
+ "version": "2.3.0",
1034
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
1035
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
1036
+ "dev": true,
1037
+ "license": "MIT",
1038
+ "engines": {
1039
+ "node": ">=8"
1040
+ },
1041
+ "funding": {
1042
+ "url": "https://github.com/sponsors/sindresorhus"
1043
+ }
1044
+ },
1045
+ "node_modules/brace-expansion": {
1046
+ "version": "2.0.2",
1047
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
1048
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
1049
+ "dev": true,
1050
+ "license": "MIT",
1051
+ "dependencies": {
1052
+ "balanced-match": "^1.0.0"
1053
+ }
1054
+ },
1055
+ "node_modules/braces": {
1056
+ "version": "3.0.3",
1057
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
1058
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
1059
+ "dev": true,
1060
+ "license": "MIT",
1061
+ "dependencies": {
1062
+ "fill-range": "^7.1.1"
1063
+ },
1064
+ "engines": {
1065
+ "node": ">=8"
1066
+ }
1067
+ },
1068
+ "node_modules/browserslist": {
1069
+ "version": "4.26.3",
1070
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz",
1071
+ "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==",
1072
+ "dev": true,
1073
+ "funding": [
1074
+ {
1075
+ "type": "opencollective",
1076
+ "url": "https://opencollective.com/browserslist"
1077
+ },
1078
+ {
1079
+ "type": "tidelift",
1080
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
1081
+ },
1082
+ {
1083
+ "type": "github",
1084
+ "url": "https://github.com/sponsors/ai"
1085
+ }
1086
+ ],
1087
+ "license": "MIT",
1088
+ "peer": true,
1089
+ "dependencies": {
1090
+ "baseline-browser-mapping": "^2.8.9",
1091
+ "caniuse-lite": "^1.0.30001746",
1092
+ "electron-to-chromium": "^1.5.227",
1093
+ "node-releases": "^2.0.21",
1094
+ "update-browserslist-db": "^1.1.3"
1095
+ },
1096
+ "bin": {
1097
+ "browserslist": "cli.js"
1098
+ },
1099
+ "engines": {
1100
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
1101
+ }
1102
+ },
1103
+ "node_modules/camelcase-css": {
1104
+ "version": "2.0.1",
1105
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
1106
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
1107
+ "dev": true,
1108
+ "license": "MIT",
1109
+ "engines": {
1110
+ "node": ">= 6"
1111
+ }
1112
+ },
1113
+ "node_modules/caniuse-lite": {
1114
+ "version": "1.0.30001750",
1115
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001750.tgz",
1116
+ "integrity": "sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==",
1117
+ "dev": true,
1118
+ "funding": [
1119
+ {
1120
+ "type": "opencollective",
1121
+ "url": "https://opencollective.com/browserslist"
1122
+ },
1123
+ {
1124
+ "type": "tidelift",
1125
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1126
+ },
1127
+ {
1128
+ "type": "github",
1129
+ "url": "https://github.com/sponsors/ai"
1130
+ }
1131
+ ],
1132
+ "license": "CC-BY-4.0"
1133
+ },
1134
+ "node_modules/chokidar": {
1135
+ "version": "3.6.0",
1136
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
1137
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
1138
+ "dev": true,
1139
+ "license": "MIT",
1140
+ "dependencies": {
1141
+ "anymatch": "~3.1.2",
1142
+ "braces": "~3.0.2",
1143
+ "glob-parent": "~5.1.2",
1144
+ "is-binary-path": "~2.1.0",
1145
+ "is-glob": "~4.0.1",
1146
+ "normalize-path": "~3.0.0",
1147
+ "readdirp": "~3.6.0"
1148
+ },
1149
+ "engines": {
1150
+ "node": ">= 8.10.0"
1151
+ },
1152
+ "funding": {
1153
+ "url": "https://paulmillr.com/funding/"
1154
+ },
1155
+ "optionalDependencies": {
1156
+ "fsevents": "~2.3.2"
1157
+ }
1158
+ },
1159
+ "node_modules/chokidar/node_modules/glob-parent": {
1160
+ "version": "5.1.2",
1161
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1162
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1163
+ "dev": true,
1164
+ "license": "ISC",
1165
+ "dependencies": {
1166
+ "is-glob": "^4.0.1"
1167
+ },
1168
+ "engines": {
1169
+ "node": ">= 6"
1170
+ }
1171
+ },
1172
+ "node_modules/color-convert": {
1173
+ "version": "2.0.1",
1174
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1175
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1176
+ "dev": true,
1177
+ "license": "MIT",
1178
+ "dependencies": {
1179
+ "color-name": "~1.1.4"
1180
+ },
1181
+ "engines": {
1182
+ "node": ">=7.0.0"
1183
+ }
1184
+ },
1185
+ "node_modules/color-name": {
1186
+ "version": "1.1.4",
1187
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1188
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1189
+ "dev": true,
1190
+ "license": "MIT"
1191
+ },
1192
+ "node_modules/commander": {
1193
+ "version": "4.1.1",
1194
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
1195
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
1196
+ "dev": true,
1197
+ "license": "MIT",
1198
+ "engines": {
1199
+ "node": ">= 6"
1200
+ }
1201
+ },
1202
+ "node_modules/convert-source-map": {
1203
+ "version": "2.0.0",
1204
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
1205
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
1206
+ "dev": true,
1207
+ "license": "MIT"
1208
+ },
1209
+ "node_modules/cross-spawn": {
1210
+ "version": "7.0.6",
1211
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1212
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
1213
+ "dev": true,
1214
+ "license": "MIT",
1215
+ "dependencies": {
1216
+ "path-key": "^3.1.0",
1217
+ "shebang-command": "^2.0.0",
1218
+ "which": "^2.0.1"
1219
+ },
1220
+ "engines": {
1221
+ "node": ">= 8"
1222
+ }
1223
+ },
1224
+ "node_modules/cssesc": {
1225
+ "version": "3.0.0",
1226
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
1227
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
1228
+ "dev": true,
1229
+ "license": "MIT",
1230
+ "bin": {
1231
+ "cssesc": "bin/cssesc"
1232
+ },
1233
+ "engines": {
1234
+ "node": ">=4"
1235
+ }
1236
+ },
1237
+ "node_modules/csstype": {
1238
+ "version": "3.1.3",
1239
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
1240
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
1241
+ "dev": true,
1242
+ "license": "MIT"
1243
+ },
1244
+ "node_modules/debug": {
1245
+ "version": "4.4.3",
1246
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1247
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1248
+ "dev": true,
1249
+ "license": "MIT",
1250
+ "dependencies": {
1251
+ "ms": "^2.1.3"
1252
+ },
1253
+ "engines": {
1254
+ "node": ">=6.0"
1255
+ },
1256
+ "peerDependenciesMeta": {
1257
+ "supports-color": {
1258
+ "optional": true
1259
+ }
1260
+ }
1261
+ },
1262
+ "node_modules/didyoumean": {
1263
+ "version": "1.2.2",
1264
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
1265
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
1266
+ "dev": true,
1267
+ "license": "Apache-2.0"
1268
+ },
1269
+ "node_modules/dlv": {
1270
+ "version": "1.1.3",
1271
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
1272
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
1273
+ "dev": true,
1274
+ "license": "MIT"
1275
+ },
1276
+ "node_modules/eastasianwidth": {
1277
+ "version": "0.2.0",
1278
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
1279
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
1280
+ "dev": true,
1281
+ "license": "MIT"
1282
+ },
1283
+ "node_modules/electron-to-chromium": {
1284
+ "version": "1.5.234",
1285
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz",
1286
+ "integrity": "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==",
1287
+ "dev": true,
1288
+ "license": "ISC"
1289
+ },
1290
+ "node_modules/emoji-regex": {
1291
+ "version": "9.2.2",
1292
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
1293
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
1294
+ "dev": true,
1295
+ "license": "MIT"
1296
+ },
1297
+ "node_modules/esbuild": {
1298
+ "version": "0.18.20",
1299
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
1300
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
1301
+ "dev": true,
1302
+ "hasInstallScript": true,
1303
+ "license": "MIT",
1304
+ "bin": {
1305
+ "esbuild": "bin/esbuild"
1306
+ },
1307
+ "engines": {
1308
+ "node": ">=12"
1309
+ },
1310
+ "optionalDependencies": {
1311
+ "@esbuild/android-arm": "0.18.20",
1312
+ "@esbuild/android-arm64": "0.18.20",
1313
+ "@esbuild/android-x64": "0.18.20",
1314
+ "@esbuild/darwin-arm64": "0.18.20",
1315
+ "@esbuild/darwin-x64": "0.18.20",
1316
+ "@esbuild/freebsd-arm64": "0.18.20",
1317
+ "@esbuild/freebsd-x64": "0.18.20",
1318
+ "@esbuild/linux-arm": "0.18.20",
1319
+ "@esbuild/linux-arm64": "0.18.20",
1320
+ "@esbuild/linux-ia32": "0.18.20",
1321
+ "@esbuild/linux-loong64": "0.18.20",
1322
+ "@esbuild/linux-mips64el": "0.18.20",
1323
+ "@esbuild/linux-ppc64": "0.18.20",
1324
+ "@esbuild/linux-riscv64": "0.18.20",
1325
+ "@esbuild/linux-s390x": "0.18.20",
1326
+ "@esbuild/linux-x64": "0.18.20",
1327
+ "@esbuild/netbsd-x64": "0.18.20",
1328
+ "@esbuild/openbsd-x64": "0.18.20",
1329
+ "@esbuild/sunos-x64": "0.18.20",
1330
+ "@esbuild/win32-arm64": "0.18.20",
1331
+ "@esbuild/win32-ia32": "0.18.20",
1332
+ "@esbuild/win32-x64": "0.18.20"
1333
+ }
1334
+ },
1335
+ "node_modules/escalade": {
1336
+ "version": "3.2.0",
1337
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1338
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1339
+ "dev": true,
1340
+ "license": "MIT",
1341
+ "engines": {
1342
+ "node": ">=6"
1343
+ }
1344
+ },
1345
+ "node_modules/fast-glob": {
1346
+ "version": "3.3.3",
1347
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
1348
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
1349
+ "dev": true,
1350
+ "license": "MIT",
1351
+ "dependencies": {
1352
+ "@nodelib/fs.stat": "^2.0.2",
1353
+ "@nodelib/fs.walk": "^1.2.3",
1354
+ "glob-parent": "^5.1.2",
1355
+ "merge2": "^1.3.0",
1356
+ "micromatch": "^4.0.8"
1357
+ },
1358
+ "engines": {
1359
+ "node": ">=8.6.0"
1360
+ }
1361
+ },
1362
+ "node_modules/fast-glob/node_modules/glob-parent": {
1363
+ "version": "5.1.2",
1364
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1365
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1366
+ "dev": true,
1367
+ "license": "ISC",
1368
+ "dependencies": {
1369
+ "is-glob": "^4.0.1"
1370
+ },
1371
+ "engines": {
1372
+ "node": ">= 6"
1373
+ }
1374
+ },
1375
+ "node_modules/fastq": {
1376
+ "version": "1.19.1",
1377
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
1378
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
1379
+ "dev": true,
1380
+ "license": "ISC",
1381
+ "dependencies": {
1382
+ "reusify": "^1.0.4"
1383
+ }
1384
+ },
1385
+ "node_modules/fill-range": {
1386
+ "version": "7.1.1",
1387
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
1388
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
1389
+ "dev": true,
1390
+ "license": "MIT",
1391
+ "dependencies": {
1392
+ "to-regex-range": "^5.0.1"
1393
+ },
1394
+ "engines": {
1395
+ "node": ">=8"
1396
+ }
1397
+ },
1398
+ "node_modules/foreground-child": {
1399
+ "version": "3.3.1",
1400
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
1401
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
1402
+ "dev": true,
1403
+ "license": "ISC",
1404
+ "dependencies": {
1405
+ "cross-spawn": "^7.0.6",
1406
+ "signal-exit": "^4.0.1"
1407
+ },
1408
+ "engines": {
1409
+ "node": ">=14"
1410
+ },
1411
+ "funding": {
1412
+ "url": "https://github.com/sponsors/isaacs"
1413
+ }
1414
+ },
1415
+ "node_modules/fraction.js": {
1416
+ "version": "4.3.7",
1417
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
1418
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
1419
+ "dev": true,
1420
+ "license": "MIT",
1421
+ "engines": {
1422
+ "node": "*"
1423
+ },
1424
+ "funding": {
1425
+ "type": "patreon",
1426
+ "url": "https://github.com/sponsors/rawify"
1427
+ }
1428
+ },
1429
+ "node_modules/fsevents": {
1430
+ "version": "2.3.3",
1431
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1432
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1433
+ "dev": true,
1434
+ "hasInstallScript": true,
1435
+ "license": "MIT",
1436
+ "optional": true,
1437
+ "os": [
1438
+ "darwin"
1439
+ ],
1440
+ "engines": {
1441
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1442
+ }
1443
+ },
1444
+ "node_modules/function-bind": {
1445
+ "version": "1.1.2",
1446
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1447
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
1448
+ "dev": true,
1449
+ "license": "MIT",
1450
+ "funding": {
1451
+ "url": "https://github.com/sponsors/ljharb"
1452
+ }
1453
+ },
1454
+ "node_modules/gensync": {
1455
+ "version": "1.0.0-beta.2",
1456
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
1457
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
1458
+ "dev": true,
1459
+ "license": "MIT",
1460
+ "engines": {
1461
+ "node": ">=6.9.0"
1462
+ }
1463
+ },
1464
+ "node_modules/glob": {
1465
+ "version": "10.4.5",
1466
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
1467
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
1468
+ "dev": true,
1469
+ "license": "ISC",
1470
+ "dependencies": {
1471
+ "foreground-child": "^3.1.0",
1472
+ "jackspeak": "^3.1.2",
1473
+ "minimatch": "^9.0.4",
1474
+ "minipass": "^7.1.2",
1475
+ "package-json-from-dist": "^1.0.0",
1476
+ "path-scurry": "^1.11.1"
1477
+ },
1478
+ "bin": {
1479
+ "glob": "dist/esm/bin.mjs"
1480
+ },
1481
+ "funding": {
1482
+ "url": "https://github.com/sponsors/isaacs"
1483
+ }
1484
+ },
1485
+ "node_modules/glob-parent": {
1486
+ "version": "6.0.2",
1487
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
1488
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
1489
+ "dev": true,
1490
+ "license": "ISC",
1491
+ "dependencies": {
1492
+ "is-glob": "^4.0.3"
1493
+ },
1494
+ "engines": {
1495
+ "node": ">=10.13.0"
1496
+ }
1497
+ },
1498
+ "node_modules/hasown": {
1499
+ "version": "2.0.2",
1500
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1501
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1502
+ "dev": true,
1503
+ "license": "MIT",
1504
+ "dependencies": {
1505
+ "function-bind": "^1.1.2"
1506
+ },
1507
+ "engines": {
1508
+ "node": ">= 0.4"
1509
+ }
1510
+ },
1511
+ "node_modules/is-binary-path": {
1512
+ "version": "2.1.0",
1513
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1514
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1515
+ "dev": true,
1516
+ "license": "MIT",
1517
+ "dependencies": {
1518
+ "binary-extensions": "^2.0.0"
1519
+ },
1520
+ "engines": {
1521
+ "node": ">=8"
1522
+ }
1523
+ },
1524
+ "node_modules/is-core-module": {
1525
+ "version": "2.16.1",
1526
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
1527
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
1528
+ "dev": true,
1529
+ "license": "MIT",
1530
+ "dependencies": {
1531
+ "hasown": "^2.0.2"
1532
+ },
1533
+ "engines": {
1534
+ "node": ">= 0.4"
1535
+ },
1536
+ "funding": {
1537
+ "url": "https://github.com/sponsors/ljharb"
1538
+ }
1539
+ },
1540
+ "node_modules/is-extglob": {
1541
+ "version": "2.1.1",
1542
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1543
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1544
+ "dev": true,
1545
+ "license": "MIT",
1546
+ "engines": {
1547
+ "node": ">=0.10.0"
1548
+ }
1549
+ },
1550
+ "node_modules/is-fullwidth-code-point": {
1551
+ "version": "3.0.0",
1552
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1553
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1554
+ "dev": true,
1555
+ "license": "MIT",
1556
+ "engines": {
1557
+ "node": ">=8"
1558
+ }
1559
+ },
1560
+ "node_modules/is-glob": {
1561
+ "version": "4.0.3",
1562
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1563
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1564
+ "dev": true,
1565
+ "license": "MIT",
1566
+ "dependencies": {
1567
+ "is-extglob": "^2.1.1"
1568
+ },
1569
+ "engines": {
1570
+ "node": ">=0.10.0"
1571
+ }
1572
+ },
1573
+ "node_modules/is-number": {
1574
+ "version": "7.0.0",
1575
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1576
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1577
+ "dev": true,
1578
+ "license": "MIT",
1579
+ "engines": {
1580
+ "node": ">=0.12.0"
1581
+ }
1582
+ },
1583
+ "node_modules/isexe": {
1584
+ "version": "2.0.0",
1585
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1586
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1587
+ "dev": true,
1588
+ "license": "ISC"
1589
+ },
1590
+ "node_modules/jackspeak": {
1591
+ "version": "3.4.3",
1592
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
1593
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
1594
+ "dev": true,
1595
+ "license": "BlueOak-1.0.0",
1596
+ "dependencies": {
1597
+ "@isaacs/cliui": "^8.0.2"
1598
+ },
1599
+ "funding": {
1600
+ "url": "https://github.com/sponsors/isaacs"
1601
+ },
1602
+ "optionalDependencies": {
1603
+ "@pkgjs/parseargs": "^0.11.0"
1604
+ }
1605
+ },
1606
+ "node_modules/jiti": {
1607
+ "version": "1.21.7",
1608
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
1609
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
1610
+ "dev": true,
1611
+ "license": "MIT",
1612
+ "peer": true,
1613
+ "bin": {
1614
+ "jiti": "bin/jiti.js"
1615
+ }
1616
+ },
1617
+ "node_modules/js-tokens": {
1618
+ "version": "4.0.0",
1619
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1620
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1621
+ "license": "MIT"
1622
+ },
1623
+ "node_modules/jsesc": {
1624
+ "version": "3.1.0",
1625
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
1626
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
1627
+ "dev": true,
1628
+ "license": "MIT",
1629
+ "bin": {
1630
+ "jsesc": "bin/jsesc"
1631
+ },
1632
+ "engines": {
1633
+ "node": ">=6"
1634
+ }
1635
+ },
1636
+ "node_modules/json5": {
1637
+ "version": "2.2.3",
1638
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
1639
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
1640
+ "dev": true,
1641
+ "license": "MIT",
1642
+ "bin": {
1643
+ "json5": "lib/cli.js"
1644
+ },
1645
+ "engines": {
1646
+ "node": ">=6"
1647
+ }
1648
+ },
1649
+ "node_modules/lilconfig": {
1650
+ "version": "3.1.3",
1651
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
1652
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
1653
+ "dev": true,
1654
+ "license": "MIT",
1655
+ "engines": {
1656
+ "node": ">=14"
1657
+ },
1658
+ "funding": {
1659
+ "url": "https://github.com/sponsors/antonk52"
1660
+ }
1661
+ },
1662
+ "node_modules/lines-and-columns": {
1663
+ "version": "1.2.4",
1664
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
1665
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
1666
+ "dev": true,
1667
+ "license": "MIT"
1668
+ },
1669
+ "node_modules/loose-envify": {
1670
+ "version": "1.4.0",
1671
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
1672
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
1673
+ "license": "MIT",
1674
+ "dependencies": {
1675
+ "js-tokens": "^3.0.0 || ^4.0.0"
1676
+ },
1677
+ "bin": {
1678
+ "loose-envify": "cli.js"
1679
+ }
1680
+ },
1681
+ "node_modules/lru-cache": {
1682
+ "version": "5.1.1",
1683
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
1684
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
1685
+ "dev": true,
1686
+ "license": "ISC",
1687
+ "dependencies": {
1688
+ "yallist": "^3.0.2"
1689
+ }
1690
+ },
1691
+ "node_modules/merge2": {
1692
+ "version": "1.4.1",
1693
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
1694
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
1695
+ "dev": true,
1696
+ "license": "MIT",
1697
+ "engines": {
1698
+ "node": ">= 8"
1699
+ }
1700
+ },
1701
+ "node_modules/micromatch": {
1702
+ "version": "4.0.8",
1703
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
1704
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
1705
+ "dev": true,
1706
+ "license": "MIT",
1707
+ "dependencies": {
1708
+ "braces": "^3.0.3",
1709
+ "picomatch": "^2.3.1"
1710
+ },
1711
+ "engines": {
1712
+ "node": ">=8.6"
1713
+ }
1714
+ },
1715
+ "node_modules/minimatch": {
1716
+ "version": "9.0.5",
1717
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
1718
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
1719
+ "dev": true,
1720
+ "license": "ISC",
1721
+ "dependencies": {
1722
+ "brace-expansion": "^2.0.1"
1723
+ },
1724
+ "engines": {
1725
+ "node": ">=16 || 14 >=14.17"
1726
+ },
1727
+ "funding": {
1728
+ "url": "https://github.com/sponsors/isaacs"
1729
+ }
1730
+ },
1731
+ "node_modules/minipass": {
1732
+ "version": "7.1.2",
1733
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
1734
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
1735
+ "dev": true,
1736
+ "license": "ISC",
1737
+ "engines": {
1738
+ "node": ">=16 || 14 >=14.17"
1739
+ }
1740
+ },
1741
+ "node_modules/ms": {
1742
+ "version": "2.1.3",
1743
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1744
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1745
+ "dev": true,
1746
+ "license": "MIT"
1747
+ },
1748
+ "node_modules/mz": {
1749
+ "version": "2.7.0",
1750
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
1751
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
1752
+ "dev": true,
1753
+ "license": "MIT",
1754
+ "dependencies": {
1755
+ "any-promise": "^1.0.0",
1756
+ "object-assign": "^4.0.1",
1757
+ "thenify-all": "^1.0.0"
1758
+ }
1759
+ },
1760
+ "node_modules/nanoid": {
1761
+ "version": "3.3.11",
1762
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1763
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1764
+ "dev": true,
1765
+ "funding": [
1766
+ {
1767
+ "type": "github",
1768
+ "url": "https://github.com/sponsors/ai"
1769
+ }
1770
+ ],
1771
+ "license": "MIT",
1772
+ "bin": {
1773
+ "nanoid": "bin/nanoid.cjs"
1774
+ },
1775
+ "engines": {
1776
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1777
+ }
1778
+ },
1779
+ "node_modules/node-releases": {
1780
+ "version": "2.0.23",
1781
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz",
1782
+ "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==",
1783
+ "dev": true,
1784
+ "license": "MIT"
1785
+ },
1786
+ "node_modules/normalize-path": {
1787
+ "version": "3.0.0",
1788
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1789
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1790
+ "dev": true,
1791
+ "license": "MIT",
1792
+ "engines": {
1793
+ "node": ">=0.10.0"
1794
+ }
1795
+ },
1796
+ "node_modules/normalize-range": {
1797
+ "version": "0.1.2",
1798
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
1799
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
1800
+ "dev": true,
1801
+ "license": "MIT",
1802
+ "engines": {
1803
+ "node": ">=0.10.0"
1804
+ }
1805
+ },
1806
+ "node_modules/object-assign": {
1807
+ "version": "4.1.1",
1808
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1809
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1810
+ "dev": true,
1811
+ "license": "MIT",
1812
+ "engines": {
1813
+ "node": ">=0.10.0"
1814
+ }
1815
+ },
1816
+ "node_modules/object-hash": {
1817
+ "version": "3.0.0",
1818
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
1819
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
1820
+ "dev": true,
1821
+ "license": "MIT",
1822
+ "engines": {
1823
+ "node": ">= 6"
1824
+ }
1825
+ },
1826
+ "node_modules/package-json-from-dist": {
1827
+ "version": "1.0.1",
1828
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
1829
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
1830
+ "dev": true,
1831
+ "license": "BlueOak-1.0.0"
1832
+ },
1833
+ "node_modules/path-key": {
1834
+ "version": "3.1.1",
1835
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1836
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1837
+ "dev": true,
1838
+ "license": "MIT",
1839
+ "engines": {
1840
+ "node": ">=8"
1841
+ }
1842
+ },
1843
+ "node_modules/path-parse": {
1844
+ "version": "1.0.7",
1845
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1846
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1847
+ "dev": true,
1848
+ "license": "MIT"
1849
+ },
1850
+ "node_modules/path-scurry": {
1851
+ "version": "1.11.1",
1852
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
1853
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
1854
+ "dev": true,
1855
+ "license": "BlueOak-1.0.0",
1856
+ "dependencies": {
1857
+ "lru-cache": "^10.2.0",
1858
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1859
+ },
1860
+ "engines": {
1861
+ "node": ">=16 || 14 >=14.18"
1862
+ },
1863
+ "funding": {
1864
+ "url": "https://github.com/sponsors/isaacs"
1865
+ }
1866
+ },
1867
+ "node_modules/path-scurry/node_modules/lru-cache": {
1868
+ "version": "10.4.3",
1869
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1870
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1871
+ "dev": true,
1872
+ "license": "ISC"
1873
+ },
1874
+ "node_modules/picocolors": {
1875
+ "version": "1.1.1",
1876
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1877
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1878
+ "dev": true,
1879
+ "license": "ISC"
1880
+ },
1881
+ "node_modules/picomatch": {
1882
+ "version": "2.3.1",
1883
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1884
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1885
+ "dev": true,
1886
+ "license": "MIT",
1887
+ "engines": {
1888
+ "node": ">=8.6"
1889
+ },
1890
+ "funding": {
1891
+ "url": "https://github.com/sponsors/jonschlinkert"
1892
+ }
1893
+ },
1894
+ "node_modules/pify": {
1895
+ "version": "2.3.0",
1896
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1897
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
1898
+ "dev": true,
1899
+ "license": "MIT",
1900
+ "engines": {
1901
+ "node": ">=0.10.0"
1902
+ }
1903
+ },
1904
+ "node_modules/pirates": {
1905
+ "version": "4.0.7",
1906
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
1907
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
1908
+ "dev": true,
1909
+ "license": "MIT",
1910
+ "engines": {
1911
+ "node": ">= 6"
1912
+ }
1913
+ },
1914
+ "node_modules/postcss": {
1915
+ "version": "8.5.6",
1916
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
1917
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
1918
+ "dev": true,
1919
+ "funding": [
1920
+ {
1921
+ "type": "opencollective",
1922
+ "url": "https://opencollective.com/postcss/"
1923
+ },
1924
+ {
1925
+ "type": "tidelift",
1926
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1927
+ },
1928
+ {
1929
+ "type": "github",
1930
+ "url": "https://github.com/sponsors/ai"
1931
+ }
1932
+ ],
1933
+ "license": "MIT",
1934
+ "peer": true,
1935
+ "dependencies": {
1936
+ "nanoid": "^3.3.11",
1937
+ "picocolors": "^1.1.1",
1938
+ "source-map-js": "^1.2.1"
1939
+ },
1940
+ "engines": {
1941
+ "node": "^10 || ^12 || >=14"
1942
+ }
1943
+ },
1944
+ "node_modules/postcss-import": {
1945
+ "version": "15.1.0",
1946
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
1947
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
1948
+ "dev": true,
1949
+ "license": "MIT",
1950
+ "dependencies": {
1951
+ "postcss-value-parser": "^4.0.0",
1952
+ "read-cache": "^1.0.0",
1953
+ "resolve": "^1.1.7"
1954
+ },
1955
+ "engines": {
1956
+ "node": ">=14.0.0"
1957
+ },
1958
+ "peerDependencies": {
1959
+ "postcss": "^8.0.0"
1960
+ }
1961
+ },
1962
+ "node_modules/postcss-js": {
1963
+ "version": "4.1.0",
1964
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
1965
+ "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
1966
+ "dev": true,
1967
+ "funding": [
1968
+ {
1969
+ "type": "opencollective",
1970
+ "url": "https://opencollective.com/postcss/"
1971
+ },
1972
+ {
1973
+ "type": "github",
1974
+ "url": "https://github.com/sponsors/ai"
1975
+ }
1976
+ ],
1977
+ "license": "MIT",
1978
+ "dependencies": {
1979
+ "camelcase-css": "^2.0.1"
1980
+ },
1981
+ "engines": {
1982
+ "node": "^12 || ^14 || >= 16"
1983
+ },
1984
+ "peerDependencies": {
1985
+ "postcss": "^8.4.21"
1986
+ }
1987
+ },
1988
+ "node_modules/postcss-load-config": {
1989
+ "version": "6.0.1",
1990
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
1991
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
1992
+ "dev": true,
1993
+ "funding": [
1994
+ {
1995
+ "type": "opencollective",
1996
+ "url": "https://opencollective.com/postcss/"
1997
+ },
1998
+ {
1999
+ "type": "github",
2000
+ "url": "https://github.com/sponsors/ai"
2001
+ }
2002
+ ],
2003
+ "license": "MIT",
2004
+ "dependencies": {
2005
+ "lilconfig": "^3.1.1"
2006
+ },
2007
+ "engines": {
2008
+ "node": ">= 18"
2009
+ },
2010
+ "peerDependencies": {
2011
+ "jiti": ">=1.21.0",
2012
+ "postcss": ">=8.0.9",
2013
+ "tsx": "^4.8.1",
2014
+ "yaml": "^2.4.2"
2015
+ },
2016
+ "peerDependenciesMeta": {
2017
+ "jiti": {
2018
+ "optional": true
2019
+ },
2020
+ "postcss": {
2021
+ "optional": true
2022
+ },
2023
+ "tsx": {
2024
+ "optional": true
2025
+ },
2026
+ "yaml": {
2027
+ "optional": true
2028
+ }
2029
+ }
2030
+ },
2031
+ "node_modules/postcss-nested": {
2032
+ "version": "6.2.0",
2033
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
2034
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
2035
+ "dev": true,
2036
+ "funding": [
2037
+ {
2038
+ "type": "opencollective",
2039
+ "url": "https://opencollective.com/postcss/"
2040
+ },
2041
+ {
2042
+ "type": "github",
2043
+ "url": "https://github.com/sponsors/ai"
2044
+ }
2045
+ ],
2046
+ "license": "MIT",
2047
+ "dependencies": {
2048
+ "postcss-selector-parser": "^6.1.1"
2049
+ },
2050
+ "engines": {
2051
+ "node": ">=12.0"
2052
+ },
2053
+ "peerDependencies": {
2054
+ "postcss": "^8.2.14"
2055
+ }
2056
+ },
2057
+ "node_modules/postcss-selector-parser": {
2058
+ "version": "6.1.2",
2059
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
2060
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
2061
+ "dev": true,
2062
+ "license": "MIT",
2063
+ "dependencies": {
2064
+ "cssesc": "^3.0.0",
2065
+ "util-deprecate": "^1.0.2"
2066
+ },
2067
+ "engines": {
2068
+ "node": ">=4"
2069
+ }
2070
+ },
2071
+ "node_modules/postcss-value-parser": {
2072
+ "version": "4.2.0",
2073
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
2074
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
2075
+ "dev": true,
2076
+ "license": "MIT"
2077
+ },
2078
+ "node_modules/queue-microtask": {
2079
+ "version": "1.2.3",
2080
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
2081
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
2082
+ "dev": true,
2083
+ "funding": [
2084
+ {
2085
+ "type": "github",
2086
+ "url": "https://github.com/sponsors/feross"
2087
+ },
2088
+ {
2089
+ "type": "patreon",
2090
+ "url": "https://www.patreon.com/feross"
2091
+ },
2092
+ {
2093
+ "type": "consulting",
2094
+ "url": "https://feross.org/support"
2095
+ }
2096
+ ],
2097
+ "license": "MIT"
2098
+ },
2099
+ "node_modules/react": {
2100
+ "version": "18.3.1",
2101
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
2102
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
2103
+ "license": "MIT",
2104
+ "peer": true,
2105
+ "dependencies": {
2106
+ "loose-envify": "^1.1.0"
2107
+ },
2108
+ "engines": {
2109
+ "node": ">=0.10.0"
2110
+ }
2111
+ },
2112
+ "node_modules/react-dom": {
2113
+ "version": "18.3.1",
2114
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
2115
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
2116
+ "license": "MIT",
2117
+ "peer": true,
2118
+ "dependencies": {
2119
+ "loose-envify": "^1.1.0",
2120
+ "scheduler": "^0.23.2"
2121
+ },
2122
+ "peerDependencies": {
2123
+ "react": "^18.3.1"
2124
+ }
2125
+ },
2126
+ "node_modules/react-refresh": {
2127
+ "version": "0.17.0",
2128
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
2129
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
2130
+ "dev": true,
2131
+ "license": "MIT",
2132
+ "engines": {
2133
+ "node": ">=0.10.0"
2134
+ }
2135
+ },
2136
+ "node_modules/react-router": {
2137
+ "version": "6.30.1",
2138
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
2139
+ "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
2140
+ "license": "MIT",
2141
+ "dependencies": {
2142
+ "@remix-run/router": "1.23.0"
2143
+ },
2144
+ "engines": {
2145
+ "node": ">=14.0.0"
2146
+ },
2147
+ "peerDependencies": {
2148
+ "react": ">=16.8"
2149
+ }
2150
+ },
2151
+ "node_modules/react-router-dom": {
2152
+ "version": "6.30.1",
2153
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
2154
+ "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
2155
+ "license": "MIT",
2156
+ "dependencies": {
2157
+ "@remix-run/router": "1.23.0",
2158
+ "react-router": "6.30.1"
2159
+ },
2160
+ "engines": {
2161
+ "node": ">=14.0.0"
2162
+ },
2163
+ "peerDependencies": {
2164
+ "react": ">=16.8",
2165
+ "react-dom": ">=16.8"
2166
+ }
2167
+ },
2168
+ "node_modules/read-cache": {
2169
+ "version": "1.0.0",
2170
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
2171
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
2172
+ "dev": true,
2173
+ "license": "MIT",
2174
+ "dependencies": {
2175
+ "pify": "^2.3.0"
2176
+ }
2177
+ },
2178
+ "node_modules/readdirp": {
2179
+ "version": "3.6.0",
2180
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
2181
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
2182
+ "dev": true,
2183
+ "license": "MIT",
2184
+ "dependencies": {
2185
+ "picomatch": "^2.2.1"
2186
+ },
2187
+ "engines": {
2188
+ "node": ">=8.10.0"
2189
+ }
2190
+ },
2191
+ "node_modules/resolve": {
2192
+ "version": "1.22.10",
2193
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
2194
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
2195
+ "dev": true,
2196
+ "license": "MIT",
2197
+ "dependencies": {
2198
+ "is-core-module": "^2.16.0",
2199
+ "path-parse": "^1.0.7",
2200
+ "supports-preserve-symlinks-flag": "^1.0.0"
2201
+ },
2202
+ "bin": {
2203
+ "resolve": "bin/resolve"
2204
+ },
2205
+ "engines": {
2206
+ "node": ">= 0.4"
2207
+ },
2208
+ "funding": {
2209
+ "url": "https://github.com/sponsors/ljharb"
2210
+ }
2211
+ },
2212
+ "node_modules/reusify": {
2213
+ "version": "1.1.0",
2214
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
2215
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
2216
+ "dev": true,
2217
+ "license": "MIT",
2218
+ "engines": {
2219
+ "iojs": ">=1.0.0",
2220
+ "node": ">=0.10.0"
2221
+ }
2222
+ },
2223
+ "node_modules/rollup": {
2224
+ "version": "3.29.5",
2225
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
2226
+ "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
2227
+ "dev": true,
2228
+ "license": "MIT",
2229
+ "bin": {
2230
+ "rollup": "dist/bin/rollup"
2231
+ },
2232
+ "engines": {
2233
+ "node": ">=14.18.0",
2234
+ "npm": ">=8.0.0"
2235
+ },
2236
+ "optionalDependencies": {
2237
+ "fsevents": "~2.3.2"
2238
+ }
2239
+ },
2240
+ "node_modules/run-parallel": {
2241
+ "version": "1.2.0",
2242
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
2243
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
2244
+ "dev": true,
2245
+ "funding": [
2246
+ {
2247
+ "type": "github",
2248
+ "url": "https://github.com/sponsors/feross"
2249
+ },
2250
+ {
2251
+ "type": "patreon",
2252
+ "url": "https://www.patreon.com/feross"
2253
+ },
2254
+ {
2255
+ "type": "consulting",
2256
+ "url": "https://feross.org/support"
2257
+ }
2258
+ ],
2259
+ "license": "MIT",
2260
+ "dependencies": {
2261
+ "queue-microtask": "^1.2.2"
2262
+ }
2263
+ },
2264
+ "node_modules/scheduler": {
2265
+ "version": "0.23.2",
2266
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
2267
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
2268
+ "license": "MIT",
2269
+ "dependencies": {
2270
+ "loose-envify": "^1.1.0"
2271
+ }
2272
+ },
2273
+ "node_modules/semver": {
2274
+ "version": "6.3.1",
2275
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
2276
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
2277
+ "dev": true,
2278
+ "license": "ISC",
2279
+ "bin": {
2280
+ "semver": "bin/semver.js"
2281
+ }
2282
+ },
2283
+ "node_modules/shebang-command": {
2284
+ "version": "2.0.0",
2285
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2286
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2287
+ "dev": true,
2288
+ "license": "MIT",
2289
+ "dependencies": {
2290
+ "shebang-regex": "^3.0.0"
2291
+ },
2292
+ "engines": {
2293
+ "node": ">=8"
2294
+ }
2295
+ },
2296
+ "node_modules/shebang-regex": {
2297
+ "version": "3.0.0",
2298
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2299
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2300
+ "dev": true,
2301
+ "license": "MIT",
2302
+ "engines": {
2303
+ "node": ">=8"
2304
+ }
2305
+ },
2306
+ "node_modules/signal-exit": {
2307
+ "version": "4.1.0",
2308
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
2309
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
2310
+ "dev": true,
2311
+ "license": "ISC",
2312
+ "engines": {
2313
+ "node": ">=14"
2314
+ },
2315
+ "funding": {
2316
+ "url": "https://github.com/sponsors/isaacs"
2317
+ }
2318
+ },
2319
+ "node_modules/source-map-js": {
2320
+ "version": "1.2.1",
2321
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
2322
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
2323
+ "dev": true,
2324
+ "license": "BSD-3-Clause",
2325
+ "engines": {
2326
+ "node": ">=0.10.0"
2327
+ }
2328
+ },
2329
+ "node_modules/string-width": {
2330
+ "version": "5.1.2",
2331
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
2332
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
2333
+ "dev": true,
2334
+ "license": "MIT",
2335
+ "dependencies": {
2336
+ "eastasianwidth": "^0.2.0",
2337
+ "emoji-regex": "^9.2.2",
2338
+ "strip-ansi": "^7.0.1"
2339
+ },
2340
+ "engines": {
2341
+ "node": ">=12"
2342
+ },
2343
+ "funding": {
2344
+ "url": "https://github.com/sponsors/sindresorhus"
2345
+ }
2346
+ },
2347
+ "node_modules/string-width-cjs": {
2348
+ "name": "string-width",
2349
+ "version": "4.2.3",
2350
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2351
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2352
+ "dev": true,
2353
+ "license": "MIT",
2354
+ "dependencies": {
2355
+ "emoji-regex": "^8.0.0",
2356
+ "is-fullwidth-code-point": "^3.0.0",
2357
+ "strip-ansi": "^6.0.1"
2358
+ },
2359
+ "engines": {
2360
+ "node": ">=8"
2361
+ }
2362
+ },
2363
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
2364
+ "version": "5.0.1",
2365
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2366
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2367
+ "dev": true,
2368
+ "license": "MIT",
2369
+ "engines": {
2370
+ "node": ">=8"
2371
+ }
2372
+ },
2373
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
2374
+ "version": "8.0.0",
2375
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2376
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2377
+ "dev": true,
2378
+ "license": "MIT"
2379
+ },
2380
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
2381
+ "version": "6.0.1",
2382
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2383
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2384
+ "dev": true,
2385
+ "license": "MIT",
2386
+ "dependencies": {
2387
+ "ansi-regex": "^5.0.1"
2388
+ },
2389
+ "engines": {
2390
+ "node": ">=8"
2391
+ }
2392
+ },
2393
+ "node_modules/strip-ansi": {
2394
+ "version": "7.1.2",
2395
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
2396
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
2397
+ "dev": true,
2398
+ "license": "MIT",
2399
+ "dependencies": {
2400
+ "ansi-regex": "^6.0.1"
2401
+ },
2402
+ "engines": {
2403
+ "node": ">=12"
2404
+ },
2405
+ "funding": {
2406
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
2407
+ }
2408
+ },
2409
+ "node_modules/strip-ansi-cjs": {
2410
+ "name": "strip-ansi",
2411
+ "version": "6.0.1",
2412
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2413
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2414
+ "dev": true,
2415
+ "license": "MIT",
2416
+ "dependencies": {
2417
+ "ansi-regex": "^5.0.1"
2418
+ },
2419
+ "engines": {
2420
+ "node": ">=8"
2421
+ }
2422
+ },
2423
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
2424
+ "version": "5.0.1",
2425
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2426
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2427
+ "dev": true,
2428
+ "license": "MIT",
2429
+ "engines": {
2430
+ "node": ">=8"
2431
+ }
2432
+ },
2433
+ "node_modules/sucrase": {
2434
+ "version": "3.35.0",
2435
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
2436
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
2437
+ "dev": true,
2438
+ "license": "MIT",
2439
+ "dependencies": {
2440
+ "@jridgewell/gen-mapping": "^0.3.2",
2441
+ "commander": "^4.0.0",
2442
+ "glob": "^10.3.10",
2443
+ "lines-and-columns": "^1.1.6",
2444
+ "mz": "^2.7.0",
2445
+ "pirates": "^4.0.1",
2446
+ "ts-interface-checker": "^0.1.9"
2447
+ },
2448
+ "bin": {
2449
+ "sucrase": "bin/sucrase",
2450
+ "sucrase-node": "bin/sucrase-node"
2451
+ },
2452
+ "engines": {
2453
+ "node": ">=16 || 14 >=14.17"
2454
+ }
2455
+ },
2456
+ "node_modules/supports-preserve-symlinks-flag": {
2457
+ "version": "1.0.0",
2458
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
2459
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
2460
+ "dev": true,
2461
+ "license": "MIT",
2462
+ "engines": {
2463
+ "node": ">= 0.4"
2464
+ },
2465
+ "funding": {
2466
+ "url": "https://github.com/sponsors/ljharb"
2467
+ }
2468
+ },
2469
+ "node_modules/tailwindcss": {
2470
+ "version": "3.4.18",
2471
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz",
2472
+ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
2473
+ "dev": true,
2474
+ "license": "MIT",
2475
+ "dependencies": {
2476
+ "@alloc/quick-lru": "^5.2.0",
2477
+ "arg": "^5.0.2",
2478
+ "chokidar": "^3.6.0",
2479
+ "didyoumean": "^1.2.2",
2480
+ "dlv": "^1.1.3",
2481
+ "fast-glob": "^3.3.2",
2482
+ "glob-parent": "^6.0.2",
2483
+ "is-glob": "^4.0.3",
2484
+ "jiti": "^1.21.7",
2485
+ "lilconfig": "^3.1.3",
2486
+ "micromatch": "^4.0.8",
2487
+ "normalize-path": "^3.0.0",
2488
+ "object-hash": "^3.0.0",
2489
+ "picocolors": "^1.1.1",
2490
+ "postcss": "^8.4.47",
2491
+ "postcss-import": "^15.1.0",
2492
+ "postcss-js": "^4.0.1",
2493
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
2494
+ "postcss-nested": "^6.2.0",
2495
+ "postcss-selector-parser": "^6.1.2",
2496
+ "resolve": "^1.22.8",
2497
+ "sucrase": "^3.35.0"
2498
+ },
2499
+ "bin": {
2500
+ "tailwind": "lib/cli.js",
2501
+ "tailwindcss": "lib/cli.js"
2502
+ },
2503
+ "engines": {
2504
+ "node": ">=14.0.0"
2505
+ }
2506
+ },
2507
+ "node_modules/thenify": {
2508
+ "version": "3.3.1",
2509
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
2510
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
2511
+ "dev": true,
2512
+ "license": "MIT",
2513
+ "dependencies": {
2514
+ "any-promise": "^1.0.0"
2515
+ }
2516
+ },
2517
+ "node_modules/thenify-all": {
2518
+ "version": "1.6.0",
2519
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
2520
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
2521
+ "dev": true,
2522
+ "license": "MIT",
2523
+ "dependencies": {
2524
+ "thenify": ">= 3.1.0 < 4"
2525
+ },
2526
+ "engines": {
2527
+ "node": ">=0.8"
2528
+ }
2529
+ },
2530
+ "node_modules/to-regex-range": {
2531
+ "version": "5.0.1",
2532
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2533
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2534
+ "dev": true,
2535
+ "license": "MIT",
2536
+ "dependencies": {
2537
+ "is-number": "^7.0.0"
2538
+ },
2539
+ "engines": {
2540
+ "node": ">=8.0"
2541
+ }
2542
+ },
2543
+ "node_modules/ts-interface-checker": {
2544
+ "version": "0.1.13",
2545
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
2546
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
2547
+ "dev": true,
2548
+ "license": "Apache-2.0"
2549
+ },
2550
+ "node_modules/update-browserslist-db": {
2551
+ "version": "1.1.3",
2552
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
2553
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
2554
+ "dev": true,
2555
+ "funding": [
2556
+ {
2557
+ "type": "opencollective",
2558
+ "url": "https://opencollective.com/browserslist"
2559
+ },
2560
+ {
2561
+ "type": "tidelift",
2562
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
2563
+ },
2564
+ {
2565
+ "type": "github",
2566
+ "url": "https://github.com/sponsors/ai"
2567
+ }
2568
+ ],
2569
+ "license": "MIT",
2570
+ "dependencies": {
2571
+ "escalade": "^3.2.0",
2572
+ "picocolors": "^1.1.1"
2573
+ },
2574
+ "bin": {
2575
+ "update-browserslist-db": "cli.js"
2576
+ },
2577
+ "peerDependencies": {
2578
+ "browserslist": ">= 4.21.0"
2579
+ }
2580
+ },
2581
+ "node_modules/util-deprecate": {
2582
+ "version": "1.0.2",
2583
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2584
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
2585
+ "dev": true,
2586
+ "license": "MIT"
2587
+ },
2588
+ "node_modules/vite": {
2589
+ "version": "4.5.14",
2590
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz",
2591
+ "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
2592
+ "dev": true,
2593
+ "license": "MIT",
2594
+ "peer": true,
2595
+ "dependencies": {
2596
+ "esbuild": "^0.18.10",
2597
+ "postcss": "^8.4.27",
2598
+ "rollup": "^3.27.1"
2599
+ },
2600
+ "bin": {
2601
+ "vite": "bin/vite.js"
2602
+ },
2603
+ "engines": {
2604
+ "node": "^14.18.0 || >=16.0.0"
2605
+ },
2606
+ "funding": {
2607
+ "url": "https://github.com/vitejs/vite?sponsor=1"
2608
+ },
2609
+ "optionalDependencies": {
2610
+ "fsevents": "~2.3.2"
2611
+ },
2612
+ "peerDependencies": {
2613
+ "@types/node": ">= 14",
2614
+ "less": "*",
2615
+ "lightningcss": "^1.21.0",
2616
+ "sass": "*",
2617
+ "stylus": "*",
2618
+ "sugarss": "*",
2619
+ "terser": "^5.4.0"
2620
+ },
2621
+ "peerDependenciesMeta": {
2622
+ "@types/node": {
2623
+ "optional": true
2624
+ },
2625
+ "less": {
2626
+ "optional": true
2627
+ },
2628
+ "lightningcss": {
2629
+ "optional": true
2630
+ },
2631
+ "sass": {
2632
+ "optional": true
2633
+ },
2634
+ "stylus": {
2635
+ "optional": true
2636
+ },
2637
+ "sugarss": {
2638
+ "optional": true
2639
+ },
2640
+ "terser": {
2641
+ "optional": true
2642
+ }
2643
+ }
2644
+ },
2645
+ "node_modules/which": {
2646
+ "version": "2.0.2",
2647
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2648
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2649
+ "dev": true,
2650
+ "license": "ISC",
2651
+ "dependencies": {
2652
+ "isexe": "^2.0.0"
2653
+ },
2654
+ "bin": {
2655
+ "node-which": "bin/node-which"
2656
+ },
2657
+ "engines": {
2658
+ "node": ">= 8"
2659
+ }
2660
+ },
2661
+ "node_modules/wrap-ansi": {
2662
+ "version": "8.1.0",
2663
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
2664
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
2665
+ "dev": true,
2666
+ "license": "MIT",
2667
+ "dependencies": {
2668
+ "ansi-styles": "^6.1.0",
2669
+ "string-width": "^5.0.1",
2670
+ "strip-ansi": "^7.0.1"
2671
+ },
2672
+ "engines": {
2673
+ "node": ">=12"
2674
+ },
2675
+ "funding": {
2676
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2677
+ }
2678
+ },
2679
+ "node_modules/wrap-ansi-cjs": {
2680
+ "name": "wrap-ansi",
2681
+ "version": "7.0.0",
2682
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2683
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2684
+ "dev": true,
2685
+ "license": "MIT",
2686
+ "dependencies": {
2687
+ "ansi-styles": "^4.0.0",
2688
+ "string-width": "^4.1.0",
2689
+ "strip-ansi": "^6.0.0"
2690
+ },
2691
+ "engines": {
2692
+ "node": ">=10"
2693
+ },
2694
+ "funding": {
2695
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2696
+ }
2697
+ },
2698
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
2699
+ "version": "5.0.1",
2700
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2701
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2702
+ "dev": true,
2703
+ "license": "MIT",
2704
+ "engines": {
2705
+ "node": ">=8"
2706
+ }
2707
+ },
2708
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
2709
+ "version": "4.3.0",
2710
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2711
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2712
+ "dev": true,
2713
+ "license": "MIT",
2714
+ "dependencies": {
2715
+ "color-convert": "^2.0.1"
2716
+ },
2717
+ "engines": {
2718
+ "node": ">=8"
2719
+ },
2720
+ "funding": {
2721
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2722
+ }
2723
+ },
2724
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
2725
+ "version": "8.0.0",
2726
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2727
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2728
+ "dev": true,
2729
+ "license": "MIT"
2730
+ },
2731
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
2732
+ "version": "4.2.3",
2733
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2734
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2735
+ "dev": true,
2736
+ "license": "MIT",
2737
+ "dependencies": {
2738
+ "emoji-regex": "^8.0.0",
2739
+ "is-fullwidth-code-point": "^3.0.0",
2740
+ "strip-ansi": "^6.0.1"
2741
+ },
2742
+ "engines": {
2743
+ "node": ">=8"
2744
+ }
2745
+ },
2746
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
2747
+ "version": "6.0.1",
2748
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2749
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2750
+ "dev": true,
2751
+ "license": "MIT",
2752
+ "dependencies": {
2753
+ "ansi-regex": "^5.0.1"
2754
+ },
2755
+ "engines": {
2756
+ "node": ">=8"
2757
+ }
2758
+ },
2759
+ "node_modules/yallist": {
2760
+ "version": "3.1.1",
2761
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
2762
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
2763
+ "dev": true,
2764
+ "license": "ISC"
2765
+ }
2766
+ }
2767
+ }
frontend/package.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "n4sm-frontend",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "vite build",
8
+ "preview": "vite preview"
9
+ },
10
+ "dependencies": {
11
+ "react": "^18.2.0",
12
+ "react-dom": "^18.2.0",
13
+ "react-router-dom": "^6.14.2"
14
+ },
15
+ "devDependencies": {
16
+ "@types/react": "^18.2.15",
17
+ "@types/react-dom": "^18.2.7",
18
+ "@vitejs/plugin-react": "^4.0.3",
19
+ "autoprefixer": "^10.4.14",
20
+ "postcss": "^8.4.27",
21
+ "tailwindcss": "^3.3.3",
22
+ "vite": "^4.4.5"
23
+ }
24
+ }
frontend/postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ }
6
+ }
frontend/src/App.jsx ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
3
+ import Navbar from './components/Navbar';
4
+ import Home from './pages/Home';
5
+ import MissionHubs from './pages/MissionHubs';
6
+ import PartnershipBuilder from './pages/PartnershipBuilder';
7
+ import AccountabilityDashboard from './pages/AccountabilityDashboard';
8
+ import AlternativeMetrics from './pages/AlternativeMetrics';
9
+ import IndigenousVoices from './pages/IndigenousVoices';
10
+ import DeliberationTool from './pages/DeliberationTool';
11
+
12
+ function App() {
13
+ return (
14
+ <Router>
15
+ <div className="min-h-screen bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50">
16
+ <Navbar />
17
+ <main className="container mx-auto px-4 py-8">
18
+ <Routes>
19
+ <Route path="/" element={<Home />} />
20
+ <Route path="/missions" element={<MissionHubs />} />
21
+ <Route path="/partnerships" element={<PartnershipBuilder />} />
22
+ <Route path="/accountability" element={<AccountabilityDashboard />} />
23
+ <Route path="/metrics" element={<AlternativeMetrics />} />
24
+ <Route path="/indigenous" element={<IndigenousVoices />} />
25
+ <Route path="/deliberation" element={<DeliberationTool />} />
26
+ </Routes>
27
+ </main>
28
+ <footer className="bg-gradient-to-r from-indigo-900 to-purple-900 text-white py-10 mt-16">
29
+ <div className="container mx-auto px-4 text-center">
30
+ <p className="text-2xl font-bold mb-2">NextGen SDG Platform - Nexus for Systems Missions (N4SM)</p>
31
+ <p className="mt-2 text-indigo-200 text-lg">Transforming the Sustainable Development Goals for a Better Future</p>
32
+ <div className="mt-6 flex justify-center space-x-6">
33
+ <a href="#" className="text-indigo-200 hover:text-white transition-colors">Privacy Policy</a>
34
+ <a href="#" className="text-indigo-200 hover:text-white transition-colors">Terms of Service</a>
35
+ <a href="#" className="text-indigo-200 hover:text-white transition-colors">Contact</a>
36
+ </div>
37
+ </div>
38
+ </footer>
39
+ </div>
40
+ </Router>
41
+ );
42
+ }
43
+
44
+ export default App;
frontend/src/components/Navbar.jsx ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Link, useLocation } from 'react-router-dom';
3
+
4
+ const Navbar = () => {
5
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
6
+ const location = useLocation();
7
+
8
+ const navLinks = [
9
+ { name: 'Home', path: '/' },
10
+ { name: 'Missions', path: '/missions' },
11
+ { name: 'Partnerships', path: '/partnerships' },
12
+ { name: 'Accountability', path: '/accountability' },
13
+ { name: 'Metrics', path: '/metrics' },
14
+ { name: 'Indigenous Voices', path: '/indigenous' },
15
+ { name: 'Deliberation', path: '/deliberation' },
16
+ ];
17
+
18
+ const toggleDarkMode = () => {
19
+ if (document.documentElement.classList.contains('dark')) {
20
+ document.documentElement.classList.remove('dark');
21
+ localStorage.theme = 'light';
22
+ } else {
23
+ document.documentElement.classList.add('dark');
24
+ localStorage.theme = 'dark';
25
+ }
26
+ };
27
+
28
+ return (
29
+ <nav className="bg-white/80 dark:bg-slate-800/80 backdrop-blur-lg shadow-lg border-b border-white/20">
30
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
31
+ <div className="flex justify-between h-20">
32
+ <div className="flex items-center">
33
+ <Link to="/" className="flex-shrink-0 flex items-center">
34
+ <span className="text-2xl font-bold bg-gradient-to-r from-indigo-600 to-purple-600 bg-clip-text text-transparent dark:from-indigo-400 dark:to-purple-400">
35
+ N4SM Platform
36
+ </span>
37
+ </Link>
38
+ </div>
39
+
40
+ {/* Desktop menu */}
41
+ <div className="hidden md:flex items-center space-x-1">
42
+ {navLinks.map((link) => (
43
+ <NavLink
44
+ key={link.path}
45
+ to={link.path}
46
+ isActive={location.pathname === link.path}
47
+ >
48
+ {link.name}
49
+ </NavLink>
50
+ ))}
51
+
52
+ {/* Dark mode toggle */}
53
+ <button
54
+ onClick={toggleDarkMode}
55
+ className="ml-4 p-2 rounded-full text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-slate-700 focus:outline-none"
56
+ aria-label="Toggle dark mode"
57
+ >
58
+ <svg
59
+ className="w-6 h-6 hidden dark:block"
60
+ fill="none"
61
+ stroke="currentColor"
62
+ viewBox="0 0 24 24"
63
+ xmlns="http://www.w3.org/2000/svg"
64
+ >
65
+ <path
66
+ strokeLinecap="round"
67
+ strokeLinejoin="round"
68
+ strokeWidth={2}
69
+ d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
70
+ />
71
+ </svg>
72
+ <svg
73
+ className="w-6 h-6 dark:hidden"
74
+ fill="none"
75
+ stroke="currentColor"
76
+ viewBox="0 0 24 24"
77
+ xmlns="http://www.w3.org/2000/svg"
78
+ >
79
+ <path
80
+ strokeLinecap="round"
81
+ strokeLinejoin="round"
82
+ strokeWidth={2}
83
+ d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
84
+ />
85
+ </svg>
86
+ </button>
87
+ </div>
88
+
89
+ {/* Mobile menu button */}
90
+ <div className="md:hidden flex items-center">
91
+ <button
92
+ onClick={toggleDarkMode}
93
+ className="p-2 mr-2 rounded-full text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-slate-700 focus:outline-none"
94
+ aria-label="Toggle dark mode"
95
+ >
96
+ <svg
97
+ className="w-6 h-6 hidden dark:block"
98
+ fill="none"
99
+ stroke="currentColor"
100
+ viewBox="0 0 24 24"
101
+ xmlns="http://www.w3.org/2000/svg"
102
+ >
103
+ <path
104
+ strokeLinecap="round"
105
+ strokeLinejoin="round"
106
+ strokeWidth={2}
107
+ d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
108
+ />
109
+ </svg>
110
+ <svg
111
+ className="w-6 h-6 dark:hidden"
112
+ fill="none"
113
+ stroke="currentColor"
114
+ viewBox="0 0 24 24"
115
+ xmlns="http://www.w3.org/2000/svg"
116
+ >
117
+ <path
118
+ strokeLinecap="round"
119
+ strokeLinejoin="round"
120
+ strokeWidth={2}
121
+ d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
122
+ />
123
+ </svg>
124
+ </button>
125
+
126
+ <button
127
+ onClick={() => setIsMenuOpen(!isMenuOpen)}
128
+ className="inline-flex items-center justify-center p-2 rounded-md text-gray-700 hover:text-indigo-600 dark:text-gray-300 dark:hover:text-indigo-400 focus:outline-none"
129
+ >
130
+ <svg
131
+ className={`${isMenuOpen ? 'hidden' : 'block'} h-8 w-8`}
132
+ stroke="currentColor"
133
+ fill="none"
134
+ viewBox="0 0 24 24"
135
+ >
136
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16M4 18h16" />
137
+ </svg>
138
+ <svg
139
+ className={`${isMenuOpen ? 'block' : 'hidden'} h-8 w-8`}
140
+ stroke="currentColor"
141
+ fill="none"
142
+ viewBox="0 0 24 24"
143
+ >
144
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
145
+ </svg>
146
+ </button>
147
+ </div>
148
+ </div>
149
+ </div>
150
+
151
+ {/* Mobile menu */}
152
+ <div className={`${isMenuOpen ? 'block' : 'hidden'} md:hidden`}>
153
+ <div className="px-2 pt-2 pb-3 space-y-1 sm:px-3 bg-white/90 dark:bg-slate-800/90 backdrop-blur-lg rounded-b-2xl border border-white/20 shadow-lg">
154
+ {navLinks.map((link) => (
155
+ <MobileNavLink
156
+ key={link.path}
157
+ to={link.path}
158
+ isActive={location.pathname === link.path}
159
+ onClick={() => setIsMenuOpen(false)}
160
+ >
161
+ {link.name}
162
+ </MobileNavLink>
163
+ ))}
164
+ </div>
165
+ </div>
166
+ </nav>
167
+ );
168
+ };
169
+
170
+ const NavLink = ({ to, children, isActive }) => (
171
+ <Link
172
+ to={to}
173
+ className={`px-4 py-2 rounded-full text-sm font-medium transition-all duration-200 ${
174
+ isActive
175
+ ? 'bg-gradient-to-r from-indigo-500 to-purple-500 text-white shadow-md'
176
+ : 'text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 dark:text-gray-300 dark:hover:bg-slate-700 dark:hover:text-indigo-400'
177
+ }`}
178
+ >
179
+ {children}
180
+ </Link>
181
+ );
182
+
183
+ const MobileNavLink = ({ to, children, isActive, onClick }) => (
184
+ <Link
185
+ to={to}
186
+ onClick={onClick}
187
+ className={`block px-4 py-3 rounded-lg text-base font-medium transition-all duration-200 ${
188
+ isActive
189
+ ? 'bg-gradient-to-r from-indigo-500 to-purple-500 text-white shadow-md'
190
+ : 'text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 dark:text-gray-300 dark:hover:bg-slate-700 dark:hover:text-indigo-400'
191
+ }`}
192
+ >
193
+ {children}
194
+ </Link>
195
+ );
196
+
197
+ export default Navbar;
frontend/src/index.css ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --foreground-rgb: 0, 0, 0;
7
+ --background-start-rgb: 245, 247, 250;
8
+ --background-end-rgb: 228, 237, 249;
9
+ }
10
+
11
+ @media (prefers-color-scheme: dark) {
12
+ :root {
13
+ --foreground-rgb: 255, 255, 255;
14
+ --background-start-rgb: 15, 23, 42;
15
+ --background-end-rgb: 30, 41, 59;
16
+ }
17
+ }
18
+
19
+ body {
20
+ margin: 0;
21
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
22
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
23
+ sans-serif;
24
+ -webkit-font-smoothing: antialiased;
25
+ -moz-osx-font-smoothing: grayscale;
26
+ background: linear-gradient(to bottom,
27
+ rgb(var(--background-start-rgb)) 0%,
28
+ rgb(var(--background-end-rgb)) 100%);
29
+ color: rgb(var(--foreground-rgb));
30
+ min-height: 100vh;
31
+ }
32
+
33
+ /* Custom styles for our SDG platform */
34
+ .sdg-card {
35
+ @apply bg-white/80 dark:bg-slate-800/80 backdrop-blur-lg rounded-2xl shadow-xl overflow-hidden transition-all duration-300 hover:shadow-2xl hover:-translate-y-1 border border-white/20;
36
+ }
37
+
38
+ .sdg-card-gradient {
39
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
40
+ @apply rounded-2xl shadow-xl overflow-hidden transition-all duration-300 hover:shadow-2xl border border-white/20;
41
+ }
42
+
43
+ .sdg-btn {
44
+ @apply px-6 py-3 rounded-full font-semibold transition-all duration-300 transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-slate-900;
45
+ }
46
+
47
+ .sdg-btn-primary {
48
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
49
+ @apply text-white hover:opacity-90 focus:ring-indigo-500;
50
+ }
51
+
52
+ .sdg-btn-secondary {
53
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
54
+ @apply text-white hover:opacity-90 focus:ring-pink-500;
55
+ }
56
+
57
+ .sdg-btn-tertiary {
58
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
59
+ @apply text-white hover:opacity-90 focus:ring-green-500;
60
+ }
61
+
62
+ .mission-icon {
63
+ @apply w-20 h-20 mx-auto mb-6 rounded-2xl flex items-center justify-center text-white text-3xl font-bold shadow-lg transform transition-transform duration-300;
64
+ }
65
+
66
+ .gradient-bg {
67
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
68
+ }
69
+
70
+ .gradient-bg-2 {
71
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
72
+ }
73
+
74
+ .gradient-bg-3 {
75
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
76
+ }
77
+
78
+ .gradient-bg-4 {
79
+ background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
80
+ }
81
+
82
+ .gradient-bg-5 {
83
+ background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
84
+ }
85
+
86
+ .gradient-bg-6 {
87
+ background: linear-gradient(135deg, #d299c2 0%, #fef9d7 100%);
88
+ }
89
+
90
+ .hero-gradient {
91
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
92
+ }
93
+
94
+ .text-gradient {
95
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
96
+ -webkit-background-clip: text;
97
+ -webkit-text-fill-color: transparent;
98
+ background-clip: text;
99
+ }
100
+
101
+ .text-gradient-2 {
102
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
103
+ -webkit-background-clip: text;
104
+ -webkit-text-fill-color: transparent;
105
+ background-clip: text;
106
+ }
107
+
108
+ .feature-card {
109
+ @apply p-6 rounded-2xl shadow-lg transition-all duration-300 hover:shadow-xl bg-white/80 dark:bg-slate-800/80 backdrop-blur-lg border border-white/20;
110
+ }
111
+
112
+ .stat-card {
113
+ @apply p-6 rounded-2xl shadow-lg bg-white/90 dark:bg-slate-800/90 backdrop-blur-lg border border-white/20;
114
+ }
115
+
116
+ /* Dark mode specific overrides */
117
+ .dark {
118
+ --foreground-rgb: 255, 255, 255;
119
+ --background-start-rgb: 15, 23, 42;
120
+ --background-end-rgb: 30, 41, 59;
121
+ }
122
+
123
+ .dark .text-gray-600 {
124
+ @apply text-gray-300;
125
+ }
126
+
127
+ .dark .text-gray-700 {
128
+ @apply text-gray-200;
129
+ }
130
+
131
+ .dark .text-gray-800 {
132
+ @apply text-gray-100;
133
+ }
134
+
135
+ .dark .bg-gray-50 {
136
+ @apply bg-slate-700;
137
+ }
138
+
139
+ .dark input, .dark textarea, .dark select {
140
+ @apply bg-slate-700 border-slate-600 text-white;
141
+ }
142
+
143
+ .dark .border-gray-100 {
144
+ @apply border-slate-700;
145
+ }
146
+
147
+ .dark .border-gray-200 {
148
+ @apply border-slate-600;
149
+ }
150
+
151
+ .dark .border-gray-300 {
152
+ @apply border-slate-600;
153
+ }
frontend/src/main.jsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react'
2
+ import ReactDOM from 'react-dom/client'
3
+ import App from './App.jsx'
4
+ import './index.css'
5
+
6
+ // Add Google Fonts
7
+ const link = document.createElement('link');
8
+ link.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap';
9
+ link.rel = 'stylesheet';
10
+ document.head.appendChild(link);
11
+
12
+ // Add dark mode support
13
+ if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
14
+ document.documentElement.classList.add('dark')
15
+ } else {
16
+ document.documentElement.classList.remove('dark')
17
+ }
18
+
19
+ ReactDOM.createRoot(document.getElementById('root')).render(
20
+ <React.StrictMode>
21
+ <App />
22
+ </React.StrictMode>,
23
+ )
frontend/src/pages/AccountabilityDashboard.jsx ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const AccountabilityDashboard = () => {
4
+ return (
5
+ <div className="max-w-7xl mx-auto">
6
+ <div className="text-center mb-16">
7
+ <h1 className="text-4xl font-bold text-gray-800 mb-6">Accountability Dashboard</h1>
8
+ <p className="text-xl text-gray-600 max-w-3xl mx-auto">
9
+ Transparent KPIs, citizen audits, deliberative inputs, and policy playbooks for tracking progress
10
+ on our Systems-Based Missions.
11
+ </p>
12
+ </div>
13
+
14
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
15
+ <div className="lg:col-span-2 feature-card">
16
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Mission Progress Overview</h2>
17
+ <div className="h-80 flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-50 rounded-2xl border-2 border-dashed border-blue-200">
18
+ <div className="text-center">
19
+ <div className="text-5xl mb-4">📊</div>
20
+ <p className="text-gray-600 text-lg">Interactive visualization of mission KPIs</p>
21
+ <p className="text-gray-500 mt-2">Real-time data from all mission hubs</p>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div className="feature-card">
26
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Recent Updates</h2>
27
+ <ul className="space-y-6">
28
+ <li className="pb-4 border-b border-gray-100">
29
+ <div className="flex items-start">
30
+ <div className="bg-green-100 p-2 rounded-lg mr-4">
31
+ <div className="text-green-600 text-xl">🌱</div>
32
+ </div>
33
+ <div>
34
+ <h3 className="font-bold text-gray-800">Regenerative Economy</h3>
35
+ <p className="text-gray-600 text-sm mt-1">New data on renewable energy adoption added</p>
36
+ <span className="text-xs text-gray-500 mt-2 inline-block">2 hours ago</span>
37
+ </div>
38
+ </div>
39
+ </li>
40
+ <li className="pb-4 border-b border-gray-100">
41
+ <div className="flex items-start">
42
+ <div className="bg-blue-100 p-2 rounded-lg mr-4">
43
+ <div className="text-blue-600 text-xl">🏥</div>
44
+ </div>
45
+ <div>
46
+ <h3 className="font-bold text-gray-800">Well-being for All</h3>
47
+ <p className="text-gray-600 text-sm mt-1">Education quality metrics updated</p>
48
+ <span className="text-xs text-gray-500 mt-2 inline-block">1 day ago</span>
49
+ </div>
50
+ </div>
51
+ </li>
52
+ <li className="pb-4">
53
+ <div className="flex items-start">
54
+ <div className="bg-purple-100 p-2 rounded-lg mr-4">
55
+ <div className="text-purple-600 text-xl">🤖</div>
56
+ </div>
57
+ <div>
58
+ <h3 className="font-bold text-gray-800">Just Digital Transition</h3>
59
+ <p className="text-gray-600 text-sm mt-1">AI ethics guidelines draft published</p>
60
+ <span className="text-xs text-gray-500 mt-2 inline-block">3 days ago</span>
61
+ </div>
62
+ </div>
63
+ </li>
64
+ </ul>
65
+ </div>
66
+ </div>
67
+
68
+ <div className="feature-card mb-12">
69
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Data Provenance</h2>
70
+ <p className="text-gray-600 mb-6">
71
+ All data in our platform follows transparent provenance tracking to ensure reliability and accountability.
72
+ </p>
73
+ <div className="flex items-center">
74
+ <div className="flex-1 h-4 bg-gradient-to-r from-green-200 via-yellow-200 to-red-200 rounded-full overflow-hidden">
75
+ <div className="h-full bg-gradient-to-r from-green-500 to-green-600 w-3/4"></div>
76
+ </div>
77
+ <span className="ml-6 text-lg font-bold text-gray-700">75% of datasets verified</span>
78
+ </div>
79
+ </div>
80
+
81
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
82
+ <div className="feature-card">
83
+ <div className="flex items-center mb-6">
84
+ <div className="bg-yellow-100 p-3 rounded-xl mr-4">
85
+ <div className="text-yellow-600 text-2xl">👥</div>
86
+ </div>
87
+ <h2 className="text-2xl font-bold text-gray-800">Citizen Audits</h2>
88
+ </div>
89
+ <p className="text-gray-600 mb-6">
90
+ Participate in or view citizen-led audits of mission progress and policy implementation.
91
+ </p>
92
+ <button className="sdg-btn sdg-btn-primary w-full py-4">
93
+ View Audits
94
+ </button>
95
+ </div>
96
+ <div className="feature-card">
97
+ <div className="flex items-center mb-6">
98
+ <div className="bg-indigo-100 p-3 rounded-xl mr-4">
99
+ <div className="text-indigo-600 text-2xl">📘</div>
100
+ </div>
101
+ <h2 className="text-2xl font-bold text-gray-800">Policy Playbooks</h2>
102
+ </div>
103
+ <p className="text-gray-600 mb-6">
104
+ Access actionable policy recommendations and implementation guides for each mission.
105
+ </p>
106
+ <button className="sdg-btn sdg-btn-primary w-full py-4">
107
+ Explore Playbooks
108
+ </button>
109
+ </div>
110
+ </div>
111
+
112
+ {/* Stats Section */}
113
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-6 mt-16">
114
+ <StatCard number="98%" label="Data Transparency" color="from-green-400 to-green-600" />
115
+ <StatCard number="42" label="Active Audits" color="from-blue-400 to-blue-600" />
116
+ <StatCard number="18" label="Policy Playbooks" color="from-purple-400 to-purple-600" />
117
+ <StatCard number="240+" label="Verified Sources" color="from-yellow-400 to-yellow-600" />
118
+ </div>
119
+ </div>
120
+ );
121
+ };
122
+
123
+ const StatCard = ({ number, label, color }) => (
124
+ <div className={`stat-card bg-gradient-to-br ${color} text-white text-center`}>
125
+ <div className="text-2xl font-bold">{number}</div>
126
+ <div className="mt-1">{label}</div>
127
+ </div>
128
+ );
129
+
130
+ export default AccountabilityDashboard;
frontend/src/pages/AlternativeMetrics.jsx ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const AlternativeMetrics = () => {
4
+ return (
5
+ <div className="max-w-7xl mx-auto">
6
+ <div className="text-center mb-16">
7
+ <h1 className="text-4xl font-bold text-gray-800 mb-6">Alternative Metrics Module</h1>
8
+ <p className="text-xl text-gray-600 max-w-3xl mx-auto">
9
+ Move beyond GDP with wellbeing and degrowth indicators like GPI, Doughnut metrics, and biodiversity indexes.
10
+ </p>
11
+ </div>
12
+
13
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
14
+ <div className="lg:col-span-2 feature-card">
15
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Upload Localized Indicators</h2>
16
+ <p className="text-gray-600 mb-8">
17
+ Contribute your own wellbeing and sustainability metrics to enrich our global dataset.
18
+ </p>
19
+
20
+ <div className="mb-6">
21
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="metric-name">
22
+ Metric Name
23
+ </label>
24
+ <input
25
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
26
+ id="metric-name"
27
+ type="text"
28
+ placeholder="e.g., Genuine Progress Indicator"
29
+ />
30
+ </div>
31
+
32
+ <div className="mb-6">
33
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="metric-description">
34
+ Description
35
+ </label>
36
+ <textarea
37
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
38
+ id="metric-description"
39
+ placeholder="Describe the metric and its relevance to sustainable development"
40
+ rows="4"
41
+ ></textarea>
42
+ </div>
43
+
44
+ <div className="mb-8">
45
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="data-file">
46
+ Upload Data File
47
+ </label>
48
+ <div className="flex items-center justify-center w-full">
49
+ <label className="flex flex-col items-center justify-center w-full h-40 border-2 border-dashed border-gray-300 rounded-2xl cursor-pointer bg-gradient-to-br from-blue-50 to-indigo-50 hover:from-blue-100 hover:to-indigo-100 transition-all">
50
+ <div className="flex flex-col items-center justify-center pt-5 pb-6">
51
+ <svg className="w-10 h-10 mb-4 text-gray-500" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
52
+ <path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"/>
53
+ </svg>
54
+ <p className="mb-2 text-sm text-gray-500"><span className="font-semibold">Click to upload</span> or drag and drop</p>
55
+ <p className="text-xs text-gray-500">CSV, JSON, or Excel (MAX. 10MB)</p>
56
+ </div>
57
+ <input id="data-file" type="file" className="hidden" />
58
+ </label>
59
+ </div>
60
+ </div>
61
+
62
+ <button className="sdg-btn sdg-btn-primary w-full py-4 text-lg">
63
+ Submit Metric
64
+ </button>
65
+ </div>
66
+
67
+ <div className="feature-card">
68
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Featured Metrics</h2>
69
+ <ul className="space-y-6">
70
+ <li className="pb-4 border-b border-gray-100">
71
+ <div className="flex">
72
+ <div className="bg-green-100 p-3 rounded-xl mr-4">
73
+ <div className="text-green-600 font-bold">GPI</div>
74
+ </div>
75
+ <div>
76
+ <h3 className="font-bold text-gray-800">Genuine Progress Indicator</h3>
77
+ <p className="text-gray-600 text-sm mt-1">Measures economic growth and well-being, accounting for environmental and social factors</p>
78
+ </div>
79
+ </div>
80
+ </li>
81
+ <li className="pb-4 border-b border-gray-100">
82
+ <div className="flex">
83
+ <div className="bg-yellow-100 p-3 rounded-xl mr-4">
84
+ <div className="text-yellow-600 font-bold">🍩</div>
85
+ </div>
86
+ <div>
87
+ <h3 className="font-bold text-gray-800">Doughnut Economics</h3>
88
+ <p className="text-gray-600 text-sm mt-1">Balances social foundations with ecological ceilings for sustainable development</p>
89
+ </div>
90
+ </div>
91
+ </li>
92
+ <li className="pb-4 border-b border-gray-100">
93
+ <div className="flex">
94
+ <div className="bg-blue-100 p-3 rounded-xl mr-4">
95
+ <div className="text-blue-600 font-bold">BI</div>
96
+ </div>
97
+ <div>
98
+ <h3 className="font-bold text-gray-800">Biodiversity Index</h3>
99
+ <p className="text-gray-600 text-sm mt-1">Tracks ecosystem health and species diversity across regions</p>
100
+ </div>
101
+ </div>
102
+ </li>
103
+ <li>
104
+ <div className="flex">
105
+ <div className="bg-purple-100 p-3 rounded-xl mr-4">
106
+ <div className="text-purple-600 font-bold">SWI</div>
107
+ </div>
108
+ <div>
109
+ <h3 className="font-bold text-gray-800">Social Wellbeing Index</h3>
110
+ <p className="text-gray-600 text-sm mt-1">Measures quality of life factors including health, education, and community connection</p>
111
+ </div>
112
+ </div>
113
+ </li>
114
+ </ul>
115
+ <button className="mt-8 sdg-btn sdg-btn-secondary w-full py-3">
116
+ View All Metrics
117
+ </button>
118
+ </div>
119
+ </div>
120
+
121
+ <div className="feature-card">
122
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Metric Visualization</h2>
123
+ <p className="text-gray-600 mb-8">
124
+ Compare and analyze alternative metrics across different regions and time periods.
125
+ </p>
126
+ <div className="h-96 flex items-center justify-center bg-gradient-to-br from-blue-50 to-purple-50 rounded-2xl border-2 border-dashed border-indigo-200">
127
+ <div className="text-center">
128
+ <div className="text-5xl mb-4">📈</div>
129
+ <p className="text-gray-600 text-lg">Interactive metric visualization dashboard</p>
130
+ <p className="text-gray-500 mt-2">Real-time data comparison and analysis</p>
131
+ </div>
132
+ </div>
133
+ </div>
134
+
135
+ {/* Stats Section */}
136
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-16">
137
+ <StatCard number="24" label="Metrics Available" color="from-green-400 to-green-600" />
138
+ <StatCard number="142" label="Datasets Uploaded" color="from-blue-400 to-blue-600" />
139
+ <StatCard number="3.2K" label="Community Contributors" color="from-purple-400 to-purple-600" />
140
+ </div>
141
+ </div>
142
+ );
143
+ };
144
+
145
+ const StatCard = ({ number, label, color }) => (
146
+ <div className={`stat-card bg-gradient-to-br ${color} text-white text-center`}>
147
+ <div className="text-3xl font-bold">{number}</div>
148
+ <div className="mt-2">{label}</div>
149
+ </div>
150
+ );
151
+
152
+ export default AlternativeMetrics;
frontend/src/pages/DeliberationTool.jsx ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const DeliberationTool = () => {
4
+ return (
5
+ <div className="max-w-7xl mx-auto">
6
+ <div className="text-center mb-16">
7
+ <h1 className="text-4xl font-bold text-gray-800 mb-6">Deliberation & Jury Tool</h1>
8
+ <p className="text-xl text-gray-600 max-w-3xl mx-auto">
9
+ Engage citizens in decision-making through small-group ballots, citizen jury templates,
10
+ and summary report generation for policy makers.
11
+ </p>
12
+ </div>
13
+
14
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
15
+ <div className="lg:col-span-2 feature-card">
16
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Create a Citizen Deliberation</h2>
17
+ <p className="text-gray-600 mb-8">
18
+ Set up a new deliberation process for community input on sustainable development policies.
19
+ </p>
20
+
21
+ <div className="mb-6">
22
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="deliberation-title">
23
+ Deliberation Title
24
+ </label>
25
+ <input
26
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
27
+ id="deliberation-title"
28
+ type="text"
29
+ placeholder="e.g., Renewable Energy Policy in Coastal Communities"
30
+ />
31
+ </div>
32
+
33
+ <div className="mb-6">
34
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="deliberation-description">
35
+ Description
36
+ </label>
37
+ <textarea
38
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
39
+ id="deliberation-description"
40
+ placeholder="Describe the policy issue and what input you're seeking from participants"
41
+ rows="4"
42
+ ></textarea>
43
+ </div>
44
+
45
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
46
+ <div>
47
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="participant-count">
48
+ Participant Count
49
+ </label>
50
+ <input
51
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
52
+ id="participant-count"
53
+ type="number"
54
+ placeholder="e.g., 20"
55
+ />
56
+ </div>
57
+ <div>
58
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="duration">
59
+ Duration (days)
60
+ </label>
61
+ <input
62
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
63
+ id="duration"
64
+ type="number"
65
+ placeholder="e.g., 7"
66
+ />
67
+ </div>
68
+ </div>
69
+
70
+ <div className="mb-8">
71
+ <label className="block text-gray-700 text-sm font-bold mb-2">
72
+ Mission Area
73
+ </label>
74
+ <select className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent appearance-none bg-white">
75
+ <option>Select a Systems-Based Mission</option>
76
+ <option>Regenerative Economy</option>
77
+ <option>Well-being for All</option>
78
+ <option>Just Digital Transition</option>
79
+ <option>Equity and Inclusion</option>
80
+ <option>Peace and Global Governance</option>
81
+ <option>Resilient Local Economies</option>
82
+ </select>
83
+ </div>
84
+
85
+ <button className="sdg-btn sdg-btn-primary w-full py-4 text-lg">
86
+ Create Deliberation
87
+ </button>
88
+ </div>
89
+
90
+ <div className="feature-card">
91
+ <div className="flex items-center mb-6">
92
+ <div className="bg-indigo-100 p-3 rounded-xl mr-4">
93
+ <div className="text-indigo-600 text-2xl">⚡</div>
94
+ </div>
95
+ <h2 className="text-2xl font-bold text-gray-800">Active Deliberations</h2>
96
+ </div>
97
+ <ul className="space-y-6">
98
+ <li className="pb-4 border-b border-gray-100">
99
+ <h3 className="font-bold text-gray-800">Urban Food Systems Transformation</h3>
100
+ <p className="text-gray-600 text-sm mt-1">Resilient Local Economies mission</p>
101
+ <div className="flex justify-between items-center mt-3">
102
+ <span className="text-xs bg-gradient-to-r from-blue-100 to-blue-200 text-blue-800 px-3 py-1 rounded-full">12/20 participants</span>
103
+ <span className="text-xs text-gray-500">3 days left</span>
104
+ </div>
105
+ <div className="mt-3 w-full bg-gray-200 rounded-full h-2">
106
+ <div className="bg-gradient-to-r from-blue-400 to-blue-600 h-2 rounded-full" style={{width: '60%'}}></div>
107
+ </div>
108
+ </li>
109
+ <li className="pb-4 border-b border-gray-100">
110
+ <h3 className="font-bold text-gray-800">Digital Rights in AI Governance</h3>
111
+ <p className="text-gray-600 text-sm mt-1">Just Digital Transition mission</p>
112
+ <div className="flex justify-between items-center mt-3">
113
+ <span className="text-xs bg-gradient-to-r from-purple-100 to-purple-200 text-purple-800 px-3 py-1 rounded-full">8/15 participants</span>
114
+ <span className="text-xs text-gray-500">5 days left</span>
115
+ </div>
116
+ <div className="mt-3 w-full bg-gray-200 rounded-full h-2">
117
+ <div className="bg-gradient-to-r from-purple-400 to-purple-600 h-2 rounded-full" style={{width: '53%'}}></div>
118
+ </div>
119
+ </li>
120
+ <li>
121
+ <h3 className="font-bold text-gray-800">Indigenous Land Rights Recognition</h3>
122
+ <p className="text-gray-600 text-sm mt-1">Equity and Inclusion mission</p>
123
+ <div className="flex justify-between items-center mt-3">
124
+ <span className="text-xs bg-gradient-to-r from-green-100 to-green-200 text-green-800 px-3 py-1 rounded-full">Completed</span>
125
+ <button className="text-xs text-indigo-600 hover:text-indigo-800 font-medium">View Results</button>
126
+ </div>
127
+ </li>
128
+ </ul>
129
+ <button className="mt-8 sdg-btn sdg-btn-secondary w-full py-3">
130
+ View All Deliberations
131
+ </button>
132
+ </div>
133
+ </div>
134
+
135
+ <div className="feature-card">
136
+ <div className="flex items-center mb-8">
137
+ <div className="bg-yellow-100 p-3 rounded-xl mr-4">
138
+ <div className="text-yellow-600 text-2xl">📋</div>
139
+ </div>
140
+ <h2 className="text-2xl font-bold text-gray-800">Deliberation Templates</h2>
141
+ </div>
142
+ <p className="text-gray-600 mb-8">
143
+ Use our pre-built templates to structure your citizen deliberation processes.
144
+ </p>
145
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
146
+ <div className="border-2 border-blue-200 rounded-2xl p-6 hover:border-blue-400 transition-all hover:shadow-lg">
147
+ <div className="text-blue-600 text-3xl mb-4">📊</div>
148
+ <h3 className="font-bold text-gray-800 mb-2">Policy Prioritization</h3>
149
+ <p className="text-gray-600 text-sm mb-4">Help citizens rank policy options based on impact and feasibility</p>
150
+ <button className="text-blue-600 font-medium hover:text-blue-800">Use Template →</button>
151
+ </div>
152
+ <div className="border-2 border-purple-200 rounded-2xl p-6 hover:border-purple-400 transition-all hover:shadow-lg">
153
+ <div className="text-purple-600 text-3xl mb-4">⚖️</div>
154
+ <h3 className="font-bold text-gray-800 mb-2">Trade-off Analysis</h3>
155
+ <p className="text-gray-600 text-sm mb-4">Guide participants through complex trade-offs between different values</p>
156
+ <button className="text-purple-600 font-medium hover:text-purple-800">Use Template →</button>
157
+ </div>
158
+ <div className="border-2 border-green-200 rounded-2xl p-6 hover:border-green-400 transition-all hover:shadow-lg">
159
+ <div className="text-green-600 text-3xl mb-4">🔮</div>
160
+ <h3 className="font-bold text-gray-800 mb-2">Scenario Planning</h3>
161
+ <p className="text-gray-600 text-sm mb-4">Explore future scenarios and their implications for policy decisions</p>
162
+ <button className="text-green-600 font-medium hover:text-green-800">Use Template →</button>
163
+ </div>
164
+ </div>
165
+ </div>
166
+
167
+ {/* Stats Section */}
168
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-6 mt-16">
169
+ <StatCard number="42" label="Active Deliberations" color="from-indigo-400 to-indigo-600" />
170
+ <StatCard number="1.2K" label="Participants Engaged" color="from-blue-400 to-blue-600" />
171
+ <StatCard number="89" label="Policies Influenced" color="from-purple-400 to-purple-600" />
172
+ <StatCard number="94%" label="Satisfaction Rate" color="from-green-400 to-green-600" />
173
+ </div>
174
+ </div>
175
+ );
176
+ };
177
+
178
+ const StatCard = ({ number, label, color }) => (
179
+ <div className={`stat-card bg-gradient-to-br ${color} text-white text-center`}>
180
+ <div className="text-2xl font-bold">{number}</div>
181
+ <div className="mt-1">{label}</div>
182
+ </div>
183
+ );
184
+
185
+ export default DeliberationTool;
frontend/src/pages/Home.jsx ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { Link } from 'react-router-dom';
3
+
4
+ const Home = () => {
5
+ return (
6
+ <div className="max-w-7xl mx-auto">
7
+ {/* Hero Section */}
8
+ <div className="hero-gradient text-white rounded-3xl p-8 md:p-12 mb-12">
9
+ <div className="max-w-4xl mx-auto text-center">
10
+ <h1 className="text-4xl md:text-6xl font-bold mb-6">
11
+ SDGLIV/GXS NextGen SDG <span className="text-gradient-2">Platform</span>
12
+ </h1>
13
+ <p className="text-xl md:text-2xl mb-8 opacity-90">
14
+ Nexus for Systems Missions: Transforming the Sustainable Development Goals into integrated, systems-based missions
15
+ </p>
16
+ <div className="flex flex-col sm:flex-row justify-center gap-4">
17
+ <Link to="/missions" className="sdg-btn sdg-btn-primary text-lg px-8 py-4">
18
+ Explore Missions
19
+ </Link>
20
+ <Link to="/partnerships" className="sdg-btn sdg-btn-tertiary text-lg px-8 py-4">
21
+ Build Partnerships
22
+ </Link>
23
+ </div>
24
+ </div>
25
+ </div>
26
+
27
+ {/* Features Section */}
28
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mt-16">
29
+ <FeatureCard
30
+ title="Mission Hubs"
31
+ description="Explore our 6 Systems-Based Missions with living roadmaps for policy, projects, and finance."
32
+ link="/missions"
33
+ color="gradient-bg"
34
+ icon="🚀"
35
+ />
36
+ <FeatureCard
37
+ title="Partnership Builder"
38
+ description="Connect with stakeholders and build multi-stakeholder partnerships for sustainable development."
39
+ link="/partnerships"
40
+ color="gradient-bg-2"
41
+ icon="🤝"
42
+ />
43
+ <FeatureCard
44
+ title="Accountability Dashboard"
45
+ description="Transparent KPIs, citizen audits, and deliberative inputs for tracking progress."
46
+ link="/accountability"
47
+ color="gradient-bg-3"
48
+ icon="📊"
49
+ />
50
+ <FeatureCard
51
+ title="Alternative Metrics"
52
+ description="Move beyond GDP with wellbeing and degrowth indicators like GPI and Doughnut metrics."
53
+ link="/metrics"
54
+ color="gradient-bg-4"
55
+ icon="📈"
56
+ />
57
+ <FeatureCard
58
+ title="Indigenous Voices"
59
+ description="Centering indigenous knowledge systems and planetary boundaries in sustainable development."
60
+ link="/indigenous"
61
+ color="gradient-bg-5"
62
+ icon="🗣️"
63
+ />
64
+ <FeatureCard
65
+ title="Deliberation Tool"
66
+ description="Engage citizens in decision-making through ballots, jury templates, and reports."
67
+ link="/deliberation"
68
+ color="gradient-bg-6"
69
+ icon="🗳️"
70
+ />
71
+ </div>
72
+
73
+ {/* SDG Framework Section */}
74
+ <div className="feature-card mt-16">
75
+ <h2 className="text-3xl font-bold text-gray-800 dark:text-white mb-6 text-center">Reforming the Sustainable Development Goals</h2>
76
+ <p className="text-gray-600 dark:text-gray-300 mb-8 text-center max-w-3xl mx-auto">
77
+ Our NextGen SDG Framework transforms the fragmented 17 Goals into 6 integrated Systems-Based Missions:
78
+ </p>
79
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
80
+ <MissionItem
81
+ title="Regenerative Economy"
82
+ description="Climate, energy, biodiversity, jobs"
83
+ color="bg-green-500"
84
+ />
85
+ <MissionItem
86
+ title="Well-being for All"
87
+ description="Health, education, social protection"
88
+ color="bg-blue-500"
89
+ />
90
+ <MissionItem
91
+ title="Just Digital Transition"
92
+ description="Infrastructure, AI ethics and governance, data justice"
93
+ color="bg-purple-500"
94
+ />
95
+ <MissionItem
96
+ title="Equity and Inclusion"
97
+ description="Gender, migration, race, intergenerational justice"
98
+ color="bg-yellow-500"
99
+ />
100
+ <MissionItem
101
+ title="Peace and Global Governance"
102
+ description="Conflict, institutions, human rights"
103
+ color="bg-red-500"
104
+ />
105
+ <MissionItem
106
+ title="Resilient Local Economies"
107
+ description="Urban-rural linkages, food systems, circular economy"
108
+ color="bg-orange-500"
109
+ />
110
+ </div>
111
+ </div>
112
+
113
+ {/* Stats Section */}
114
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-6 mt-16">
115
+ <StatCard number="6" label="Systems-Based Missions" />
116
+ <StatCard number="17→6" label="Simplified Goals" />
117
+ <StatCard number="∞" label="Partnerships" />
118
+ <StatCard number="100%" label="Transparency" />
119
+ </div>
120
+ </div>
121
+ );
122
+ };
123
+
124
+ const FeatureCard = ({ title, description, link, color, icon }) => (
125
+ <Link to={link} className={`${color} sdg-card-gradient block group transform transition-all duration-300 hover:-translate-y-2`}>
126
+ <div className="p-8 h-full flex flex-col">
127
+ <div className="text-4xl mb-4">{icon}</div>
128
+ <h3 className="text-xl font-bold text-white mb-3">{title}</h3>
129
+ <p className="text-white opacity-90 flex-grow">{description}</p>
130
+ <div className="mt-4 text-white font-semibold flex items-center">
131
+ Explore
132
+ <svg className="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
133
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"></path>
134
+ </svg>
135
+ </div>
136
+ </div>
137
+ </Link>
138
+ );
139
+
140
+ const MissionItem = ({ title, description, color }) => (
141
+ <div className="flex items-start p-4 bg-white dark:bg-slate-700 rounded-xl shadow-md hover:shadow-lg transition-shadow border border-white/50 dark:border-slate-600">
142
+ <div className={`${color} w-12 h-12 rounded-lg flex items-center justify-center text-white font-bold mr-4 flex-shrink-0`}>
143
+ {title.charAt(0)}
144
+ </div>
145
+ <div>
146
+ <h3 className="font-bold text-gray-800 dark:text-white">{title}</h3>
147
+ <p className="text-gray-600 dark:text-gray-300 text-sm">{description}</p>
148
+ </div>
149
+ </div>
150
+ );
151
+
152
+ const StatCard = ({ number, label }) => (
153
+ <div className="stat-card text-center transform transition-transform hover:-translate-y-1">
154
+ <div className="text-3xl md:text-4xl font-bold text-gradient dark:text-white">{number}</div>
155
+ <div className="text-gray-600 dark:text-gray-300 mt-2">{label}</div>
156
+ </div>
157
+ );
158
+
159
+ export default Home;
frontend/src/pages/IndigenousVoices.jsx ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const IndigenousVoices = () => {
4
+ return (
5
+ <div className="max-w-7xl mx-auto">
6
+ <div className="text-center mb-16">
7
+ <h1 className="text-4xl font-bold text-gray-800 mb-6">Indigenous Voices Space</h1>
8
+ <p className="text-xl text-gray-600 max-w-3xl mx-auto">
9
+ Centering indigenous knowledge systems and planetary boundaries in sustainable development.
10
+ Audio/text submissions, community protocols, and consent tags.
11
+ </p>
12
+ </div>
13
+
14
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-12">
15
+ <div className="feature-card">
16
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Share Your Knowledge</h2>
17
+ <p className="text-gray-600 mb-8">
18
+ Contribute traditional ecological knowledge, community practices, and perspectives on sustainable development.
19
+ </p>
20
+
21
+ <div className="mb-6">
22
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="knowledge-title">
23
+ Title
24
+ </label>
25
+ <input
26
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
27
+ id="knowledge-title"
28
+ type="text"
29
+ placeholder="Title of your knowledge contribution"
30
+ />
31
+ </div>
32
+
33
+ <div className="mb-6">
34
+ <label className="block text-gray-700 text-sm font-bold mb-2">
35
+ Content Type
36
+ </label>
37
+ <div className="grid grid-cols-3 gap-4">
38
+ <label className="flex flex-col items-center p-4 border-2 border-gray-200 rounded-xl cursor-pointer hover:border-indigo-400 has-[:checked]:border-indigo-500 has-[:checked]:bg-indigo-50">
39
+ <input type="radio" className="form-radio h-5 w-5 text-indigo-600" name="content-type" value="audio" />
40
+ <span className="mt-2 text-gray-700">Audio</span>
41
+ <span className="text-2xl mt-2">🔊</span>
42
+ </label>
43
+ <label className="flex flex-col items-center p-4 border-2 border-gray-200 rounded-xl cursor-pointer hover:border-indigo-400 has-[:checked]:border-indigo-500 has-[:checked]:bg-indigo-50">
44
+ <input type="radio" className="form-radio h-5 w-5 text-indigo-600" name="content-type" value="text" />
45
+ <span className="mt-2 text-gray-700">Text</span>
46
+ <span className="text-2xl mt-2">📝</span>
47
+ </label>
48
+ <label className="flex flex-col items-center p-4 border-2 border-gray-200 rounded-xl cursor-pointer hover:border-indigo-400 has-[:checked]:border-indigo-500 has-[:checked]:bg-indigo-50">
49
+ <input type="radio" className="form-radio h-5 w-5 text-indigo-600" name="content-type" value="video" />
50
+ <span className="mt-2 text-gray-700">Video</span>
51
+ <span className="text-2xl mt-2">🎥</span>
52
+ </label>
53
+ </div>
54
+ </div>
55
+
56
+ <div className="mb-6">
57
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="knowledge-content">
58
+ Content
59
+ </label>
60
+ <textarea
61
+ className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
62
+ id="knowledge-content"
63
+ placeholder="Share your knowledge, story, or practice"
64
+ rows="5"
65
+ ></textarea>
66
+ </div>
67
+
68
+ <div className="mb-8">
69
+ <label className="block text-gray-700 text-sm font-bold mb-3">
70
+ Consent and Permissions
71
+ </label>
72
+ <div className="space-y-3">
73
+ <label className="flex items-start p-4 bg-yellow-50 rounded-xl border border-yellow-200">
74
+ <input type="checkbox" className="form-checkbox h-5 w-5 text-yellow-600 mt-0.5" />
75
+ <span className="ml-3 text-gray-700">
76
+ <span className="font-medium">I consent to this content being shared publicly</span>
77
+ <p className="text-sm text-gray-600 mt-1">Your contribution will be visible to all platform users</p>
78
+ </span>
79
+ </label>
80
+ <label className="flex items-start p-4 bg-blue-50 rounded-xl border border-blue-200">
81
+ <input type="checkbox" className="form-checkbox h-5 w-5 text-blue-600 mt-0.5" />
82
+ <span className="ml-3 text-gray-700">
83
+ <span className="font-medium">I understand this content will be archived for future generations</span>
84
+ <p className="text-sm text-gray-600 mt-1">This contribution will be preserved for long-term access</p>
85
+ </span>
86
+ </label>
87
+ <label className="flex items-start p-4 bg-green-50 rounded-xl border border-green-200">
88
+ <input type="checkbox" className="form-checkbox h-5 w-5 text-green-600 mt-0.5" />
89
+ <span className="ml-3 text-gray-700">
90
+ <span className="font-medium">I have the authority to share this knowledge</span>
91
+ <p className="text-sm text-gray-600 mt-1">You have permission from your community to share this</p>
92
+ </span>
93
+ </label>
94
+ </div>
95
+ </div>
96
+
97
+ <button className="sdg-btn sdg-btn-primary w-full py-4 text-lg">
98
+ Submit Knowledge
99
+ </button>
100
+ </div>
101
+
102
+ <div>
103
+ <div className="feature-card mb-8">
104
+ <div className="flex items-center mb-6">
105
+ <div className="bg-red-100 p-3 rounded-xl mr-4">
106
+ <div className="text-red-600 text-2xl">📜</div>
107
+ </div>
108
+ <h2 className="text-2xl font-bold text-gray-800">Community Protocols</h2>
109
+ </div>
110
+ <p className="text-gray-600 mb-6">
111
+ Access established protocols for respectful engagement with indigenous communities.
112
+ </p>
113
+ <ul className="space-y-4 mb-6">
114
+ <li className="flex items-start">
115
+ <div className="bg-green-100 rounded-full p-2 mr-3 mt-1">
116
+ <svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
117
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
118
+ </svg>
119
+ </div>
120
+ <div>
121
+ <span className="font-medium">Free, Prior, and Informed Consent (FPIC)</span>
122
+ <p className="text-gray-600 text-sm">Guidelines for obtaining consent from indigenous communities</p>
123
+ </div>
124
+ </li>
125
+ <li className="flex items-start">
126
+ <div className="bg-green-100 rounded-full p-2 mr-3 mt-1">
127
+ <svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
128
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
129
+ </svg>
130
+ </div>
131
+ <div>
132
+ <span className="font-medium">Data Sovereignty Principles</span>
133
+ <p className="text-gray-600 text-sm">Respecting indigenous control over their data and knowledge</p>
134
+ </div>
135
+ </li>
136
+ <li className="flex items-start">
137
+ <div className="bg-green-100 rounded-full p-2 mr-3 mt-1">
138
+ <svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
139
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
140
+ </svg>
141
+ </div>
142
+ <div>
143
+ <span className="font-medium">Cultural Sensitivity Guidelines</span>
144
+ <p className="text-gray-600 text-sm">Best practices for respectful engagement</p>
145
+ </div>
146
+ </li>
147
+ </ul>
148
+ <button className="sdg-btn sdg-btn-secondary w-full py-3">
149
+ View All Protocols
150
+ </button>
151
+ </div>
152
+
153
+ <div className="feature-card">
154
+ <div className="flex items-center mb-6">
155
+ <div className="bg-purple-100 p-3 rounded-xl mr-4">
156
+ <div className="text-purple-600 text-2xl">📚</div>
157
+ </div>
158
+ <h2 className="text-2xl font-bold text-gray-800">Knowledge Library</h2>
159
+ </div>
160
+ <p className="text-gray-600 mb-6">
161
+ Explore existing contributions from indigenous communities and traditional knowledge holders.
162
+ </p>
163
+ <div className="space-y-5 mb-6">
164
+ <div className="p-4 bg-gradient-to-r from-amber-50 to-orange-50 rounded-xl border border-amber-200">
165
+ <h3 className="font-bold text-gray-800">Traditional Water Management in Arid Regions</h3>
166
+ <p className="text-gray-600 text-sm mt-1">Submitted by Indigenous Water Keepers Alliance</p>
167
+ <div className="flex items-center mt-3 text-sm text-amber-700">
168
+ <span>💧</span>
169
+ <span className="ml-2">Water Systems</span>
170
+ </div>
171
+ </div>
172
+ <div className="p-4 bg-gradient-to-r from-emerald-50 to-teal-50 rounded-xl border border-emerald-200">
173
+ <h3 className="font-bold text-gray-800">Forest Stewardship Practices</h3>
174
+ <p className="text-gray-600 text-sm mt-1">Submitted by Amazonian Indigenous Council</p>
175
+ <div className="flex items-center mt-3 text-sm text-emerald-700">
176
+ <span>🌲</span>
177
+ <span className="ml-2">Biodiversity Conservation</span>
178
+ </div>
179
+ </div>
180
+ <div className="p-4 bg-gradient-to-r from-rose-50 to-pink-50 rounded-xl border border-rose-200">
181
+ <h3 className="font-bold text-gray-800">Seasonal Agricultural Calendars</h3>
182
+ <p className="text-gray-600 text-sm mt-1">Submitted by Highland Farmers Collective</p>
183
+ <div className="flex items-center mt-3 text-sm text-rose-700">
184
+ <span>🌾</span>
185
+ <span className="ml-2">Food Systems</span>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ <button className="sdg-btn sdg-btn-secondary w-full py-3">
190
+ Browse Library
191
+ </button>
192
+ </div>
193
+ </div>
194
+ </div>
195
+
196
+ <div className="feature-card">
197
+ <div className="flex flex-col md:flex-row md:items-center justify-between mb-8">
198
+ <div>
199
+ <h2 className="text-2xl font-bold text-gray-800 mb-2">Planetary Boundaries Framework</h2>
200
+ <p className="text-gray-600">
201
+ All contributions are contextualized within the planetary boundaries framework to ensure ecological sustainability.
202
+ </p>
203
+ </div>
204
+ <button className="mt-4 md:mt-0 sdg-btn sdg-btn-tertiary px-6 py-3">
205
+ Learn More
206
+ </button>
207
+ </div>
208
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
209
+ <div className="text-center p-6 bg-gradient-to-br from-blue-500 to-blue-600 text-white rounded-2xl shadow-lg">
210
+ <div className="text-3xl font-bold">9</div>
211
+ <div className="text-sm">Boundaries</div>
212
+ </div>
213
+ <div className="text-center p-6 bg-gradient-to-br from-green-500 to-green-600 text-white rounded-2xl shadow-lg">
214
+ <div className="text-3xl font-bold">4</div>
215
+ <div className="text-sm">Safe Zones</div>
216
+ </div>
217
+ <div className="text-center p-6 bg-gradient-to-br from-yellow-500 to-yellow-600 text-white rounded-2xl shadow-lg">
218
+ <div className="text-3xl font-bold">3</div>
219
+ <div className="text-sm">High Risk</div>
220
+ </div>
221
+ <div className="text-center p-6 bg-gradient-to-br from-red-500 to-red-600 text-white rounded-2xl shadow-lg">
222
+ <div className="text-3xl font-bold">2</div>
223
+ <div className="text-sm">Exceeded</div>
224
+ </div>
225
+ </div>
226
+ </div>
227
+
228
+ {/* Stats Section */}
229
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-16">
230
+ <StatCard number="87" label="Knowledge Contributions" color="from-amber-400 to-amber-600" />
231
+ <StatCard number="34" label="Indigenous Communities" color="from-emerald-400 to-emerald-600" />
232
+ <StatCard number="12" label="Countries Represented" color="from-rose-400 to-rose-600" />
233
+ </div>
234
+ </div>
235
+ );
236
+ };
237
+
238
+ const StatCard = ({ number, label, color }) => (
239
+ <div className={`stat-card bg-gradient-to-br ${color} text-white text-center`}>
240
+ <div className="text-3xl font-bold">{number}</div>
241
+ <div className="mt-2">{label}</div>
242
+ </div>
243
+ );
244
+
245
+ export default IndigenousVoices;
frontend/src/pages/MissionHubs.jsx ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+
3
+ const MissionHubs = () => {
4
+ const [missions, setMissions] = useState([]);
5
+ const [loading, setLoading] = useState(true);
6
+ const [selectedMission, setSelectedMission] = useState(null);
7
+ const [backendStatus, setBackendStatus] = useState('unknown');
8
+
9
+ useEffect(() => {
10
+ // Check backend health
11
+ fetch('/api/health')
12
+ .then(response => response.json())
13
+ .then(data => {
14
+ setBackendStatus(data.status);
15
+ // Fetch missions from backend
16
+ return fetch('/api/missions');
17
+ })
18
+ .then(response => response.json())
19
+ .then(data => {
20
+ setMissions(data);
21
+ setLoading(false);
22
+ })
23
+ .catch(err => {
24
+ console.error('Error fetching data:', err);
25
+ // Use mock data if backend is not available
26
+ const mockMissions = [
27
+ {
28
+ id: 1,
29
+ name: "Regenerative Economy",
30
+ description: "Climate, energy, biodiversity, jobs",
31
+ objectives: "Reduce carbon emissions, promote renewable energy, protect biodiversity, create green jobs",
32
+ target_actors: "Government agencies, environmental organizations, businesses",
33
+ color: "bg-gradient-to-r from-green-400 to-green-600"
34
+ },
35
+ {
36
+ id: 2,
37
+ name: "Well-being for All",
38
+ description: "Health, education, social protection",
39
+ objectives: "Improve healthcare access, enhance education quality, strengthen social protection systems",
40
+ target_actors: "Healthcare providers, educational institutions, social services",
41
+ color: "bg-gradient-to-r from-blue-400 to-blue-600"
42
+ },
43
+ {
44
+ id: 3,
45
+ name: "Just Digital Transition",
46
+ description: "Infrastructure, AI ethics and governance, data justice",
47
+ objectives: "Build equitable digital infrastructure, establish AI ethics guidelines, ensure data justice",
48
+ target_actors: "Tech companies, policymakers, civil society",
49
+ color: "bg-gradient-to-r from-purple-400 to-purple-600"
50
+ },
51
+ {
52
+ id: 4,
53
+ name: "Equity and Inclusion",
54
+ description: "Gender, migration, race, intergenerational justice",
55
+ objectives: "Promote gender equality, protect migrant rights, combat racial discrimination, ensure intergenerational justice",
56
+ target_actors: "Human rights organizations, advocacy groups, government bodies",
57
+ color: "bg-gradient-to-r from-yellow-400 to-yellow-600"
58
+ },
59
+ {
60
+ id: 5,
61
+ name: "Peace and Global Governance",
62
+ description: "Conflict, institutions, human rights",
63
+ objectives: "Prevent conflicts, strengthen international institutions, protect human rights",
64
+ target_actors: "International organizations, peacekeeping bodies, legal institutions",
65
+ color: "bg-gradient-to-r from-red-400 to-red-600"
66
+ },
67
+ {
68
+ id: 6,
69
+ name: "Resilient Local Economies",
70
+ description: "Urban-rural linkages, food systems, circular economy",
71
+ objectives: "Strengthen urban-rural connections, develop sustainable food systems, promote circular economy practices",
72
+ target_actors: "Local governments, agricultural cooperatives, circular economy practitioners",
73
+ color: "bg-gradient-to-r from-orange-400 to-orange-600"
74
+ }
75
+ ];
76
+
77
+ setMissions(mockMissions);
78
+ setLoading(false);
79
+ setBackendStatus('offline');
80
+ });
81
+ }, []);
82
+
83
+ const openMissionDetails = (mission) => {
84
+ setSelectedMission(mission);
85
+ };
86
+
87
+ const closeMissionDetails = () => {
88
+ setSelectedMission(null);
89
+ };
90
+
91
+ return (
92
+ <div className="max-w-7xl mx-auto">
93
+ <div className="text-center mb-12">
94
+ <h1 className="text-4xl font-bold text-gray-800 mb-4">Mission Hubs</h1>
95
+ <p className="text-xl text-gray-600 max-w-3xl mx-auto">
96
+ Explore our 6 Systems-Based Missions designed to transform the Sustainable Development Goals
97
+ into integrated, actionable roadmaps for policy, projects, finance, and metrics.
98
+ </p>
99
+ <div className="mt-6">
100
+ {backendStatus === 'OK' ? (
101
+ <span className="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium bg-green-100 text-green-800">
102
+ <svg className="mr-2 h-3 w-3 text-green-400" fill="currentColor" viewBox="0 0 8 8">
103
+ <circle cx="4" cy="4" r="3" />
104
+ </svg>
105
+ Connected to backend
106
+ </span>
107
+ ) : (
108
+ <span className="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium bg-yellow-100 text-yellow-800">
109
+ <svg className="mr-2 h-3 w-3 text-yellow-400" fill="currentColor" viewBox="0 0 8 8">
110
+ <circle cx="4" cy="4" r="3" />
111
+ </svg>
112
+ Working offline with mock data
113
+ </span>
114
+ )}
115
+ </div>
116
+ </div>
117
+
118
+ {loading ? (
119
+ <div className="flex justify-center items-center h-96">
120
+ <div className="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-indigo-500"></div>
121
+ </div>
122
+ ) : (
123
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
124
+ {missions.map((mission) => (
125
+ <div
126
+ key={mission.id}
127
+ className="sdg-card cursor-pointer transform transition-all duration-300 hover:-translate-y-2"
128
+ onClick={() => openMissionDetails(mission)}
129
+ >
130
+ <div className="p-8">
131
+ <div className={`${mission.color} mission-icon text-white shadow-lg`}>
132
+ {mission.name.charAt(0)}
133
+ </div>
134
+ <h3 className="text-2xl font-bold text-gray-800 mb-3">{mission.name}</h3>
135
+ <p className="text-gray-600 mb-6">{mission.description}</p>
136
+ <div className="flex justify-between items-center">
137
+ <span className="text-sm text-gray-500">Click for details</span>
138
+ <svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
139
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"></path>
140
+ </svg>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ ))}
145
+ </div>
146
+ )}
147
+
148
+ {/* Mission Details Modal */}
149
+ {selectedMission && (
150
+ <div className="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center p-4 z-50">
151
+ <div className="bg-white rounded-3xl max-w-3xl w-full max-h-[90vh] overflow-y-auto">
152
+ <div className="p-8">
153
+ <div className="flex justify-between items-start mb-6">
154
+ <div>
155
+ <div className={`${selectedMission.color} mission-icon w-24 h-24 text-4xl`}>
156
+ {selectedMission.name.charAt(0)}
157
+ </div>
158
+ <h2 className="text-3xl font-bold text-gray-800 mt-4">{selectedMission.name}</h2>
159
+ <p className="text-xl text-gray-600">{selectedMission.description}</p>
160
+ </div>
161
+ <button
162
+ onClick={closeMissionDetails}
163
+ className="text-gray-500 hover:text-gray-700 bg-gray-100 rounded-full p-2"
164
+ >
165
+ <svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
166
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path>
167
+ </svg>
168
+ </button>
169
+ </div>
170
+
171
+ <div className="mt-8">
172
+ <h3 className="text-2xl font-semibold text-gray-800 mb-4">Objectives</h3>
173
+ <p className="text-gray-700 text-lg bg-gray-50 p-6 rounded-2xl">{selectedMission.objectives}</p>
174
+ </div>
175
+
176
+ <div className="mt-8">
177
+ <h3 className="text-2xl font-semibold text-gray-800 mb-4">Target Actors</h3>
178
+ <p className="text-gray-700 text-lg bg-gray-50 p-6 rounded-2xl">{selectedMission.target_actors}</p>
179
+ </div>
180
+
181
+ <div className="mt-10 flex justify-end">
182
+ <button
183
+ onClick={closeMissionDetails}
184
+ className="sdg-btn sdg-btn-primary px-8 py-4 text-lg"
185
+ >
186
+ Close
187
+ </button>
188
+ </div>
189
+ </div>
190
+ </div>
191
+ </div>
192
+ )}
193
+ </div>
194
+ );
195
+ };
196
+
197
+ export default MissionHubs;
frontend/src/pages/PartnershipBuilder.jsx ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const PartnershipBuilder = () => {
4
+ return (
5
+ <div className="max-w-6xl mx-auto">
6
+ <div className="text-center mb-16">
7
+ <h1 className="text-4xl font-bold text-gray-800 mb-6">Partnership Builder</h1>
8
+ <p className="text-xl text-gray-600 max-w-3xl mx-auto">
9
+ Connect with stakeholders and build multi-stakeholder partnerships for sustainable development.
10
+ Lightweight matchmaking, MOUs templating, and micro-grant applications.
11
+ </p>
12
+ </div>
13
+
14
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
15
+ <div className="lg:col-span-2">
16
+ <div className="feature-card h-full">
17
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Find Partners</h2>
18
+ <p className="text-gray-600 mb-8">
19
+ Discover organizations, communities, and individuals working on similar missions.
20
+ Match based on roles, asks, and offers.
21
+ </p>
22
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
23
+ <div className="bg-gradient-to-br from-blue-50 to-blue-100 rounded-2xl p-6 border border-blue-200">
24
+ <div className="text-blue-600 text-3xl mb-4">🌎</div>
25
+ <h3 className="font-bold text-gray-800 mb-2">By Mission</h3>
26
+ <p className="text-gray-600 text-sm">Filter partners by Systems-Based Missions</p>
27
+ </div>
28
+ <div className="bg-gradient-to-br from-purple-50 to-purple-100 rounded-2xl p-6 border border-purple-200">
29
+ <div className="text-purple-600 text-3xl mb-4">🧠</div>
30
+ <h3 className="font-bold text-gray-800 mb-2">By Expertise</h3>
31
+ <p className="text-gray-600 text-sm">Find partners with specific skills or knowledge</p>
32
+ </div>
33
+ <div className="bg-gradient-to-br from-green-50 to-green-100 rounded-2xl p-6 border border-green-200">
34
+ <div className="text-green-600 text-3xl mb-4">📍</div>
35
+ <h3 className="font-bold text-gray-800 mb-2">By Geography</h3>
36
+ <p className="text-gray-600 text-sm">Locate partners in specific regions or countries</p>
37
+ </div>
38
+ </div>
39
+ <div className="mt-8">
40
+ <button className="sdg-btn sdg-btn-primary text-lg px-8 py-4">
41
+ Search Partners
42
+ </button>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+ <div>
48
+ <div className="feature-card h-full">
49
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Create Agreements</h2>
50
+ <p className="text-gray-600 mb-8">
51
+ Use our template library to create Memorandums of Understanding (MOUs) and partnership agreements.
52
+ </p>
53
+ <div className="space-y-4">
54
+ <button className="w-full sdg-btn sdg-btn-secondary py-4">
55
+ View Templates
56
+ </button>
57
+ <button className="w-full sdg-btn sdg-btn-primary py-4">
58
+ Create New Agreement
59
+ </button>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <div className="feature-card">
66
+ <h2 className="text-2xl font-bold text-gray-800 mb-6">Micro-Grant Applications</h2>
67
+ <p className="text-gray-600 mb-8">
68
+ Apply for funding to support collaborative initiatives aligned with the Systems-Based Missions.
69
+ </p>
70
+ <div className="flex flex-col sm:flex-row gap-4">
71
+ <button className="flex-1 sdg-btn sdg-btn-primary py-4 text-lg">
72
+ Start Application
73
+ </button>
74
+ <button className="flex-1 sdg-btn sdg-btn-tertiary py-4 text-lg">
75
+ View Guidelines
76
+ </button>
77
+ </div>
78
+ </div>
79
+
80
+ {/* Stats Section */}
81
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-16">
82
+ <StatCard number="1,240+" label="Active Partners" color="from-blue-400 to-blue-600" />
83
+ <StatCard number="890+" label="Partnerships Created" color="from-purple-400 to-purple-600" />
84
+ <StatCard number="$24M+" label="Funding Mobilized" color="from-green-400 to-green-600" />
85
+ </div>
86
+ </div>
87
+ );
88
+ };
89
+
90
+ const StatCard = ({ number, label, color }) => (
91
+ <div className={`stat-card bg-gradient-to-br ${color} text-white`}>
92
+ <div className="text-3xl md:text-4xl font-bold">{number}</div>
93
+ <div className="mt-2 text-lg">{label}</div>
94
+ </div>
95
+ );
96
+
97
+ export default PartnershipBuilder;
frontend/tailwind.config.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: [
4
+ "./index.html",
5
+ "./src/**/*.{js,ts,jsx,tsx}",
6
+ ],
7
+ theme: {
8
+ extend: {
9
+ colors: {
10
+ 'sdg-blue': '#1976d2',
11
+ 'sdg-green': '#388e3c',
12
+ 'sdg-red': '#d32f2f',
13
+ },
14
+ backgroundImage: {
15
+ 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
16
+ 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
17
+ },
18
+ animation: {
19
+ 'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
20
+ 'float': 'float 6s ease-in-out infinite',
21
+ },
22
+ keyframes: {
23
+ float: {
24
+ '0%, 100%': { transform: 'translateY(0)' },
25
+ '50%': { transform: 'translateY(-10px)' },
26
+ }
27
+ }
28
+ },
29
+ },
30
+ plugins: [],
31
+ }
frontend/vite.config.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react'
3
+
4
+ // https://vitejs.dev/config/
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ server: {
8
+ host: '0.0.0.0',
9
+ port: 5173,
10
+ proxy: {
11
+ '/api': {
12
+ target: 'http://backend:3000',
13
+ changeOrigin: true,
14
+ secure: false,
15
+ }
16
+ }
17
+ }
18
+ })