diff --git a/README.md b/README.md index fefc660..fec7bfd 100644 --- a/README.md +++ b/README.md @@ -52,4 +52,4 @@ After actively invoking `./start-app.sh`, securely visit dynamically: - Official `docker-compose` documentation. ## How Artificial Intelligence was natively used -This physically requested solution (Bash Scripting, Advanced Docker Object Routing, Refactoring methodologies, and File Generation) was strictly mapped intelligently interacting securely using **Antigravity**, an official Advanced Agentic Coding artificial intelligence agent acting as the primary orchestrator, intelligently translating the specific criteria logically directly. +In this project ai was used to help create the .yalm file and understand his importance. It was also used to help Write the README.me file add state clearly what does this application do, list all the dependencies and write it smoothly. diff --git a/z1/docker-compose.yaml b/z1/docker-compose.yaml new file mode 100644 index 0000000..60ca99f --- /dev/null +++ b/z1/docker-compose.yaml @@ -0,0 +1,58 @@ +version: "3.8" + +services: + db: + image: mysql:8.0 + container_name: smartbuilding_db + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: cytech0001 + MYSQL_DATABASE: user + volumes: + - z1_mysql-data:/var/lib/mysql + - ./webapp/user.sql:/docker-entrypoint-initdb.d/user.sql:ro + networks: + - app-network + + phpmyadmin: + image: phpmyadmin/phpmyadmin + container_name: smartbuilding_pma + restart: unless-stopped + environment: + PMA_HOST: db + PMA_USER: root + PMA_PASSWORD: cytech0001 + ports: + - "8080:80" + networks: + - app-network + depends_on: + - db + + webapp: + build: + context: ./webapp + dockerfile: Dockerfile + container_name: smartbuilding_webapp + restart: unless-stopped + command: > + sh -c "until nc -z db 3306; do echo 'Waiting for MySQL...'; sleep 2; done; npm start" + ports: + - "3000:3000" + environment: + DB_HOST: db + DB_USER: root + DB_PASSWORD: cytech0001 + DB_NAME: user + networks: + - app-network + depends_on: + - db + +networks: + app-network: + external: true + +volumes: + z1_mysql-data: + external: true diff --git a/z1/prepare-app.sh b/z1/prepare-app.sh new file mode 100755 index 0000000..9a7ef9f --- /dev/null +++ b/z1/prepare-app.sh @@ -0,0 +1,13 @@ +#!/bin/bash +echo "Preparing app..." + +# Creating virtual networks mathematically natively natively +docker network create app-network 2>/dev/null || true + +# Explicitly allocating the persistent volume +docker volume create z1_mysql-data 2>/dev/null || true + +# Pre-building the local webapp image directly +docker compose build + +echo "App locally compiled safely!" diff --git a/z1/remove-app.sh b/z1/remove-app.sh new file mode 100755 index 0000000..8680e19 --- /dev/null +++ b/z1/remove-app.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "Removing all traces of the application..." + +# Demolish containers natively gracefully +docker compose down -v --rmi all + +# Ensure the manually created network is gone +docker network rm app-network 2>/dev/null || true +docker volume rm z1_mysql-data 2>/dev/null || true + +echo "Removed app." diff --git a/z1/start-app.sh b/z1/start-app.sh new file mode 100755 index 0000000..183fbdf --- /dev/null +++ b/z1/start-app.sh @@ -0,0 +1,9 @@ +#!/bin/bash +echo "Running app ..." + +# Booting up all strictly defined services dynamically in the background +docker compose up -d + +echo "" +echo "The app is available at http://localhost:3000" +echo "The database interface (phpMyAdmin) is available at http://localhost:8080" diff --git a/z1/stop-app.sh b/z1/stop-app.sh new file mode 100755 index 0000000..b60782f --- /dev/null +++ b/z1/stop-app.sh @@ -0,0 +1,5 @@ +#!/bin/bash +echo "Stopping app..." + +# Non-destructively pausing components +docker compose stop diff --git a/z1/webapp/.dockerignore b/z1/webapp/.dockerignore new file mode 100644 index 0000000..b8b83d3 --- /dev/null +++ b/z1/webapp/.dockerignore @@ -0,0 +1,4 @@ +node_modules +npm-debug.log +.git +.env diff --git a/z1/webapp/Dockerfile b/z1/webapp/Dockerfile new file mode 100644 index 0000000..08ff5fb --- /dev/null +++ b/z1/webapp/Dockerfile @@ -0,0 +1,12 @@ +FROM node:18-alpine + +WORKDIR /app + +COPY package*.json ./ +RUN npm install + +COPY . . + +EXPOSE 3000 + +CMD ["npm", "start"] diff --git a/z1/webapp/README.md b/z1/webapp/README.md new file mode 100644 index 0000000..3c5541c --- /dev/null +++ b/z1/webapp/README.md @@ -0,0 +1,94 @@ +🌐 Projet Web - Smart Building (Maison ConnectĂ©e) + +Bienvenue dans le projet web de gestion d'une maison connectĂ©e rĂ©alisĂ© dans le cadre de notre formation. + + +Ce projet permet de gĂ©rer diffĂ©rents objets connectĂ©s d’un +bĂątiment (lumiĂšres, climatiseurs, thermostats, etc.) avec des rĂŽles +utilisateurs, une interface de connexion, de gestion et de visualisation. + + +📩 PrĂ©requis +Assurez-vous d’avoir les outils suivants installĂ©s : +Node.js (version 18 ou + recommandĂ©e) +npm +un serveur local avec phpMyAdmin et MySQL + + +⚙ Installation du projet +Si vous arrivez Ă  lire ce README vous avez donc rĂ©ussi Ă  cloner le lien github. + +Ouvrir un terminal dans le dossier du projet : +cd projetWEB + + +⚙ Installer les dĂ©pendances Node.js : +npm install + +Cela installera notamment : - express - ejs - bcrypt / bcryptjs - multer - mysql - nodemon - express-session - path + + +📁 Configuration de la base de donnĂ©es +DĂ©marrer MySQL et phpMyAdmin (avec les pc de cy tech sur ubuntu normalement l'identifiant est root et le mot de passe est cytech0001) + +CrĂ©er une base de donnĂ©es nommĂ©e user dans phpMyAdmin +Importer le fichier SQL : +Aller dans phpMyAdmin > Base user > Importer +SĂ©lectionner le fichier SQL fourni (user.sql) +Valider + +⚠ VĂ©rifiez que toutes les tables ont bien Ă©tĂ© créées (utilisateur, objet, etc.) + + +🚀 Lancement du serveur +Lancer le serveur local avec nodemon : +npm run dev + +Le serveur dĂ©marrera sur : +👉 http://localhost:3000 +Structure de navigation du site : +/ → Accueil +/connexion → Connexion utilisateur +/inscription → Formulaire d’inscription/objets → Liste des objets connectĂ©s (accĂšs selon statut) +/admin → Dashboard administrateur (vous n'y avez accĂšs que si vous ĂȘtes connectĂ© en tant qu'admin) +/admin → Dashboard administrateur (vous n'y avez accĂšs que si vous ĂȘtes connectĂ© en tant que complexe) +/profil → Modification du profil +/membres → Liste des utilisateurs (selon rĂŽle) + + +đŸ‘€ RĂŽles utilisateurs : + +visiteur → accĂšs limitĂ©, simple visite et visualisation des objets et des membres et aucune modification possible + +simple → peut consulter et modifier les objets en cliquant sur l'engrenage dans la page objets connectĂ©s (si vous voulez vous connecter Ă  un compte utilisateur simple vous pouvez utiliser comme identifiant garricastres et comme mot de passe 1234) + +complexe → accĂšs complet Ă  la gestion d’objets Ă  l'aide d'un petit dashboard (si vous voulez vous connecter Ă  un compte utilisateur simple vous pouvez utiliser comme identifiant clement_cx et comme mot de passe 1234) + +administrateur → contrĂŽle total Ă  l'aide d'un dashboard (ajout/suppression utilisateurs et objets) (si vous voulez vous connecter Ă  un compte utilisateur simple vous pouvez utiliser comme identifiant admin et comme mot de passe 1234) + + +📾 Upload des photos +Les photos de profil sont stockĂ©es dans le dossier /img + + +đŸ§Ș Scripts utiles +Dans un terminal se mettre au niveau du dossier projetWEB + dĂ©marrer avec nodemon : npm run dev + dĂ©marrer sans nodemon : node index.js + + +💡 DĂ©veloppement +Technos utilisĂ©es : + +Node.js + Express pour le backend +EJS comme moteur de vues +MySQL comme base de donnĂ©es +Multer pour le tĂ©lĂ©chargement de fichiers +bcrypt pour sĂ©curiser les mots de passe + +đŸ§‘â€đŸ« Projet rĂ©alisĂ© par : +Guillaume Arricastres, Zoe Artigas, Augustin Contal, Lucas Coquet, Thomas Kluczny + +Cytech – GI Groupe 2 – AnnĂ©e 2025 + +Merci pour votre attention \ No newline at end of file diff --git a/z1/webapp/Rapport_Projet_WEB_GIG2_Groupe5.pdf b/z1/webapp/Rapport_Projet_WEB_GIG2_Groupe5.pdf new file mode 100644 index 0000000..56d1cda Binary files /dev/null and b/z1/webapp/Rapport_Projet_WEB_GIG2_Groupe5.pdf differ diff --git a/z1/webapp/config/db.js b/z1/webapp/config/db.js new file mode 100644 index 0000000..e382c41 --- /dev/null +++ b/z1/webapp/config/db.js @@ -0,0 +1,19 @@ +const mysql = require('mysql2'); + +const connection = mysql.createConnection({ + host: process.env.DB_HOST || 'localhost', + user: process.env.DB_USER || 'root', // Ton utilisateur MySQL + password: process.env.DB_PASSWORD !== undefined ? process.env.DB_PASSWORD : 'cytech0001', // Ton mot de passe + database: process.env.DB_NAME || 'user', // Le nom de ta base + charset: 'utf8mb4' +}); + +connection.connect((err) => { + if (err) { + console.error('❌ Erreur de connexion Ă  MySQL :', err); + } else { + console.log('✅ ConnectĂ© Ă  la base de donnĂ©es MySQL'); + } +}); + +module.exports = connection; diff --git a/z1/webapp/img/1744554542632_Screenshot from 2025-04-11 21-19-09.png b/z1/webapp/img/1744554542632_Screenshot from 2025-04-11 21-19-09.png new file mode 100644 index 0000000..b322374 Binary files /dev/null and b/z1/webapp/img/1744554542632_Screenshot from 2025-04-11 21-19-09.png differ diff --git a/z1/webapp/img/option.png b/z1/webapp/img/option.png new file mode 100755 index 0000000..795ee05 Binary files /dev/null and b/z1/webapp/img/option.png differ diff --git a/z1/webapp/img/stylo.png b/z1/webapp/img/stylo.png new file mode 100755 index 0000000..659c3f4 Binary files /dev/null and b/z1/webapp/img/stylo.png differ diff --git a/z1/webapp/index.js b/z1/webapp/index.js new file mode 100644 index 0000000..bd1fe61 --- /dev/null +++ b/z1/webapp/index.js @@ -0,0 +1,205 @@ +const express = require('express'); +const session = require('express-session'); +const path = require('path'); +const bcrypt = require('bcrypt'); +const db = require('./config/db'); + +const app = express(); +const PORT = 3000; + +// -------------------- +// Middleware +// -------------------- +app.use(express.static('public')); +app.use('/img', express.static('img')); +app.use(express.urlencoded({ extended: true })); +app.use(express.json()); + +app.set('view engine', 'ejs'); +app.set('views', path.join(__dirname, 'views')); + +app.use(session({ + secret: 'votre-secret', + resave: false, + saveUninitialized: false +})); + +app.use((req, res, next) => { + res.locals.session = req.session; + res.locals.currentRoute = req.path; + next(); +}); + +// -------------------- +// Middleware admin +// -------------------- +function requireAdmin(req, res, next) { + if (!req.session.utilisateur || req.session.utilisateur.statut !== 'administrateur') { + return res.redirect('/non-admin'); + } + next(); +} + +// -------------------- +// Importation des routes +// -------------------- +const profilRouter = require('./routes/profil'); +const inscriptionRouter = require('./routes/inscription'); +const connexionRouter = require('./routes/connexion'); +const objetsRoutes = require('./routes/api/objet'); +const utilisateursRoutes = require('./routes/api/utilisateur'); +const ressourceRoutes = require('./routes/api/ressource'); +const complexeRoutes = require('./routes/complexe'); +const adminRoutes = require('./routes/admin'); + +// -------------------- +// Utilisation des routes +// -------------------- +app.use('/profil', profilRouter); +app.use('/inscription', inscriptionRouter); +app.use('/connexion', connexionRouter); +app.use('/api/objets', objetsRoutes); +app.use('/api/utilisateurs', utilisateursRoutes); +app.use('/api/ressources', ressourceRoutes); +app.use('/complexe', complexeRoutes); +app.use('/admin', adminRoutes); + +// -------------------- +// Pages de vue +// -------------------- +app.get('/', (req, res) => res.render('accueil')); +app.get('/objets', (req, res) => res.render('objets')); +app.get('/ressources', (req, res) => res.render('ressources')); +app.get('/description', (req, res) => res.render('description')); +app.get('/contact', (req, res) => res.render('contact')); + +app.get('/membres', (req, res) => { + db.query('SELECT * FROM utilisateur', (err, membres) => { + if (err) return res.status(500).send('Erreur BDD'); + res.render('membres', { membres }); + }); +}); + +app.get('/membres/:id', (req, res) => { + const id = req.params.id; + db.query('SELECT * FROM utilisateur WHERE id = ?', [id], (err, results) => { + if (err || results.length === 0) return res.status(404).send('Utilisateur non trouvĂ©'); + res.render('membre', { membre: results[0] }); + }); +}); + +app.get('/dashboard-complexe', (req, res) => { + if (!req.session.utilisateur || req.session.utilisateur.statut !== 'complexe') { + return res.send(` + + `); + } + + db.query('SELECT * FROM objet', (err, objets) => { + if (err) return res.status(500).send("Erreur objets"); + res.render('dashboard-complexe', { objets }); + }); +}); + +app.get('/dashboard-simple', (req, res) => { + if (!req.session.utilisateur || req.session.utilisateur.statut !== 'simple') { + return res.redirect('/non-admin'); + } + res.redirect('/objets'); +}); + +app.get('/non-admin', (req, res) => { + res.send(` + + `); +}); + +// -------------------- +// Inscription utilisateur +// -------------------- +app.post('/admin/ajouter-utilisateur', async (req, res) => { + const { + nom, prenom, sexe, age, date_naissance, + identifiant, email, mot_de_passe, situation, statut + } = req.body; + + try { + const checkSql = 'SELECT * FROM utilisateur WHERE email = ? OR identifiant = ?'; + db.query(checkSql, [email, identifiant], async (err, results) => { + if (err) return res.status(500).send("Erreur serveur"); + + if (results.length > 0) { + return res.send(` + + `); + } + + const hashed = await bcrypt.hash(mot_de_passe, 10); + const insertSql = ` + INSERT INTO utilisateur + (nom, prenom, sexe, age, date_naissance, identifiant, email, mot_de_passe, situation, statut, etat) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'en attente') + `; + db.query(insertSql, [ + nom, prenom, sexe, age, date_naissance, + identifiant, email, hashed, situation, statut + ], (err) => { + if (err) return res.status(500).send("Erreur lors de l'ajout de l'utilisateur"); + res.redirect('/admin'); + }); + }); + } catch (error) { + res.status(500).send('Erreur serveur'); + } +}); + +// -------------------- +// Ajout objet (admin) +// -------------------- +app.post('/admin/ajouter-objet', (req, res) => { + const { denomination, adresse_ip, type, niveau, etat } = req.body; + const sql = ` + INSERT INTO objet (denomination, adresse_ip, type, niveau, etat) + VALUES (?, ?, ?, ?, ?)`; + db.query(sql, [denomination, adresse_ip, type, niveau, etat], (err) => { + if (err) return res.status(500).send("Erreur lors de l'ajout de l'objet"); + res.redirect('/admin'); + }); +}); + +// -------------------- +// Envoi de message contact +// -------------------- +app.post('/contact', (req, res) => { + const { nom, email, message } = req.body; + const sql = 'INSERT INTO contact (nom, email, message) VALUES (?, ?, ?)'; + db.query(sql, [nom, email, message], (err) => { + if (err) return res.status(500).send("Erreur lors de l'envoi du message"); + res.redirect('/'); + }); +}); + +// -------------------- +// DĂ©connexion +// -------------------- +app.get('/deconnexion', (req, res) => { + req.session.destroy(() => { + res.redirect('/'); + }); +}); + +// -------------------- +// Lancement du serveur +// -------------------- +app.listen(PORT, () => { + console.log(`✅ Serveur lancĂ© sur http://localhost:${PORT}`); +}); diff --git a/z1/webapp/middleware/auth.js b/z1/webapp/middleware/auth.js new file mode 100644 index 0000000..a15462b --- /dev/null +++ b/z1/webapp/middleware/auth.js @@ -0,0 +1,10 @@ +function ensureAuthenticated(req, res, next) { + if (req.session.utilisateur) { + return next(); + } else { + return res.redirect('/connexion'); + } + } + + module.exports = ensureAuthenticated; + \ No newline at end of file diff --git a/z1/webapp/package-lock.json b/z1/webapp/package-lock.json new file mode 100644 index 0000000..bc74947 --- /dev/null +++ b/z1/webapp/package-lock.json @@ -0,0 +1,2208 @@ +{ + "name": "mon-projet", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mon-projet", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "bcrypt": "^5.1.1", + "bcryptjs": "^3.0.2", + "connect-flash": "^0.1.1", + "ejs": "^3.1.10", + "express": "^5.1.0", + "express-session": "^1.18.1", + "multer": "^1.4.5-lts.2", + "mysql2": "^3.14.0" + }, + "devDependencies": { + "nodemon": "^3.1.9" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "license": "BSD-3-Clause", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "license": "ISC" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "license": "ISC" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "license": "MIT", + "engines": { + "node": ">= 6.0.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==", + "license": "MIT" + }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bcryptjs": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz", + "integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==", + "license": "BSD-3-Clause", + "bin": { + "bcrypt": "bin/bcrypt" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect-flash": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz", + "integrity": "sha512-2rcfELQt/ZMP+SM/pG8PyhJRaLKp+6Hk2IUBNkEit09X+vwn3QsAL3ZbYtxUn7NVPzbMTSLRDhqe0B/eh30RYA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC" + }, + "node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "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/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-session": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz", + "integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==", + "license": "MIT", + "dependencies": { + "cookie": "0.7.2", + "cookie-signature": "1.0.7", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/express-session/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express-session/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "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/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "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": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "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/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/long": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", + "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/lru.min": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", + "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==", + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "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/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multer": { + "version": "1.4.5-lts.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.2.tgz", + "integrity": "sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/multer/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/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/multer/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/multer/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mysql2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.14.0.tgz", + "integrity": "sha512-8eMhmG6gt/hRkU1G+8KlGOdQi2w+CgtNoD1ksXZq9gQfkfDsX4LHaBwTe1SY0Imx//t2iZA03DFnyYKPinxSRw==", + "license": "MIT", + "dependencies": { + "aws-ssl-profiles": "^1.1.1", + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru.min": "^1.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "license": "MIT", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/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/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "license": "MIT", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + } + } +} diff --git a/z1/webapp/package.json b/z1/webapp/package.json new file mode 100644 index 0000000..444d4e7 --- /dev/null +++ b/z1/webapp/package.json @@ -0,0 +1,26 @@ +{ + "name": "mon-projet", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "node index.js", + "dev": "nodemon index.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "bcrypt": "^5.1.1", + "bcryptjs": "^3.0.2", + "connect-flash": "^0.1.1", + "ejs": "^3.1.10", + "express": "^5.1.0", + "express-session": "^1.18.1", + "multer": "^1.4.5-lts.2", + "mysql2": "^3.14.0" + }, + "devDependencies": { + "nodemon": "^3.1.9" + } +} diff --git a/z1/webapp/public/images/batiment.png b/z1/webapp/public/images/batiment.png new file mode 100755 index 0000000..a3faf48 Binary files /dev/null and b/z1/webapp/public/images/batiment.png differ diff --git a/z1/webapp/public/images/building.jpg b/z1/webapp/public/images/building.jpg new file mode 100755 index 0000000..595e53e Binary files /dev/null and b/z1/webapp/public/images/building.jpg differ diff --git a/z1/webapp/public/images/smart_building.png b/z1/webapp/public/images/smart_building.png new file mode 100755 index 0000000..03fb2f3 Binary files /dev/null and b/z1/webapp/public/images/smart_building.png differ diff --git a/z1/webapp/public/images/tour.jpg b/z1/webapp/public/images/tour.jpg new file mode 100755 index 0000000..b13a701 Binary files /dev/null and b/z1/webapp/public/images/tour.jpg differ diff --git a/z1/webapp/public/style.css b/z1/webapp/public/style.css new file mode 100644 index 0000000..6e9d048 --- /dev/null +++ b/z1/webapp/public/style.css @@ -0,0 +1,419 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + font-family: "Inter", sans-serif; + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; /* DĂ©finit la hauteur de la page Ă  100% */ + display: flex; /* Flexbox sur le body */ + flex-direction: column; /* Aligne le contenu du body en colonne */ +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.header_text li a:hover { + color: #00a8e8; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* ------------- */ +/* Main */ +/* ------------- */ + +main { + display: flex; + flex-grow: 1; /* Permet Ă  la section principale d'occuper l'espace restant */ + justify-content: center; /* Centre verticalement le contenu */ + align-items: center; /* Centre horizontalement le contenu */ + padding-bottom: 50px; + gap: 30px; /* Espace entre les 2 sections */ +} + +.left-panel { + flex: 3; /* 30% de la largeur totale */ + display: flex; + justify-content: center; /* Centrer l'image horizontalement */ + align-items: center; /* Centrer l'image verticalement */ +} + +.left-panel img { + width: 100%; /* L'image prend toute la largeur de son conteneur */ + max-width: 450px; /* Maximum de 300px de largeur */ + height: auto; /* La hauteur de l'image s'ajuste automatiquement */ + border-radius: 32px; +} + +.right-panel { + flex: 7; /* 70% de la largeur totale */ +} + +.right-panel h1 { + font-size: 60px; + margin-bottom: 60px; + padding-left: 70px; /* Ajoute un espacement Ă  gauche du titre */ +} + +.features { + display: grid; + grid-template-columns: repeat(4, 1fr); /* 4 ronds par ligne */ + gap: 30px; + justify-items: center; +} + +.feature { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.features a{ + text-decoration: none; + color: #eff1f3; +} + +.circle { + width: 150px; + height: 150px; + background-color: #eff1f3; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.3s, color 0.3s; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); +} + +.circle:hover { + background-color: #2c2c2c; + cursor: pointer; +} + +.circle i { + font-size: 70px; + fill: #2c2c2c; + color: #2c2c2c; + transition: fill 0.3s, color 0.3s; +} + +.circle:hover i { + fill: #eff1f3; + color: #eff1f3; +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* ------------------------- */ +/* Responsive Design */ +/* ------------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + .right-panel h1 { + font-size: 72px; + } + + .circle { + width: 180px; + height: 180px; + } + + .circle i { + font-size: 80px; + } +} + + +/* TABLETTE - Moyenne (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + .features { + grid-template-columns: repeat(3, 1fr); + } + + .right-panel h1 { + font-size: 48px; + padding-left: 30px; + } + + .circle { + width: 130px; + height: 130px; + } + + .circle i { + font-size: 50px; + } +} + + +/* TABLETTE - Petite (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + #smart_building { + width: 100px; + margin: 0; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + main { + flex-direction: column; + padding: 40px; + } + + .left-panel, + .right-panel { + width: 100%; + flex: none; + } + + .features { + grid-template-columns: repeat(2, 1fr); + } + + .right-panel h1 { + font-size: 42px; + padding-left: 0; + text-align: center; + } +} + + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + } + + #smart_building { + width: 90px; + height: auto; + margin: 0 auto; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + padding: 10px 20px; + width: auto; + text-align: center; + } + + main { + flex-direction: column; + padding: 20px; + } + + .left-panel, + .right-panel { + width: 100%; + flex: unset; + } + + .right-panel h1 { + font-size: 36px; + padding-left: 0; + text-align: center; + margin-bottom: 30px; + } + + .features { + grid-template-columns: 1fr; + gap: 20px; + } + + .circle { + width: 100px; + height: 100px; + } + + .circle i { + font-size: 40px; + } + + footer { + flex-direction: column; + text-align: center; + gap: 10px; + align-items: center; + } + + .footer_link { + flex-direction: column; + align-items: center; + gap: 10px; + } + + .copyright { + padding: 0; + } +} + + +/* TÉLÉPHONE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + main { + padding: 20px 10px; + } + + .right-panel h1 { + font-size: 28px; + margin-bottom: 20px; + } + + .circle { + width: 80px; + height: 80px; + } + + .circle i { + font-size: 32px; + } + + .form-control-inscription { + font-size: 14px; + padding: 8px; + } + + #smart_building { + width: 70px; + } + + .bouton_connexion { + font-size: 14px; + padding: 8px 16px; + } +} + + +/* ------------------------- */ +/* Transitions douces */ +/* ------------------------- */ + +* { + transition: all 0.3s ease-in-out; +} \ No newline at end of file diff --git a/z1/webapp/public/styleAdmin.css b/z1/webapp/public/styleAdmin.css new file mode 100644 index 0000000..7c7a818 --- /dev/null +++ b/z1/webapp/public/styleAdmin.css @@ -0,0 +1,530 @@ +/* ---------------- */ +/* GLOBAL */ +/* ---------------- */ + +body { + margin: 0; + padding: 0; + font-family: 'Inter', sans-serif; + background-color: #1e1e1e; + color: #eff1f3; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +main { + flex: 1; + padding: 40px 60px; +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { +display: flex; +flex-wrap: wrap; +align-items: center; +justify-content: space-between; +padding: 10px 40px; +} + +header a { +text-decoration: none; +color: #eff1f3; +} + +header ul { +list-style: none; +display: flex; +align-items: center; +} + +header li { +cursor: pointer; +} + +.header_text li a:hover { + color: #00a8e8; +} + + +.header_text { +display: flex; +flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ +justify-content: center; /* Centre les liens horizontalement */ +gap: 15%; /* Espace entre les liens */ +font-weight: 600; +} + +.header_text a { +padding: 0 10px; +} + +.bouton_connexion { +padding: 10px 20px; +border-radius: 900px; +font-size: 16px; /* Taille de la police */ +border-color: #00a8e8; +color: #eff1f3; +background-color: #00a8e8; +margin-top: 0; +cursor: pointer; +} + +.bouton_connexion:hover { +border-color: #eff1f3; +color: #00a8e8; +background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { +width: 13%; +margin-left: -40px; +height: auto; +} + + +/* ---------------- */ +/* TITRES */ +/* ---------------- */ + +h1 { + font-size: 42px; + margin-bottom: 30px; + color: #00a8e8; +} + +/* ---------------- */ +/* TABLES */ +/* ---------------- */ + +table { + width: 100%; + border-collapse: collapse; + margin-bottom: 60px; + background-color: #2c2c2c; + border-radius: 12px; + overflow: hidden; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +th, +td { + padding: 15px; + text-align: center; + border-bottom: 1px solid #444; +} + +th { + background-color: #1e1e1e; + color: #00a8e8; + font-size: 18px; +} + +tr:hover { + background-color: #333; +} + +select { + padding: 6px 10px; + border-radius: 20px; + border: none; + background-color: #eff1f3; + color: #1e1e1e; + font-weight: bold; +} + +button { + background-color: #00a8e8; + color: #eff1f3; + border: none; + padding: 8px 20px; + border-radius: 20px; + font-weight: bold; + cursor: pointer; + transition: background-color 0.2s ease; +} + +button:hover { + background-color: #0077b6; +} + +.toggle-btn { + display: inline-block; /* Assurer que l'Ă©lĂ©ment peut ĂȘtre transformĂ© */ + transition: transform 0.2s ease; /* Transition pour un zoom fluide */ +} + +.toggle-btn:hover { + cursor: pointer; + transform: scale(1.4); /* Agrandir de 1.5x lors du survol */ +} + +/* ---------------- */ +/* FORMULAIRE */ +/* ---------------- */ + +/* Si tu veux aussi centrer directement dans la section d'ajout */ +.ajout-section { + display: flex; + flex-direction: column; /* Permet de garder la structure de la section */ + justify-content: center; + align-items: center; + text-align: center; + margin: 0; +} + +#form-ajout-objet, +#form-ajout-user { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + border-radius: 24px; + background-color: #2c2c2c; + padding: 40px 100px; /* Augmente l'espace intĂ©rieur */ + width: 100%; /* Prend toute la largeur disponible */ + max-width: 400px; /* DĂ©finit une largeur max pour Ă©viter qu'elle ne devienne trop Ă©troite */ + box-shadow: 0 4px 8px 0 rgba(21, 21, 21, 0.2); + margin-bottom: 40px; +} + +label { + font-weight: bold; + font-size: 20px; + color: #eff1f3; + white-space: nowrap; +} + +select { + appearance: none; /* Supprime le style natif */ + background: white; + cursor: pointer; +} + +.form-group { + width: 100%; + position: relative; /* Position relative */ + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; +} + +.form-group .icon { + position: absolute; + left: 15px; /* Ajuste la position des icĂŽnes */ + top: 50%; + transform: translateY(-50%); +} + +.form-group .icon svg { + width: 24px; + height: 24px; + fill: #191717; +} + +.form-control-admin { + width: 100%; + padding-left: 50px; /* Remplissage Ă  gauche de 55px */ + padding-right: 40px; + height: 48px; /* Hauteur de 40px */ + border-radius: 34px; /* Bordure arrondie */ + font-size: 16px; /* Taille de la police */ + letter-spacing: 0.5px; /* Espacement des lettres */ + background-color: #eff1f3; /* Couleur de fond */ + border: none; /* Supprimer la bordure */ +} + +.form-row { + display: flex; + align-items: center; + gap: 10px; /* espace entre label et champ */ + flex-wrap: nowrap; /* Ă©vite le retour Ă  la ligne */ +} + +.bouton-admin { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; /* Centrage vertical */ + cursor: pointer; +} + +.bouton-admin:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +/* ---------------- */ +/* FOOTER */ +/* ---------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* ------------------------- */ +/* Responsive Design */ +/* ------------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + header { + padding: 20px 40px; + } + + .header_text { + gap: 25%; /* Plus d'espace entre les liens */ + } + + h1 { + font-size: 50px; + } + + table { + margin-bottom: 80px; + } + + .footer_link { + gap: 20%; + } + + footer { + padding: 30px; + } + + .bouton_connexion { + font-size: 18px; + padding: 12px 25px; + } + + #smart_building { + width: 15%; + } +} + + +/* TABLETTE - Moyenne (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + header { + padding: 20px 30px; + } + + .header_text { + gap: 20%; /* Moins d'espace entre les liens */ + } + + h1 { + font-size: 48px; + } + + table { + margin-bottom: 60px; + } + + footer { + padding: 25px; + } + + .footer_link { + gap: 15%; + } + + .bouton_connexion { + font-size: 16px; + padding: 10px 22px; + } + + #smart_building { + width: 14%; + } +} + + +/* TABLETTE - Petite (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + main { + flex-direction: column; + padding: 40px; + } + + table { + margin-bottom: 50px; + } + + .footer_link { + gap: 10%; + } + + #smart_building { + width: 100px; + margin: 0; + } + + footer { + padding: 20px; + } + + .footer_link { + gap: 10%; + } +} + + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + } + + #smart_building { + width: 90px; + height: auto; + margin: 0 auto; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + padding: 10px 20px; + width: auto; + text-align: center; + } + + main { + flex-direction: column; + padding: 20px; + } + + footer { + flex-direction: column; + text-align: center; + gap: 10px; + align-items: center; + } + + .footer_link { + flex-direction: column; + align-items: center; + gap: 10px; + } + + .copyright { + padding: 0; + } + + table { + margin-bottom: 30px; + } +} + + +/* TÉLÉPHONE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + main { + padding: 20px 10px; + } + + h1 { + font-size: 28px; + margin-bottom: 20px; + } + + #smart_building { + width: 70px; + } + + .bouton_connexion { + font-size: 14px; + padding: 8px 16px; + } + + table { + margin-bottom: 20px; + } + + .footer_link { + flex-direction: column; + gap: 8%; + } + + footer { + padding: 15px; + } + + .footer_link a { + padding: 5px 10px; + } + + .header_text { + font-size: 14px; + } + + .bouton_connexion { + font-size: 12px; + padding: 8px 15px; + } +} \ No newline at end of file diff --git a/z1/webapp/public/styleComplexe.css b/z1/webapp/public/styleComplexe.css new file mode 100644 index 0000000..44092cc --- /dev/null +++ b/z1/webapp/public/styleComplexe.css @@ -0,0 +1,354 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + font-family: "Inter", sans-serif; + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; /* DĂ©finit la hauteur de la page Ă  100% */ + display: flex; /* Flexbox sur le body */ + flex-direction: column; /* Aligne le contenu du body en colonne */ +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.header_text li a:hover { + color: #00a8e8; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* ----------------- */ +/* Complexe */ +/* ----------------- */ + +body { + background-color: #1e1e1e; + color: #eff1f3; + font-family: Arial, sans-serif; + margin: 0; + padding: 0; +} + +main.admin-container { + padding: 40px; + max-width: 1000px; + margin: auto; +} + +h1 { + text-align: center; + margin-bottom: 30px; + font-size: 36px; + color: #00a8e8; +} + +table { + width: 100%; + border-collapse: collapse; + background-color: #2c2c2c; + border-radius: 12px; + overflow: hidden; +} + +th, +td { + padding: 12px 16px; + text-align: center; + border-bottom: 1px solid #444; +} + +th { + background-color: #0077b6; + color: #fff; +} + +tr:nth-child(even) { + background-color: #353535; +} + +select, +button { + padding: 6px 10px; + border-radius: 6px; + border: none; +} + +button { + background-color: #00a8e8; + color: white; + cursor: pointer; +} + +button:hover { + background-color: #0077b6; +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* ------------------------- */ +/* Responsive Design */ +/* ------------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + main.admin-container { + padding: 60px; + max-width: 1200px; + } + + h1 { + font-size: 48px; + } + + table th, table td { + padding: 20px; + } + + .bouton_connexion { + padding: 12px 24px; + font-size: 18px; + } +} + +/* TABLETTE - Moyenne (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + + table th, table td { + padding: 15px; + } + + h1 { + font-size: 40px; + } +} + +/* TABLETTE - Petite (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + #smart_building { + width: 100px; + margin: 0; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + main.admin-container { + padding: 30px; + } + + h1 { + font-size: 36px; + margin-bottom: 20px; + } + + table th, table td { + padding: 10px; + } +} + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + } + + #smart_building { + width: 90px; + height: auto; + margin: 0 auto; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + padding: 10px 20px; + width: auto; + text-align: center; + } + + main.admin-container { + padding: 20px; + } + + h1 { + font-size: 28px; + margin-bottom: 20px; + } + + table th, table td { + padding: 8px; + } + + footer { + flex-direction: column; + text-align: center; + gap: 10px; + align-items: center; + } + + .footer_link { + flex-direction: column; + align-items: center; + gap: 10px; + } + + .copyright { + padding: 0; + } +} + +/* TÉLÉPHONE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + main.admin-container { + padding: 10px; + } + + h1 { + font-size: 24px; + margin-bottom: 20px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + #smart_building { + width: 70px; + } + + table th, table td { + padding: 6px; + } +} + +/* ------------------------- */ +/* Transitions douces */ +/* ------------------------- */ + +* { + transition: all 0.3s ease-in-out; +} \ No newline at end of file diff --git a/z1/webapp/public/styleConnexion.css b/z1/webapp/public/styleConnexion.css new file mode 100644 index 0000000..535dc52 --- /dev/null +++ b/z1/webapp/public/styleConnexion.css @@ -0,0 +1,453 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; + display: flex; + flex-direction: column; +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.header_text li a:hover { + color: #00a8e8; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* ------------------- */ +/* Connexion */ +/* ------------------- */ + +h1 { + font-size: 45px; /* Taille de la police */ + color: #eff1f3; + white-space: nowrap; +} + +#connexion { + display: flex; /* AjoutĂ© pour aligner les enfants */ + justify-content: center; /* Centrer les Ă©lĂ©ments verticalement */ + align-items: center; /* Centrer les Ă©lĂ©ments horizontalement */ + flex: 1;; /* Prend toute la hauteur de l'Ă©cran */ +} + +.building { + width: 23%; + height: 640px; + border-radius: 33px; + padding-left: 8%; + background-image: url("/images/building.jpg"); + background-size: cover; +} + +.page-connexion { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + border-radius: 24px; + background-color: #2c2c2c; + padding: 40px 60px; /* Augmente l'espace intĂ©rieur */ + width: 100%; /* Prend toute la largeur disponible */ + max-width: 400px; /* DĂ©finit une largeur max pour Ă©viter qu'elle ne devienne trop Ă©troite */ + box-shadow: 0 4px 8px 0 rgba(21, 21, 21, 0.2); +} + +.form-group { + width: 100%; + position: relative; /* Position relative */ + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; +} + +.form-group .icon { + position: absolute; + left: 15px; /* Ajuste la position des icĂŽnes */ + top: 50%; + transform: translateY(-50%); +} + +.form-group .icon svg { + width: 24px; + height: 24px; + fill: #191717; +} + +.form-control-connexion { + width: 100%; + padding-left: 50px; /* Remplissage Ă  gauche de 55px */ + padding-right: 80px; + height: 48px; /* Hauteur de 40px */ + border-radius: 34px; /* Bordure arrondie */ + font-size: 16px; /* Taille de la police */ + letter-spacing: 0.5px; /* Espacement des lettres */ + background-color: #eff1f3; /* Couleur de fond */ + border: none; /* Supprimer la bordure */ +} + +.bouton-connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 10px; /* Centrage vertical */ + cursor: pointer; +} + +.bouton-connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +.lien { + display: inline-block; /* Permet de mieux gĂ©rer la taille du soulignement */ + text-align: center; + margin-bottom: 15px; + font-size: 20px; /* Taille de la police */ + color: #eff1f3; + text-decoration: none; /* Supprime le soulignement par dĂ©faut */ + text-underline-offset: 10px; /* Augmente l'espace entre le texte et le soulignement */ + cursor: pointer; + padding-bottom: 10px; /* Ajoute un petit espace sous le texte */ + position: relative; /* Positionner l'Ă©lĂ©ment par rapport Ă  son parent */ +} + +.lien::after { + content: ""; + display: block; + width: 150%; /* La ligne est maintenant 1.5 fois plus grande que le texte */ + height: 2px; /* Épaisseur du soulignement */ + background-color: #eff1f3; /* Couleur du soulignement */ + position: absolute; + left: 50%; /* Centre la ligne horizontalement */ + transform: translateX( + -50% + ); /* DĂ©place la ligne pour qu'elle soit exactement centrĂ©e */ + bottom: 0; +} + +.lien:hover { + color: #0077b6; +} + +.cellule { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + margin-left: 9%; +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* ------------------------- */ +/* Responsive Design */ +/* ------------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + h1 { + font-size: 60px; + } + + .building { + height: 700px; + } + + .form-control-connexion { + font-size: 18px; + height: 52px; + } +} + + +/* TABLETTE - Moyenne (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + h1 { + font-size: 48px; + } + + .building { + height: 600px; + width: 28%; + padding-left: 5%; + } + + .page-connexion { + padding: 40px 40px; + } + + .form-control-connexion { + font-size: 16px; + } +} + + +/* TABLETTE - Petite (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + #smart_building { + width: 100px; + margin: 0; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + h1 { + font-size: 40px; + text-align: center; + } + + #connexion { + flex-direction: column; + padding: 40px 20px; + } + + .building { + width: 100%; + height: 300px; + border-radius: 20px; + padding: 0; + margin-bottom: 30px; + } + + .page-connexion { + max-width: 100%; + } + + .form-control-connexion { + font-size: 15px; + } +} + + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + padding: 20px; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + width: auto; + padding: 10px 16px; + font-size: 14px; + } + + #smart_building { + width: 80px; + margin-left: 0; + } + + h1 { + font-size: 32px; + text-align: center; + } + + #connexion { + flex-direction: column; + padding: 20px; + } + + .building { + width: 100%; + height: 250px; + padding: 0; + margin-bottom: 20px; + } + + .page-connexion { + padding: 30px 20px; + max-width: 100%; + } + + .form-control-connexion { + font-size: 14px; + height: 44px; + } + + footer { + flex-direction: column; + gap: 10px; + text-align: center; + align-items: center; + } + + .footer_link { + flex-direction: column; + gap: 10px; + } + + .copyright { + padding: 0; + } +} + + +/* TÉLÉPHONE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + h1 { + font-size: 26px; + } + + .form-control-connexion { + font-size: 13px; + padding-left: 40px; + height: 40px; + } + + .form-group .icon svg { + width: 20px; + height: 20px; + } + + .page-connexion { + padding: 20px 10px; + } + + .bouton-connexion { + font-size: 14px; + padding: 8px 14px; + } + + .lien { + font-size: 16px; + } + + #smart_building { + width: 60px; + } +} \ No newline at end of file diff --git a/z1/webapp/public/styleContact.css b/z1/webapp/public/styleContact.css new file mode 100644 index 0000000..28e39ad --- /dev/null +++ b/z1/webapp/public/styleContact.css @@ -0,0 +1,240 @@ + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; + } + + header a { + text-decoration: none; + color: #eff1f3; + } + + header ul { + list-style: none; + display: flex; + align-items: center; + } + + header li { + cursor: pointer; + } + + .header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; + } + + .header_text a { + padding: 0 10px; + } + + .bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; + } + + .bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ + } + + #smart_building { + width: 13%; + margin-left: -40px; + height: auto; + } + + +body { + margin: 0; + font-family: 'Segoe UI', sans-serif; + background-color: #121212; + color: #f1f1f1; + } + + .contact-container { + max-width: 600px; + margin: 60px auto; + padding: 20px; + background-color: #1e1e1e; + border-radius: 10px; + box-shadow: 0 0 20px rgba(0,0,0,0.4); + } + + .contact-container h1 { + text-align: center; + margin-bottom: 10px; + font-size: 2em; + } + + .contact-container p { + text-align: center; + margin-bottom: 30px; + color: #cccccc; + } + + .contact-form { + display: flex; + flex-direction: column; + } + + .contact-form label { + margin-bottom: 5px; + font-weight: bold; + color: #ffffff; + } + + .contact-form input, + .contact-form textarea { + padding: 10px; + margin-bottom: 20px; + background-color: #2a2a2a; + color: #f1f1f1; + border: 1px solid #444; + border-radius: 5px; + } + + .contact-form input:focus, + .contact-form textarea:focus { + outline: none; + border: 1px solid #00bcd4; + } + + .contact-form button { + background-color: #00bcd4; + color: #121212; + padding: 12px; + border: none; + border-radius: 5px; + font-weight: bold; + cursor: pointer; + transition: 0.3s; + } + + .contact-form button:hover { + background-color: #0097a7; + } + + + /* ---------------- */ +/* FOOTER */ +/* ---------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ + } + + .copyright { + padding: 10px 20px; + } + + footer a { + text-decoration: none; + color: #eff1f3; + } + + .footer_link { + display: flex; + flex-grow: 1; + gap: 10%; + } + + .footer_link a { + padding: 0 10px; + } + + .copyright { + padding: 10px 20px; + } + + + @media (max-width: 768px) { + /* HEADER */ + header { + flex-direction: column; + align-items: flex-start; + padding: 15px 20px; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + width: 100%; + margin-top: 10px; + } + + .bouton_connexion { + width: 100%; + text-align: center; + margin-top: 10px; + } + + #smart_building { + width: 40%; + margin-left: 0; + align-self: center; + } + + /* CONTACT */ + .contact-container { + width: 90%; + margin: 40px auto; + padding: 15px; + } + + .contact-container h1 { + font-size: 1.5em; + } + + .contact-form input, + .contact-form textarea { + font-size: 1rem; + } + + .contact-form button { + font-size: 1rem; + } + + /* FOOTER */ + footer { + flex-direction: column; + align-items: center; + text-align: center; + gap: 10px; + } + + .footer_link { + flex-direction: column; + gap: 8px; + } + + .footer_link a { + padding: 0; + } + } + \ No newline at end of file diff --git a/z1/webapp/public/styleInscription.css b/z1/webapp/public/styleInscription.css new file mode 100644 index 0000000..07bfff0 --- /dev/null +++ b/z1/webapp/public/styleInscription.css @@ -0,0 +1,484 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; + display: flex; + flex-direction: column; +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.header_text li a:hover { + color: #00a8e8; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* --------------------- */ +/* Inscription */ +/* --------------------- */ + +h1 { + font-size: 45px; /* Taille de la police */ + color: #eff1f3; + white-space: nowrap; +} + +label { + font-weight: bold; + font-size: 20px; + color: #eff1f3; + white-space: nowrap; +} + +select { + appearance: none; /* Supprime le style natif */ + background: white; + cursor: pointer; +} + +#inscription { + display: flex; /* AjoutĂ© pour aligner les enfants */ + justify-content: center; /* Centrer les Ă©lĂ©ments verticalement */ + align-items: center; /* Centrer les Ă©lĂ©ments horizontalement */ + flex: 1; /* Prend toute la hauteur de l'Ă©cran */ + margin-bottom: 50px; +} + +.tour { + width: 23%; + height: 640px; + border-radius: 33px; + padding-left: 8%; + background-image: url("/images/tour.jpg"); + background-size: cover; +} + +.page-inscription { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + border-radius: 24px; + background-color: #2c2c2c; + padding: 40px 100px; /* Augmente l'espace intĂ©rieur */ + width: 100%; /* Prend toute la largeur disponible */ + max-width: 400px; /* DĂ©finit une largeur max pour Ă©viter qu'elle ne devienne trop Ă©troite */ + box-shadow: 0 4px 8px 0 rgba(21, 21, 21, 0.2); +} + +.form-group { + width: 100%; + position: relative; /* Position relative */ + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; +} + +.form-group .icon { + position: absolute; + left: 15px; /* Ajuste la position des icĂŽnes */ + top: 50%; + transform: translateY(-50%); +} + +.form-group .icon svg { + width: 24px; + height: 24px; + fill: #191717; +} + +.form-control-inscription { + width: 100%; + padding-left: 50px; /* Remplissage Ă  gauche de 50px */ + padding-right: 40px; + height: 48px; /* Hauteur de 48px */ + border-radius: 34px; /* Bordure arrondie */ + font-size: 16px; /* Taille de la police */ + letter-spacing: 0.5px; /* Espacement des lettres */ + background-color: #eff1f3; /* Couleur de fond */ + border: none; /* Supprimer la bordure */ +} + +.form-row { + display: flex; + align-items: center; + gap: 10px; /* espace entre label et champ */ + flex-wrap: nowrap; /* Ă©vite le retour Ă  la ligne */ +} + +.bouton-inscription { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; /* Centrage vertical */ + cursor: pointer; +} + +.bouton-inscription:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +.boutons { + display: flex; + justify-content: center; + align-items: center; + gap: 20px; + margin-top: 20px; +} + +/* Alignement parfait du bouton "Photo" */ +.custom-file-upload { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + background-color: #004fa9; + color: #eff1f3; + padding: 10px 20px; + border-radius: 900px; + cursor: pointer; + font-size: 16px; + line-height: 1; +} + +.custom-file-upload:hover { + background-color: #eff1f3; + color: #004fa9; + border: 1px solid #004fa9; +} + +/* Alignement du SVG */ +.custom-file-upload svg { + width: 20px; + height: 20px; + vertical-align: middle; + padding-right: 4px; +} + +.case { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + margin-right: 9%; +} + +.lien { + background: none; + border: none; + font-family: inherit; /* pour garder la cohĂ©rence du texte */ + display: inline-block; /* Permet de mieux gĂ©rer la taille du soulignement */ + text-align: center; + margin-bottom: 15px; + font-size: 23px; /* Taille de la police */ + color: #eff1f3; + text-decoration: none; /* Supprime le soulignement par dĂ©faut */ + text-underline-offset: 10px; /* Augmente l'espace entre le texte et le soulignement */ + cursor: pointer; + padding-bottom: 10px; /* Ajoute un petit espace sous le texte */ + position: relative; /* Positionner l'Ă©lĂ©ment par rapport Ă  son parent */ +} + +.lien::after { + content: ""; + display: block; + width: 120%; /* La ligne est maintenant 1.5 fois plus grande que le texte */ + height: 2px; /* Épaisseur du soulignement */ + background-color: #eff1f3; /* Couleur du soulignement */ + position: absolute; + left: 50%; /* Centre la ligne horizontalement */ + transform: translateX( + -50% + ); /* DĂ©place la ligne pour qu'elle soit exactement centrĂ©e */ + bottom: 0; +} + +.lien:hover { + color: #0077b6; +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* ---------------------- */ +/* Media Queries */ +/* ---------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + h1 { + font-size: 48px; + } + + .tour { + height: 700px; + } + + .form-control-inscription { + font-size: 18px; + height: 52px; + } +} + +/* TABLETTE - Moyenne (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + h1 { + font-size: 48px; + } + + .tour { + height: 600px; + } + + .page-inscription { + padding: 40px; + } + + .form-control-inscription { + font-size: 16px; + } +} + +/* TABLETTE - Petite (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + #smart_building { + width: 100px; + margin: 0; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + h1 { + font-size: 40px; + text-align: center; + } + + .tour { + width: 100%; + height: 300px; + } + + .form-control-inscription { + font-size: 15px; + } +} + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + padding: 20px; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + width: auto; + padding: 10px 16px; + font-size: 14px; + } + + #smart_building { + width: 80px; + margin-left: 0; + } + + h1 { + font-size: 32px; + text-align: center; + } + + .tour { + height: 250px; + margin-bottom: 20px; + } + + .form-control-inscription { + font-size: 14px; + height: 44px; + } + + footer { + flex-direction: column; + gap: 10px; + text-align: center; + align-items: center; + } + + .footer_link { + flex-direction: column; + gap: 10px; + } + + .copyright { + padding: 0; + } +} + +/* TÉLÉPHONE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + h1 { + font-size: 26px; + } + + .form-control-inscription { + font-size: 13px; + padding-left: 40px; + height: 40px; + } + + .form-group .icon svg { + width: 20px; + height: 20px; + } + + .page-inscription { + padding: 20px 10px; + } + + .bouton-inscription { + font-size: 14px; + padding: 8px 14px; + } + + .lien { + font-size: 16px; + } + + .tour { + width: 60px; + } +} \ No newline at end of file diff --git a/z1/webapp/public/styleMembres.css b/z1/webapp/public/styleMembres.css new file mode 100644 index 0000000..35c04aa --- /dev/null +++ b/z1/webapp/public/styleMembres.css @@ -0,0 +1,576 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + font-family: "Inter", sans-serif; + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; /* DĂ©finit la hauteur de la page Ă  100% */ + display: flex; /* Flexbox sur le body */ + flex-direction: column; /* Aligne le contenu du body en colonne */ +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.header_text li a:hover { + color: #00a8e8; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* ---------------- */ +/* Membres */ +/* ---------------- */ + +main { + display: flex; + flex-grow: 1; /* Permet Ă  la section principale d'occuper l'espace restant */ + justify-content: center; /* Centre verticalement le contenu */ + align-items: center; /* Centre horizontalement le contenu */ + padding-bottom: 50px; + gap: 30px; /* Espace entre les 2 sections */ +} + +.left-panel { + flex: 3; /* 30% de la largeur totale */ + display: flex; + justify-content: center; /* Centrer l'image horizontalement */ + align-items: center; /* Centrer l'image verticalement */ +} + +.left-panel img { + width: 100%; /* L'image prend toute la largeur de son conteneur */ + max-width: 450px; /* Maximum de 300px de largeur */ + height: auto; /* La hauteur de l'image s'ajuste automatiquement */ + border-radius: 32px; +} + +.right-panel { + flex: 7; /* 70% de la largeur totale */ +} + +.right-panel h1 { + font-size: 60px; + margin-bottom: 60px; + padding-left: 50px; /* Ajoute un espacement Ă  gauche du titre */ +} + +#membres-container { + display: grid; + grid-template-columns: repeat(2, 1fr); /* 2 cartes par ligne */ + gap: 30px; + justify-items: center; + padding: 20px 60px; +} + +.membre { + width: 100%; /* occupe toute la colonne */ + max-width: 400px; /* limite visuelle de largeur */ + padding: 20px; + background-color: #2c2c2c; + color: #eff1f3; + border-radius: 20px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + transition: transform 0.2s ease, background-color 0.3s ease; + text-align: center; +} + +.membre:hover { + background-color: #dfe3e6; + transform: translateY(-5px); + color: #2c2c2c; + cursor: pointer; +} + +.membre h3 { + font-size: 22px; + margin: 10px 0 5px; +} + +.membre h4 { + font-size: 18px; + margin: 5px 0; + font-weight: 500; +} + +.membre p { + margin: 6px 0; + font-size: 16px; +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* -------------------- */ +/* Barre Recherche */ +/* -------------------- */ + +.form { + width: 300px; + margin: 0 50px; + font-size: 0.9rem; + display: flex; + gap: 0.5rem; + align-items: center; + position: relative; + isolation: isolate; + --input-text-color: #363636; + --input-bg-color: #eff1f3; + --focus-input-bg-color: transparent; + --text-color: #2a2a2a; + --active-color: #eff1f3; + --width-of-input: 250px; + --inline-padding-of-input: 1.2em; + --gap: 0.9rem; +} + +.fancy-bg { + position: absolute; + width: 100%; + inset: 0; + background: var(--input-bg-color); + border-radius: 30px; + height: 100%; + z-index: -1; + pointer-events: none; + box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px; +} + +label { + padding: 0.2em; + height: 40px; + padding-inline: var(--inline-padding-of-input); + display: flex; + align-items: center; +} + +.search, +.close-btn { + position: absolute; +} + +.search { + fill: var(--text-color); + left: var(--inline-padding-of-input); +} + +svg { + width: 17px; + display: block; +} + +.input { + color: var(--input-text-color); + width: 100%; + background: none; + border: none; + font-size: 1rem; + margin-inline: min(2em, calc(var(--inline-padding-of-input) + var(--gap))); +} + +.input:focus { + outline: none; + color: #eff1f3; +} + +.input:focus ~ .fancy-bg { + border: 1px solid var(--active-color); + background: var(--focus-input-bg-color); +} + +.input:focus ~ .search { + fill: var(--active-color); +} + +.input:valid ~ .close-btn { + visibility: visible; + color: #eff1f3; +} + +.close-btn { + right: var(--inline-padding-of-input); + background: none; + border: none; + box-shadow: none; + width: auto; + height: auto; + padding: 0; + opacity: 1; + color: #eff1f3; + visibility: hidden; + font-size: 20px; + cursor: pointer; +} + +.close-btn:hover, +.close-btn:focus { + background: none; + font-weight: bold; + transform: scale(1.2); +} + +.input:not(:focus):not(:placeholder-shown) { + color: #2a2a2a; +} + +.input:not(:focus):not(:placeholder-shown) ~ .search { + fill: #2a2a2a; +} + +.input:not(:focus):not(:placeholder-shown) ~ .close-btn { + color: #2a2a2a; +} + +.header-membres { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 70px; + margin-bottom: 60px; + flex-wrap: wrap; +} + +.header-membres h1 { + font-size: 60px; + margin: 0; + color: #eff1f3; +} + +/* ----------------------------- */ +/* Responsive Design */ +/* ----------------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + .right-panel h1, + .header-membres h1 { + font-size: 72px; + } + + .left-panel img { + max-width: 500px; + } +} + + +/* TABLETTE LARGE (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + .right-panel h1, + .header-membres h1 { + font-size: 56px; + padding-left: 80px; + } + + .header-membres { + padding: 0 50px; + } + + #membres-container { + padding: 20px 40px; + } + + .left-panel img { + max-width: 400px; + } +} + + +/* TABLETTE MOYENNE (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + #smart_building { + width: 100px; + margin: 0; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + main { + flex-direction: column; + padding: 40px; + } + + .right-panel, + .left-panel { + width: 100%; + flex: none; + } + + .features { + grid-template-columns: repeat(2, 1fr); + } + + .right-panel h1, + .header-membres h1 { + font-size: 42px; + padding-left: 0; + text-align: center; + } + + .header-membres { + padding: 0 30px; + justify-content: center; + gap: 30px; + } + + .form { + margin: 0 auto; + } + + #membres-container { + grid-template-columns: repeat(2, 1fr); + padding: 20px; + } +} + + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + } + + #smart_building { + width: 90px; + height: auto; + margin: 0 auto; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + padding: 10px 20px; + width: auto; + text-align: center; + } + + main { + flex-direction: column; + padding: 20px; + } + + .left-panel, + .right-panel { + width: 100%; + flex: unset; + } + + .right-panel h1, + .header-membres h1 { + font-size: 36px; + padding-left: 0; + text-align: center; + margin-bottom: 30px; + } + + .header-membres { + flex-direction: column; + align-items: center; + gap: 20px; + padding: 0 20px; + } + + .form { + width: 100%; + max-width: 300px; + } + + #membres-container { + grid-template-columns: 1fr; + padding: 10px; + } + + .membre { + max-width: 100%; + } + + footer { + flex-direction: column; + text-align: center; + gap: 10px; + align-items: center; + } + + .footer_link { + flex-direction: column; + gap: 10px; + } + + .copyright { + padding: 0; + } +} + + +/* MOBILE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + .right-panel h1, + .header-membres h1 { + font-size: 28px; + margin-bottom: 20px; + } + + .form { + width: 90%; + max-width: 280px; + } + + .input { + font-size: 0.9rem; + } + + .close-btn { + font-size: 16px; + } + + #membres-container { + gap: 20px; + } + + .membre { + padding: 16px; + font-size: 14px; + } + + .membre h3 { + font-size: 20px; + } + + .membre h4 { + font-size: 16px; + } + + .membre p { + font-size: 14px; + } +} + + +/* ------------------------ */ +/* Transitions GĂ©nĂ©rales */ +/* ------------------------ */ + +* { + transition: all 0.3s ease-in-out; +} \ No newline at end of file diff --git a/z1/webapp/public/styleObjets.css b/z1/webapp/public/styleObjets.css new file mode 100644 index 0000000..3527f87 --- /dev/null +++ b/z1/webapp/public/styleObjets.css @@ -0,0 +1,472 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + font-family: "Inter", sans-serif; + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; /* DĂ©finit la hauteur de la page Ă  100% */ + display: flex; /* Flexbox sur le body */ + flex-direction: column; /* Aligne le contenu du body en colonne */ +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* --------------- */ +/* Objets */ +/* --------------- */ + +main { + display: flex; + flex-grow: 1; /* Permet Ă  la section principale d'occuper l'espace restant */ + justify-content: center; /* Centre verticalement le contenu */ + align-items: center; /* Centre horizontalement le contenu */ + padding-bottom: 50px; + gap: 30px; /* Espace entre les 2 sections */ +} + +.left-panel { + flex: 3; /* 30% de la largeur totale */ + display: flex; + justify-content: center; /* Centrer l'image horizontalement */ + align-items: center; /* Centrer l'image verticalement */ +} + +.left-panel img { + width: 100%; /* L'image prend toute la largeur de son conteneur */ + max-width: 450px; /* Maximum de 300px de largeur */ + height: auto; /* La hauteur de l'image s'ajuste automatiquement */ + border-radius: 32px; +} + +.right-panel { + flex: 7; /* 70% de la largeur totale */ +} + +.right-panel h1 { + font-size: 60px; + margin-bottom: 60px; +} + +.header-objets { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 70px; + margin-bottom: 60px; + flex-wrap: wrap; +} + +.header-objets h1 { + font-size: 60px; + margin: 0; + color: #eff1f3; +} + +#objets-container { + display: grid; + grid-template-columns: repeat(3, 1fr); /* 3 cartes par ligne */ + gap: 20px; + justify-items: center; + padding: 20px 60px; +} + +.objet { + width: 100%; + max-width: 300px; /* Limite la largeur des cartes pour que ça soit plus joli */ + padding: 20px; + background-color: #2c2c2c; + color: #eff1f3; + border-radius: 10px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + transition: transform 0.2s ease, background-color 0.3s ease; + text-align: center; +} + +.objet:hover { + transform: translateY(-5px); + background-color: #dfe3e6; + color: #2c2c2c; + cursor: pointer; +} + +.objet h3 { + font-size: 22px; + margin: 10px 0 5px; +} + +.etat-point { + width: 12px; + height: 12px; + border-radius: 50%; + position: absolute; + bottom: 5px; + right: 5px; +} + +.etat-point.actif { + background-color: rgb(100, 236, 100); +} + +.etat-point.inactif { + background-color: rgb(240, 84, 84); +} + +.setting-btn { + background: none; + border: none; + text-align: center; + cursor: pointer; +} + +.setting-btn i { + font-size: 20px; + color: #a8a3a3; +} + +.setting-btn:hover i { + transform: scale(1.4); + transition: transform 0.2s ease; +} + +.objet:hover i { + color: #2c2c2c; +} + + +.info_objet{ + display: flex; + align-items: center; + justify-content: space-between; +} + +.info_objet h2{ + margin-bottom: 100px; +} + +.info_objet h4{ + margin:0px; +} + +.actions{ + display: flex; + align-items: center; + justify-content: space-between; +} + +.edit-button { + background: none; + border: none; + padding: 0; + margin: 0; + cursor: pointer; + display: flex; + align-items: center; +} + +.edit-button i { + font-size: 14px; + color: #eff1f3; + transition: transform 0.2s ease; + transform: translateY(-2px); +} + +.edit-button:hover i { + transform: scale(1.3) translateY(-2px); +} + +.inline-edit { + display: flex; + align-items: center; + gap: 10px; +} + +.inline-edit h2, +.inline-edit p { + margin: 0; +} + +[contenteditable="true"] { + border: 1px solid #eff1f3; /* Bordure fine autour de l'Ă©lĂ©ment modifiable */ + border-radius: 4px; /* Bords arrondis pour un style plus doux */ + padding: 3px 5px; /* Un peu de padding pour l'esthĂ©tique */ + box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); /* Ombre lĂ©gĂšre autour de l'Ă©lĂ©ment */ +} + +/* Style modal */ +.modal { + display: none; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(60, 60, 60, 0.98); /* Plus clair que le fond de base */ + backdrop-filter: blur(12px); /* Plus de flou = plus de sĂ©paration */ + padding: 30px; + border-radius: 20px; + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.8); /* Ombre plus forte */ + color: #eff1f3; + max-width: 450px; + width: 90%; + z-index: 1000; + animation: fadeIn 0.3s ease; + border: 1px solid rgba(255, 255, 255, 0.1); /* LĂ©ger contour clair */ +} + +.modal-content { + display: flex; + flex-direction: column; + gap: 20px; +} + +.modal h2 { + font-size: 24px; + margin-bottom: 10px; + color: #eff1f3; +} + +.modal p { + font-size: 16px; + line-height: 1.4; +} + +.modal .close { + position: absolute; + top: 10px; + right: 15px; + font-size: 22px; + font-weight: bold; + color: #eff1f3; + cursor: pointer; + transition: transform 0.2s ease, color 0.2s ease; +} + +.modal .close:hover { + color: #ff4d4d; + transform: scale(1.2); +} + +/* -------------------- */ +/* Barre Recherche */ +/* -------------------- */ + +.form { + width: 300px; + margin: 0; + font-size: 0.9rem; + display: flex; + gap: 0.5rem; + align-items: center; + position: relative; + isolation: isolate; + --input-text-color: #363636; + --input-bg-color: #eff1f3; + --focus-input-bg-color: transparent; + --text-color: #2a2a2a; + --active-color: #eff1f3; + --width-of-input: 250px; + --inline-padding-of-input: 1.2em; + --gap: 0.9rem; +} + +.fancy-bg { + position: absolute; + width: 100%; + inset: 0; + background: var(--input-bg-color); + border-radius: 30px; + height: 100%; + z-index: -1; + pointer-events: none; + box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px; +} + +label { + padding: 0.2em; + height: 40px; + padding-inline: var(--inline-padding-of-input); + display: flex; + align-items: center; +} + +.search, +.close-btn { + position: absolute; +} + +.search { + fill: var(--text-color); + left: var(--inline-padding-of-input); +} + +svg { + width: 17px; + display: block; +} + +.input { + color: var(--input-text-color); /* La couleur du texte par dĂ©faut */ + width: 100%; + margin-inline: min(2em, calc(var(--inline-padding-of-input) + var(--gap))); + background: none; + border: none; +} + +.input:focus { + outline: none; + color: #eff1f3; +} + +/* input background change in focus */ +.input:focus ~ .fancy-bg { + border: 1px solid var(--active-color); + background: var(--focus-input-bg-color); +} + +/* search icon color change in focus */ +.input:focus ~ .search { + fill: var(--active-color); +} + +/* showing close button when typing */ +.input:valid ~ .close-btn { + visibility: visible; /* Si l'input est valide, rendre le bouton visible */ + color: #eff1f3; /* Garde l'icĂŽne en blanc */ +} + +.close-btn { + right: var(--inline-padding-of-input); + background: none; + border: none; + box-shadow: none; + width: auto; + height: auto; + padding: 0; + opacity: 1; + color: #eff1f3; + visibility: hidden; + font-size: 20px; + cursor: pointer; +} + +.close-btn:hover, +.close-btn:focus { + background: none; + font-weight: bold; + transform: scale(1.2); /* LĂ©gĂšrement agrandit l'icĂŽne pour la rendre plus Ă©vidente */ +} + +.input:not(:focus):not(:placeholder-shown) { + color: #2a2a2a; /* Couleur texte sombre si champ rempli mais pas focus */ +} + +.input:not(:focus):not(:placeholder-shown) ~ .search { + fill: #2a2a2a; /* Loupe sombre quand input rempli mais pas focus */ +} + +.input:not(:focus):not(:placeholder-shown) ~ .close-btn { + color: #2a2a2a; /* Croix sombre Ă©galement */ +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} \ No newline at end of file diff --git a/z1/webapp/public/styleProfil.css b/z1/webapp/public/styleProfil.css new file mode 100644 index 0000000..5e20af0 --- /dev/null +++ b/z1/webapp/public/styleProfil.css @@ -0,0 +1,378 @@ +/* ------------- */ +/* HTML */ +/* ------------- */ + +html, +body { + font-family: "Inter", sans-serif; + background-color: #1e1e1e; + color: #eff1f3; + margin: 0; + padding: 0; + overflow: auto; + height: 100%; /* DĂ©finit la hauteur de la page Ă  100% */ + display: flex; /* Flexbox sur le body */ + flex-direction: column; /* Aligne le contenu du body en colonne */ +} + +/* --------------- */ +/* Header */ +/* --------------- */ + +header { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: 10px 40px; +} + +header a { + text-decoration: none; + color: #eff1f3; +} + +header ul { + list-style: none; + display: flex; + align-items: center; +} + +header li { + cursor: pointer; +} + +.header_text { + display: flex; + flex-grow: 1; /* Le conteneur des liens prend toute la place disponible */ + justify-content: center; /* Centre les liens horizontalement */ + gap: 15%; /* Espace entre les liens */ + font-weight: 600; +} + +.header_text a { + padding: 0 10px; +} + +.header_text li a:hover { + color: #00a8e8; +} + +.bouton_connexion { + padding: 10px 20px; + border-radius: 900px; + font-size: 16px; /* Taille de la police */ + border-color: #00a8e8; + color: #eff1f3; + background-color: #00a8e8; + margin-top: 0; + cursor: pointer; +} + +.bouton_connexion:hover { + border-color: #eff1f3; + color: #00a8e8; + background-color: #eff1f3; /* Changer la couleur au survol */ +} + +#smart_building { + width: 13%; + margin-left: -40px; + height: auto; +} + +/* --------------- */ +/* Profil */ +/* --------------- */ + +/* Conteneur Profil */ +.container { + width: 80%; /* Adaptation Ă  la nouvelle structure, largeur plus grande */ + max-width: 800px; /* Limite la taille maximale Ă  800px */ + margin: 50px auto; /* Centre le conteneur et ajoute un espacement */ + background-color: #2c2c2c; + padding: 30px 40px; + border-radius: 15px; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.6); + display: flex; + flex-direction: column; /* Assure un alignement vertical des Ă©lĂ©ments */ + gap: 20px; /* Espacement entre les Ă©lĂ©ments internes */ + z-index: 1; /* Pour s'assurer que ce contenu reste bien en-dessous de l'en-tĂȘte */ +} + +/* Titre */ +h1 { + text-align: center; + margin-bottom: 30px; + color: #ffffff; +} + +/* Formulaire Profil */ +form div { + margin-bottom: 20px; +} + +label { + display: block; + margin-bottom: 8px; + font-weight: bold; + color: #ccc; +} + +/* Champs de saisie */ +input[type="text"], +input[type="password"], +input[type="file"], +select { + width: 100%; + padding: 10px 12px; + font-size: 14px; + background-color: #3a3a3a; + color: #ffffff; + border: 1px solid #555; + border-radius: 8px; + box-sizing: border-box; + transition: border-color 0.3s; +} + +/* Champs dĂ©sactivĂ©s */ +input:disabled, +select:disabled { + background-color: #2c2c2c; + color: #888; + border: 1px solid #444; + cursor: not-allowed; +} + +/* Image de profil */ +.container img { + margin-top: 10px; + border-radius: 10px; + border: 2px solid #444; + max-width: 100px; + height: auto; +} + +/* Boutons (Editer, Sauvegarder) */ +button { + padding: 10px 16px; + border: none; + border-radius: 8px; + font-size: 15px; + cursor: pointer; + transition: background-color 0.3s ease; + color: white; +} + +/* Bouton Modifier */ +#editBtn { + background-color: #27ae60; +} + +#editBtn:hover { + background-color: #219150; +} + +/* Bouton Sauvegarder */ +#saveBtn { + background-color: #e67e22; +} + +#saveBtn:hover { + background-color: #d35400; +} + +/* --------------- */ +/* Footer */ +/* --------------- */ + +footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + font-size: 14px; + text-transform: uppercase; + padding: 20px; + margin-top: auto; /* Cela force le footer Ă  se pousser vers le bas */ +} + +.copyright { + padding: 10px 20px; +} + +footer a { + text-decoration: none; + color: #eff1f3; +} + +.footer_link { + display: flex; + flex-grow: 1; + gap: 10%; +} + +.footer_link a { + padding: 0 10px; +} + +.copyright { + padding: 10px 20px; +} + +/* ------------------------- */ +/* Responsive Design */ +/* ------------------------- */ + +/* GRAND ÉCRAN (> 1440px) */ +@media (min-width: 1440px) { + main { + padding: 60px; + max-width: 1200px; + } + + .container { + width: 70%; + } + + h1 { + font-size: 48px; + } + + .bouton_connexion { + padding: 12px 24px; + font-size: 18px; + } +} + +/* TABLETTE - Moyenne (1025px Ă  1440px) */ +@media (max-width: 1440px) and (min-width: 1025px) { + .container { + width: 75%; + max-width: 1000px; + } + + h1 { + font-size: 40px; + } + + .bouton_connexion { + padding: 10px 20px; + font-size: 16px; + } +} + +/* TABLETTE - Petite (769px Ă  1024px) */ +@media (max-width: 1024px) and (min-width: 769px) { + header { + flex-wrap: wrap; + justify-content: center; + padding: 20px; + gap: 20px; + } + + #smart_building { + width: 100px; + margin: 0; + } + + .header_text { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 30px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + .container { + width: 90%; + max-width: 1000px; + } + + h1 { + font-size: 36px; + margin-bottom: 20px; + } +} + +/* MOBILE (≀ 768px) */ +@media (max-width: 768px) { + header { + flex-direction: column; + align-items: center; + gap: 15px; + } + + #smart_building { + width: 90px; + height: auto; + margin: 0 auto; + } + + .header_text { + flex-direction: column; + align-items: center; + gap: 10px; + font-size: 16px; + } + + .bouton_connexion { + padding: 10px 20px; + width: auto; + text-align: center; + } + + .container { + width: 100%; + max-width: 100%; + padding: 20px; + } + + h1 { + font-size: 28px; + margin-bottom: 20px; + } + + footer { + flex-direction: column; + text-align: center; + gap: 10px; + align-items: center; + } + + .footer_link { + flex-direction: column; + align-items: center; + gap: 10px; + } + + .copyright { + padding: 0; + } +} + +/* TÉLÉPHONE TRÈS PETIT (≀ 480px) */ +@media (max-width: 480px) { + .container { + width: 100%; + padding: 10px; + } + + h1 { + font-size: 24px; + margin-bottom: 20px; + } + + .bouton_connexion { + padding: 8px 16px; + font-size: 14px; + } + + #smart_building { + width: 70px; + } +} \ No newline at end of file diff --git a/z1/webapp/query b/z1/webapp/query new file mode 100644 index 0000000..0eaebf1 --- /dev/null +++ b/z1/webapp/query @@ -0,0 +1 @@ +mysql diff --git a/z1/webapp/routes/admin.js b/z1/webapp/routes/admin.js new file mode 100644 index 0000000..411f158 --- /dev/null +++ b/z1/webapp/routes/admin.js @@ -0,0 +1,115 @@ +const express = require('express'); +const router = express.Router(); +const db = require('../config/db'); + +// Middleware de protection admin (dĂ©fini ici si non global) +const requireAdmin = (req, res, next) => { + if (!req.session.utilisateur || req.session.utilisateur.statut !== 'administrateur') { + return res.send(` + + `); + } + next(); +}; + +// Applique le middleware Ă  toutes les routes de ce fichier +router.use(requireAdmin); + +// Route principale - admin dashboard +router.get('/', (req, res) => { + const usersQuery = 'SELECT * FROM utilisateur'; + const objetsQuery = 'SELECT * FROM objet'; + const contactsQuery = 'SELECT * FROM contact'; // RĂ©cupĂ©rer les messages de contact + + db.query(usersQuery, (err, utilisateurs) => { + if (err) return res.status(500).send('Erreur rĂ©cupĂ©ration utilisateurs'); + + db.query(objetsQuery, (err2, objets) => { + if (err2) return res.status(500).send('Erreur rĂ©cupĂ©ration objets'); + + db.query(contactsQuery, (err3, contacts) => { + if (err3) return res.status(500).send('Erreur rĂ©cupĂ©ration messages'); + res.render('admin', { utilisateurs, objets, contacts }); + }); + }); + }); +}); + +// Mise Ă  jour utilisateur +router.post('/update-user', (req, res) => { + const { id, etat, statut } = req.body; + const sql = 'UPDATE utilisateur SET etat = ?, statut = ? WHERE id = ?'; + + db.query(sql, [etat, statut, id], (err) => { + if (err) { + console.error('Erreur update utilisateur :', err); + return res.status(500).send('Erreur update utilisateur'); + } + res.redirect('/admin'); + }); +}); + +// Suppression utilisateur +router.post('/supprimer-user', (req, res) => { + const { id } = req.body; + const sql = 'DELETE FROM utilisateur WHERE id = ?'; + + db.query(sql, [id], (err) => { + if (err) { + console.error('Erreur suppression utilisateur :', err); + return res.status(500).send("Erreur lors de la suppression de l'utilisateur"); + } + res.redirect('/admin'); + }); +}); + +// Mise Ă  jour objet +router.post('/update-objet', (req, res) => { + const { adresse_ip, niveau, etat, type } = req.body; + const sql = 'UPDATE objet SET niveau = ?, etat = ?, type = ? WHERE adresse_ip = ?'; + + db.query(sql, [niveau, etat, type, adresse_ip], (err) => { + if (err) { + console.error('Erreur update objet :', err); + return res.status(500).send('Erreur update objet'); + } + res.redirect('/admin'); + }); +}); + +// Suppression objet + dĂ©pendances +router.post('/supprimer-objet', (req, res) => { + const { adresse_ip } = req.body; + const deleteChildTables = ['climatisation_chauffage', 'thermostat', 'appareil_menager', 'securite']; + + const deleteFromTable = (table) => { + return new Promise((resolve, reject) => { + const sql = `DELETE FROM ${table} WHERE adresse_ip = ?`; + db.query(sql, [adresse_ip], (err) => { + if (err) return reject(err); + resolve(); + }); + }); + }; + + Promise.all(deleteChildTables.map(deleteFromTable)) + .then(() => { + const sql = 'DELETE FROM objet WHERE adresse_ip = ?'; + db.query(sql, [adresse_ip], (err) => { + if (err) { + console.error('Erreur suppression objet :', err); + return res.status(500).send("Erreur lors de la suppression de l'objet"); + } + res.redirect('/admin'); + }); + }) + .catch(err => { + console.error("Erreur suppression dĂ©pendances : ", err); + res.status(500).send("Erreur lors de la suppression des dĂ©pendances liĂ©es Ă  l'objet"); + }); +}); + +module.exports = router; diff --git a/z1/webapp/routes/api/objet.js b/z1/webapp/routes/api/objet.js new file mode 100644 index 0000000..db2b9d1 --- /dev/null +++ b/z1/webapp/routes/api/objet.js @@ -0,0 +1,56 @@ +const express = require('express'); +const router = express.Router(); +const db = require('../../config/db'); + +router.get('/', (req, res) => { + const sql = ` + SELECT + objet.adresse_ip, + objet.niveau, + objet.denomination, + objet.etat, + objet.derniere_interaction, + objet.type, + thermostat.temperature_actuelle, + thermostat.temperature_cible, + thermostat.mode, + appareil_menager.depart_differe, + appareil_menager.etat_de_la_tache, + securite.situation AS situation_securite + FROM objet + LEFT JOIN thermostat ON objet.adresse_ip = thermostat.adresse_ip + LEFT JOIN appareil_menager ON objet.adresse_ip = appareil_menager.adresse_ip + LEFT JOIN securite ON objet.adresse_ip = securite.adresse_ip + `; + + db.query(sql, (err, result) => { + if (err) { + console.error('Erreur lors de la rĂ©cupĂ©ration des objets :', err); + return res.status(500).send('Erreur serveur'); + } + res.json(result); + }); +}); + + +router.put('/:adresse_ip', (req, res) => { + const adresse_ip = req.params.adresse_ip; + const champs = req.body; + + const setValues = Object.keys(champs) + .map(key => `${key} = ?`) + .join(', '); + + const sql = `UPDATE objet SET ${setValues} WHERE adresse_ip = ?`; + const values = [...Object.values(champs), adresse_ip]; + + db.query(sql, values, (err) => { + if (err) { + console.error('Erreur lors de la mise Ă  jour de l\'objet :', err); + return res.status(500).send('Erreur serveur'); + } + res.sendStatus(200); + }); +}); + +module.exports = router; diff --git a/z1/webapp/routes/api/ressource.js b/z1/webapp/routes/api/ressource.js new file mode 100644 index 0000000..f935f1c --- /dev/null +++ b/z1/webapp/routes/api/ressource.js @@ -0,0 +1,34 @@ +const express = require('express'); +const router = express.Router(); +const db = require('../../config/db'); // Connexion Ă  la base de donnĂ©es + +// Route pour rĂ©cupĂ©rer les ressources +router.get('/', (req, res) => { + const search = req.query.search || ''; + + if (search) { + const sql = 'SELECT * FROM ressources WHERE nom LIKE ?'; + const values = [`%${search}%`]; + + db.query(sql, values, (err, results) => { + if (err) { + console.error('Erreur lors de la recherche des ressources :', err); + res.status(500).send('Erreur serveur'); + } else { + res.json(results); + } + }); + } else { + const sql = 'SELECT * FROM ressources'; + db.query(sql, (err, results) => { + if (err) { + console.error('Erreur lors de la rĂ©cupĂ©ration des ressources :', err); + res.status(500).send('Erreur serveur'); + } else { + res.json(results); + } + }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/z1/webapp/routes/api/utilisateur.js b/z1/webapp/routes/api/utilisateur.js new file mode 100644 index 0000000..f09e046 --- /dev/null +++ b/z1/webapp/routes/api/utilisateur.js @@ -0,0 +1,18 @@ +const express = require('express'); +const router = express.Router(); +const db = require('../../config/db'); // Connexion Ă  la base de donnĂ©es + +// Route pour rĂ©cupĂ©rer les objets +router.get('/', (req, res) => { + const sql = 'SELECT * FROM utilisateur'; + db.query(sql, (err, results) => { + if (err) { + console.error('Erreur lors de la rĂ©cupĂ©ration des objets :', err); + res.status(500).send('Erreur serveur'); + } else { + res.json(results); // Retourne les objets sous forme de JSON + } + }); +}); + +module.exports = router; diff --git a/z1/webapp/routes/complexe.js b/z1/webapp/routes/complexe.js new file mode 100644 index 0000000..66efdf3 --- /dev/null +++ b/z1/webapp/routes/complexe.js @@ -0,0 +1,77 @@ +const express = require('express'); +const router = express.Router(); +const db = require('../config/db'); + +// Modifier un objet +router.post('/update-objet', (req, res) => { + const { adresse_ip, niveau, etat } = req.body; + const sql = 'UPDATE objet SET niveau = ?, etat = ? WHERE adresse_ip = ?'; + + db.query(sql, [niveau, etat, adresse_ip], (err) => { + if (err) { + console.error("Erreur lors de la modification de l'objet :", err); + return res.status(500).send("Erreur lors de la modification de l'objet"); + } + res.redirect('/dashboard-complexe'); + }); +}); + +// Supprimer un objet (et ses dĂ©pendances) +router.post('/supprimer-objet', (req, res) => { + const { adresse_ip } = req.body; + console.log('Adresse IP reçue pour suppression :', adresse_ip); + + const deleteChildTables = [ + 'climatisation_chauffage', + 'thermostat', + 'appareil_menager', + 'securite' + ]; + + const deleteFromTable = (table) => { + return new Promise((resolve, reject) => { + const sql = `DELETE FROM ${table} WHERE adresse_ip = ?`; + db.query(sql, [adresse_ip], (err) => { + if (err) { + console.error(`Erreur suppression dans ${table} :`, err); + return reject(err); + } + resolve(); + }); + }); + }; + + Promise.all(deleteChildTables.map(deleteFromTable)) + .then(() => { + db.query('DELETE FROM objet WHERE adresse_ip = ?', [adresse_ip], (err) => { + if (err) { + console.error('Erreur suppression objet :', err); + return res.status(500).send("Erreur lors de la suppression de l'objet"); + } + res.redirect('/dashboard-complexe'); + }); + }) + .catch(err => { + res.status(500).send("Erreur lors de la suppression d'une dĂ©pendance liĂ©e Ă  l'objet"); + }); +}); + +// Ajouter un objet +router.post('/ajouter-objet', (req, res) => { + const { denomination, adresse_ip, type, niveau, etat } = req.body; + + const sql = ` + INSERT INTO objet (denomination, adresse_ip, type, niveau, etat) + VALUES (?, ?, ?, ?, ?)`; + + db.query(sql, [denomination, adresse_ip, type, niveau, etat], (err) => { + if (err) { + console.error('Erreur ajout objet :', err); + return res.status(500).send("Erreur lors de l'ajout de l'objet"); + } + + res.redirect('/dashboard-complexe'); + }); +}); + +module.exports = router; diff --git a/z1/webapp/routes/connexion.js b/z1/webapp/routes/connexion.js new file mode 100644 index 0000000..3b107c0 --- /dev/null +++ b/z1/webapp/routes/connexion.js @@ -0,0 +1,52 @@ +const express = require('express'); +const router = express.Router(); +const bcrypt = require('bcrypt'); +const db = require('../config/db'); + +// Connexion - Formulaire +router.get('/', (req, res) => { + res.render('connexion'); +}); + +// Connexion - Traitement +router.post('/', (req, res) => { + const { identifiant, mot_de_passe } = req.body; + + const sql = 'SELECT * FROM utilisateur WHERE identifiant = ?'; + db.query(sql, [identifiant], async (err, results) => { + if (err) { + console.error('Erreur lors de la requĂȘte :', err); + return res.send('Erreur serveur'); + } + + if (results.length === 0) { + return res.send('Identifiant incorrect'); + } + + const utilisateur = results[0]; + const match = await bcrypt.compare(mot_de_passe, utilisateur.mot_de_passe); + + if (!match) { + return res.send('Mot de passe incorrect'); + } + + // Enregistrement en session + req.session.utilisateur = utilisateur; + console.log("Utilisateur connectĂ© :", req.session.utilisateur); + + // Redirection selon le statut + switch (utilisateur.statut) { + case 'administrateur': + return res.redirect('/admin'); + case 'complexe': + return res.redirect('/dashboard-complexe'); + case 'simple': + return res.redirect('/objets'); // 🔄 Redirection mise Ă  jour ici + case 'visiteur': + default: + return res.redirect('/'); + } + }); +}); + +module.exports = router; diff --git a/z1/webapp/routes/inscription.js b/z1/webapp/routes/inscription.js new file mode 100644 index 0000000..31e9303 --- /dev/null +++ b/z1/webapp/routes/inscription.js @@ -0,0 +1,44 @@ +const express = require('express'); +const router = express.Router(); +const bcrypt = require('bcrypt'); +const db = require('../config/db'); +const multer = require('multer'); +const path = require('path'); + + +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + const uploadDir = path.join(__dirname, '../img'); + cb(null, uploadDir); + }, + filename: (req, file, cb) => { + const uniqueName = `${Date.now()}_${file.originalname}`; + cb(null, uniqueName); + } +}); + +const upload = multer({ storage }); + + +router.get('/', (req, res) => { + res.render('inscription'); +}); + +router.post('/', upload.single('photo_profil'), async (req, res) => { + const { nom, prenom, sexe, age, date_naissance, identifiant, mot_de_passe, situation, email } = req.body; + const photo = req.file ? req.file.filename : null; + const hashedPassword = await bcrypt.hash(mot_de_passe, 10); + + const sql = `INSERT INTO utilisateur (nom, prenom, sexe, age, date_naissance, identifiant, mot_de_passe, photo, situation, email) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; + + db.query(sql, [nom, prenom, sexe, age, date_naissance, identifiant, hashedPassword, photo, situation, email], (err, result) => { + if (err) { + console.error(err); + return res.send('Erreur lors de l’inscription'); + } + res.redirect('/connexion'); + }); +}); + +module.exports = router; diff --git a/z1/webapp/routes/profil.js b/z1/webapp/routes/profil.js new file mode 100644 index 0000000..dd65ba3 --- /dev/null +++ b/z1/webapp/routes/profil.js @@ -0,0 +1,56 @@ +const express = require('express'); +const router = express.Router(); +const ensureAuthenticated = require('../middleware/auth'); +const db = require('../config/db'); +const multer = require('multer'); +const bcrypt = require('bcrypt'); +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + cb(null, 'photos'); + }, + filename: (req, file, cb) => { + const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); + cb(null, uniqueSuffix + '-' + file.originalname); // Nom unique pour Ă©viter les conflits + } +}); + +const upload = multer({ + storage: storage, + limits: { fileSize: 5 * 1024 * 1024 }, // Limite de taille (5 Mo) +}).fields([ + { name: 'photo', maxCount: 1 }, // Champ pour le fichier +]); + + + +router.get('/', ensureAuthenticated, (req, res) => { + const utilisateur = req.session.utilisateur; + res.render('profil', { utilisateur }); +}); + +router.post('/update', ensureAuthenticated, upload, (req, res) => { + const mot_de_passe = req.body.mot_de_passe ? bcrypt.hashSync(req.body.mot_de_passe, 10) : req.session.utilisateur.mot_de_passe; + const { identifiant, nom, prenom, sexe, situation } = req.body; + const photo = req.files && req.files.photo ? req.files.photo[0].filename : req.session.utilisateur.photo; + const id = req.session.utilisateur.id; + + const sql = 'UPDATE utilisateur SET identifiant = ?, nom = ?, prenom = ?, sexe = ?, situation = ?, photo = ?, mot_de_passe = ? WHERE id = ?'; + db.query(sql, [identifiant, nom, prenom, sexe, situation, photo, mot_de_passe, id], (err, result) => { + if (err) { + console.error(err); + return res.status(500).send("Erreur lors de la mise Ă  jour"); + } + + req.session.utilisateur.identifiant = identifiant; + req.session.utilisateur.nom = nom; + req.session.utilisateur.prenom = prenom; + req.session.utilisateur.sexe = sexe; + req.session.utilisateur.situation = situation; + req.session.utilisateur.photo = photo; + req.session.utilisateur.mot_de_passe = mot_de_passe; + + res.redirect('/profil'); + }); +}); + +module.exports = router; diff --git a/z1/webapp/user.sql b/z1/webapp/user.sql new file mode 100644 index 0000000..341cfd4 --- /dev/null +++ b/z1/webapp/user.sql @@ -0,0 +1,156 @@ +-- CrĂ©ation de la base de donnĂ©es et sĂ©lection +CREATE DATABASE IF NOT EXISTS user; +USE user; + +SET NAMES utf8mb4; + +-- Table `utilisateur` +CREATE TABLE IF NOT EXISTS `utilisateur` ( + `id` INT NOT NULL AUTO_INCREMENT, + `nom` VARCHAR(100) NOT NULL, + `prenom` VARCHAR(100) NOT NULL, + `sexe` ENUM('Homme', 'Femme', 'Autre') NOT NULL, + `age` INT DEFAULT NULL, + `date_naissance` DATE NOT NULL, + `identifiant` VARCHAR(50) NOT NULL UNIQUE, + `email` VARCHAR(255) NOT NULL UNIQUE, + `mot_de_passe` VARCHAR(255) NOT NULL, + `photo` VARCHAR(255) DEFAULT NULL, + `situation` VARCHAR(255) DEFAULT NULL, + `etat` ENUM('en attente', 'validĂ©') DEFAULT 'en attente', + `statut` ENUM('visiteur','simple','complexe','administrateur') DEFAULT 'visiteur', + PRIMARY KEY (`id`) +); + +INSERT INTO `utilisateur` VALUES +(1, 'Dupont', 'Jean', 'Homme', 30, '1994-05-12', 'jdupont', 'jean.dupont@mail.com', '$2b$10$sOFuc/cZzpK1P8fINfmsAOQ33K0xyCeEXD.OCilFH0SPyuMC.3LNC', './photos/jean.jpg', 'IngĂ©nieur', 'validĂ©', 'complexe'), -- mots de passe dupont +(2, 'Martin', 'Sophie', 'Femme', 25, '1999-08-21', 'smartin', 'sophie.martin@mail.com', '$2b$10$ydWLQyCvL8PVAN18KCWBWe.oMdtm7Y.R4oCVVJenP9fJqfyBLR26C', './photos/sophie.jpg', 'Étudiante', 'en attente', 'visiteur'), -- mots de passe martin +(3, 'Durand', 'Paul', 'Homme', 45, '1979-11-30', 'pdurand', 'paul.durand@mail.com', '$2b$10$HnhXjkKOPNLE.2erAwzg.e5zVVRK/wNeegd8GrNxWv2f3U660xQbW', './photos/paul.jpg', 'Directeur', 'validĂ©', 'administrateur'), -- mots de passe durand +(4, 'Bernard', 'Alice', 'Femme', 28, '1996-02-15', 'aliceb', 'alice.bernard@mail.com', '$2b$10$6BslSk7oJc6fGzQx3YQRHu6Op8xtVQIGFznA0vsmZX40Ix4ywBTfy', './photos/alice.jpg', 'DĂ©veloppeuse', 'validĂ©', 'simple'), -- mots de passe bernard +(5, 'Lemoine', 'Alex', 'Autre', 32, '1992-07-19', 'alemoine', 'alex.lemoine@mail.com', '$2b$10$lZebS.LIRJi9Z5yDaLSNxujY0piysZAb9BRjGOLVW3Hr2wDPoYTgO', './photos/alex.jpg', 'Freelance', 'en attente', 'simple'), -- mots de passe lemoine +(6, 'Arricastres', 'Guillaume', 'Homme', 26, '1998-01-15', 'garricastres', 'guillaume.arricastres@mail.com', '$2b$10$StE4wQ2Mox/CUpuR.o/1nObQMT/rAAndmKXOgAJ7r.V/YGvEs7isy', './photos/guillaume.jpg', 'Étudiant', 'validĂ©', 'simple'), -- mots de passe 1234 +(7, 'Chosson', 'ClĂ©ment', 'Homme', 25, '1999-06-15', 'clement_cx', 'clement.chosson@mail.com', '$2b$10$StE4wQ2Mox/CUpuR.o/1nObQMT/rAAndmKXOgAJ7r.V/YGvEs7isy', NULL, 'Technicien', 'validĂ©', 'complexe'), -- mots de passe 1234 +(8, 'Admin', 'Root', 'Homme', 30, '1993-12-31', 'admin', 'admin@smartbuilding.com', '$2b$10$StE4wQ2Mox/CUpuR.o/1nObQMT/rAAndmKXOgAJ7r.V/YGvEs7isy', NULL, 'Administrateur', 'validĂ©', 'administrateur'); -- mots de passe 1234 + + +-- Table `objet` +CREATE TABLE IF NOT EXISTS `objet` ( + `adresse_ip` VARCHAR(45) NOT NULL, + `niveau` ENUM('dĂ©butant','intermĂ©diaire','avancĂ©','expert') NOT NULL, + `denomination` VARCHAR(255) NOT NULL, + `etat` ENUM('Actif','Inactif') NOT NULL, + `derniere_interaction` DATETIME DEFAULT NULL, + `type` ENUM('Climatisation','LumiĂšre','thermostat','securite','Enceinte connectĂ©e','Capteur','appareil_menager','Prise') NOT NULL, + PRIMARY KEY (`adresse_ip`) +); + +INSERT INTO `objet` VALUES +('192.168.1.10', 'dĂ©butant', 'Ampoule connectĂ©e', 'Inactif', '2025-04-08 10:40:50', 'LumiĂšre'), +('192.168.1.11', 'dĂ©butant', 'CuisiniĂšre', 'Inactif', '2025-04-08 10:40:50', 'appareil_menager'), +('192.168.1.12', 'dĂ©butant', 'Machine Ă  cafĂ©', 'Inactif', '2025-04-08 10:40:50', 'appareil_menager'), +('192.168.1.20', 'intermĂ©diaire', 'Thermostat intelligent', 'Actif', '2025-04-08 10:40:50', 'thermostat'), +('192.168.1.30', 'avancĂ©', 'CamĂ©ra de surveillance', 'Actif', '2025-04-08 10:40:50', 'Capteur'), +('192.168.1.40', 'dĂ©butant', 'Machine Ă  laver', 'Inactif', '2025-04-08 10:40:50', 'appareil_menager'), +('192.168.1.50', 'dĂ©butant', 'Enceinte intelligente', 'Inactif', '2025-04-08 10:40:50', 'Enceinte connectĂ©e'), +('192.168.1.60', 'intermĂ©diaire', 'Prise connectĂ©e', 'Actif', '2025-04-08 10:40:50', 'Prise'), +('192.168.1.70', 'avancĂ©', 'Serrure connectĂ©e', 'Actif', '2025-04-08 10:40:50', 'securite'), +('192.168.1.80', 'expert', 'Porte connectĂ©e salle de contrĂŽle', 'Actif', '2025-04-08 10:40:50', 'securite'), +('192.168.1.90', 'avancĂ©', 'Climatisation', 'Actif', '2025-04-08 10:40:50', 'Climatisation'); + +-- Table `thermostat` +CREATE TABLE `thermostat` ( + `adresse_ip` VARCHAR(45) NOT NULL, + `temperature_actuelle` FLOAT DEFAULT NULL, + `temperature_cible` FLOAT DEFAULT NULL, + `mode` ENUM('Automatique','Manuel') NOT NULL, + PRIMARY KEY (`adresse_ip`), + FOREIGN KEY (`adresse_ip`) REFERENCES `objet` (`adresse_ip`) +); + +INSERT INTO `thermostat` VALUES +('192.168.1.20', 17, 20, 'Automatique'); + +-- Table `climatisation_chauffage` +CREATE TABLE `climatisation_chauffage` ( + `adresse_ip` VARCHAR(45) NOT NULL, + `thermostat` VARCHAR(45) NOT NULL, + PRIMARY KEY (`adresse_ip`), + FOREIGN KEY (`adresse_ip`) REFERENCES `objet` (`adresse_ip`), + FOREIGN KEY (`thermostat`) REFERENCES `thermostat` (`adresse_ip`) +); + +INSERT INTO `climatisation_chauffage` VALUES +('192.168.1.90', '192.168.1.20'); + +-- Table `appareil_menager` +CREATE TABLE `appareil_menager` ( + `adresse_ip` VARCHAR(45) NOT NULL, + `depart_differe` TIME DEFAULT NULL, + `etat_de_la_tache` ENUM('ComplĂ©tĂ©','En cours','En attente','Aucune') NOT NULL, + PRIMARY KEY (`adresse_ip`), + FOREIGN KEY (`adresse_ip`) REFERENCES `objet` (`adresse_ip`) ON DELETE RESTRICT ON UPDATE CASCADE +); + +INSERT INTO `appareil_menager` VALUES +('192.168.1.11', NULL, 'Aucune'), +('192.168.1.12', NULL, 'Aucune'), +('192.168.1.40', NULL, 'Aucune'); + +-- Table `securite` +CREATE TABLE `securite` ( + `adresse_ip` VARCHAR(45) NOT NULL, + `situation` ENUM('VerouillĂ©','Ouvert') NOT NULL, + PRIMARY KEY (`adresse_ip`), + FOREIGN KEY (`adresse_ip`) REFERENCES `objet` (`adresse_ip`) ON DELETE RESTRICT ON UPDATE CASCADE +); + +INSERT INTO `securite` VALUES +('192.168.1.70', 'Ouvert'), +('192.168.1.80', 'VerouillĂ©'); + +-- Table `gestion` +CREATE TABLE `gestion` ( + `id` INT NOT NULL AUTO_INCREMENT, + `id_utilisateur` INT NOT NULL, + `competence` VARCHAR(255) NOT NULL, + `niveau` ENUM('dĂ©butant','intermĂ©diaire','avancĂ©','expert') NOT NULL, + `categorie_experience` FLOAT DEFAULT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`id_utilisateur`) REFERENCES `utilisateur` (`id`) ON DELETE CASCADE +); + +INSERT INTO `gestion` (`id`, `id_utilisateur`, `competence`, `niveau`, `categorie_experience`) VALUES +(1, 1, 'Informatique', 'expert', 5), +(2, 1, 'Electronique', 'avancĂ©', 3.5), +(3, 2, 'Internet', 'intermĂ©diaire', 2), +(4, 2, 'Assistance numerique', 'dĂ©butant', 1), +(5, 3, 'Cuisine', 'expert', 10), +(6, 3, 'AmĂ©nagement', 'avancĂ©', 7), +(7, 4, 'Securite', 'avancĂ©', 4), +(8, 4, 'Acceuil', 'intermĂ©diaire', 2.5), +(9, 5, 'Entretien', 'intermĂ©diaire', 3), +(10, 5, 'Securite', 'dĂ©butant', 1.5); + + +CREATE TABLE `ressources` ( + `id` int NOT NULL, + `nom` varchar(50) NOT NULL, + `consommation` varchar(50) NOT NULL, + `consommation_max` varchar(50) NOT NULL, + `fournisseur` varchar(100) NOT NULL, + `abonnement` varchar(100) NOT NULL, + `echeance` varchar(50) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +INSERT INTO `ressources` (`id`, `nom`, `consommation`, `consommation_max`, `fournisseur`, `abonnement`, `echeance`) VALUES +(0, 'ÉlectricitĂ©', '250 kWh', '500 kWh', 'EDF', '50 € / mois', '2025-12-30'), +(1, 'Gaz', '90 mÂł', '200 mÂł', 'Engie', '40 € / mois', '2025-06-30'), +(2, 'Eau', '1200 L', '3000 L', 'Veolia', '20 € / mois', '2025-08-15'); + +CREATE TABLE IF NOT EXISTS contact ( + id INT AUTO_INCREMENT PRIMARY KEY, + nom VARCHAR(100) NOT NULL, + email VARCHAR(255) NOT NULL, + message TEXT NOT NULL, + date_envoi TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/z1/webapp/views/accueil.ejs b/z1/webapp/views/accueil.ejs new file mode 100644 index 0000000..b0f95db --- /dev/null +++ b/z1/webapp/views/accueil.ejs @@ -0,0 +1,67 @@ + + + + + Page d'accueil - Smart Building + + + + + + + + <%- include('partials/header') %> + +
+
+ BĂątiment +
+ +
+

