diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb491ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +node_modules/ +dist/ + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Environment files +.env +.env.* +!.env.example + +# Editor/OS files +.DS_Store +Thumbs.db +.vscode/ +.idea/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..42f0956 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +FROM node:20-bookworm-slim AS builder + +WORKDIR /app + +# If npm/yarn fail with "unable to get local issuer certificate" during install, build with: +# docker compose build --build-arg NPM_STRICT_SSL=false client-prod +# (Only use on trusted networks; prefer mounting your org CA via NODE_EXTRA_CA_CERTS instead.) +ARG NPM_STRICT_SSL=true +RUN if [ "$NPM_STRICT_SSL" = "false" ]; then npm config set strict-ssl false; fi + +COPY package.json package-lock.json ./ + +ENV CI=true \ + npm_config_maxsockets=1 \ + NPM_CONFIG_LEGACY_PEER_DEPS=true + +# Mitigate npm "Exit handler never called!" in some Docker/npm builds (see npm/cli issues). +RUN npm install --no-audit --no-fund + +COPY . . + +ARG VITE_API_ORIGIN= +ENV VITE_API_ORIGIN=$VITE_API_ORIGIN + +RUN npm run build + +FROM nginx:alpine + +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /app/dist /usr/share/nginx/html + +EXPOSE 80 diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..c1cd6e6 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,21 @@ +FROM node:20-bookworm-slim + +WORKDIR /app + +ARG NPM_STRICT_SSL=true +RUN if [ "$NPM_STRICT_SSL" = "false" ]; then npm config set strict-ssl false; fi + +COPY package.json package-lock.json ./ + +ENV CI=true \ + npm_config_maxsockets=1 \ + NPM_CONFIG_LEGACY_PEER_DEPS=true + +RUN npm install --no-audit --no-fund + +COPY docker-entrypoint.dev.sh /docker-entrypoint.dev.sh +RUN chmod +x /docker-entrypoint.dev.sh + +EXPOSE 5173 + +ENTRYPOINT ["/docker-entrypoint.dev.sh"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7a0ab0f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +services: + client: + build: + context: . + dockerfile: Dockerfile.dev + args: + NPM_STRICT_SSL: ${NPM_STRICT_SSL:-true} + ports: + - '5173:5173' + volumes: + - .:/app + - client_node_modules:/app/node_modules + environment: + # Laravel API — Windows/macOS Docker Desktop resolves this; Linux uses extra_hosts below. + VITE_PROXY_API: ${VITE_PROXY_API:-http://host.docker.internal:8000} + extra_hosts: + - 'host.docker.internal:host-gateway' + + client-prod: + build: + context: . + dockerfile: Dockerfile + args: + VITE_API_ORIGIN: ${VITE_API_ORIGIN:-} + NPM_STRICT_SSL: ${NPM_STRICT_SSL:-true} + ports: + - '8080:80' + profiles: + - prod + +volumes: + client_node_modules: diff --git a/docker-entrypoint.dev.sh b/docker-entrypoint.dev.sh new file mode 100644 index 0000000..3de1310 --- /dev/null +++ b/docker-entrypoint.dev.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e +cd /app + +if [ ! -f node_modules/.installed ]; then + export CI=true + export npm_config_maxsockets=1 + export NPM_CONFIG_LEGACY_PEER_DEPS=true + npm install --no-audit --no-fund + touch node_modules/.installed +fi + +exec npm run dev -- --host 0.0.0.0 --port 5173 diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..5e6b472 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/index.html b/index.html new file mode 100644 index 0000000..f479766 --- /dev/null +++ b/index.html @@ -0,0 +1,32 @@ + + + + + + + + Al Rahma Sunday School + + + + + + + +
+ + + + diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..2d96d15 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,10 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4dd2d83 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5408 @@ +{ + "name": "client_laravel", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "client_laravel", + "version": "0.0.0", + "dependencies": { + "react": "^19.2.5", + "react-dom": "^19.2.5", + "react-router-dom": "^7.14.2", + "swagger-ui-react": "^5.32.4" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/node": "^24.12.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.5.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.58.2", + "vite": "^8.0.9" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.2.tgz", + "integrity": "sha512-Lc94FOD5+0aXhdb0Tdg3RUtqT6yWbI/BbFWvlaSJ3gAb9Ks+99nHRDKADVqC37er4eCB0fHyWT+y+K3QOvJKbw==", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.48.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.126.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz", + "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz", + "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz", + "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz", + "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz", + "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz", + "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz", + "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz", + "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz", + "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz", + "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.9.2", + "@emnapi/runtime": "1.9.2", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz", + "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz", + "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@scarf/scarf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", + "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", + "hasInstallScript": true, + "license": "Apache-2.0" + }, + "node_modules/@swagger-api/apidom-ast": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.10.2.tgz", + "integrity": "sha512-vTl8gWyeZaj887/NSWYs3as4K8wXHar5wY/606XRBjR2UgmJBokBgKjq7S23LW9tsYjsT4MjQKC8idjgw17xvg==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-error": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "unraw": "^3.0.0" + } + }, + "node_modules/@swagger-api/apidom-core": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.10.2.tgz", + "integrity": "sha512-qryNBGHNWDvSRyK1w5rox0UOrHrVBjZOHgeXFpGHF+oBO7ntSc/H7BSiYMDR+KQESkzMcAxn4tZMLYItaBt06w==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-ast": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@types/ramda": "~0.30.0", + "minim": "~0.23.8", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "short-unique-id": "^5.3.2", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-error": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.10.2.tgz", + "integrity": "sha512-SWyPyL5xwTUsDzPi0A5zwTFwqPezvlwj4opEqruqjESNTYupUA7+vt4Mdj7IlDaRYRG1qyCWQgKhIBXznVUD4w==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7" + } + }, + "node_modules/@swagger-api/apidom-json-pointer": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.10.2.tgz", + "integrity": "sha512-zySHPqIXF4HZ3VWbHwTxO+H1e9dJw7mGHzoX+tZjx5wVyLQO3kZDCAAXzz3c3/TIY21Y2Zkpkez3q9hjFyuLvQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swaggerexpert/json-pointer": "^2.10.1" + } + }, + "node_modules/@swagger-api/apidom-ns-api-design-systems": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.10.2.tgz", + "integrity": "sha512-MsZ4GWmWN7wkWv7G9Pwk8sHU1j0bwk7xoGeaZmNCylbTfYvGkg6jJGMHdAdQNCQXbbpfLeKt1O+3YCN//JUQ7w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-1": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-arazzo-1": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.10.2.tgz", + "integrity": "sha512-fQSwDlIR85tbnLXAjtV/ypSGUBfrzFcZ4NbH6BL1DSTR4uEunVxAULdD4wlhCt9gGNDl/zxZD3vQtlYDkXDFmw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-2020-12": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-asyncapi-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.10.2.tgz", + "integrity": "sha512-obWHe3pyAj65Nf9ISwnbtJ4C5mZ15C6mtQXxzHVW5maVZqlqt3s/YbPY87EqK9ArdNOwOZHkQt2Uth02GMmjxA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-asyncapi-3": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-3/-/apidom-ns-asyncapi-3-1.10.2.tgz", + "integrity": "sha512-yqNmXeObF2OLAusgGEapXz2CrGjXwkcfG3DYcQDtOvgRytvGZxC2EkCUR+wEXCVNYhoJ7QpVzzTJOHs3jOvptg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-asyncapi-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-2019-09": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.10.2.tgz", + "integrity": "sha512-I1FaBoDFMjybF4QVsesIYl8OilkwycZ0mQ0jf1P++zfTRG27uIePB8M+Iuj6iqMsE3qpkjjJJ6ZLnrLPdKvmRw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-2020-12": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.10.2.tgz", + "integrity": "sha512-lg9XfRlJRNoBa2EDGpEFc7HvFV39G6RG0/SbjQY0BE/WZer10wmfTCU7l3RUNJXRFGKH6/O/nsYgP7AFjTanXQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-2019-09": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.10.2.tgz", + "integrity": "sha512-C50KnSKynrmHky/oOB6+hHyZVpwng78Fz5aZjay3h8X5C/PJHmm3sDJFvF3/9wkYHO3N9sPp7cpu4Xm9VJ4/wQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-ast": "^1.10.2", + "@swagger-api/apidom-core": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.10.2.tgz", + "integrity": "sha512-/wiP8+2lF8UJRrkoQ9HvKnMbnqijk2uY/hAg+/Bo73T9NGKkEa29jYVUKYNYj7gJBw4hhkUHfHFWuZUpxPC4ZA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.10.2.tgz", + "integrity": "sha512-firN/uvnVxQgACqcyzV3NU9qjbMvNMJkpmm3wOat3URmaFMaFBT3qjbU1pFHBGbnXI3+I9pQJZHmJSwqNzfUbQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-draft-6": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.10.2.tgz", + "integrity": "sha512-FK5kYvo/1uwAByumRVRsynBlnKxUUImfsjPEFgRCW6yhbCGRqN47NaZ7GYFHpbhjC3OmMN5/etYj6B0jnZx7Gg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-0": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.10.2.tgz", + "integrity": "sha512-ziyv85QbJYHRdc9oTEFBy3pxwxg7BW/a9GrwH01/SmuXVQPjLjwzRb+SjCxLogJppm0yjxOkDFI2VWPp2RADFg==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-1": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.10.2.tgz", + "integrity": "sha512-ngcmO4dH77JT5hZB04OJdyTzgKnt2lNhAZQ+4wXjum/xhszjUmDhOeYfXdHw3Lm7MxsEsTesWzLYQ5LKADc41A==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-ast": "^1.10.2", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-json-pointer": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-2020-12": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-0": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-2/-/apidom-ns-openapi-3-2-1.10.2.tgz", + "integrity": "sha512-3SWJ5ipWwn+w11HTUESWex/522jy2aGLzBqqMgH36sy+Wdwx+9Mw2bgSDqkxmNC5+jpzOGUOIWoQAMuCpS/Gzg==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-ast": "^1.10.2", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-json-pointer": "^1.10.2", + "@swagger-api/apidom-ns-json-schema-2020-12": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-0": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-1": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.10.2.tgz", + "integrity": "sha512-kzhJUGzsJ38Uohj5xRQDkQC08rqNhatbqgD30LZ0/UWryJ9nAsjqK2ovuP9t+5WKcDE4iwcYeGSt1NA2XgEZwg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-api-design-systems": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.10.2.tgz", + "integrity": "sha512-i3CmSxJ/iG67ybRDAJ9xpuMrOMFvC/obX2lI36E0VZzBTb+llw4Zd5qFmBqNnImLpwdmk11Z1V7i+5HM+J7ijQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-api-design-systems": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-arazzo-json-1": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.10.2.tgz", + "integrity": "sha512-HwiUkwvo5i2hV2SS6KWrdj62BdceZGfhuXhr1il8akWekpU4jXPtr5pv4gOnKKJN7VgjAmwt/DlcCSRo1+9jVA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-arazzo-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-arazzo-yaml-1": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.10.2.tgz", + "integrity": "sha512-w8VTVuE7GPbRqWxvMgRoTb726JRsMhFPMfTBf8+MJ4pQThjk78dSXPV2Zlse71b2DWBuQy2sr6zGyLUNs/3ePQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-arazzo-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.10.2.tgz", + "integrity": "sha512-FDNjqmn2vV1jFoVVwQDO0XPPm8R5xzmcyY/6yBLFmKZADin3smSKVZ+njYHmfRjpspXwN0AwI0drdvuH0FZLJg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-asyncapi-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-3": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-3/-/apidom-parser-adapter-asyncapi-json-3-1.10.2.tgz", + "integrity": "sha512-x/0vM2nDDzYzFnXr69+so/KSH+2py2TiZd1K49pWcX8cHsPV1Y4Ppih7GVOMymd8m/IOCjLYlV7qt4eWDwdldg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-asyncapi-3": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.10.2.tgz", + "integrity": "sha512-2bVACmU9ZmAVVnqQWSc3Bs+xG0HHLU1tfZbYL8xNgSi8kw4HcnejF5mWtN+MLFzTaBmWCi2In7P7BYNR8+2Dyg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-asyncapi-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-3/-/apidom-parser-adapter-asyncapi-yaml-3-1.10.2.tgz", + "integrity": "sha512-oHpbf+iqBcDS3qtsipMpgCwAeckKMxg0qFKYTCRZyJdctRgupJTxVeir6t/SGo0Ny0a1iknt2LN0u5frEen0kg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-asyncapi-3": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-json": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.10.2.tgz", + "integrity": "sha512-VnwEkarKfsJYRF0zCI9AGiSIyBUXqS2d32KQuhVCt/HeuF1XO9sjeLjGiosA/24YVOnO0ul5TpiNFQn0pw89mA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-ast": "^1.10.2", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "tree-sitter": "=0.21.1", + "tree-sitter-json": "=0.24.8", + "web-tree-sitter": "=0.24.5" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.10.2.tgz", + "integrity": "sha512-+d/o/8TrNBjvFzgPb0RQhrCc8gOWnrHZF+xvCO5gwp+4MUr1XP1AJIox1e6t1SO+j7IQjiF2ocx2r7eFE5QC7w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.10.2.tgz", + "integrity": "sha512-3ieUeX8/WywkUzdOO1U1QKQDNmpZFfOeTAeb4ISDd/PKOVwuEx/b0w5I8EuOu97tKAe3UUesEdii+pJlkcFlFw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-0": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.10.2.tgz", + "integrity": "sha512-z0c7IgMPLSDhE+ldTb54Xlhq+yPF0w/8LHXyeHX4V6BS1VG3Utb+mM/qTVfy1Eo+p1KGNlwNDEPsBp6jIaVb5Q==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-2/-/apidom-parser-adapter-openapi-json-3-2-1.10.2.tgz", + "integrity": "sha512-bx/kEIXWtpHu+4LEiyNdt0v8ER5EVwPjhQdlpOaC5qghnRH9aUYOTawZtVHsNHAQWTIMNn9DdPKYQgttQKD0Pw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.10.2.tgz", + "integrity": "sha512-e86JUXHGGEVsO4/xpy/GRSvYXGN30hLt1lMUhjzCFuE95N6/K3hmQHE3rA/H7ot1ajCWUhzukW5rGQac79NIjA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.10.2.tgz", + "integrity": "sha512-ucfc13Ai31tJ0ruAm1YiHhqENgcBuiOXL00OhoICWA56ggAcnA5WfWmvtsXVMlZsTHVbhZP3XpsH5rui2N8u5w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-0": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.10.2.tgz", + "integrity": "sha512-7o8j93qgf9yYAaaJ/GpH+5sB3fC9EmvmjTCqlw5YWXp+cRgCn9q7f80Sv4+NjbracUafB6qL4i9F/m+Xs0XZaQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-2/-/apidom-parser-adapter-openapi-yaml-3-2-1.10.2.tgz", + "integrity": "sha512-blDIeVmo8bpXYV/C+b6PYi54yS+5jPEZTFsK5jQ2NzpCPrkBPacp/KTuHBUBzJsYj4bj/ivRL3+JXGw4YovUHw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.10.2.tgz", + "integrity": "sha512-I5eCls8XS3SVEwH/cuL6T3iar1TPaFYh3gXwS/2rzP1aZQNKSHDP3y3ney7nAomKG4dFvE8Q248FL36arG7T/w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-ast": "^1.10.2", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@tree-sitter-grammars/tree-sitter-yaml": "=0.7.1", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "tree-sitter": "=0.22.4", + "web-tree-sitter": "=0.24.5" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/@tree-sitter-grammars/tree-sitter-yaml": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@tree-sitter-grammars/tree-sitter-yaml/-/tree-sitter-yaml-0.7.1.tgz", + "integrity": "sha512-AynBwkIoQCTgjDR33bDUp9Mqq+YTco0is3n5hRApMqG9of/6A4eQsfC1/uSEeHSUyMQSYawcAWamsexnVpIP4Q==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.3.1", + "node-gyp-build": "^4.8.4" + }, + "peerDependencies": { + "tree-sitter": "^0.22.4" + }, + "peerDependenciesMeta": { + "tree-sitter": { + "optional": true + } + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/tree-sitter": { + "version": "0.22.4", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.4.tgz", + "integrity": "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.3.0", + "node-gyp-build": "^4.8.4" + } + }, + "node_modules/@swagger-api/apidom-reference": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.10.2.tgz", + "integrity": "sha512-H5UqOmae9CXdiLJbbh1j+/hwvcECmr6ci2XtUKTQpFviemvsIDZmPV1DKUAxCfzGr2iOkDO6SZc+/OEWlETqiQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.26.10", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@types/ramda": "~0.30.0", + "axios": "^1.15.0", + "minimatch": "^10.2.1", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + }, + "optionalDependencies": { + "@swagger-api/apidom-json-pointer": "^1.10.2", + "@swagger-api/apidom-ns-arazzo-1": "^1.10.2", + "@swagger-api/apidom-ns-asyncapi-2": "^1.10.2", + "@swagger-api/apidom-ns-openapi-2": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-0": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-1": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.10.2", + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.10.2", + "@swagger-api/apidom-parser-adapter-arazzo-json-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-arazzo-yaml-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-asyncapi-json-3": "^1.10.2", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": "^1.10.2", + "@swagger-api/apidom-parser-adapter-json": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-json-3-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^1.10.2", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-2": "^1.10.2", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.10.2" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@swaggerexpert/cookie": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@swaggerexpert/cookie/-/cookie-2.0.2.tgz", + "integrity": "sha512-DPI8YJ0Vznk4CT+ekn3rcFNq1uQwvUHZhH6WvTSPD0YKBIlMS9ur2RYKghXuxxOiqOam/i4lHJH4xTIiTgs3Mg==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.3" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@swaggerexpert/json-pointer": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@swaggerexpert/json-pointer/-/json-pointer-2.10.2.tgz", + "integrity": "sha512-qMx1nOrzoB+PF+pzb26Q4Tc2sOlrx9Ba2UBNX9hB31Omrq+QoZ2Gly0KLrQWw4Of1AQ4J9lnD+XOdwOdcdXqqw==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.4" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz", + "integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==", + "license": "MIT" + }, + "node_modules/@types/ramda": { + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.2.tgz", + "integrity": "sha512-PyzHvjCalm2BRYjAU6nIB3TprYwMNOUY/7P/N8bSzp9W/yM2YrtGtAnnVtaCNSeOZ8DzKyFDvaqQs7LnWwwmBA==", + "license": "MIT", + "dependencies": { + "types-ramda": "^0.30.1" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.0.tgz", + "integrity": "sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.0", + "@typescript-eslint/type-utils": "8.59.0", + "@typescript-eslint/utils": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.0.tgz", + "integrity": "sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.0.tgz", + "integrity": "sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.0", + "@typescript-eslint/types": "^8.59.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.0.tgz", + "integrity": "sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.0.tgz", + "integrity": "sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.0.tgz", + "integrity": "sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0", + "@typescript-eslint/utils": "8.59.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.0.tgz", + "integrity": "sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.0.tgz", + "integrity": "sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.0", + "@typescript-eslint/tsconfig-utils": "8.59.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.0.tgz", + "integrity": "sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.0.tgz", + "integrity": "sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", + "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.7" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/apg-lite": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.5.tgz", + "integrity": "sha512-SlI+nLMQDzCZfS39ihzjGp3JNBQfJXyMi6cg9tkLOCPVErgFsUIAEdO9IezR7kbP5Xd0ozcPNQBkf9TO5cHgWw==", + "license": "BSD-2-Clause" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/autolinker": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", + "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.21.tgz", + "integrity": "sha512-Q+rUQ7Uz8AHM7DEaNdwvfFCTq7a43lNTzuS94eiWqwyxfV/wJv+oUivef51T91mmRY4d4A1u9rcSvkeufCVXlA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001790", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001790.tgz", + "integrity": "sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-js-pure": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.49.0.tgz", + "integrity": "sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dompurify": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.1.tgz", + "integrity": "sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/drange": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", + "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.343", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.343.tgz", + "integrity": "sha512-YHnQ3MXI08icvL9ZKnEBy05F2EQ8ob01UaMOuMbM8l+4UcAq6MPPbBTJBbsBUg3H8JeZNt+O4fjsoWth3p6IFg==", + "dev": true, + "license": "ISC" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.2.tgz", + "integrity": "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", + "integrity": "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "license": "CC0-1.0" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.3.tgz", + "integrity": "sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-file-download": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", + "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "license": "MIT", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minim": { + "version": "0.23.8", + "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", + "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", + "license": "MIT", + "dependencies": { + "lodash": "^4.15.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", + "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch-commonjs": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch-commonjs/-/node-fetch-commonjs-3.3.2.tgz", + "integrity": "sha512-VBlAiynj3VMLrotgwOS3OyECFxas5y7ltLcK4t41lMUZeaK15Ym4QRkqN0EQKAFL42q9i21EPKjzLUPfltR72A==", + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/openapi-path-templating": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-2.2.1.tgz", + "integrity": "sha512-eN14VrDvl/YyGxxrkGOHkVkWEoPyhyeydOUrbvjoz8K5eIGgELASwN1eqFOJ2CTQMGCy2EntOK1KdtJ8ZMekcg==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.4" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/openapi-server-url-templating": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.3.0.tgz", + "integrity": "sha512-DPlCms3KKEbjVQb0spV6Awfn6UWNheuG/+folQPzh/wUaKwuqvj8zt5gagD7qoyxtE03cIiKPgLFS3Q8Bz00uQ==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.4" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, + "node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/randexp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", + "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", + "license": "MIT", + "dependencies": { + "drange": "^1.0.2", + "ret": "^0.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", + "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.5" + } + }, + "node_modules/react-immutable-proptypes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", + "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.2" + }, + "peerDependencies": { + "immutable": ">=3.6.2" + } + }, + "node_modules/react-immutable-pure-component": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", + "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", + "license": "MIT", + "peerDependencies": { + "immutable": ">= 2 || >= 4.0.0-rc", + "react": ">= 16.6", + "react-dom": ">= 16.6" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.2.tgz", + "integrity": "sha512-yCqNne6I8IB6rVCH7XUvlBK7/QKyqypBFGv+8dj4QBFJiiRX+FG7/nkdAvGElyvVZ/HQP5N19wzteuTARXi5Gw==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.2.tgz", + "integrity": "sha512-YZcM5ES8jJSM+KrJ9BdvHHqlnGTg5tH3sC5ChFRj4inosKctdyzBDhOyyHdGk597q2OT6NTrCA1OvB/YDwfekQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.14.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-syntax-highlighter": { + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-16.1.1.tgz", + "integrity": "sha512-PjVawBGy80C6YbC5DDZJeUjBmC7skaoEUdvfFQediQHgCL7aKyVHe57SaJGfQsloGDac+gCpTfRdtxzWWKmCXA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", + "lowlight": "^1.17.0", + "prismjs": "^1.30.0", + "refractor": "^5.0.0" + }, + "engines": { + "node": ">= 16.20.2" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", + "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", + "license": "BSD-3-Clause", + "peerDependencies": { + "immutable": "^3.8.1 || ^4.0.0-rc.1" + } + }, + "node_modules/refractor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-5.0.0.tgz", + "integrity": "sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/prismjs": "^1.0.0", + "hastscript": "^9.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remarkable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", + "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.10", + "autolinker": "^3.11.0" + }, + "bin": { + "remarkable": "bin/remarkable.js" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/remarkable/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ret": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rolldown": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz", + "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.126.0", + "@rolldown/pluginutils": "1.0.0-rc.16" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.16", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", + "@rolldown/binding-darwin-x64": "1.0.0-rc.16", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz", + "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/short-unique-id": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-5.3.2.tgz", + "integrity": "sha512-KRT/hufMSxXKEDSQujfVE0Faa/kZ51ihUcZQAcmP04t00DvPj7Ox5anHke1sJYUtzSuiT/Y5uyzg/W7bBEGhCg==", + "license": "Apache-2.0", + "bin": { + "short-unique-id": "bin/short-unique-id", + "suid": "bin/short-unique-id" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/swagger-client": { + "version": "3.37.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.37.2.tgz", + "integrity": "sha512-KcB8psL1On4GWwv9Ribp1oteh50ygNnAyvQbd5MwiXMGkcB4f53rkZEdvZKPDdJO764mQjgErxQEGDVw6QBUMQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.22.15", + "@scarf/scarf": "=1.4.0", + "@swagger-api/apidom-core": "^1.10.2", + "@swagger-api/apidom-error": "^1.10.2", + "@swagger-api/apidom-json-pointer": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-1": "^1.10.2", + "@swagger-api/apidom-ns-openapi-3-2": "^1.10.2", + "@swagger-api/apidom-reference": "^1.10.2", + "@swaggerexpert/cookie": "^2.0.2", + "deepmerge": "~4.3.0", + "fast-json-patch": "^3.0.0-1", + "js-yaml": "^4.1.0", + "neotraverse": "=0.6.18", + "node-abort-controller": "^3.1.1", + "node-fetch-commonjs": "^3.3.2", + "openapi-path-templating": "^2.2.1", + "openapi-server-url-templating": "^1.3.0", + "ramda": "^0.30.1", + "ramda-adjunct": "^5.1.0" + } + }, + "node_modules/swagger-ui-react": { + "version": "5.32.4", + "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.32.4.tgz", + "integrity": "sha512-OsTqKCiDT/o8/oqZbt+p1djPkrOk3unKK/7+wGvP1+WY6pOzFoDLM4D39cNFtpIArtlg9uoK6MKIz3W00WX8qw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.27.1", + "@scarf/scarf": "=1.4.0", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "classnames": "^2.5.1", + "css.escape": "1.5.1", + "deep-extend": "0.6.0", + "dompurify": "^3.3.2", + "ieee754": "^1.2.1", + "immutable": "^3.x.x", + "js-file-download": "^0.4.12", + "js-yaml": "=4.1.1", + "lodash": "^4.18.1", + "prop-types": "^15.8.1", + "randexp": "^0.5.3", + "randombytes": "^2.1.0", + "react-copy-to-clipboard": "5.1.0", + "react-debounce-input": "=3.3.0", + "react-immutable-proptypes": "2.2.0", + "react-immutable-pure-component": "^2.2.0", + "react-inspector": "^6.0.1", + "react-redux": "^9.2.0", + "react-syntax-highlighter": "^16.0.0", + "redux": "^5.0.1", + "redux-immutable": "^4.0.0", + "remarkable": "^2.0.1", + "reselect": "^5.1.1", + "serialize-error": "^8.1.0", + "sha.js": "^2.4.12", + "swagger-client": "^3.37.2", + "url-parse": "^1.5.10", + "xml": "=1.0.1", + "xml-but-prettier": "^1.0.1", + "zenscroll": "^4.0.2" + }, + "peerDependencies": { + "react": ">=16.8.0 <20", + "react-dom": ">=16.8.0 <20" + } + }, + "node_modules/swagger-ui-react/node_modules/react-copy-to-clipboard": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", + "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", + "license": "MIT", + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, + "node_modules/swagger-ui-react/node_modules/react-debounce-input": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", + "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", + "license": "MIT", + "dependencies": { + "lodash.debounce": "^4", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, + "node_modules/swagger-ui-react/node_modules/react-inspector": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", + "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, + "node_modules/tree-sitter": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", + "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.0.0", + "node-gyp-build": "^4.8.0" + } + }, + "node_modules/tree-sitter-json": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.24.8.tgz", + "integrity": "sha512-Tc9ZZYwHyWZ3Tt1VEw7Pa2scu1YO7/d2BCBbKTx5hXwig3UfdQjsOPkPyLpDJOn/m1UBEWYAtSdGAwCSyagBqQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.2.2", + "node-gyp-build": "^4.8.2" + }, + "peerDependencies": { + "tree-sitter": "^0.21.1" + }, + "peerDependenciesMeta": { + "tree-sitter": { + "optional": true + } + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-mixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", + "license": "MIT" + }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/types-ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.1.tgz", + "integrity": "sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==", + "license": "MIT", + "dependencies": { + "ts-toolbelt": "^9.6.0" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.0.tgz", + "integrity": "sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.59.0", + "@typescript-eslint/parser": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0", + "@typescript-eslint/utils": "8.59.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unraw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", + "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vite": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz", + "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.10", + "rolldown": "1.0.0-rc.16", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web-tree-sitter": { + "version": "0.24.5", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.5.tgz", + "integrity": "sha512-+J/2VSHN8J47gQUAvF8KDadrfz6uFYVjxoxbKWDoXVsH2u7yLdarCnIURnrMA6uSRkgX3SdmqM5BOoQjPdSh5w==", + "license": "MIT", + "optional": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "license": "MIT" + }, + "node_modules/xml-but-prettier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", + "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", + "license": "MIT", + "dependencies": { + "repeat-string": "^1.5.2" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zenscroll": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", + "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==", + "license": "Unlicense" + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a59287e --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "client_laravel", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "test:api": "node scripts/test-api.mjs", + "gen:ci-meta": "node scripts/gen-ci-route-meta.mjs", + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.2.5", + "react-dom": "^19.2.5", + "react-router-dom": "^7.14.2", + "swagger-ui-react": "^5.32.4" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/node": "^24.12.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.5.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.58.2", + "vite": "^8.0.9" + } +} diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons.svg b/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/docker-up-wsl.sh b/scripts/docker-up-wsl.sh new file mode 100644 index 0000000..a4219d5 --- /dev/null +++ b/scripts/docker-up-wsl.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Run the Vite dev container from WSL (Docker Desktop with WSL2 backend, or Docker Engine in WSL). +# +# Usage (from repo root): +# chmod +x scripts/docker-up-wsl.sh +# ./scripts/docker-up-wsl.sh +# +# Or from anywhere: +# bash /mnt/d/Test/alrahma/client_laravel/scripts/docker-up-wsl.sh +# +# Windows D: drive in WSL is usually: /mnt/d/Test/alrahma/client_laravel +# +# Laravel API proxy: defaults to host port 8000. Override if requests fail: +# export VITE_PROXY_API=http://172.17.0.1:8000 +# ./scripts/docker-up-wsl.sh +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +cd "$ROOT" + +if [[ "$(pwd)" == /mnt/* ]]; then + echo "Note: Project is on a Windows mount (/mnt/...). File sync can be slower; Vite uses polling." >&2 +fi + +export VITE_PROXY_API="${VITE_PROXY_API:-http://host.docker.internal:8000}" + +echo "Using VITE_PROXY_API=${VITE_PROXY_API}" >&2 +echo "App → http://localhost:5173 (ensure Laravel is reachable from the container at the proxy target)" >&2 + +exec docker compose up --build client diff --git a/scripts/gen-ci-route-meta.mjs b/scripts/gen-ci-route-meta.mjs new file mode 100644 index 0000000..17f0133 --- /dev/null +++ b/scripts/gen-ci-route-meta.mjs @@ -0,0 +1,92 @@ +/** + * Generates src/lib/ciRouteMeta.generated.ts from CodeIgniter app/Views/*.php files. + * Run: node scripts/gen-ci-route-meta.mjs + */ +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const viewsRoot = path.resolve(__dirname, '../../app_codeigniter/app/Views') +const outFile = path.resolve(__dirname, '../src/lib/ciRouteMeta.generated.ts') + +const SKIP_DIRS = new Set([ + 'layout', + 'partials', + 'errors', + 'pagination', + 'docs', +]) + +function humanize(slug) { + const s = slug.replace(/\.php$/i, '').replace(/_/g, ' ') + return s.replace(/\b\w/g, (c) => c.toUpperCase()) +} + +function walk(dir, baseRel) { + const out = [] + let entries = [] + try { + entries = fs.readdirSync(dir, { withFileTypes: true }) + } catch { + return out + } + for (const e of entries) { + const rel = path.join(baseRel, e.name) + const full = path.join(dir, e.name) + if (e.isDirectory()) { + if (SKIP_DIRS.has(e.name)) continue + out.push(...walk(full, rel)) + } else if (e.isFile() && e.name.endsWith('.php')) { + out.push(rel.replace(/\\/g, '/')) + } + } + return out +} + +function main() { + if (!fs.existsSync(viewsRoot)) { + console.error('Missing Views folder:', viewsRoot) + process.exit(1) + } + + const files = walk(viewsRoot, '') + .filter((f) => !f.includes('/layout/')) + .sort() + + const entries = [] + for (const f of files) { + const parts = f.split('/') + const base = parts.pop().replace(/\.php$/i, '') + const section = parts.join('/') || '(root)' + const routeKey = [...parts, base].filter(Boolean).join('/') + const ciViewPath = f + const title = humanize(base) + entries.push({ routeKey, title, ciViewPath }) + } + + const lines = [] + lines.push(`/** Auto-generated by scripts/gen-ci-route-meta.mjs — do not edit by hand. */`) + lines.push(``) + lines.push(`export type CiRouteMetaEntry = {`) + lines.push(` title: string`) + lines.push(` ciViewPath: string`) + lines.push(`}`) + lines.push(``) + lines.push(`export const ciRouteMeta: Record = {`) + + for (const { routeKey, title, ciViewPath } of entries) { + const safeTitle = title.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + const safeView = ciViewPath.replace(/\\/g, '/') + lines.push(` '${routeKey}': { title: '${safeTitle}', ciViewPath: '${safeView}' },`) + } + + lines.push(`}`) + lines.push(``) + + fs.mkdirSync(path.dirname(outFile), { recursive: true }) + fs.writeFileSync(outFile, lines.join('\n'), 'utf8') + console.log(`Wrote ${entries.length} entries → ${path.relative(process.cwd(), outFile)}`) +} + +main() diff --git a/scripts/test-api.mjs b/scripts/test-api.mjs new file mode 100644 index 0000000..111b7a9 --- /dev/null +++ b/scripts/test-api.mjs @@ -0,0 +1,85 @@ +/** + * Smoke-test the same API routes the Vite client uses. + * Usage: node scripts/test-api.mjs + * $env:API_BASE="http://127.0.0.1:5173"; node scripts/test-api.mjs # via Vite proxy + */ +const base = (process.env.API_BASE ?? 'http://127.0.0.1:8000').replace(/\/$/, '') + +const tests = [ + ['GET', '/up', null], + ['GET', '/api/v1/health', null], + ['GET', '/api/v1/auth/register/captcha', null], + ['GET', '/api/v1/policies/school', null], + ['GET', '/api/docs/public', null], + [ + 'POST', + '/api/v1/auth/login', + JSON.stringify({ email: 'nosuch@example.org', password: 'wrong-password' }), + ], +] + +async function main() { + console.log(`API_BASE=${base}\n`) + + for (const [method, path, body] of tests) { + const url = `${base}${path}` + try { + const init = { + method, + headers: { + Accept: 'application/json', + ...(body ? { 'Content-Type': 'application/json' } : {}), + }, + ...(body ? { body } : {}), + } + const res = await fetch(url, init) + const text = await res.text() + let snippet = text.slice(0, 280).replace(/\s+/g, ' ') + let fatal = false + let dbError = false + try { + const j = JSON.parse(text) + const msg = + typeof j.message === 'string' + ? j.message + : typeof j.exception === 'string' + ? j.exception + : '' + if (j.exception?.includes?.('FatalError') || /FatalError/i.test(j.message ?? '')) { + fatal = true + snippet = `PHP FatalError: ${(j.message ?? '').slice(0, 100)}` + } else if (j.message && typeof j.message === 'string') { + snippet = j.message.slice(0, 120) + } + if (/SQLSTATE/i.test(msg) || /SQLSTATE/i.test(text)) { + dbError = true + snippet = `${snippet.slice(0, 80)}… (DB unavailable?)` + } + if (j.ok === true && path.includes('captcha')) { + snippet = `ok=true captcha=<${String(j.captcha ?? '').length} chars>` + } + if (j.status === true && path.includes('docs/public')) { + snippet = `title=${j.title ?? 'n/a'} openapi=${!!j.openapi_url}` + } + if (j.data?.policy && path.includes('policies/school')) { + snippet = `policy content len=${String(j.data.policy.content ?? '').length}` + } + } catch { + /* not JSON */ + } + const ok = + !fatal && + !dbError && + (res.ok || + (path.endsWith('/login') && (res.status === 401 || res.status === 400)) || + res.status === 422) + console.log( + `${method} ${path} → ${res.status} ${ok ? '✓' : '✗'} ${snippet}`, + ) + } catch (e) { + console.log(`${method} ${path} → ERROR ${e instanceof Error ? e.message : e}`) + } + } +} + +main() diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..cc160d5 --- /dev/null +++ b/src/App.css @@ -0,0 +1,75 @@ +html, +body, +#root { + height: 100%; + margin: 0; +} + +body { + font-family: + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif; + background-color: #fafafa; +} + +.docs-root { + min-height: 100vh; +} + +.admin-banner { + background-color: #15654f; + color: white; + padding: 0.75rem 1.25rem; + text-align: right; + font-weight: 600; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: sticky; + top: 0; + z-index: 1000; +} + +.admin-banner span { + color: #f2f2f2; + font-weight: 500; + opacity: 0.9; +} + +.docs-loading, +.docs-error { + padding: 2rem; + font-size: 1rem; +} + +.docs-error { + color: #b00020; +} + +.admin-docs-shell { + display: flex; + flex-direction: column; + min-height: 100vh; +} + +.docs-toolbar { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + align-items: center; + padding: 0.5rem 1rem; + background: #e8f0ec; + border-bottom: 1px solid #c5d5ce; + font-size: 0.9rem; +} + +.docs-toolbar input { + min-width: 220px; + padding: 0.35rem 0.5rem; +} + +.docs-toolbar a { + color: #15654f; + font-weight: 600; +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..84888f1 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,177 @@ +import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom' +import { AuthProvider } from './auth/AuthProvider' +import { RequireAuth } from './auth/RequireAuth' +import { PublicLayout } from './layout/PublicLayout' +import { ManagementLayout } from './layout/ManagementLayout' +import { AdminDocs } from './pages/AdminDocs' +import { AppHome } from './pages/AppHome' +import { CiPlaceholderPage } from './pages/CiPlaceholderPage' +import { CiSitemapPage } from './pages/CiSitemapPage' +import { ForgotPasswordPage } from './pages/ForgotPasswordPage' +import { HomePage } from './pages/HomePage' +import { LoginPage } from './pages/LoginPage' +import { RegisterPage } from './pages/RegisterPage' +import { ParentAttendancePage } from './pages/parent/ParentAttendancePage' +import { ParentHomePage } from './pages/parent/ParentHomePage' +import { + ParentEmergencyContactEditPage, + ParentProgressAttachmentFilePage, + ParentProgressAttachmentPage, + ParentProgressViewPage, + ParentReportCardsSignPage, + ParentReportCardsViewPage, + ParentStudentEditPage, +} from './pages/parent/dynamicParityPages' +import { + ParentAddEmergencyFormPage, + ParentAddStudentFormPage, + ParentEditAllStudentsPage, + ParentUpdateProfileParityPage, +} from './pages/parent/extraParentParityPages' +import { + ParentAttendanceReportsHistoryPage, + ParentAuthorizedUsersPage, +} from './pages/parent/ParentAccountListPages' +import { ParentEmergencyContactsPage } from './pages/parent/ParentEmergencyContactsPage' +import { + RedirectParentLegacyEmergencyContactEdit, + RedirectParentLegacyStudentEdit, +} from './pages/parent/ParentCiRouteRedirects' +import { + ParentAddSecondParentPage, + ParentAssignmentsPage, + ParentCalendarPage, + ParentClassesPage, + ParentEnrollFailurePage, + ParentEnrollSuccessPage, + ParentInvoicePaymentPage, + ParentMessagePage, + ParentNoKidsRegisteredPage, + ParentPaymentSuccessPage, + ParentProgressListPage, + ParentReportCardsPage, + ParentScoresPage, + ParentSuccessMessagePage, + ParentWithdrawSuccessPage, +} from './pages/parent/staticParityPages' +import { + ParentContactPage, + ParentEnrollClassesPage, + ParentEventsPage, + ParentPaymentInvoicesPage, + ParentRegisterStudentPage, + ParentReportAttendancePage, +} from './pages/parent/WiredParentScreens' +import { SwaggerDocs } from './pages/SwaggerDocs' +import './App.css' + +export default function App() { + return ( + + + + }> + } /> + } /> + } /> + } /> + + + + + + } + /> + } /> + + }> + }> + } /> + } /> + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } /> + } /> + + } /> + + } /> + + } + /> + } + /> + + } /> + } /> + } /> + } /> + + } /> + } /> + } /> + } /> + + } /> + } /> + + } + /> + } /> + + } /> + } /> + } /> + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } /> + } /> + + + + } /> + + + + ) +} diff --git a/src/api/http.ts b/src/api/http.ts new file mode 100644 index 0000000..d0c359e --- /dev/null +++ b/src/api/http.ts @@ -0,0 +1,52 @@ +import { apiUrl } from '../lib/apiOrigin' + +const TOKEN_KEY = 'alrahma_api_token' + +export function getStoredToken(): string | null { + return localStorage.getItem(TOKEN_KEY) +} + +export function setStoredToken(token: string | null): void { + if (token) localStorage.setItem(TOKEN_KEY, token) + else localStorage.removeItem(TOKEN_KEY) +} + +export class ApiHttpError extends Error { + readonly status: number + readonly body: unknown + + constructor(message: string, status: number, body: unknown) { + super(message) + this.name = 'ApiHttpError' + this.status = status + this.body = body + } +} + +export async function apiFetch( + path: string, + init: RequestInit = {}, + opts: { attachAuth?: boolean } = {}, +): Promise { + const attachAuth = opts.attachAuth !== false + const headers = new Headers(init.headers) + if (!headers.has('Accept')) headers.set('Accept', 'application/json') + + const token = getStoredToken() + if (attachAuth && token && !headers.has('Authorization')) { + headers.set('Authorization', `Bearer ${token}`) + } + + const res = await fetch(apiUrl(path), { ...init, headers }) + const body: unknown = await res.json().catch(() => null) + + if (!res.ok) { + const msg = + typeof body === 'object' && body !== null && 'message' in body + ? String((body as { message?: unknown }).message ?? '') + : '' + throw new ApiHttpError(msg || `HTTP ${res.status}`, res.status, body) + } + + return body as T +} diff --git a/src/api/registerFull.ts b/src/api/registerFull.ts new file mode 100644 index 0000000..88c3414 --- /dev/null +++ b/src/api/registerFull.ts @@ -0,0 +1,127 @@ +import { apiUrl } from '../lib/apiOrigin' + +export type FullRegisterPayload = { + firstname: string + lastname: string + gender: string + cellphone: string + email: string + confirm_email: string + address_street: string + apt?: string + city: string + state: string + zip: string + is_parent: boolean + no_second_parent_info: boolean + second_firstname?: string + second_lastname?: string + second_gender?: string + second_email?: string + second_cellphone?: string + accept_school_policy: boolean + captcha: string +} + +export async function fetchRegisterCaptcha(): Promise<{ challenge: string }> { + const res = await fetch(apiUrl('/api/v1/auth/register/captcha'), { + method: 'GET', + headers: { Accept: 'application/json' }, + }) + const body: unknown = await res.json().catch(() => null) + if (!res.ok || !body || typeof body !== 'object') { + throw new Error('Could not load CAPTCHA.') + } + const o = body as { ok?: boolean; captcha?: string } + if (!o.ok || typeof o.captcha !== 'string') { + throw new Error('Invalid CAPTCHA response.') + } + return { challenge: o.captcha } +} + +export type FullRegisterSuccess = { + ok: true + message?: string + registration?: unknown +} + +export type FullRegisterFailure = { + ok: false + message: string + errors?: Record +} + +export async function submitFullRegistration( + payload: FullRegisterPayload, +): Promise { + const body: Record = { + firstname: payload.firstname.trim(), + lastname: payload.lastname.trim(), + gender: payload.gender, + cellphone: payload.cellphone.trim(), + email: payload.email.trim(), + confirm_email: payload.confirm_email.trim(), + address_street: payload.address_street.trim(), + apt: payload.apt?.trim() || '', + city: payload.city.trim(), + state: payload.state, + zip: payload.zip.trim(), + is_parent: payload.is_parent, + no_second_parent_info: payload.no_second_parent_info, + accept_school_policy: payload.accept_school_policy, + captcha: payload.captcha.trim(), + } + + if (payload.is_parent && !payload.no_second_parent_info) { + body.second_firstname = payload.second_firstname?.trim() ?? '' + body.second_lastname = payload.second_lastname?.trim() ?? '' + body.second_gender = payload.second_gender ?? '' + body.second_email = payload.second_email?.trim() ?? '' + body.second_cellphone = payload.second_cellphone?.trim() ?? '' + } + + const res = await fetch(apiUrl('/api/v1/auth/register'), { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }) + + const data: unknown = await res.json().catch(() => null) + + if (res.ok && data && typeof data === 'object' && 'ok' in data && (data as { ok?: boolean }).ok === true) { + return { ok: true, message: (data as { message?: string }).message, registration: (data as { registration?: unknown }).registration } + } + + let message = 'Registration failed.' + let errors: Record | undefined + if (data && typeof data === 'object') { + const o = data as { message?: string; errors?: Record } + if (typeof o.message === 'string') message = o.message + if (o.errors && typeof o.errors === 'object') { + errors = {} + for (const [k, v] of Object.entries(o.errors)) { + if (Array.isArray(v)) errors[k] = v.map(String) + else errors[k] = [String(v)] + } + } + } + + return { ok: false, message, errors } +} + +export async function fetchSchoolPolicyHtml(): Promise { + const res = await fetch(apiUrl('/api/v1/policies/school'), { + headers: { Accept: 'application/json' }, + }) + const json = (await res.json().catch(() => null)) as { + data?: { policy?: { content?: string } } + } + const html = json?.data?.policy?.content + if (!res.ok || !html) { + return '