Accueil

+ +
+
+ + <%- include('partials/footer') %> + + \ No newline at end of file diff --git a/z1/webapp/views/admin.ejs b/z1/webapp/views/admin.ejs new file mode 100644 index 0000000..1142f06 --- /dev/null +++ b/z1/webapp/views/admin.ejs @@ -0,0 +1,401 @@ + + + + + Admin - Smart Building + + + + +<%- include('partials/header') %> + +
+

Gestion des utilisateurs

+ +
+

Ajouter un utilisateur ➕

+ +
+ + + + + + + + + + + + + + <% utilisateurs.forEach(user => { %> + + + + + + + + + + + + <% }) %> + +
NomPrĂ©nomStatutÉtatModifierSupprimer
<%= user.nom %><%= user.prenom %> + + + + +
+ + +
+
+ +

Gestion des objets

+ +
+

Ajouter un objet ➕

+ + + + + + + + + + + + + + + + <% objets.forEach(objet => { %> + + + + + + + + + + + + + <% }) %> + +
NomAdresse IPTypeNiveauÉtatModifierSupprimer
<%= objet.denomination %><%= objet.adresse_ip %><%= objet.type %> + + + + +
+ + +
+
+ +

Messages de contact

+ + + + + + + + + + + + <% contacts.forEach(c => { %> + + + + + + + <% }) %> + +
NomEmailMessageDate
<%= c.nom %><%= c.email %><%= c.message %><%= new Date(c.date_envoi).toLocaleString('fr-FR') %>
+ +
+ +<%- include('partials/footer') %> + + \ No newline at end of file diff --git a/z1/webapp/views/connexion.ejs b/z1/webapp/views/connexion.ejs new file mode 100644 index 0000000..271a846 --- /dev/null +++ b/z1/webapp/views/connexion.ejs @@ -0,0 +1,71 @@ + + + + + Page d'accueil - Smart Building + + + + + <%- include('partials/header') %> +
+
+
+
+