Unable to load policy. Please contact the school.

' + } + return html +} diff --git a/src/api/session.ts b/src/api/session.ts new file mode 100644 index 0000000..6d97452 --- /dev/null +++ b/src/api/session.ts @@ -0,0 +1,122 @@ +import { apiFetch } from './http' +import type { + ApiEnvelope, + DashboardPayload, + LoginFailure, + LoginResponse, + LoginSuccess, + NavMenuResponse, + ParentAttendanceResponse, + ParentAttendanceReportFormResponse, + ParentEnrollmentsResponse, + ParentEventsResponse, + ParentInvoicesResponse, + ParentProfileResponse, + ParentRegistrationResponse, + ParentEmergencyContactsResponse, + ParentAttendanceReportsListResponse, + ParentAuthorizedUsersApiResponse, + ContactSubmitResponse, +} from './types' + +export async function loginRequest( + email: string, + password: string, +): Promise { + const body = await apiFetch( + '/api/v1/auth/login', + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password }), + }, + { attachAuth: false }, + ) + + if (body.status === false) { + const fail = body as LoginFailure + return { status: false, message: fail.message } + } + + return body as LoginSuccess +} + +export async function fetchDashboardRoute(): Promise> { + return apiFetch>('/api/v1/dashboard/route') +} + +export async function fetchNavMenu(): Promise { + return apiFetch('/api/v1/nav-builder/menu') +} + +export async function fetchParentAttendance( + schoolYear: string | null, +): Promise { + const q = schoolYear ? `?school_year=${encodeURIComponent(schoolYear)}` : '' + return apiFetch(`/api/v1/parents/attendance${q}`) +} + +export async function fetchParentProfile(): Promise { + return apiFetch('/api/v1/parents/profile') +} + +export async function fetchParentEnrollments( + schoolYear: string | null, +): Promise { + const q = schoolYear ? `?school_year=${encodeURIComponent(schoolYear)}` : '' + return apiFetch(`/api/v1/parents/enrollments${q}`) +} + +export async function fetchParentInvoices( + schoolYear: string | null, +): Promise { + const q = schoolYear ? `?school_year=${encodeURIComponent(schoolYear)}` : '' + return apiFetch(`/api/v1/parents/invoices${q}`) +} + +export async function fetchParentEventsOverview(): Promise { + return apiFetch('/api/v1/parents/events') +} + +export async function fetchParentRegistrationOverview(): Promise { + return apiFetch('/api/v1/parents/registration') +} + +export async function fetchAttendanceReportForm(): Promise { + return apiFetch( + '/api/v1/parents/attendance-reports/form', + ) +} + +export async function submitContactMessage(payload: { + name: string + email: string + subject: string + message: string +}): Promise { + return apiFetch('/api/v1/contact', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }) +} + +export async function fetchParentEmergencyContacts(): Promise { + return apiFetch('/api/v1/parents/emergency-contacts') +} + +export async function fetchParentAttendanceReportsList( + query?: Record, +): Promise { + const q = + query && Object.keys(query).length > 0 + ? `?${new URLSearchParams(query).toString()}` + : '' + return apiFetch( + `/api/v1/parents/attendance-reports${q}`, + ) +} + +export async function fetchParentAuthorizedUsers(): Promise { + return apiFetch('/api/v1/parents/authorized-users') +} diff --git a/src/api/types.ts b/src/api/types.ts new file mode 100644 index 0000000..36f5454 --- /dev/null +++ b/src/api/types.ts @@ -0,0 +1,138 @@ +export type AuthUser = { + id: number + name: string + roles: Record +} + +export type LoginSuccess = { + status: true + token: string + user: AuthUser +} + +export type LoginFailure = { + status: false + message?: string +} + +export type LoginResponse = LoginSuccess | LoginFailure + +export type ApiEnvelope = { + status: boolean + message?: string + data?: T +} + +export type DashboardPayload = { + dashboard: { + route: string | null + role: string | null + role_slug: string | null + roles: string[] + } +} + +export type NavItem = { + id: number + menu_parent_id: number | null + label: string + url: string | null + icon_class: string | null + target: string | null + sort_order: number + is_enabled: number + children: NavItem[] +} + +export type NavMenuResponse = ApiEnvelope<{ items: NavItem[] }> + +export type ParentAttendanceRow = { + firstname: string + lastname: string + date: string + status: string + reason: string | null +} + +export type ParentAttendanceResponse = { + ok: true + attendance: ParentAttendanceRow[] + schoolYears: { school_year: string }[] + selectedYear: string | null +} + +/** Laravel `User::toArray()` for the logged-in parent (password hidden server-side). */ +export type ParentProfileRecord = { + id?: number + firstname?: string | null + lastname?: string | null + email?: string | null + cellphone?: string | null + city?: string | null + state?: string | null + zip?: string | null + address_street?: string | null +} + +export type ParentProfileResponse = { + ok: true + profile: ParentProfileRecord | null +} + +export type ParentInvoiceRow = { + id: number + invoice_number?: string | null + balance?: number + status?: string | null + due_date?: string | null +} + +export type ParentInvoicesResponse = { + ok: true + invoices: ParentInvoiceRow[] +} + +export type ParentEnrollmentStudent = { + id: number + firstname: string + lastname: string + class_section?: string | null +} + +export type ParentEnrollmentsResponse = { + ok: true + students: ParentEnrollmentStudent[] + schoolYears: { school_year: string }[] + selectedYear: string | null +} + +export type ContactSubmitResponse = { + status: boolean + message?: string +} + +/** Loose JSON payloads for complex parent dashboards (events, registration, attendance report form). */ +export type ParentEventsResponse = Record +export type ParentRegistrationResponse = Record +export type ParentAttendanceReportFormResponse = Record + +export type ParentEmergencyContactRow = { + id: number + name?: string + cellphone?: string + email?: string | null + relation?: string | null +} + +export type ParentEmergencyContactsResponse = { + ok: true + contacts: ParentEmergencyContactRow[] +} + +export type ParentAttendanceReportsListResponse = { + ok: true + reports: Record[] +} + +/** `GET /api/v1/parents/authorized-users` — envelope from BaseApiController. */ +export type ParentAuthorizedUsersApiResponse = ApiEnvelope diff --git a/src/assets/hero.png b/src/assets/hero.png new file mode 100644 index 0000000..02251f4 Binary files /dev/null and b/src/assets/hero.png differ diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/vite.svg b/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/src/auth/AuthProvider.tsx b/src/auth/AuthProvider.tsx new file mode 100644 index 0000000..3e51055 --- /dev/null +++ b/src/auth/AuthProvider.tsx @@ -0,0 +1,131 @@ +import { + createContext, + useCallback, + useContext, + useMemo, + useSyncExternalStore, +} from 'react' +import { setStoredToken, getStoredToken } from '../api/http' +import type { AuthUser } from '../api/types' +import { loginRequest } from '../api/session' + +export type { AuthUser } + +type AuthState = { + token: string | null + user: AuthUser | null +} + +const STORAGE_USER = 'alrahma_api_user' + +function readUser(): AuthUser | null { + try { + const raw = localStorage.getItem(STORAGE_USER) + if (!raw) return null + return JSON.parse(raw) as AuthUser + } catch { + return null + } +} + +function writeUser(user: AuthUser | null): void { + if (user) localStorage.setItem(STORAGE_USER, JSON.stringify(user)) + else localStorage.removeItem(STORAGE_USER) +} + +let memory: AuthState = { + token: getStoredToken(), + user: readUser(), +} + +const listeners = new Set<() => void>() + +function emit(): void { + listeners.forEach((fn) => fn()) +} + +function setAuth(next: AuthState): void { + memory = next + emit() +} + +function subscribe(listener: () => void): () => void { + listeners.add(listener) + return () => listeners.delete(listener) +} + +function getSnapshot(): AuthState { + return memory +} + +export function hydrateAuthFromStorage(): void { + memory = { + token: getStoredToken(), + user: readUser(), + } + emit() +} + +export function AuthProvider({ children }: { children: React.ReactNode }) { + const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot) + + const login = useCallback(async (email: string, password: string) => { + const result = await loginRequest(email, password) + if (result.status === false) { + return { + ok: false as const, + message: result.message ?? 'Login failed.', + } + } + setStoredToken(result.token) + writeUser(result.user) + setAuth({ token: result.token, user: result.user }) + return { ok: true as const } + }, []) + + const logout = useCallback(() => { + setStoredToken(null) + writeUser(null) + setAuth({ token: null, user: null }) + }, []) + + const setSession = useCallback((token: string, user: AuthUser) => { + setStoredToken(token) + writeUser(user) + setAuth({ token, user }) + }, []) + + const value = useMemo( + () => ({ + login, + logout, + setSession, + token: state.token, + user: state.user, + isAuthenticated: Boolean(state.token && state.user), + }), + [state.token, state.user, login, logout, setSession], + ) + + return {children} +} + +type AuthContextValue = { + login: ( + email: string, + password: string, + ) => Promise<{ ok: true } | { ok: false; message: string }> + logout: () => void + setSession: (token: string, user: AuthUser) => void + token: string | null + user: AuthUser | null + isAuthenticated: boolean +} + +const AuthContext = createContext(null) + +export function useAuth(): AuthContextValue { + const ctx = useContext(AuthContext) + if (!ctx) throw new Error('useAuth must be used within AuthProvider') + return ctx +} diff --git a/src/auth/RequireAuth.tsx b/src/auth/RequireAuth.tsx new file mode 100644 index 0000000..d9c05a2 --- /dev/null +++ b/src/auth/RequireAuth.tsx @@ -0,0 +1,13 @@ +import { Navigate, Outlet, useLocation } from 'react-router-dom' +import { useAuth } from './AuthProvider' + +export function RequireAuth() { + const { isAuthenticated } = useAuth() + const location = useLocation() + + if (!isAuthenticated) { + return + } + + return +} diff --git a/src/data/neStates.ts b/src/data/neStates.ts new file mode 100644 index 0000000..238566e --- /dev/null +++ b/src/data/neStates.ts @@ -0,0 +1,10 @@ +/** Northeast states — same labels as CodeIgniter user/register.php */ +export const NE_STATES: { abbr: string; name: string }[] = [ + { abbr: 'CT', name: 'Connecticut' }, + { abbr: 'ME', name: 'Maine' }, + { abbr: 'MA', name: 'Massachusetts' }, + { abbr: 'NH', name: 'New Hampshire' }, + { abbr: 'NY', name: 'New York' }, + { abbr: 'RI', name: 'Rhode Island' }, + { abbr: 'VT', name: 'Vermont' }, +] diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..cb2765d --- /dev/null +++ b/src/index.css @@ -0,0 +1,78 @@ +:root { + /* Mirrors CodeIgniter management_layout theme tokens */ + --mgmt-primary: #22a047; + --mgmt-primary-hover: #1c863b; + --mgmt-text: #1f2937; + --mgmt-muted: #64748b; + --mgmt-bg: #f5f7fb; + + font-family: + Heebo, + system-ui, + 'Segoe UI', + Roboto, + sans-serif; + color: var(--mgmt-text); + background-color: var(--mgmt-bg); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; +} + +html, +body { + margin: 0; + min-height: 100%; +} + +#root { + min-height: 100svh; + width: 100%; + margin: 0 auto; +} + +/* Swagger / docs pages (narrow column) */ +.docs-root-inner { + max-width: 1126px; + margin: 0 auto; + padding: 0 1rem; + box-sizing: border-box; +} + +.management-app { + font-family: Heebo, system-ui, sans-serif; + background-color: var(--mgmt-bg); + color: var(--mgmt-text); +} + +.management-app .navbar { + background-color: #14532d !important; +} + +.management-app .navbar .navbar-brand, +.management-app .navbar .navbar-text { + color: rgba(255, 255, 255, 0.95) !important; +} + +.management-main { + background: transparent; +} + +.management-app .nav-link.active { + background-color: rgba(34, 160, 71, 0.12); + color: var(--mgmt-primary) !important; +} + +.login-page, +.register-page { + background: linear-gradient(160deg, #ecfdf3 0%, var(--mgmt-bg) 45%, #fff 100%); +} + +.public-shell .hero-gradient { + background: linear-gradient(135deg, #14532d 0%, #166534 45%, #15803d 100%); +} + +/* Preserve docs styling from App.css */ +.docs-root { + min-height: 100vh; +} diff --git a/src/layout/ManagementLayout.tsx b/src/layout/ManagementLayout.tsx new file mode 100644 index 0000000..9d4032d --- /dev/null +++ b/src/layout/ManagementLayout.tsx @@ -0,0 +1,194 @@ +import { useEffect, useState, type ReactNode } from 'react' +import { Link, NavLink, Outlet, useNavigate } from 'react-router-dom' +import { fetchNavMenu } from '../api/session' +import type { NavItem } from '../api/types' +import { useAuth } from '../auth/AuthProvider' +import { + isExternalNavUrl, + spaPathFromCiUrl, +} from '../lib/ciSpaPaths' + +function normalizeNavItems(payload: unknown): NavItem[] { + if (Array.isArray(payload)) { + return payload as NavItem[] + } + if ( + payload && + typeof payload === 'object' && + 'data' in payload && + Array.isArray((payload as { data: unknown }).data) + ) { + return (payload as { data: NavItem[] }).data + } + return [] +} + +function NavTree({ items }: { items: NavItem[] }) { + return ( +
    + {items.map((item) => ( + + ))} +
+ ) +} + +function NavBranch({ item, depth }: { item: NavItem; depth: number }) { + const enabled = item.is_enabled !== 0 + if (!enabled) return null + + const label = item.label?.trim() || 'Menu' + const url = item.url?.trim() || '' + const external = isExternalNavUrl(url) + const spa = spaPathFromCiUrl(url) + const pad = 8 + depth * 10 + + const icon = item.icon_class ? ( + + ) : null + + const linkInner = ( + <> + {icon} + {label} + + ) + + const linkClass = ({ isActive }: { isActive: boolean }) => + `nav-link rounded py-2 px-2 ${isActive ? 'active fw-semibold' : ''}` + + let main: ReactNode + if (external) { + main = ( + + {linkInner} + + ) + } else if (spa) { + main = ( + + {linkInner} + + ) + } else { + main = ( + + {linkInner} + + ) + } + + const children = (item.children ?? []).filter((c) => c.is_enabled !== 0) + + return ( +
  • + {main} + {children.length > 0 ? ( +
    + {children.map((ch) => ( + + ))} +
    + ) : null} +
  • + ) +} + +export function ManagementLayout() { + const { user, logout } = useAuth() + const navigate = useNavigate() + const [items, setItems] = useState([]) + const [menuError, setMenuError] = useState(null) + + useEffect(() => { + let cancelled = false + ;(async () => { + try { + const res = await fetchNavMenu() + const list = res.data?.items + if (!cancelled && list != null) { + setItems(normalizeNavItems(list)) + setMenuError(null) + } + } catch (e) { + if (!cancelled) { + setItems([]) + setMenuError(e instanceof Error ? e.message : 'Unable to load menu.') + } + } + })() + return () => { + cancelled = true + } + }, []) + + return ( +
    +
    +
    + + Al Rahma Sunday School + +
    + {user?.name} + +
    +
    +
    + +
    +
    + + +
    + +
    +
    +
    +
    + ) +} diff --git a/src/layout/PublicLayout.tsx b/src/layout/PublicLayout.tsx new file mode 100644 index 0000000..967ffa1 --- /dev/null +++ b/src/layout/PublicLayout.tsx @@ -0,0 +1,92 @@ +import { Link, Outlet } from 'react-router-dom' +import { useAuth } from '../auth/AuthProvider' + +export function PublicLayout() { + const { isAuthenticated, user, logout } = useAuth() + + return ( +
    + + +
    + +
    + +
    +
    +

    Al Rahma Sunday School

    +
    +
    +
    + ) +} diff --git a/src/lib/apiOrigin.ts b/src/lib/apiOrigin.ts new file mode 100644 index 0000000..27be51c --- /dev/null +++ b/src/lib/apiOrigin.ts @@ -0,0 +1,11 @@ +/** Prefix for Laravel API when the SPA is served from another origin (production). Empty in dev with Vite proxy. */ +export function apiOrigin(): string { + const v = import.meta.env.VITE_API_ORIGIN + return typeof v === 'string' ? v.replace(/\/$/, '') : '' +} + +export function apiUrl(path: string): string { + const base = apiOrigin() + const p = path.startsWith('/') ? path : `/${path}` + return `${base}${p}` +} diff --git a/src/lib/ciRouteLookup.ts b/src/lib/ciRouteLookup.ts new file mode 100644 index 0000000..eef8f9e --- /dev/null +++ b/src/lib/ciRouteLookup.ts @@ -0,0 +1,21 @@ +import { type CiRouteMetaEntry, ciRouteMeta } from './ciRouteMeta.generated' +import { ciRouteManual } from './ciRouteManual' + +/** Match CI `app/Views/...` keys: lowercase, hyphens in URL map to underscores. */ +export function getCiMeta(splat: string): CiRouteMetaEntry | null { + const raw = splat + .trim() + .replace(/^\/+|\/+$/g, '') + .toLowerCase() + if (!raw) return null + const withUnderscores = raw.replace(/-/g, '_') + return ( + ciRouteManual[withUnderscores] ?? ciRouteMeta[withUnderscores] ?? null + ) +} + +/** Build canonical SPA path from a registry key (snake segments) using kebab-case segments. */ +export function ciRegistryKeyToAppPath(routeKey: string): string { + const parts = routeKey.split('/').map((seg) => seg.replace(/_/g, '-')) + return `/app/${parts.join('/')}` +} diff --git a/src/lib/ciRouteManual.ts b/src/lib/ciRouteManual.ts new file mode 100644 index 0000000..e9d3cb0 --- /dev/null +++ b/src/lib/ciRouteManual.ts @@ -0,0 +1,24 @@ +import type { CiRouteMetaEntry } from './ciRouteMeta.generated' + +/** + * CI routes that do not map 1:1 to a single Views/*.php filename (composed dashboards, aliases). + * Keys use snake_case segments like the generated registry. + */ +export const ciRouteManual: Record = { + 'teacher/dashboard': { + title: 'Teacher dashboard', + ciViewPath: '(TeacherController::dashboard — see Views/teacher/*.php)', + }, + 'administrator/dashboard': { + title: 'Administrator dashboard', + ciViewPath: '(Support/administrator dashboards — see Views/administrator/*.php)', + }, + 'administrator/administratordashboard': { + title: 'Administrator dashboard', + ciViewPath: 'administrator/administratordashboard.php', + }, + 'landing_page/guest_dashboard': { + title: 'Guest dashboard', + ciViewPath: 'landing_page/guest_dashboard.php', + }, +} diff --git a/src/lib/ciRouteMeta.generated.ts b/src/lib/ciRouteMeta.generated.ts new file mode 100644 index 0000000..361b2cd --- /dev/null +++ b/src/lib/ciRouteMeta.generated.ts @@ -0,0 +1,324 @@ +/** Auto-generated by scripts/gen-ci-route-meta.mjs — do not edit by hand. */ + +export type CiRouteMetaEntry = { + title: string + ciViewPath: string +} + +export const ciRouteMeta: Record = { + 'about': { title: 'About', ciViewPath: 'about.php' }, + 'account/choose_account': { title: 'Choose Account', ciViewPath: 'account/choose_account.php' }, + 'activate_account': { title: 'Activate Account', ciViewPath: 'activate_account.php' }, + 'admin/class_progress_list': { title: 'Class Progress List', ciViewPath: 'admin/class_progress_list.php' }, + 'admin/class_progress_view': { title: 'Class Progress View', ciViewPath: 'admin/class_progress_view.php' }, + 'admin/competition_winners/form': { title: 'Form', ciViewPath: 'admin/competition_winners/form.php' }, + 'admin/competition_winners/index': { title: 'Index', ciViewPath: 'admin/competition_winners/index.php' }, + 'admin/competition_winners/preview': { title: 'Preview', ciViewPath: 'admin/competition_winners/preview.php' }, + 'admin/competition_winners/scores': { title: 'Scores', ciViewPath: 'admin/competition_winners/scores.php' }, + 'admin/competition_winners/winners': { title: 'Winners', ciViewPath: 'admin/competition_winners/winners.php' }, + 'admin/student_score_card': { title: 'Student Score Card', ciViewPath: 'admin/student_score_card.php' }, + 'administrator/absence_vacation': { title: 'Absence Vacation', ciViewPath: 'administrator/absence_vacation.php' }, + 'administrator/academic_performance': { title: 'Academic Performance', ciViewPath: 'administrator/academic_performance.php' }, + 'administrator/admin_attendance_records': { title: 'Admin Attendance Records', ciViewPath: 'administrator/admin_attendance_records.php' }, + 'administrator/admin_profiles': { title: 'Admin Profiles', ciViewPath: 'administrator/admin_profiles.php' }, + 'administrator/administratordashboard': { title: 'Administratordashboard', ciViewPath: 'administrator/administratordashboard.php' }, + 'administrator/attendance': { title: 'Attendance', ciViewPath: 'administrator/attendance.php' }, + 'administrator/attendance_records': { title: 'Attendance Records', ciViewPath: 'administrator/attendance_records.php' }, + 'administrator/behavior_reports': { title: 'Behavior Reports', ciViewPath: 'administrator/behavior_reports.php' }, + 'administrator/broadcast_email': { title: 'Broadcast Email', ciViewPath: 'administrator/broadcast_email.php' }, + 'administrator/budget_reports': { title: 'Budget Reports', ciViewPath: 'administrator/budget_reports.php' }, + 'administrator/calendar': { title: 'Calendar', ciViewPath: 'administrator/calendar.php' }, + 'administrator/calendar_add_event': { title: 'Calendar Add Event', ciViewPath: 'administrator/calendar_add_event.php' }, + 'administrator/calendar_edit': { title: 'Calendar Edit', ciViewPath: 'administrator/calendar_edit.php' }, + 'administrator/calendar_view': { title: 'Calendar View', ciViewPath: 'administrator/calendar_view.php' }, + 'administrator/class_assignment': { title: 'Class Assignment', ciViewPath: 'administrator/class_assignment.php' }, + 'administrator/class_section': { title: 'Class Section', ciViewPath: 'administrator/class_section.php' }, + 'administrator/class_warning_modal': { title: 'Class Warning Modal', ciViewPath: 'administrator/class_warning_modal.php' }, + 'administrator/communication_logs': { title: 'Communication Logs', ciViewPath: 'administrator/communication_logs.php' }, + 'administrator/course_materials': { title: 'Course Materials', ciViewPath: 'administrator/course_materials.php' }, + 'administrator/create_parent': { title: 'Create Parent', ciViewPath: 'administrator/create_parent.php' }, + 'administrator/daily_attendance': { title: 'Daily Attendance', ciViewPath: 'administrator/daily_attendance.php' }, + 'administrator/daily_attendance_analysis': { title: 'Daily Attendance Analysis', ciViewPath: 'administrator/daily_attendance_analysis.php' }, + 'administrator/edit_parent': { title: 'Edit Parent', ciViewPath: 'administrator/edit_parent.php' }, + 'administrator/edit_teacher': { title: 'Edit Teacher', ciViewPath: 'administrator/edit_teacher.php' }, + 'administrator/emergency_contact/edit': { title: 'Edit', ciViewPath: 'administrator/emergency_contact/edit.php' }, + 'administrator/emergency_contact/index': { title: 'Index', ciViewPath: 'administrator/emergency_contact/index.php' }, + 'administrator/events/create_event': { title: 'Create Event', ciViewPath: 'administrator/events/create_event.php' }, + 'administrator/events/edit_event': { title: 'Edit Event', ciViewPath: 'administrator/events/edit_event.php' }, + 'administrator/events/event_charges': { title: 'Event Charges', ciViewPath: 'administrator/events/event_charges.php' }, + 'administrator/events/event_list': { title: 'Event List', ciViewPath: 'administrator/events/event_list.php' }, + 'administrator/exam_drafts': { title: 'Exam Drafts', ciViewPath: 'administrator/exam_drafts.php' }, + 'administrator/expense_management': { title: 'Expense Management', ciViewPath: 'administrator/expense_management.php' }, + 'administrator/fee_collection': { title: 'Fee Collection', ciViewPath: 'administrator/fee_collection.php' }, + 'administrator/fee_payment_records': { title: 'Fee Payment Records', ciViewPath: 'administrator/fee_payment_records.php' }, + 'administrator/feedback_complaints': { title: 'Feedback Complaints', ciViewPath: 'administrator/feedback_complaints.php' }, + 'administrator/grades': { title: 'Grades', ciViewPath: 'administrator/grades.php' }, + 'administrator/grading_management': { title: 'Grading Management', ciViewPath: 'administrator/grading_management.php' }, + 'administrator/health_records': { title: 'Health Records', ciViewPath: 'administrator/health_records.php' }, + 'administrator/index': { title: 'Index', ciViewPath: 'administrator/index.php' }, + 'administrator/ip_bans': { title: 'Ip Bans', ciViewPath: 'administrator/ip_bans.php' }, + 'administrator/late_slip_logs': { title: 'Late Slip Logs', ciViewPath: 'administrator/late_slip_logs.php' }, + 'administrator/manage_users': { title: 'Manage Users', ciViewPath: 'administrator/manage_users.php' }, + 'administrator/notifications_alerts': { title: 'Notifications Alerts', ciViewPath: 'administrator/notifications_alerts.php' }, + 'administrator/parent': { title: 'Parent', ciViewPath: 'administrator/parent.php' }, + 'administrator/parent_profile': { title: 'Parent Profile', ciViewPath: 'administrator/parent_profile.php' }, + 'administrator/paypal_transactions': { title: 'Paypal Transactions', ciViewPath: 'administrator/paypal_transactions.php' }, + 'administrator/payroll_management': { title: 'Payroll Management', ciViewPath: 'administrator/payroll_management.php' }, + 'administrator/performance_reviews': { title: 'Performance Reviews', ciViewPath: 'administrator/performance_reviews.php' }, + 'administrator/print_notification_admins': { title: 'Print Notification Admins', ciViewPath: 'administrator/print_notification_admins.php' }, + 'administrator/removed_students': { title: 'Removed Students', ciViewPath: 'administrator/removed_students.php' }, + 'administrator/scholarship_information': { title: 'Scholarship Information', ciViewPath: 'administrator/scholarship_information.php' }, + 'administrator/search_results': { title: 'Search Results', ciViewPath: 'administrator/search_results.php' }, + 'administrator/sections_auto_distribute': { title: 'Sections Auto Distribute', ciViewPath: 'administrator/sections_auto_distribute.php' }, + 'administrator/settings': { title: 'Settings', ciViewPath: 'administrator/settings.php' }, + 'administrator/student_class_assignment': { title: 'Student Class Assignment', ciViewPath: 'administrator/student_class_assignment.php' }, + 'administrator/student_profiles': { title: 'Student Profiles', ciViewPath: 'administrator/student_profiles.php' }, + 'administrator/subject_curriculum': { title: 'Subject Curriculum', ciViewPath: 'administrator/subject_curriculum.php' }, + 'administrator/teacher_class_assignment': { title: 'Teacher Class Assignment', ciViewPath: 'administrator/teacher_class_assignment.php' }, + 'administrator/teacher_submissions': { title: 'Teacher Submissions', ciViewPath: 'administrator/teacher_submissions.php' }, + 'administrator/teachers': { title: 'Teachers', ciViewPath: 'administrator/teachers.php' }, + 'appointment': { title: 'Appointment', ciViewPath: 'appointment.php' }, + 'attendance/admins_attendance_form': { title: 'Admins Attendance Form', ciViewPath: 'attendance/admins_attendance_form.php' }, + 'attendance/attendance_tracking': { title: 'Attendance Tracking', ciViewPath: 'attendance/attendance_tracking.php' }, + 'attendance/compose_email': { title: 'Compose Email', ciViewPath: 'attendance/compose_email.php' }, + 'attendance/early_dismissals': { title: 'Early Dismissals', ciViewPath: 'attendance/early_dismissals.php' }, + 'attendance/early_dismissals_add': { title: 'Early Dismissals Add', ciViewPath: 'attendance/early_dismissals_add.php' }, + 'attendance/edit_modal': { title: 'Edit Modal', ciViewPath: 'attendance/edit_modal.php' }, + 'attendance/parent_reports': { title: 'Parent Reports', ciViewPath: 'attendance/parent_reports.php' }, + 'attendance/teacher_attendance_form': { title: 'Teacher Attendance Form', ciViewPath: 'attendance/teacher_attendance_form.php' }, + 'attendance/teacher_attendance_month': { title: 'Teacher Attendance Month', ciViewPath: 'attendance/teacher_attendance_month.php' }, + 'attendance/view': { title: 'View', ciViewPath: 'attendance/view.php' }, + 'attendance/violations_notified': { title: 'Violations Notified', ciViewPath: 'attendance/violations_notified.php' }, + 'attendance/violations_pending': { title: 'Violations Pending', ciViewPath: 'attendance/violations_pending.php' }, + 'attendance_templates/index': { title: 'Index', ciViewPath: 'attendance_templates/index.php' }, + 'auth/select_role': { title: 'Select Role', ciViewPath: 'auth/select_role.php' }, + 'calendar': { title: 'Calendar', ciViewPath: 'calendar.php' }, + 'call_to_action': { title: 'Call To Action', ciViewPath: 'call_to_action.php' }, + 'class_prep/list': { title: 'List', ciViewPath: 'class_prep/list.php' }, + 'class_prep/print': { title: 'Print', ciViewPath: 'class_prep/print.php' }, + 'classes': { title: 'Classes', ciViewPath: 'classes.php' }, + 'communications/index': { title: 'Index', ciViewPath: 'communications/index.php' }, + 'configuration/configuration_view': { title: 'Configuration View', ciViewPath: 'configuration/configuration_view.php' }, + 'contact': { title: 'Contact', ciViewPath: 'contact.php' }, + 'contact_process': { title: 'Contact Process', ciViewPath: 'contact_process.php' }, + 'discounts/apply_voucher': { title: 'Apply Voucher', ciViewPath: 'discounts/apply_voucher.php' }, + 'discounts/create': { title: 'Create', ciViewPath: 'discounts/create.php' }, + 'discounts/list': { title: 'List', ciViewPath: 'discounts/list.php' }, + 'emails/_wrap_layout': { title: ' Wrap Layout', ciViewPath: 'emails/_wrap_layout.php' }, + 'emails/admin_student_registered': { title: 'Admin Student Registered', ciViewPath: 'emails/admin_student_registered.php' }, + 'emails/below_sixty_performance': { title: 'Below Sixty Performance', ciViewPath: 'emails/below_sixty_performance.php' }, + 'emails/broadcast_wrapper': { title: 'Broadcast Wrapper', ciViewPath: 'emails/broadcast_wrapper.php' }, + 'emails/calendar_notification': { title: 'Calendar Notification', ciViewPath: 'emails/calendar_notification.php' }, + 'emails/custom_html': { title: 'Custom Html', ciViewPath: 'emails/custom_html.php' }, + 'emails/dismissal': { title: 'Dismissal', ciViewPath: 'emails/dismissal.php' }, + 'emails/event_broadcast': { title: 'Event Broadcast', ciViewPath: 'emails/event_broadcast.php' }, + 'emails/extra_charge_notice': { title: 'Extra Charge Notice', ciViewPath: 'emails/extra_charge_notice.php' }, + 'emails/final_warning': { title: 'Final Warning', ciViewPath: 'emails/final_warning.php' }, + 'emails/follow_up': { title: 'Follow Up', ciViewPath: 'emails/follow_up.php' }, + 'emails/parent_attendance_admin': { title: 'Parent Attendance Admin', ciViewPath: 'emails/parent_attendance_admin.php' }, + 'emails/parent_attendance_parent': { title: 'Parent Attendance Parent', ciViewPath: 'emails/parent_attendance_parent.php' }, + 'emails/parent_email_extractor': { title: 'Parent Email Extractor', ciViewPath: 'emails/parent_email_extractor.php' }, + 'emails/payment_receipt': { title: 'Payment Receipt', ciViewPath: 'emails/payment_receipt.php' }, + 'emails/reset_password': { title: 'Reset Password', ciViewPath: 'emails/reset_password.php' }, + 'emails/status_admission_review': { title: 'Status Admission Review', ciViewPath: 'emails/status_admission_review.php' }, + 'emails/status_denied': { title: 'Status Denied', ciViewPath: 'emails/status_denied.php' }, + 'emails/status_enrolled': { title: 'Status Enrolled', ciViewPath: 'emails/status_enrolled.php' }, + 'emails/status_not_enrolled': { title: 'Status Not Enrolled', ciViewPath: 'emails/status_not_enrolled.php' }, + 'emails/status_payment_pending': { title: 'Status Payment Pending', ciViewPath: 'emails/status_payment_pending.php' }, + 'emails/status_refund_pending': { title: 'Status Refund Pending', ciViewPath: 'emails/status_refund_pending.php' }, + 'emails/status_waitlist': { title: 'Status Waitlist', ciViewPath: 'emails/status_waitlist.php' }, + 'emails/status_withdraw_review': { title: 'Status Withdraw Review', ciViewPath: 'emails/status_withdraw_review.php' }, + 'emails/status_withdrawn': { title: 'Status Withdrawn', ciViewPath: 'emails/status_withdrawn.php' }, + 'emails/student_removed': { title: 'Student Removed', ciViewPath: 'emails/student_removed.php' }, + 'emails/support_new_account': { title: 'Support New Account', ciViewPath: 'emails/support_new_account.php' }, + 'emails/welcome_parent': { title: 'Welcome Parent', ciViewPath: 'emails/welcome_parent.php' }, + 'emails/welcome_staff': { title: 'Welcome Staff', ciViewPath: 'emails/welcome_staff.php' }, + 'emails/welcome_user': { title: 'Welcome User', ciViewPath: 'emails/welcome_user.php' }, + 'emails/whatsapp_group_invitation': { title: 'Whatsapp Group Invitation', ciViewPath: 'emails/whatsapp_group_invitation.php' }, + 'emails/whatsapp_invite': { title: 'Whatsapp Invite', ciViewPath: 'emails/whatsapp_invite.php' }, + 'enroll_withdraw/enrollment_withdrawal': { title: 'Enrollment Withdrawal', ciViewPath: 'enroll_withdraw/enrollment_withdrawal.php' }, + 'enroll_withdraw/new-students': { title: 'New-Students', ciViewPath: 'enroll_withdraw/new-students.php' }, + 'expenses/create': { title: 'Create', ciViewPath: 'expenses/create.php' }, + 'expenses/edit': { title: 'Edit', ciViewPath: 'expenses/edit.php' }, + 'expenses/index': { title: 'Index', ciViewPath: 'expenses/index.php' }, + 'facility': { title: 'Facility', ciViewPath: 'facility.php' }, + 'family/card': { title: 'Card', ciViewPath: 'family/card.php' }, + 'family/compose_email': { title: 'Compose Email', ciViewPath: 'family/compose_email.php' }, + 'family/index': { title: 'Index', ciViewPath: 'family/index.php' }, + 'flags/flags_management': { title: 'Flags Management', ciViewPath: 'flags/flags_management.php' }, + 'flags/incident_analysis': { title: 'Incident Analysis', ciViewPath: 'flags/incident_analysis.php' }, + 'flags/processed_flags': { title: 'Processed Flags', ciViewPath: 'flags/processed_flags.php' }, + 'footer': { title: 'Footer', ciViewPath: 'footer.php' }, + 'grading/below_sixty': { title: 'Below Sixty', ciViewPath: 'grading/below_sixty.php' }, + 'grading/below_sixty_email_editor': { title: 'Below Sixty Email Editor', ciViewPath: 'grading/below_sixty_email_editor.php' }, + 'grading/comments': { title: 'Comments', ciViewPath: 'grading/comments.php' }, + 'grading/final': { title: 'Final', ciViewPath: 'grading/final.php' }, + 'grading/grading_main': { title: 'Grading Main', ciViewPath: 'grading/grading_main.php' }, + 'grading/homework': { title: 'Homework', ciViewPath: 'grading/homework.php' }, + 'grading/homework_tracking': { title: 'Homework Tracking', ciViewPath: 'grading/homework_tracking.php' }, + 'grading/midterm': { title: 'Midterm', ciViewPath: 'grading/midterm.php' }, + 'grading/participation': { title: 'Participation', ciViewPath: 'grading/participation.php' }, + 'grading/placement': { title: 'Placement', ciViewPath: 'grading/placement.php' }, + 'grading/placement_batch': { title: 'Placement Batch', ciViewPath: 'grading/placement_batch.php' }, + 'grading/placement_index': { title: 'Placement Index', ciViewPath: 'grading/placement_index.php' }, + 'grading/project': { title: 'Project', ciViewPath: 'grading/project.php' }, + 'grading/quiz': { title: 'Quiz', ciViewPath: 'grading/quiz.php' }, + 'grading/schedule_meeting': { title: 'Schedule Meeting', ciViewPath: 'grading/schedule_meeting.php' }, + 'grading/test': { title: 'Test', ciViewPath: 'grading/test.php' }, + 'header': { title: 'Header', ciViewPath: 'header.php' }, + 'home': { title: 'Home', ciViewPath: 'home.php' }, + 'index': { title: 'Index', ciViewPath: 'index.php' }, + 'inventory/adjust_form': { title: 'Adjust Form', ciViewPath: 'inventory/adjust_form.php' }, + 'inventory/book/form': { title: 'Form', ciViewPath: 'inventory/book/form.php' }, + 'inventory/book/index': { title: 'Index', ciViewPath: 'inventory/book/index.php' }, + 'inventory/classroom/audit_form': { title: 'Audit Form', ciViewPath: 'inventory/classroom/audit_form.php' }, + 'inventory/classroom/form': { title: 'Form', ciViewPath: 'inventory/classroom/form.php' }, + 'inventory/classroom/index': { title: 'Index', ciViewPath: 'inventory/classroom/index.php' }, + 'inventory/kitchen/form': { title: 'Form', ciViewPath: 'inventory/kitchen/form.php' }, + 'inventory/kitchen/index': { title: 'Index', ciViewPath: 'inventory/kitchen/index.php' }, + 'inventory/movements/edit': { title: 'Edit', ciViewPath: 'inventory/movements/edit.php' }, + 'inventory/movements/form': { title: 'Form', ciViewPath: 'inventory/movements/form.php' }, + 'inventory/movements/index': { title: 'Index', ciViewPath: 'inventory/movements/index.php' }, + 'inventory/office/form': { title: 'Form', ciViewPath: 'inventory/office/form.php' }, + 'inventory/office/index': { title: 'Index', ciViewPath: 'inventory/office/index.php' }, + 'inventory/summary': { title: 'Summary', ciViewPath: 'inventory/summary.php' }, + 'inventory/teacher_distribute': { title: 'Teacher Distribute', ciViewPath: 'inventory/teacher_distribute.php' }, + 'invoice_payment/invoice_management': { title: 'Invoice Management', ciViewPath: 'invoice_payment/invoice_management.php' }, + 'invoice_payment/pdf_template': { title: 'Pdf Template', ciViewPath: 'invoice_payment/pdf_template.php' }, + 'landing_page/admin_dashboard': { title: 'Admin Dashboard', ciViewPath: 'landing_page/admin_dashboard.php' }, + 'landing_page/guest_dashboard': { title: 'Guest Dashboard', ciViewPath: 'landing_page/guest_dashboard.php' }, + 'landing_page/parent_dashboard': { title: 'Parent Dashboard', ciViewPath: 'landing_page/parent_dashboard.php' }, + 'landing_page/student_dashboard': { title: 'Student Dashboard', ciViewPath: 'landing_page/student_dashboard.php' }, + 'landing_page/teacher_dashboard': { title: 'Teacher Dashboard', ciViewPath: 'landing_page/teacher_dashboard.php' }, + 'nav_builder/edit': { title: 'Edit', ciViewPath: 'nav_builder/edit.php' }, + 'nav_builder/index': { title: 'Index', ciViewPath: 'nav_builder/index.php' }, + 'navbar': { title: 'Navbar', ciViewPath: 'navbar.php' }, + 'notifications/list_active': { title: 'List Active', ciViewPath: 'notifications/list_active.php' }, + 'notifications/list_deleted': { title: 'List Deleted', ciViewPath: 'notifications/list_deleted.php' }, + 'parent/add_second_parent': { title: 'Add Second Parent', ciViewPath: 'parent/add_second_parent.php' }, + 'parent/assignments': { title: 'Assignments', ciViewPath: 'parent/assignments.php' }, + 'parent/attendance': { title: 'Attendance', ciViewPath: 'parent/attendance.php' }, + 'parent/calendar': { title: 'Calendar', ciViewPath: 'parent/calendar.php' }, + 'parent/class_progress_list': { title: 'Class Progress List', ciViewPath: 'parent/class_progress_list.php' }, + 'parent/class_progress_view': { title: 'Class Progress View', ciViewPath: 'parent/class_progress_view.php' }, + 'parent/classes': { title: 'Classes', ciViewPath: 'parent/classes.php' }, + 'parent/contact': { title: 'Contact', ciViewPath: 'parent/contact.php' }, + 'parent/edit_emergency_contact': { title: 'Edit Emergency Contact', ciViewPath: 'parent/edit_emergency_contact.php' }, + 'parent/edit_student_modal': { title: 'Edit Student Modal', ciViewPath: 'parent/edit_student_modal.php' }, + 'parent/enroll_classes': { title: 'Enroll Classes', ciViewPath: 'parent/enroll_classes.php' }, + 'parent/enroll_failure': { title: 'Enroll Failure', ciViewPath: 'parent/enroll_failure.php' }, + 'parent/enroll_success': { title: 'Enroll Success', ciViewPath: 'parent/enroll_success.php' }, + 'parent/event_participation': { title: 'Event Participation', ciViewPath: 'parent/event_participation.php' }, + 'parent/invoice_payment': { title: 'Invoice Payment', ciViewPath: 'parent/invoice_payment.php' }, + 'parent/no_kids_registred': { title: 'No Kids Registred', ciViewPath: 'parent/no_kids_registred.php' }, + 'parent/parent_message': { title: 'Parent Message', ciViewPath: 'parent/parent_message.php' }, + 'parent/payment_success': { title: 'Payment Success', ciViewPath: 'parent/payment_success.php' }, + 'parent/payment_view': { title: 'Payment View', ciViewPath: 'parent/payment_view.php' }, + 'parent/register_student': { title: 'Register Student', ciViewPath: 'parent/register_student.php' }, + 'parent/report_attendance': { title: 'Report Attendance', ciViewPath: 'parent/report_attendance.php' }, + 'parent/report_cards': { title: 'Report Cards', ciViewPath: 'parent/report_cards.php' }, + 'parent/scores': { title: 'Scores', ciViewPath: 'parent/scores.php' }, + 'parent/success_message': { title: 'Success Message', ciViewPath: 'parent/success_message.php' }, + 'parent/withdraw_success': { title: 'Withdraw Success', ciViewPath: 'parent/withdraw_success.php' }, + 'payment/_list_modal': { title: ' List Modal', ciViewPath: 'payment/_list_modal.php' }, + 'payment/discount': { title: 'Discount', ciViewPath: 'payment/discount.php' }, + 'payment/extra_charges': { title: 'Extra Charges', ciViewPath: 'payment/extra_charges.php' }, + 'payment/financial_report': { title: 'Financial Report', ciViewPath: 'payment/financial_report.php' }, + 'payment/financial_report_summary': { title: 'Financial Report Summary', ciViewPath: 'payment/financial_report_summary.php' }, + 'payment/manual_pay': { title: 'Manual Pay', ciViewPath: 'payment/manual_pay.php' }, + 'payment/manual_payment': { title: 'Manual Payment', ciViewPath: 'payment/manual_payment.php' }, + 'payment/notification_management': { title: 'Notification Management', ciViewPath: 'payment/notification_management.php' }, + 'payment/payment_redirect': { title: 'Payment Redirect', ciViewPath: 'payment/payment_redirect.php' }, + 'payment/unpaid_parents': { title: 'Unpaid Parents', ciViewPath: 'payment/unpaid_parents.php' }, + 'payment_list': { title: 'Payment List', ciViewPath: 'payment_list.php' }, + 'policy/picture_policy': { title: 'Picture Policy', ciViewPath: 'policy/picture_policy.php' }, + 'policy/picture_policy_partial': { title: 'Picture Policy Partial', ciViewPath: 'policy/picture_policy_partial.php' }, + 'policy/school_policy': { title: 'School Policy', ciViewPath: 'policy/school_policy.php' }, + 'policy/school_policy_partial': { title: 'School Policy Partial', ciViewPath: 'policy/school_policy_partial.php' }, + 'preferences': { title: 'Preferences', ciViewPath: 'preferences.php' }, + 'print_requests/admin_index': { title: 'Admin Index', ciViewPath: 'print_requests/admin_index.php' }, + 'print_requests/teacher_index': { title: 'Teacher Index', ciViewPath: 'print_requests/teacher_index.php' }, + 'printables_reports/badge_form': { title: 'Badge Form', ciViewPath: 'printables_reports/badge_form.php' }, + 'printables_reports/report_card': { title: 'Report Card', ciViewPath: 'printables_reports/report_card.php' }, + 'printables_reports/sticker_form': { title: 'Sticker Form', ciViewPath: 'printables_reports/sticker_form.php' }, + 'profile': { title: 'Profile', ciViewPath: 'profile.php' }, + 'refunds/list': { title: 'List', ciViewPath: 'refunds/list.php' }, + 'reimbursements/create': { title: 'Create', ciViewPath: 'reimbursements/create.php' }, + 'reimbursements/edit': { title: 'Edit', ciViewPath: 'reimbursements/edit.php' }, + 'reimbursements/index': { title: 'Index', ciViewPath: 'reimbursements/index.php' }, + 'reimbursements/under_processing': { title: 'Under Processing', ciViewPath: 'reimbursements/under_processing.php' }, + 'rfid/rfid_coming_soon': { title: 'Rfid Coming Soon', ciViewPath: 'rfid/rfid_coming_soon.php' }, + 'rfid/rfid_log_view': { title: 'Rfid Log View', ciViewPath: 'rfid/rfid_log_view.php' }, + 'rolepermission/add_permission': { title: 'Add Permission', ciViewPath: 'rolepermission/add_permission.php' }, + 'rolepermission/add_role': { title: 'Add Role', ciViewPath: 'rolepermission/add_role.php' }, + 'rolepermission/assign_role': { title: 'Assign Role', ciViewPath: 'rolepermission/assign_role.php' }, + 'rolepermission/edit_permission': { title: 'Edit Permission', ciViewPath: 'rolepermission/edit_permission.php' }, + 'rolepermission/edit_role': { title: 'Edit Role', ciViewPath: 'rolepermission/edit_role.php' }, + 'rolepermission/edit_role_permissions': { title: 'Edit Role Permissions', ciViewPath: 'rolepermission/edit_role_permissions.php' }, + 'rolepermission/list_roles': { title: 'List Roles', ciViewPath: 'rolepermission/list_roles.php' }, + 'rolepermission/permissionList': { title: 'PermissionList', ciViewPath: 'rolepermission/permissionList.php' }, + 'score_analysis/score_prediction': { title: 'Score Prediction', ciViewPath: 'score_analysis/score_prediction.php' }, + 'slips/preview_list': { title: 'Preview List', ciViewPath: 'slips/preview_list.php' }, + 'slips/slip_pdf': { title: 'Slip Pdf', ciViewPath: 'slips/slip_pdf.php' }, + 'spinner': { title: 'Spinner', ciViewPath: 'spinner.php' }, + 'staff/create': { title: 'Create', ciViewPath: 'staff/create.php' }, + 'staff/edit': { title: 'Edit', ciViewPath: 'staff/edit.php' }, + 'staff/index': { title: 'Index', ciViewPath: 'staff/index.php' }, + 'student/score_card': { title: 'Score Card', ciViewPath: 'student/score_card.php' }, + 'student/score_card_list': { title: 'Score Card List', ciViewPath: 'student/score_card_list.php' }, + 'success': { title: 'Success', ciViewPath: 'success.php' }, + 'support': { title: 'Support', ciViewPath: 'support.php' }, + 'support_requests': { title: 'Support Requests', ciViewPath: 'support_requests.php' }, + 'swagger_ui': { title: 'Swagger Ui', ciViewPath: 'swagger_ui.php' }, + 'teacher/absence_vacation': { title: 'Absence Vacation', ciViewPath: 'teacher/absence_vacation.php' }, + 'teacher/add_final_exam': { title: 'Add Final Exam', ciViewPath: 'teacher/add_final_exam.php' }, + 'teacher/add_homework': { title: 'Add Homework', ciViewPath: 'teacher/add_homework.php' }, + 'teacher/add_midterm_exam': { title: 'Add Midterm Exam', ciViewPath: 'teacher/add_midterm_exam.php' }, + 'teacher/add_participation': { title: 'Add Participation', ciViewPath: 'teacher/add_participation.php' }, + 'teacher/add_project': { title: 'Add Project', ciViewPath: 'teacher/add_project.php' }, + 'teacher/add_quiz': { title: 'Add Quiz', ciViewPath: 'teacher/add_quiz.php' }, + 'teacher/add_quiz_column_form': { title: 'Add Quiz Column Form', ciViewPath: 'teacher/add_quiz_column_form.php' }, + 'teacher/calendar': { title: 'Calendar', ciViewPath: 'teacher/calendar.php' }, + 'teacher/class_progress_history': { title: 'Class Progress History', ciViewPath: 'teacher/class_progress_history.php' }, + 'teacher/class_progress_submit': { title: 'Class Progress Submit', ciViewPath: 'teacher/class_progress_submit.php' }, + 'teacher/class_progress_view': { title: 'Class Progress View', ciViewPath: 'teacher/class_progress_view.php' }, + 'teacher/class_view': { title: 'Class View', ciViewPath: 'teacher/class_view.php' }, + 'teacher/competition_scores/index': { title: 'Index', ciViewPath: 'teacher/competition_scores/index.php' }, + 'teacher/competition_scores/scores': { title: 'Scores', ciViewPath: 'teacher/competition_scores/scores.php' }, + 'teacher/drafts': { title: 'Drafts', ciViewPath: 'teacher/drafts.php' }, + 'teacher/exam_drafts': { title: 'Exam Drafts', ciViewPath: 'teacher/exam_drafts.php' }, + 'teacher/homework_list': { title: 'Homework List', ciViewPath: 'teacher/homework_list.php' }, + 'teacher/inbox': { title: 'Inbox', ciViewPath: 'teacher/inbox.php' }, + 'teacher/no_classes': { title: 'No Classes', ciViewPath: 'teacher/no_classes.php' }, + 'teacher/scores': { title: 'Scores', ciViewPath: 'teacher/scores.php' }, + 'teacher/select_semester': { title: 'Select Semester', ciViewPath: 'teacher/select_semester.php' }, + 'teacher/sent': { title: 'Sent', ciViewPath: 'teacher/sent.php' }, + 'teacher/showupdate_attendance': { title: 'Showupdate Attendance', ciViewPath: 'teacher/showupdate_attendance.php' }, + 'teacher/teacher_assignment': { title: 'Teacher Assignment', ciViewPath: 'teacher/teacher_assignment.php' }, + 'teacher/teacher_contactus': { title: 'Teacher Contactus', ciViewPath: 'teacher/teacher_contactus.php' }, + 'teacher/teacher_message': { title: 'Teacher Message', ciViewPath: 'teacher/teacher_message.php' }, + 'teacher/teacher_navbar': { title: 'Teacher Navbar', ciViewPath: 'teacher/teacher_navbar.php' }, + 'teacher/teacher_support': { title: 'Teacher Support', ciViewPath: 'teacher/teacher_support.php' }, + 'teacher/trash': { title: 'Trash', ciViewPath: 'teacher/trash.php' }, + 'team': { title: 'Team', ciViewPath: 'team.php' }, + 'testimonial': { title: 'Testimonial', ciViewPath: 'testimonial.php' }, + 'user/create': { title: 'Create', ciViewPath: 'user/create.php' }, + 'user/edit': { title: 'Edit', ciViewPath: 'user/edit.php' }, + 'user/forgot_password': { title: 'Forgot Password', ciViewPath: 'user/forgot_password.php' }, + 'user/login': { title: 'Login', ciViewPath: 'user/login.php' }, + 'user/login_activity': { title: 'Login Activity', ciViewPath: 'user/login_activity.php' }, + 'user/password_reset_confirmation': { title: 'Password Reset Confirmation', ciViewPath: 'user/password_reset_confirmation.php' }, + 'user/password_set_success': { title: 'Password Set Success', ciViewPath: 'user/password_set_success.php' }, + 'user/register': { title: 'Register', ciViewPath: 'user/register.php' }, + 'user/reset_password': { title: 'Reset Password', ciViewPath: 'user/reset_password.php' }, + 'user/set_authorized_user_password': { title: 'Set Authorized User Password', ciViewPath: 'user/set_authorized_user_password.php' }, + 'user/set_password': { title: 'Set Password', ciViewPath: 'user/set_password.php' }, + 'user/user_list': { title: 'User List', ciViewPath: 'user/user_list.php' }, + 'user/welcome_back': { title: 'Welcome Back', ciViewPath: 'user/welcome_back.php' }, + 'welcome_message': { title: 'Welcome Message', ciViewPath: 'welcome_message.php' }, + 'whatsapp/manage_links': { title: 'Manage Links', ciViewPath: 'whatsapp/manage_links.php' }, + 'whatsapp/parent_contacts': { title: 'Parent Contacts', ciViewPath: 'whatsapp/parent_contacts.php' }, + 'whatsapp/parent_contacts_by_class': { title: 'Parent Contacts By Class', ciViewPath: 'whatsapp/parent_contacts_by_class.php' }, + 'winners/competitions/index': { title: 'Index', ciViewPath: 'winners/competitions/index.php' }, + 'winners/competitions/show': { title: 'Show', ciViewPath: 'winners/competitions/show.php' }, +} diff --git a/src/lib/ciSpaPaths.ts b/src/lib/ciSpaPaths.ts new file mode 100644 index 0000000..16951f7 --- /dev/null +++ b/src/lib/ciSpaPaths.ts @@ -0,0 +1,65 @@ +/** Map legacy CodeIgniter-style paths (as stored on roles / nav items) to this SPA. */ + +export function spaPathFromCiUrl(url: string | null | undefined): string | null { + if (url == null) return null + const u = url.trim() + if (u === '' || u === '#') return '/app/home' + if (/^https?:\/\//i.test(u)) return null + + const path = u.replace(/^\/+/, '').replace(/\/+$/, '') + if (!path) return '/app/home' + + const slug = path + .split('/') + .map((s) => s.trim()) + .filter(Boolean) + .map((s) => s.toLowerCase()) + .join('/') + + const shortcuts: Record = { + 'landing_page/guest_dashboard': '/app/home', + 'teacher/dashboard': '/app/teacher/dashboard', + 'administrator/dashboard': '/app/administrator/dashboard', + 'administrator/administratordashboard': '/app/admin/dashboard', + 'parent/parent_dashboard': '/app/parent/home', + parent_dashboard: '/app/parent/home', + 'parent/attendance-reports': '/app/parent/attendance-reports', + 'parent/authorized-users': '/app/parent/authorized-users', + 'parent/update-profile': '/app/parent/update-profile', + 'parent/add_second_parent': '/app/parent/add-second-parent', + 'parent/add-second-parent': '/app/parent/add-second-parent', + 'parent/enroll_classes': '/app/parent/enroll-classes', + 'parent/enroll-classes': '/app/parent/enroll-classes', + 'parent/enroll_success': '/app/parent/enroll/success', + 'parent/enroll_failure': '/app/parent/enroll/failure', + 'parent/payment': '/app/parent/payment', + 'parent/invoice_payment': '/app/parent/invoice-payment', + 'parent/invoice-payment': '/app/parent/invoice-payment', + 'parent/calendar': '/app/parent/calendar', + 'parent/attendance': '/app/parent/attendance', + 'parent/report-attendance': '/app/parent/report-attendance', + 'parent/report_cards': '/app/parent/report-cards', + 'parent/report-cards': '/app/parent/report-cards', + 'parent/progress': '/app/parent/progress', + 'parent/events': '/app/parent/events', + 'parent/contact': '/app/parent/contact', + 'parent/register_student': '/app/parent/register-student', + 'parent/register-student': '/app/parent/register-student', + 'parent/scores': '/app/parent/scores', + 'parent/assignments': '/app/parent/assignments', + 'parent/classes': '/app/parent/classes', + 'parent/viewsecondparent': '/app/parent/add-second-parent', + 'parent/child_register': '/app/parent/register-student', + 'parent/edit-emergency-contact': '/app/parent/edit-emergency-contact', + 'parent/emergency-contacts': '/app/parent/emergency-contacts', + 'parent/edit_all_students': '/app/parent/edit-all-students', + 'parent/edit-all-students': '/app/parent/edit-all-students', + } + + return shortcuts[slug] ?? `/app/${slug}` +} + +export function isExternalNavUrl(url: string | null | undefined): boolean { + if (!url) return false + return /^https?:\/\//i.test(url.trim()) +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..e6a0192 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,11 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import './styles/ci-registration.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/src/pages/AdminDocs.tsx b/src/pages/AdminDocs.tsx new file mode 100644 index 0000000..1050fea --- /dev/null +++ b/src/pages/AdminDocs.tsx @@ -0,0 +1,68 @@ +import { useCallback, useEffect, useState } from 'react' +import { Link } from 'react-router-dom' +import { SwaggerDocs } from './SwaggerDocs' + +const STORAGE_KEY = 'alrahma_docs_jwt' + +export function AdminDocs() { + const [token, setToken] = useState('') + const [saved, setSaved] = useState(null) + + useEffect(() => { + try { + const t = localStorage.getItem(STORAGE_KEY) + if (t) { + setSaved(t) + } + } catch { + /* ignore */ + } + }, []) + + const authHeader = saved ? `Bearer ${saved}` : null + + const saveToken = useCallback(() => { + const t = token.trim() + if (!t) { + localStorage.removeItem(STORAGE_KEY) + setSaved(null) + return + } + localStorage.setItem(STORAGE_KEY, t) + setSaved(t) + }, [token]) + + return ( +
    +
    + Public docs + + + {saved ? ( + + ) : null} +
    + +
    + ) +} diff --git a/src/pages/AppHome.tsx b/src/pages/AppHome.tsx new file mode 100644 index 0000000..1de8900 --- /dev/null +++ b/src/pages/AppHome.tsx @@ -0,0 +1,105 @@ +import { useEffect, useState } from 'react' +import { Link } from 'react-router-dom' +import { fetchDashboardRoute } from '../api/session' +import { useAuth } from '../auth/AuthProvider' + +export function AppHome() { + const { user } = useAuth() + const [route, setRoute] = useState(null) + const [roles, setRoles] = useState([]) + const [error, setError] = useState(null) + + useEffect(() => { + let cancelled = false + ;(async () => { + try { + const res = await fetchDashboardRoute() + const d = res.data?.dashboard + if (!cancelled && d) { + setRoute(d.route) + setRoles(d.roles ?? []) + setError(null) + } + } catch (e) { + if (!cancelled) { + setError(e instanceof Error ? e.message : 'Unable to load dashboard.') + } + } + })() + return () => { + cancelled = true + } + }, []) + + const roleKeys = user?.roles ? Object.keys(user.roles).filter((k) => user.roles[k]) : [] + + return ( +
    +

    Welcome

    +

    + Signed in as {user?.name}. +

    + +
    +
    +
    +
    +

    Roles (from login)

    +
      + {roleKeys.length ? ( + roleKeys.map((r) =>
    • {r}
    • ) + ) : ( +
    • None reported
    • + )} +
    +
    +
    +
    +
    +
    +
    +

    Dashboard route (API)

    + {error ? ( +

    {error}

    + ) : ( + <> +

    + {route ?? '—'} +

    +

    + Resolved roles: {roles.length ? roles.join(', ') : '—'} +

    + + )} +
    +
    +
    +
    + +
    +

    Shortcuts

    +
      +
    • + Parent — Dashboard (parity with + CodeIgniter parent/parent_dashboard) +
    • +
    • + Parent — Attendance (parity + with CodeIgniter Views/parent/attendance.php) +
    • +
    • + Parent — All pages (navigation for + every view under Views/parent/) +
    • +
    • + Public API docs (Swagger) +
    • +
    • + All CodeIgniter views (sitemap) — open any{' '} + app/Views screen as an /app/… parity route +
    • +
    +
    +
    + ) +} diff --git a/src/pages/CiPlaceholderPage.tsx b/src/pages/CiPlaceholderPage.tsx new file mode 100644 index 0000000..526729c --- /dev/null +++ b/src/pages/CiPlaceholderPage.tsx @@ -0,0 +1,54 @@ +import { Link, useParams } from 'react-router-dom' +import { getCiMeta } from '../lib/ciRouteLookup' + +/** Fallback for CI-style paths not yet ported to dedicated React pages. */ +export function CiPlaceholderPage() { + const params = useParams() + const star = params['*'] ?? '' + const segments = star.split('/').filter(Boolean) + const meta = getCiMeta(star) + + const title = meta?.title ?? 'Section placeholder' + const viewsPath = meta?.ciViewPath ?? (star ? `…/${star}` : '…') + + return ( +
    + + +

    {title}

    +

    + CodeIgniter view:{' '} + + app/Views/{viewsPath} + +

    +

    + Implement this screen using the matching routes in app_laravel/routes/api.php{' '} + (JWT Authorization: Bearer). See also API docs. +

    +

    + SPA path: /app/{star || '…'} +

    +

    + Browse all CI view routes + {' · '} + App home +

    +
    + ) +} diff --git a/src/pages/CiSitemapPage.tsx b/src/pages/CiSitemapPage.tsx new file mode 100644 index 0000000..aba816b --- /dev/null +++ b/src/pages/CiSitemapPage.tsx @@ -0,0 +1,61 @@ +import { useMemo } from 'react' +import { Link } from 'react-router-dom' +import { ciRouteMeta } from '../lib/ciRouteMeta.generated' +import { ciRegistryKeyToAppPath } from '../lib/ciRouteLookup' + +/** Browse every CodeIgniter view file mapped under `/app/…` (parity placeholders unless a dedicated route exists). */ +export function CiSitemapPage() { + const grouped = useMemo(() => { + const g = new Map() + for (const key of Object.keys(ciRouteMeta).sort()) { + const top = key.includes('/') ? key.slice(0, key.indexOf('/')) : key + const title = ciRouteMeta[key]?.title ?? key + const list = g.get(top) ?? [] + list.push({ key, title }) + g.set(top, list) + } + return [...g.entries()].sort(([a], [b]) => a.localeCompare(b)) + }, []) + + return ( +
    + + +

    CodeIgniter views → SPA routes

    +

    + Generated from app_codeigniter/app/Views/**/*.php. Each link opens the parity + route under /app/…; unimplemented screens use the section placeholder with the + matching view path. Regenerate: npm run gen:ci-meta. +

    + +
    + {grouped.map(([section, items]) => ( +
    +
    +
    {section}
    +
      + {items.map(({ key, title }) => ( +
    • + {title} +
      + {key.replace(/\//g, ' / ')} +
      +
    • + ))} +
    +
    +
    + ))} +
    +
    + ) +} diff --git a/src/pages/ForgotPasswordPage.tsx b/src/pages/ForgotPasswordPage.tsx new file mode 100644 index 0000000..b9c7363 --- /dev/null +++ b/src/pages/ForgotPasswordPage.tsx @@ -0,0 +1,44 @@ +import { Link } from 'react-router-dom' + +/** Mirrors CodeIgniter `Views/user/forgot_password.php` shell; reset flow remains on the Laravel site. */ +export function ForgotPasswordPage() { + return ( +
    +
    +
    + + { + ;(ev.target as HTMLImageElement).style.display = 'none' + }} + /> + +
    + +

    + Reset Your Password +

    + +
    +

    Password reset requests are handled through the school's main website.

    +

    + If this SPA is only the API client, open the legacy site or contact the office for a + reset link. +

    +
    + +
    + + Back to Sign in + + + Register now + +
    +
    +
    + ) +} diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx new file mode 100644 index 0000000..444354c --- /dev/null +++ b/src/pages/HomePage.tsx @@ -0,0 +1,78 @@ +import { Link } from 'react-router-dom' +import { useAuth } from '../auth/AuthProvider' + +/** Public landing — structure inspired by CodeIgniter `Views/landing_page/guest_dashboard.php` hero. */ +export function HomePage() { + const { isAuthenticated } = useAuth() + + return ( +
    +
    +
    +

    + Welcome to Al Rahma Sunday School +

    +

    + {isAuthenticated ? 'Welcome back' : 'Welcome, Guest!'} +

    +

    + Use the portal to manage enrollment, attendance, grades, and family information — the + same workflows as the CodeIgniter site, backed by the Laravel API. +

    +
    + {isAuthenticated ? ( + + Go to dashboard + + ) : ( + <> + + Sign in + + + Registration Form + + + )} + + API documentation + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    + + Families +

    +

    + Parents sign in after registration is activated by email. +

    +
    +
    +
    +
    +
    +
    +

    + + Secure portal +

    +

    + Sessions use JWT from the Laravel API (/api/v1/auth/login). +

    +
    +
    +
    +
    +
    +
    +
    + ) +} diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx new file mode 100644 index 0000000..b93e327 --- /dev/null +++ b/src/pages/LoginPage.tsx @@ -0,0 +1,146 @@ +import { useState, type FormEvent } from 'react' +import { Link, useLocation, useNavigate } from 'react-router-dom' +import { fetchDashboardRoute } from '../api/session' +import { useAuth } from '../auth/AuthProvider' +import { spaPathFromCiUrl } from '../lib/ciSpaPaths' + +/** Matches CodeIgniter `Views/user/login.php` (JWT via `/api/v1/auth/login`). */ +export function LoginPage() { + const { login } = useAuth() + const navigate = useNavigate() + const location = useLocation() + const locState = location.state as { from?: string; registered?: boolean; message?: string } | null + + const from = locState?.from ?? '/app/home' + const flashSuccess = + locState?.registered === true ? locState?.message ?? 'Registration submitted.' : null + + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [showPassword, setShowPassword] = useState(false) + const [error, setError] = useState(null) + const [busy, setBusy] = useState(false) + + async function onSubmit(e: FormEvent) { + e.preventDefault() + setError(null) + setBusy(true) + try { + const result = await login(email, password) + if (result.ok === false) { + setError(result.message) + return + } + + let target = from.startsWith('/app') ? from : '/app/home' + try { + const dash = await fetchDashboardRoute() + const route = dash.data?.dashboard?.route + const mapped = spaPathFromCiUrl(route) + if (mapped) target = mapped + } catch { + /* keep default */ + } + + navigate(target, { replace: true }) + } finally { + setBusy(false) + } + } + + return ( +
    +
    +
    +
    + + { + ;(ev.target as HTMLImageElement).style.display = 'none' + }} + /> + +
    + +

    + Login to Your Account +

    + + {flashSuccess ? ( +
    + {flashSuccess} +
    + ) : null} + +
    + + setEmail(e.target.value)} + /> +
    + +
    + + setPassword(e.target.value)} + /> + +
    + + {error ? ( +
    + {error} +
    + ) : null} + +
    + +
    + +
    + Forgot Password? +
    + +

    + Need an account? Register now +

    + +
    +
    + ) +} diff --git a/src/pages/RegisterPage.tsx b/src/pages/RegisterPage.tsx new file mode 100644 index 0000000..652e18e --- /dev/null +++ b/src/pages/RegisterPage.tsx @@ -0,0 +1,610 @@ +import { useEffect, useState, type FormEvent } from 'react' +import { Link, useNavigate } from 'react-router-dom' +import { + fetchRegisterCaptcha, + fetchSchoolPolicyHtml, + submitFullRegistration, + type FullRegisterPayload, +} from '../api/registerFull' +import { NE_STATES } from '../data/neStates' + +function formatUsPhone(input: string): string { + const raw = input.replace(/\D/g, '').slice(0, 10) + if (raw.length <= 3) return raw + if (raw.length <= 6) return `${raw.slice(0, 3)}-${raw.slice(3)}` + return `${raw.slice(0, 3)}-${raw.slice(3, 6)}-${raw.slice(6)}` +} + +/** Matches CodeIgniter `Views/user/register.php` + Laravel `POST /api/v1/auth/register` (captcha flow). */ +export function RegisterPage() { + const navigate = useNavigate() + + const [captchaChallenge, setCaptchaChallenge] = useState('') + const [captchaLoading, setCaptchaLoading] = useState(true) + + const [firstname, setFirstname] = useState('') + const [lastname, setLastname] = useState('') + const [gender, setGender] = useState('') + const [cellphone, setCellphone] = useState('') + const [email, setEmail] = useState('') + const [confirmEmail, setConfirmEmail] = useState('') + const [addressStreet, setAddressStreet] = useState('') + const [apt, setApt] = useState('') + const [city, setCity] = useState('') + const [state, setState] = useState('') + const [zip, setZip] = useState('') + + const [isParent, setIsParent] = useState(false) + const [noSecondParentInfo, setNoSecondParentInfo] = useState(false) + const [secondFirstname, setSecondFirstname] = useState('') + const [secondLastname, setSecondLastname] = useState('') + const [secondGender, setSecondGender] = useState('') + const [secondEmail, setSecondEmail] = useState('') + const [secondCellphone, setSecondCellphone] = useState('') + + const [acceptPolicy, setAcceptPolicy] = useState(false) + const [captchaAnswer, setCaptchaAnswer] = useState('') + + const [policyHtml, setPolicyHtml] = useState(null) + const [policyLoading, setPolicyLoading] = useState(false) + + const [busy, setBusy] = useState(false) + const [error, setError] = useState(null) + const [fieldErrors, setFieldErrors] = useState>({}) + + async function loadCaptcha() { + setCaptchaLoading(true) + try { + const { challenge } = await fetchRegisterCaptcha() + setCaptchaChallenge(challenge) + setCaptchaAnswer('') + } catch (e) { + setError(e instanceof Error ? e.message : 'Could not load CAPTCHA.') + } finally { + setCaptchaLoading(false) + } + } + + useEffect(() => { + void loadCaptcha() + }, []) + + async function openPolicyModal() { + if (!policyHtml) { + setPolicyLoading(true) + try { + const html = await fetchSchoolPolicyHtml() + setPolicyHtml(html) + } catch { + setPolicyHtml('

    Unable to load policy.

    ') + } finally { + setPolicyLoading(false) + } + } + const el = document.getElementById('policyModal') + const B = ( + window as unknown as { + bootstrap?: { Modal: { getOrCreateInstance: (n: HTMLElement) => { show: () => void } } } + } + ).bootstrap + if (el && B?.Modal) { + B.Modal.getOrCreateInstance(el).show() + } + } + + function fieldErr(key: string): string | undefined { + return fieldErrors[key]?.[0] + } + + async function onSubmit(e: FormEvent) { + e.preventDefault() + setError(null) + setFieldErrors({}) + + if (email.trim() !== confirmEmail.trim()) { + setError('Email and confirm email must match.') + return + } + if (!acceptPolicy) { + setError('You must accept the school policies.') + return + } + const zipOk = /^\d{5}$/.test(zip.trim()) + if (!zipOk) { + setError('Zip must be exactly 5 digits.') + return + } + const phoneDigits = cellphone.replace(/\D/g, '') + if (phoneDigits.length !== 10) { + setError('Please enter a valid 10-digit cell phone number.') + return + } + + if (isParent && !noSecondParentInfo) { + const sd = secondCellphone.replace(/\D/g, '') + if (sd.length !== 10) { + setError('Second parent phone must be a valid 10-digit number.') + return + } + if (!secondFirstname.trim() || !secondLastname.trim() || !secondGender || !secondEmail.trim()) { + setError('Please complete second parent / guardian information.') + return + } + } + + const payload: FullRegisterPayload = { + firstname, + lastname, + gender, + cellphone, + email, + confirm_email: confirmEmail, + address_street: addressStreet, + apt, + city, + state, + zip: zip.trim(), + is_parent: isParent, + no_second_parent_info: noSecondParentInfo, + accept_school_policy: acceptPolicy, + captcha: captchaAnswer, + second_firstname: secondFirstname, + second_lastname: secondLastname, + second_gender: secondGender, + second_email: secondEmail, + second_cellphone: secondCellphone, + } + + setBusy(true) + try { + const result = await submitFullRegistration(payload) + if (!result.ok) { + setError(result.message) + if ('errors' in result && result.errors) setFieldErrors(result.errors) + void loadCaptcha() + return + } + navigate('/login', { + replace: true, + state: { + registered: true, + message: + 'Registration submitted. Please check your email to activate your account when instructed.', + }, + }) + } finally { + setBusy(false) + } + } + + const showSecondSection = isParent + const showSecondFields = isParent && !noSecondParentInfo + + return ( +
    +
    +
    +
    + + Al Rahma Sunday School { + ;(ev.target as HTMLImageElement).style.display = 'none' + }} + /> + +
    + +

    + Registration Form +

    + +
    + - This account is for parents/guardians to manage students. If you already registered + in a prior year, please reuse your existing account. +
    - If you cannot access your old email, reset your password. +
    + +

    + (All fields with * are required) +

    + + {error ? ( +
    + {error} +
    + ) : null} + +
    + setFirstname(e.target.value)} + /> + {fieldErr('firstname') ? ( +
    {fieldErr('firstname')}
    + ) : null} +
    + +
    + setLastname(e.target.value)} + /> + {fieldErr('lastname') ? ( +
    {fieldErr('lastname')}
    + ) : null} +
    + +
    + + {fieldErr('gender') ? ( +
    {fieldErr('gender')}
    + ) : null} +
    + +
    + setCellphone(formatUsPhone(e.target.value))} + /> + {fieldErr('cellphone') ? ( +
    {fieldErr('cellphone')}
    + ) : null} +
    + +
    + setEmail(e.target.value)} + /> + {fieldErr('email') ? ( +
    {fieldErr('email')}
    + ) : null} +
    + +
    + setConfirmEmail(e.target.value)} + autoComplete="off" + /> + {fieldErr('confirm_email') ? ( +
    {fieldErr('confirm_email')}
    + ) : null} +
    + +
    + setAddressStreet(e.target.value)} + /> + {fieldErr('address_street') ? ( +
    {fieldErr('address_street')}
    + ) : null} +
    + +
    + setApt(e.target.value)} + /> +
    + +
    + setCity(e.target.value)} + /> + {fieldErr('city') ? ( +
    {fieldErr('city')}
    + ) : null} +
    + +
    + + {fieldErr('state') ? ( +
    {fieldErr('state')}
    + ) : null} +
    + +
    + setZip(e.target.value.replace(/\D/g, '').slice(0, 5))} + /> + {fieldErr('zip') ? ( +
    {fieldErr('zip')}
    + ) : null} +
    + +
    + { + setIsParent(e.target.checked) + if (!e.target.checked) { + setNoSecondParentInfo(false) + } + }} + /> + +
    + + {showSecondSection ? ( +
    +
    Second Parent/Guardian Information
    + +
    + setNoSecondParentInfo(e.target.checked)} + /> + +
    + + {showSecondFields ? ( + <> +
    + setSecondFirstname(e.target.value)} + /> + {fieldErr('second_firstname') ? ( +
    {fieldErr('second_firstname')}
    + ) : null} +
    +
    + setSecondLastname(e.target.value)} + /> + {fieldErr('second_lastname') ? ( +
    {fieldErr('second_lastname')}
    + ) : null} +
    +
    + +
    +
    + setSecondEmail(e.target.value)} + /> + {fieldErr('second_email') ? ( +
    {fieldErr('second_email')}
    + ) : null} +
    +
    + setSecondCellphone(formatUsPhone(e.target.value))} + /> + {fieldErr('second_cellphone') ? ( +
    {fieldErr('second_cellphone')}
    + ) : null} +
    + + ) : null} +
    + ) : null} + +
    + setAcceptPolicy(e.target.checked)} + /> + +
    + +
    +
    + {captchaLoading ? ( + Loading CAPTCHA… + ) : ( + {captchaChallenge} + )} +
    + +
    + +
    + setCaptchaAnswer(e.target.value)} + /> + {fieldErr('captcha') ? ( +
    {fieldErr('captcha')}
    + ) : null} +
    + +
    + + + Back to Home + +
    +
    +
    + + + ) +} diff --git a/src/pages/SwaggerDocs.tsx b/src/pages/SwaggerDocs.tsx new file mode 100644 index 0000000..5806d38 --- /dev/null +++ b/src/pages/SwaggerDocs.tsx @@ -0,0 +1,102 @@ +import { useEffect, useMemo, useState } from 'react' +import SwaggerUI from 'swagger-ui-react' +import 'swagger-ui-react/swagger-ui.css' +import type { DocsBootstrap } from '../types/docsBootstrap' +import { apiUrl } from '../lib/apiOrigin' + +type Props = { + bootstrapPath: string + authorization?: string | null +} + +export function SwaggerDocs({ bootstrapPath, authorization }: Props) { + const [bootstrap, setBootstrap] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + let cancelled = false + ;(async () => { + try { + const headers: HeadersInit = { Accept: 'application/json' } + if (authorization) { + headers.Authorization = authorization + } + const res = await fetch(apiUrl(bootstrapPath), { headers }) + const body = await res.json().catch(() => null) + if (!res.ok) { + const msg = + typeof body?.message === 'string' + ? body.message + : `HTTP ${res.status}` + throw new Error(msg) + } + if (!cancelled) { + setBootstrap(body as DocsBootstrap) + setError(null) + } + } catch (e) { + if (!cancelled) { + setBootstrap(null) + setError(e instanceof Error ? e.message : 'Failed to load docs config') + } + } + })() + return () => { + cancelled = true + } + }, [bootstrapPath, authorization]) + + useEffect(() => { + if (bootstrap?.title) { + document.title = bootstrap.title + } + }, [bootstrap?.title]) + + const specUrl = useMemo(() => { + if (!bootstrap?.openapi_url) { + return '' + } + return apiUrl(bootstrap.openapi_url) + }, [bootstrap]) + + if (error) { + return ( +
    +

    {error}

    +
    + ) + } + + if (!bootstrap || !specUrl) { + return
    Loading documentation…
    + } + + const hideAuthorize = !bootstrap.show_authorize_button + + return ( +
    + {bootstrap.welcome_name ? ( +
    + Welcome, {bootstrap.welcome_name} +
    + ) : null} + {hideAuthorize ? : null} + + }) => { + if (authorization && !req.headers.Authorization) { + req.headers.Authorization = authorization + } + return req + }} + /> +
    + ) +} diff --git a/src/pages/parent/ParentAccountListPages.tsx b/src/pages/parent/ParentAccountListPages.tsx new file mode 100644 index 0000000..e38a391 --- /dev/null +++ b/src/pages/parent/ParentAccountListPages.tsx @@ -0,0 +1,99 @@ +import { useEffect, useState } from 'react' +import { Link } from 'react-router-dom' +import { + fetchParentAttendanceReportsList, + fetchParentAuthorizedUsers, +} from '../../api/session' +import { ParentParityShell } from './ParentParityShell' + +/** Secondary / authorized users — `GET /api/v1/parents/authorized-users`. */ +export function ParentAuthorizedUsersPage() { + const [payload, setPayload] = useState('') + const [error, setError] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + let cancelled = false + ;(async () => { + setLoading(true) + try { + const res = await fetchParentAuthorizedUsers() + if (cancelled) return + setPayload(JSON.stringify(res, null, 2)) + setError(null) + } catch (e) { + if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load.') + } finally { + if (!cancelled) setLoading(false) + } + })() + return () => { + cancelled = true + } + }, []) + + return ( + + {error ?
    {error}
    : null} + {loading ? ( +

    Loading…

    + ) : ( +
    +          {payload}
    +        
    + )} +
    + ) +} + +/** Submitted reports — `GET /api/v1/parents/attendance-reports`. */ +export function ParentAttendanceReportsHistoryPage() { + const [payload, setPayload] = useState('') + const [error, setError] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + let cancelled = false + ;(async () => { + setLoading(true) + try { + const res = await fetchParentAttendanceReportsList() + if (cancelled) return + setPayload(JSON.stringify(res, null, 2)) + setError(null) + } catch (e) { + if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load.') + } finally { + if (!cancelled) setLoading(false) + } + })() + return () => { + cancelled = true + } + }, []) + + return ( + + {error ?
    {error}
    : null} + {loading ? ( +

    Loading…

    + ) : ( +
    +          {payload}
    +        
    + )} +

    + New submission:{' '} + Report attendance form +

    +
    + ) +} diff --git a/src/pages/parent/ParentAttendancePage.tsx b/src/pages/parent/ParentAttendancePage.tsx new file mode 100644 index 0000000..b1655e0 --- /dev/null +++ b/src/pages/parent/ParentAttendancePage.tsx @@ -0,0 +1,142 @@ +import { useEffect, useState } from 'react' +import { Link, useSearchParams } from 'react-router-dom' +import { fetchParentAttendance } from '../../api/session' +import type { ParentAttendanceRow } from '../../api/types' + +export function ParentAttendancePage() { + const [params, setParams] = useSearchParams() + const schoolYearParam = params.get('school_year') + + const [rows, setRows] = useState([]) + const [schoolYears, setSchoolYears] = useState<{ school_year: string }[]>([]) + const [selectedYear, setSelectedYear] = useState(null) + const [error, setError] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + let cancelled = false + ;(async () => { + setLoading(true) + try { + const data = await fetchParentAttendance(schoolYearParam) + if (cancelled) return + setRows(data.attendance ?? []) + setSchoolYears(data.schoolYears ?? []) + setSelectedYear(data.selectedYear ?? null) + setError(null) + } catch (e) { + if (!cancelled) { + setRows([]) + setSchoolYears([]) + setSelectedYear(null) + setError(e instanceof Error ? e.message : 'Unable to load attendance.') + } + } finally { + if (!cancelled) setLoading(false) + } + })() + return () => { + cancelled = true + } + }, [schoolYearParam]) + + function onYearChange(next: string) { + const nextParams = new URLSearchParams(params) + if (next) nextParams.set('school_year', next) + else nextParams.delete('school_year') + setParams(nextParams) + } + + const yearOptions = + schoolYears.length > 0 + ? schoolYears + : selectedYear + ? [{ school_year: selectedYear }] + : [] + + return ( +
    +
    +

    + Attendance Record +

    +
    + +
    { + e.preventDefault() + }} + > +
    + + +
    +
    + +
    +
    + + {error ? ( +
    {error}
    + ) : null} + + {loading ? ( +

    Loading…

    + ) : rows.length === 0 ? ( +

    No attendance rows for this school year.

    + ) : ( +
    + + + + + + + + + + + + {rows.map((row, i) => ( + + + + + + + + ))} + +
    First NameLast NameDateStatusReason
    {row.firstname}{row.lastname}{row.date}{row.status}{row.reason ?? '—'}
    +
    + )} + +

    + Parent dashboard + {' · '} + App home +

    +
    + ) +} diff --git a/src/pages/parent/ParentCiRouteRedirects.tsx b/src/pages/parent/ParentCiRouteRedirects.tsx new file mode 100644 index 0000000..4854ec6 --- /dev/null +++ b/src/pages/parent/ParentCiRouteRedirects.tsx @@ -0,0 +1,16 @@ +import { Navigate, useParams } from 'react-router-dom' + +/** CI uses `parent/edit_student/(:num)` — canonical SPA uses `parent/students/:id/edit`. */ +export function RedirectParentLegacyStudentEdit() { + const { studentId } = useParams<{ studentId: string }>() + return +} + +/** + * CI `parent/edit_emergency_contact/(:num)` and `parent/edit-emergency-contact/(:num)` → + * SPA `parent/emergency-contact/:contactId`. + */ +export function RedirectParentLegacyEmergencyContactEdit() { + const { contactId } = useParams<{ contactId: string }>() + return +} diff --git a/src/pages/parent/ParentEmergencyContactsPage.tsx b/src/pages/parent/ParentEmergencyContactsPage.tsx new file mode 100644 index 0000000..98879d8 --- /dev/null +++ b/src/pages/parent/ParentEmergencyContactsPage.tsx @@ -0,0 +1,60 @@ +import { Link } from 'react-router-dom' +import { useEffect, useState } from 'react' +import { fetchParentEmergencyContacts } from '../../api/session' +import type { ParentEmergencyContactRow } from '../../api/types' +import { ParentParityShell } from './ParentParityShell' + +/** CI `parent/edit-emergency-contact` (no id) — GET /api/v1/parents/emergency-contacts */ +export function ParentEmergencyContactsPage() { + const [rows, setRows] = useState([]) + const [error, setError] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + let cancelled = false + ;(async () => { + setLoading(true) + try { + const data = await fetchParentEmergencyContacts() + if (cancelled) return + setRows(data.contacts ?? []) + setError(null) + } catch (e) { + if (!cancelled) setError(e instanceof Error ? e.message : 'Unable to load contacts.') + } finally { + if (!cancelled) setLoading(false) + } + })() + return () => { + cancelled = true + } + }, []) + + return ( + + {error ?
    {error}
    : null} + {loading ? ( +

    Loading…

    + ) : rows.length === 0 ? ( +

    No emergency contacts.

    + ) : ( +
      + {rows.map((c) => ( +
    • + + {c.name || 'Contact'} + +
      + {[c.cellphone, c.email].filter(Boolean).join(' · ') || '—'} +
      +
    • + ))} +
    + )} +
    + ) +} diff --git a/src/pages/parent/ParentHomePage.tsx b/src/pages/parent/ParentHomePage.tsx new file mode 100644 index 0000000..1073a82 --- /dev/null +++ b/src/pages/parent/ParentHomePage.tsx @@ -0,0 +1,136 @@ +import { useEffect, useMemo, useState } from 'react' +import { Link } from 'react-router-dom' +import { fetchParentProfile } from '../../api/session' +import type { ParentProfileRecord } from '../../api/types' +import { useAuth } from '../../auth/AuthProvider' +import { ParentSectionNav } from './ParentSectionNav' + +function displayName(p: ParentProfileRecord | null): string { + if (!p) return '' + const fn = (p.firstname ?? '').trim() + const ln = (p.lastname ?? '').trim() + const full = `${fn} ${ln}`.trim() + return full || (p.email ?? '').trim() +} + +export function ParentHomePage() { + const { user } = useAuth() + const [profile, setProfile] = useState(null) + const [error, setError] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + let cancelled = false + ;(async () => { + setLoading(true) + try { + const data = await fetchParentProfile() + if (cancelled) return + setProfile(data.profile ?? null) + setError(null) + } catch (e) { + if (!cancelled) { + setProfile(null) + setError(e instanceof Error ? e.message : 'Unable to load profile.') + } + } finally { + if (!cancelled) setLoading(false) + } + })() + return () => { + cancelled = true + } + }, []) + + const greeting = useMemo(() => { + const fromApi = displayName(profile) + if (fromApi) return fromApi + return user?.name?.trim() || 'Parent' + }, [profile, user?.name]) + + return ( +
    +
    +

    + Parent dashboard +

    +

    + Parity with CodeIgniter Views/parent/parent_dashboard +

    +
    + + {error ? ( +
    + {error}{' '} + + Parent-only APIs require a parent account. Use the general{' '} + app home if you landed here by mistake. + +
    + ) : null} + + {loading ? ( +

    Loading…

    + ) : ( +
    +
    +
    +
    +

    Account

    +

    + {greeting} +

    + {profile?.email ? ( +

    {profile.email}

    + ) : null} + {profile?.cellphone ? ( +

    {profile.cellphone}

    + ) : null} +
    +
    +
    +
    +
    +
    +

    Address

    + {profile?.address_street || profile?.city || profile?.state ? ( +

    + {[profile.address_street, profile.city, profile.state, profile.zip] + .filter(Boolean) + .join(', ')} +

    + ) : ( +

    No address on file.

    + )} +
    +
    +
    +
    + )} + +
    +
    +
    +

    Shortcuts

    +
      +
    • + Attendance record +
    • +
    • + App home +
    • +
    +
    +
    +
    +
    +

    All parent pages (CI parity)

    +
    + +
    +
    +
    +
    +
    + ) +} diff --git a/src/pages/parent/ParentParityShell.tsx b/src/pages/parent/ParentParityShell.tsx new file mode 100644 index 0000000..223d725 --- /dev/null +++ b/src/pages/parent/ParentParityShell.tsx @@ -0,0 +1,73 @@ +import type { ReactNode } from 'react' +import { Link } from 'react-router-dom' +import { ParentSectionNav } from './ParentSectionNav' + +export type ParentParitySpec = { + title: string + /** File name under `app/Views/parent/` (e.g. `calendar.php`). */ + ciViewFile: string + /** Example CodeIgniter URL paths (with leading slash). */ + legacyCiRoutes?: string[] +} + +type ShellProps = ParentParitySpec & { + children?: ReactNode +} + +export function ParentParityShell({ + title, + ciViewFile, + legacyCiRoutes, + children, +}: ShellProps) { + return ( +
    +
    +

    + {title} +

    +

    + CodeIgniter view:{' '} + + app/Views/parent/{ciViewFile} + +

    +
    + + {legacyCiRoutes?.length ? ( +

    + Legacy routes:{' '} + {legacyCiRoutes.map((r, i) => ( + + {i > 0 ? ' · ' : null} + {r} + + ))} +

    + ) : null} + +
    + +
    +
    + This SPA route mirrors the CI parent view. Implement using the matching handlers in{' '} + app_laravel/routes/api.php (prefix /api/v1/parents/... where + available). +
    + {children} +
    +
    + +

    + ← Parent dashboard + {' · '} + App home +

    +
    + ) +} diff --git a/src/pages/parent/ParentSectionNav.tsx b/src/pages/parent/ParentSectionNav.tsx new file mode 100644 index 0000000..1374271 --- /dev/null +++ b/src/pages/parent/ParentSectionNav.tsx @@ -0,0 +1,51 @@ +import { NavLink } from 'react-router-dom' + +const LINKS: { to: string; label: string }[] = [ + { to: '/app/parent/home', label: 'Dashboard' }, + { to: '/app/parent/add-second-parent', label: 'Add second parent' }, + { to: '/app/parent/assignments', label: 'Assignments' }, + { to: '/app/parent/attendance', label: 'Attendance' }, + { to: '/app/parent/calendar', label: 'Calendar' }, + { to: '/app/parent/classes', label: 'Classes' }, + { to: '/app/parent/progress', label: 'Class progress' }, + { to: '/app/parent/edit-emergency-contact', label: 'Emergency contacts' }, + { to: '/app/parent/edit-all-students', label: 'Edit all students' }, + { to: '/app/parent/add-student-form', label: 'Add student form' }, + { to: '/app/parent/add-emergency-form', label: 'Add emergency form' }, + { to: '/app/parent/contact', label: 'Contact' }, + { to: '/app/parent/enroll-classes', label: 'Enroll in classes' }, + { to: '/app/parent/enroll/success', label: 'Enroll success' }, + { to: '/app/parent/enroll/failure', label: 'Enroll failure' }, + { to: '/app/parent/events', label: 'Events' }, + { to: '/app/parent/invoice-payment', label: 'Invoice payment' }, + { to: '/app/parent/no-kids-registered', label: 'No kids registered' }, + { to: '/app/parent/message', label: 'Message' }, + { to: '/app/parent/payment', label: 'Payments / invoices' }, + { to: '/app/parent/payment/success', label: 'Payment success' }, + { to: '/app/parent/register-student', label: 'Register student' }, + { to: '/app/parent/report-attendance', label: 'Report attendance' }, + { to: '/app/parent/attendance-reports', label: 'My attendance reports' }, + { to: '/app/parent/authorized-users', label: 'Authorized users' }, + { to: '/app/parent/update-profile', label: 'Update profile' }, + { to: '/app/parent/report-cards', label: 'Report cards' }, + { to: '/app/parent/scores', label: 'Scores' }, + { to: '/app/parent/success', label: 'Success message' }, + { to: '/app/parent/withdraw/success', label: 'Withdraw success' }, +] + +export function ParentSectionNav() { + const linkClass = ({ isActive }: { isActive: boolean }) => + `d-block px-2 py-1 rounded text-decoration-none small ${ + isActive ? 'bg-success text-white' : 'text-body' + }` + + return ( + + ) +} diff --git a/src/pages/parent/WiredParentScreens.tsx b/src/pages/parent/WiredParentScreens.tsx new file mode 100644 index 0000000..61c9cd7 --- /dev/null +++ b/src/pages/parent/WiredParentScreens.tsx @@ -0,0 +1,437 @@ +import { useEffect, useState, type FormEvent } from 'react' +import { ParentParityShell } from './ParentParityShell' +import { + fetchAttendanceReportForm, + fetchParentEnrollments, + fetchParentEventsOverview, + fetchParentInvoices, + fetchParentProfile, + fetchParentRegistrationOverview, + submitContactMessage, +} from '../../api/session' +import type { ParentEnrollmentStudent, ParentInvoiceRow } from '../../api/types' +import { useAuth } from '../../auth/AuthProvider' + +/** `Views/parent/contact.php` — POST /api/v1/contact */ +export function ParentContactPage() { + const { user } = useAuth() + const [name, setName] = useState('') + const [email, setEmail] = useState('') + const [subject, setSubject] = useState('') + const [message, setMessage] = useState('') + const [status, setStatus] = useState(null) + const [error, setError] = useState(null) + const [loading, setLoading] = useState(false) + + useEffect(() => { + let cancelled = false + ;(async () => { + try { + const res = await fetchParentProfile() + const p = res.profile + if (cancelled || !p) return + const fn = (p.firstname ?? '').trim() + const ln = (p.lastname ?? '').trim() + const full = `${fn} ${ln}`.trim() + if (full) setName(full) + if (p.email) setEmail(String(p.email)) + } catch { + /* optional */ + } + })() + return () => { + cancelled = true + } + }, []) + + useEffect(() => { + if (!user?.name) return + setName((n) => n || user.name) + }, [user?.name]) + + async function onSubmit(e: FormEvent) { + e.preventDefault() + setLoading(true) + setError(null) + setStatus(null) + try { + const res = await submitContactMessage({ name, email, subject, message }) + if (res.status) { + setStatus(res.message ?? 'Message sent.') + setSubject('') + setMessage('') + } else { + setError('Could not send message.') + } + } catch (err) { + setError(err instanceof Error ? err.message : 'Request failed.') + } finally { + setLoading(false) + } + } + + return ( + + {status ?
    {status}
    : null} + {error ?
    {error}
    : null} +
    +
    + + setName(e.target.value)} + required + minLength={3} + /> +
    +
    + + setEmail(e.target.value)} + required + /> +
    +
    + + setSubject(e.target.value)} + required + minLength={3} + /> +
    +
    + +