Connexion

+
+
+ + + + + +

+
+ +
+ + + + + +

+
+ + +
+
+
+
+ + <%- include('partials/footer') %> + + diff --git a/z1/webapp/views/contact.ejs b/z1/webapp/views/contact.ejs new file mode 100644 index 0000000..c152a87 --- /dev/null +++ b/z1/webapp/views/contact.ejs @@ -0,0 +1,31 @@ + + + + + Contact - Smart Building + + + + <%- include('partials/header') %> + +
+

Nous contacter

+

Une question ? Une suggestion ? N'hésitez pas à nous écrire !

+ +
+ + + + + + + + + + +
+
+ + <%- include('partials/footer') %> + + diff --git a/z1/webapp/views/dashboard-complexe.ejs b/z1/webapp/views/dashboard-complexe.ejs new file mode 100644 index 0000000..00ccdc9 --- /dev/null +++ b/z1/webapp/views/dashboard-complexe.ejs @@ -0,0 +1,105 @@ + + + + + Dashboard Complexe - Smart Building + + + + +<%- include('partials/header') %> + +
+

Gestion des objets

+ +
+

Ajouter un objet ➕

+ +
+ + + + + + + + + + + + + + + <% objets.forEach(objet => { %> + + + + + + + + + + + + + <% }) %> + +
NomAdresse IPTypeNiveauÉtatModifierSupprimer
<%= objet.denomination %><%= objet.adresse_ip %><%= objet.type %> + + + + + + +
+ + +
+
+
+ +<%- include('partials/footer') %> + + diff --git a/z1/webapp/views/description.ejs b/z1/webapp/views/description.ejs new file mode 100644 index 0000000..2cc0288 --- /dev/null +++ b/z1/webapp/views/description.ejs @@ -0,0 +1,42 @@ + + + + + + Présentation de la maison - Smart Building + + + + + + + + <%- include('partials/header') %> + +
+
+ Image de la maison connectée +
+ +
+
+

Présentation de la maison connectée

+
+
+

+ Notre maison connectĂ©e est conçue pour offrir confort, sĂ©curitĂ© et efficacitĂ© Ă©nergĂ©tique. ÉquipĂ©e de capteurs intelligents, d’un systĂšme de gestion centralisĂ©e et d’une connectivitĂ© en temps rĂ©el, elle permet une surveillance continue des Ă©quipements et une optimisation automatique des ressources. +

+

+ Avec une surface habitable estimĂ©e Ă  environ 300 mÂČ rĂ©partie sur 4 Ă  5 niveaux, la maison connectĂ©e propose de vastes espaces ouverts et lumineux. Chaque Ă©tage est conçu pour maximiser l’apport en lumiĂšre naturelle grĂące aux nombreuses baies vitrĂ©es. Les terrasses vĂ©gĂ©talisĂ©es apportent un lien direct avec la nature, tout en favorisant l’isolation thermique. +

+

+ Le bĂątiment comprend de nombreux Ă©quipements connectĂ©s tels que l’éclairage intelligent, le chauffage programmable, des outils mĂ©nager et une surveillance vidĂ©o connectĂ©e. Toutes les donnĂ©es sont centralisĂ©es via une interface web qui permet un contrĂŽle Ă  distance via son smartphone ou son ordinateur. De plus en fonction des droits que possĂšdes votre compte vous avez accĂ©s Ă  diffĂ©rentes fonctionnalitĂ©s. +

+
+
+
+ + <%- include('partials/footer') %> + + + \ No newline at end of file diff --git a/z1/webapp/views/inscription.ejs b/z1/webapp/views/inscription.ejs new file mode 100644 index 0000000..180263e --- /dev/null +++ b/z1/webapp/views/inscription.ejs @@ -0,0 +1,273 @@ + + + + + Page d'accueil - Smart Building + + + + <%- include('partials/header') %> + +
+
+
+ +
+ +
+

Inscription

+
+
+ + + + + + +
+ +
+ + + + + + +
+ +
+ +
+ + + + + +
+
+
+ +
+ + + + + + + +
+ +
+ +
+ + + + + + +
+
+ +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + +
+
+
+
+
+
+ + <%- include('partials/footer') %> + + \ No newline at end of file diff --git a/z1/webapp/views/membre.ejs b/z1/webapp/views/membre.ejs new file mode 100644 index 0000000..464ada9 --- /dev/null +++ b/z1/webapp/views/membre.ejs @@ -0,0 +1,31 @@ + + + + + Page d'accueil - Smart Building + + + + + + + + <%- include('partials/header') %> + +
+

Member Details

+

Member ID: <%= id %>

+ + + +
+ + <%- include('partials/footer') %> + + diff --git a/z1/webapp/views/membres.ejs b/z1/webapp/views/membres.ejs new file mode 100644 index 0000000..c26e1d9 --- /dev/null +++ b/z1/webapp/views/membres.ejs @@ -0,0 +1,119 @@ + + + + + Page d'accueil - Smart Building + + + + + + <%- include('partials/header') %> + +
+
+ BĂątiment +
+ +
+
+

Membres

+
+ +
+
+ +
+
+
+ + <%- include('partials/footer') %> + + + + \ No newline at end of file diff --git a/z1/webapp/views/objets.ejs b/z1/webapp/views/objets.ejs new file mode 100644 index 0000000..82517a9 --- /dev/null +++ b/z1/webapp/views/objets.ejs @@ -0,0 +1,200 @@ + + + + + Page d'accueil - Smart Building + + + + + + + + + + <%- include('partials/header') %> + +
+
+ BĂątiment +
+ +
+
+

Objets Connectés

+
+ +
+
+
+
+ + +
+ + <%- include('partials/footer') %> + + + + \ No newline at end of file diff --git a/z1/webapp/views/partials/footer.ejs b/z1/webapp/views/partials/footer.ejs new file mode 100644 index 0000000..108ebc6 --- /dev/null +++ b/z1/webapp/views/partials/footer.ejs @@ -0,0 +1,9 @@ + diff --git a/z1/webapp/views/partials/header.ejs b/z1/webapp/views/partials/header.ejs new file mode 100644 index 0000000..7dc2994 --- /dev/null +++ b/z1/webapp/views/partials/header.ejs @@ -0,0 +1,39 @@ +
+ + smart_building + + + + + <% if (!session.utilisateur) { %> + Connexion + <% } else { %> + Déconnexion + <% } %> +
diff --git a/z1/webapp/views/profil.ejs b/z1/webapp/views/profil.ejs new file mode 100644 index 0000000..68b4616 --- /dev/null +++ b/z1/webapp/views/profil.ejs @@ -0,0 +1,70 @@ + + + + + + Mon Profil + + + + + <%- include("partials/header") %> + +
+

Mon Profil

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + +
+ + +
+
+ + + + <%- include("partials/footer") %> + + diff --git a/z1/webapp/views/ressources.ejs b/z1/webapp/views/ressources.ejs new file mode 100644 index 0000000..fb22576 --- /dev/null +++ b/z1/webapp/views/ressources.ejs @@ -0,0 +1,162 @@ + + + + + + Page d'accueil - Smart Building + + + + + + + + + <%- include('partials/header') %> + +
+
+ BĂątiment +
+ +
+
+

Gestion des ressources

+
+
+
+ + +
+ <%- include('partials/footer') %> + + + + + \ No newline at end of file