├── assets
├── icon.png
├── splash.png
├── favicon.png
└── adaptive-icon.png
├── babel.config.js
├── app
├── (tabs)
│ ├── bio
│ │ ├── _layout.js
│ │ └── index.js
│ ├── profile
│ │ ├── _layout.js
│ │ └── index.js
│ ├── chat
│ │ ├── _layout.js
│ │ ├── index.js
│ │ ├── chatroom.js
│ │ └── select.js
│ └── _layout.js
├── index.js
└── (authenticate)
│ ├── _layout.js
│ ├── select.js
│ ├── login.js
│ └── register.js
├── api
├── models
│ ├── message.js
│ └── user.js
├── package.json
├── index.js
└── yarn.lock
├── .gitignore
├── App.js
├── app.json
├── package.json
├── components
├── UserChat.js
└── Profile.js
└── data.js
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SSA-988/dating-app/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SSA-988/dating-app/HEAD/assets/splash.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SSA-988/dating-app/HEAD/assets/favicon.png
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SSA-988/dating-app/HEAD/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | plugins: ['expo-router/babel']
6 | };
7 | };
8 |
--------------------------------------------------------------------------------
/app/(tabs)/bio/_layout.js:
--------------------------------------------------------------------------------
1 | import { Stack } from "expo-router";
2 |
3 | export default function Layout() {
4 | return (
5 | <>
6 |
7 |
8 |
9 | >
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/app/(tabs)/profile/_layout.js:
--------------------------------------------------------------------------------
1 | import { Stack } from "expo-router";
2 |
3 | export default function Layout() {
4 | return (
5 | <>
6 |
7 |
8 |
9 | >
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/app/index.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Text, View } from 'react-native'
2 | import React from 'react'
3 | import { Redirect } from 'expo-router'
4 |
5 | const index = () => {
6 | return (
7 |
8 | )
9 | }
10 |
11 | export default index
12 |
13 | const styles = StyleSheet.create({})
14 |
15 | // -> "/"
--------------------------------------------------------------------------------
/app/(authenticate)/_layout.js:
--------------------------------------------------------------------------------
1 | import { Stack } from "expo-router";
2 |
3 | export default function Layout() {
4 | return (
5 | <>
6 |
7 |
8 |
9 |
10 |
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/app/(tabs)/chat/_layout.js:
--------------------------------------------------------------------------------
1 | import { Stack } from "expo-router";
2 |
3 | export default function Layout() {
4 | return (
5 | <>
6 |
7 |
8 |
9 |
10 |
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/api/models/message.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const chatSchema = new mongoose.Schema({
4 | senderId: {
5 | type: String,
6 | required: true,
7 | },
8 | receiverId: {
9 | type: String,
10 | required: true,
11 | },
12 | message: {
13 | type: String,
14 | required: true,
15 | },
16 | timestamp: {
17 | type: Date,
18 | default: Date.now,
19 | },
20 | });
21 |
22 | const Chat = mongoose.model("Chat", chatSchema);
23 |
24 | module.exports = Chat;
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2 |
3 | # dependencies
4 | node_modules/
5 |
6 | # Expo
7 | .expo/
8 | dist/
9 | web-build/
10 |
11 | # Native
12 | *.orig.*
13 | *.jks
14 | *.p8
15 | *.p12
16 | *.key
17 | *.mobileprovision
18 |
19 | # Metro
20 | .metro-health-check*
21 |
22 | # debug
23 | npm-debug.*
24 | yarn-debug.*
25 | yarn-error.*
26 |
27 | # macOS
28 | .DS_Store
29 | *.pem
30 |
31 | # local env files
32 | .env*.local
33 |
34 | # typescript
35 | *.tsbuildinfo
36 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import { StatusBar } from 'expo-status-bar';
2 | import { StyleSheet, Text, View } from 'react-native';
3 |
4 | export default function App() {
5 | return (
6 |
7 | Open up App.js to start working on your app!
8 |
9 |
10 | );
11 | }
12 |
13 | const styles = StyleSheet.create({
14 | container: {
15 | flex: 1,
16 | backgroundColor: '#fff',
17 | alignItems: 'center',
18 | justifyContent: 'center',
19 | },
20 | });
21 |
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "description": "backend",
5 | "main": "index.js",
6 | "scripts": {
7 | "start":"nodemon index.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "body-parser": "^1.20.2",
14 | "cors": "^2.8.5",
15 | "express": "^4.18.2",
16 | "jsonwebtoken": "^9.0.2",
17 | "mongoose": "^8.0.3",
18 | "nodemailer": "^6.9.8",
19 | "nodemon": "^3.0.2",
20 | "socket.io": "^4.7.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "dating-app-yt",
4 | "slug": "dating-app-yt",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "userInterfaceStyle": "light",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#ffffff"
13 | },
14 | "assetBundlePatterns": [
15 | "**/*"
16 | ],
17 | "ios": {
18 | "supportsTablet": true
19 | },
20 | "android": {
21 | "adaptiveIcon": {
22 | "foregroundImage": "./assets/adaptive-icon.png",
23 | "backgroundColor": "#ffffff"
24 | }
25 | },
26 | "scheme": "dating-app-yt",
27 | "web": {
28 | "favicon": "./assets/favicon.png"
29 | },
30 | "plugins": [
31 | "expo-router"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dating-app-yt",
3 | "version": "1.0.0",
4 | "main": "expo-router/entry",
5 | "scripts": {
6 | "start": "expo start",
7 | "android": "expo start --android",
8 | "ios": "expo start --ios",
9 | "web": "expo start --web"
10 | },
11 | "dependencies": {
12 | "@react-native-async-storage/async-storage": "1.18.2",
13 | "@react-navigation/native": "^6.1.9",
14 | "axios": "^1.6.5",
15 | "core-js": "^3.35.0",
16 | "expo": "~49.0.15",
17 | "expo-constants": "~14.4.2",
18 | "expo-linking": "~5.0.2",
19 | "expo-router": "^2.0.0",
20 | "expo-status-bar": "~1.6.0",
21 | "jwt-decode": "^4.0.0",
22 | "react": "18.2.0",
23 | "react-native": "0.72.6",
24 | "react-native-animatable": "^1.4.0",
25 | "react-native-safe-area-context": "4.6.3",
26 | "react-native-screens": "~3.22.0",
27 | "react-native-snap-carousel": "^3.9.1",
28 | "socket.io-client": "^4.7.3"
29 | },
30 | "devDependencies": {
31 | "@babel/core": "^7.20.0"
32 | },
33 | "private": true
34 | }
35 |
--------------------------------------------------------------------------------
/api/models/user.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const userSchema = new mongoose.Schema({
4 | name: {
5 | type: String,
6 | required: true,
7 | },
8 | email: {
9 | type: String,
10 | required: true,
11 | unique: true,
12 | },
13 | password: {
14 | type: String,
15 | required: true,
16 | },
17 | gender: {
18 | type: String,
19 | enum: ["male", "female", "other"],
20 | },
21 | verified: {
22 | type: Boolean,
23 | default: false,
24 | },
25 | verificationToken: String,
26 | crushes: [
27 | {
28 | type: mongoose.Schema.Types.ObjectId,
29 | ref: "User",
30 | },
31 | ],
32 | recievedLikes: [
33 | {
34 | type: mongoose.Schema.Types.ObjectId,
35 | ref: "User",
36 | },
37 | ],
38 | matches: [
39 | {
40 | type: mongoose.Schema.Types.ObjectId,
41 | ref: "User",
42 | },
43 | ],
44 | profileImages: [
45 | {
46 | type: String,
47 | },
48 | ],
49 | description: {
50 | type: String,
51 | },
52 | turnOns: [
53 | {
54 | type: String, //Array of string for turn ons
55 | },
56 | ],
57 | lookingFor: [
58 | {
59 | type: String, // Array of strings for what they are looking for
60 | },
61 | ],
62 | });
63 |
64 |
65 | const User = mongoose.model("User",userSchema);
66 |
67 | module.exports = User
--------------------------------------------------------------------------------
/app/(tabs)/_layout.js:
--------------------------------------------------------------------------------
1 | import { Tabs } from "expo-router";
2 | import { Feather } from "@expo/vector-icons";
3 | import { Ionicons } from "@expo/vector-icons";
4 | import { MaterialCommunityIcons } from "@expo/vector-icons";
5 |
6 | export default function Layout() {
7 | return (
8 |
9 |
15 | focused ? (
16 |
17 | ) : (
18 |
19 | ),
20 | }}
21 | />
22 |
23 |
29 | focused ? (
30 |
35 | ) : (
36 |
41 | ),
42 | }}
43 | />
44 |
45 |
51 | focused ? (
52 |
57 | ) : (
58 |
63 | ),
64 | }}
65 | />
66 |
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/app/(tabs)/profile/index.js:
--------------------------------------------------------------------------------
1 | import { FlatList, StyleSheet, Text, View } from "react-native";
2 | import React, { useState, useEffect } from "react";
3 | import "core-js/stable/atob";
4 | import { jwtDecode } from "jwt-decode";
5 | import AsyncStorage from "@react-native-async-storage/async-storage";
6 | import axios from "axios";
7 | import Profile from "../../../components/Profile";
8 |
9 | const index = () => {
10 | const [userId, setUserId] = useState("");
11 | const [user, setUser] = useState();
12 | const [profiles, setProfiles] = useState([]);
13 | useEffect(() => {
14 | const fetchUser = async () => {
15 | const token = await AsyncStorage.getItem("auth");
16 | const decodedToken = jwtDecode(token);
17 | const userId = decodedToken.userId;
18 | setUserId(userId);
19 | };
20 |
21 | fetchUser();
22 | }, []);
23 | const fetchUserDescription = async () => {
24 | try {
25 | const response = await axios.get(`http://localhost:3000/users/${userId}`);
26 | console.log(response);
27 | const user = response.data;
28 | setUser(user?.user);
29 | } catch (error) {
30 | console.log("Error fetching user description", error);
31 | }
32 | };
33 |
34 | const fetchProfiles = async () => {
35 | try {
36 | const response = await axios.get("http://localhost:3000/profiles", {
37 | params: {
38 | userId: userId,
39 | gender: user?.gender,
40 | turnOns: user?.turnOns,
41 | lookingFor: user?.lookingFor,
42 | },
43 | });
44 |
45 | setProfiles(response.data.profiles);
46 | } catch (error) {
47 | console.log("error", error);
48 | }
49 | };
50 | useEffect(() => {
51 | if (userId) {
52 | fetchUserDescription();
53 | }
54 | }, [userId]);
55 | useEffect(() => {
56 | if (userId && user) {
57 | fetchProfiles();
58 | }
59 | }, [userId, user]);
60 | console.log("profiles", profiles);
61 | return (
62 |
63 | item.id}
66 | renderItem={({ item, index }) => (
67 |
74 | )}
75 | />
76 |
77 | );
78 | };
79 |
80 | export default index;
81 |
82 | const styles = StyleSheet.create({});
83 |
--------------------------------------------------------------------------------
/components/UserChat.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Text, View, Pressable, Image } from "react-native";
2 | import React ,{useEffect,useState} from "react";
3 | import { useRouter } from "expo-router";
4 | import axios from "axios"
5 |
6 | const UserChat = ({ item, userId }) => {
7 | const router = useRouter();
8 | const [messages,setMessages] = useState([]);
9 | const getLastMessage = () => {
10 | const n = messages.length;
11 |
12 |
13 | return messages[n-1];
14 | }
15 | const lastMessage = getLastMessage();
16 | useEffect(() => {
17 | fetchMessages();
18 | }, []);
19 |
20 | const fetchMessages = async () => {
21 | try {
22 | const senderId = userId;
23 | const receiverId = item?._id;
24 | const response = await axios.get("http://localhost:3000/messages", {
25 | params: { senderId, receiverId },
26 | });
27 |
28 | // Assuming messages are stored in state to display in the UI
29 | setMessages(response.data);
30 | } catch (error) {
31 | console.error("Error fetching messages:", error);
32 | // Handle error scenarios
33 | }
34 | };
35 | return (
36 |
38 | router.push({
39 | pathname: "/chat/chatroom",
40 | params: {
41 | image: item?.profileImages[0],
42 | name: item?.name,
43 | receiverId: item?._id,
44 | senderId: userId,
45 | },
46 | })
47 | }
48 | style={{
49 | flexDirection: "row",
50 | alignItems: "center",
51 | gap: 12,
52 | marginVertical: 12,
53 | }}
54 | >
55 |
56 |
60 |
61 |
62 |
63 |
71 | {item?.name}
72 |
73 |
81 | {lastMessage ? lastMessage?.message : `Start Chat with ${item?.name}`}
82 |
83 |
84 |
85 | );
86 | };
87 |
88 | export default UserChat;
89 |
90 | const styles = StyleSheet.create({});
91 |
--------------------------------------------------------------------------------
/app/(tabs)/chat/index.js:
--------------------------------------------------------------------------------
1 | import { Pressable, StyleSheet, Text, View } from "react-native";
2 | import React, { useState, useEffect,useCallback } from "react";
3 | import { Ionicons } from "@expo/vector-icons";
4 | import { Feather } from "@expo/vector-icons";
5 | import { MaterialIcons } from "@expo/vector-icons";
6 | import "core-js/stable/atob";
7 | import { jwtDecode } from "jwt-decode";
8 | import AsyncStorage from "@react-native-async-storage/async-storage";
9 | import axios from "axios";
10 | import { useRouter } from "expo-router";
11 | import { useFocusEffect } from "@react-navigation/native";
12 | import UserChat from "../../../components/UserChat";
13 |
14 | const index = () => {
15 | const router = useRouter();
16 | const [userId, setUserId] = useState("");
17 | const [profiles, setProfiles] = useState([]);
18 | const [matches, setMatches] = useState([]);
19 | useEffect(() => {
20 | const fetchUser = async () => {
21 | const token = await AsyncStorage.getItem("auth");
22 | const decodedToken = jwtDecode(token);
23 | const userId = decodedToken.userId;
24 | setUserId(userId);
25 | };
26 |
27 | fetchUser();
28 | }, []);
29 | const fetchRecievedLikesDetails = async () => {
30 | try {
31 | const response = await axios.get(
32 | `http://localhost:3000/received-likes/${userId}/details`
33 | );
34 |
35 | console.log(response);
36 |
37 | const receivedLikesDetails = response.data.receivedLikesDetails;
38 |
39 | setProfiles(receivedLikesDetails);
40 | } catch (error) {
41 | console.log("error fetching the details", error);
42 | }
43 | };
44 | const fetchUserMatches = async () => {
45 | try {
46 | const response = await axios.get(
47 | `http://localhost:3000/users/${userId}/matches`
48 | );
49 |
50 | const userMatches = response.data.matches;
51 |
52 | setMatches(userMatches);
53 | } catch (error) {
54 | console.log("Error", error);
55 | }
56 | };
57 | useEffect(() => {
58 | if (userId) {
59 | fetchRecievedLikesDetails();
60 | }
61 | }, [userId]);
62 | useEffect(() => {
63 | if (userId) {
64 | fetchUserMatches();
65 | }
66 | }, [userId]);
67 | useFocusEffect(
68 | useCallback(() => {
69 | if (userId) {
70 | fetchUserMatches();
71 | }
72 | }, [])
73 | );
74 | console.log("matches",matches)
75 | return (
76 |
77 |
84 | CHATS
85 |
86 |
87 |
89 | router.push({
90 | pathname: "/chat/select",
91 | params: {
92 | profiles: JSON.stringify(profiles),
93 | userId: userId,
94 | },
95 | })
96 | }
97 | style={{
98 | marginVertical: 12,
99 | flexDirection: "row",
100 | alignItems: "center",
101 | }}
102 | >
103 |
113 |
114 |
115 |
116 | You have got {profiles?.length} likes
117 |
118 |
119 |
120 |
121 |
122 | {matches?.map((item,index) => (
123 |
124 | ))}
125 |
126 |
127 | );
128 | };
129 |
130 | export default index;
131 |
132 | const styles = StyleSheet.create({});
133 |
--------------------------------------------------------------------------------
/app/(authenticate)/select.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Text, View, Pressable, Image } from "react-native";
2 | import React, { useState, useEffect } from "react";
3 | import AsyncStorage from "@react-native-async-storage/async-storage";
4 | import "core-js/stable/atob";
5 | import {jwtDecode} from "jwt-decode";
6 | import axios from "axios"
7 | import { useRouter } from "expo-router";
8 |
9 | const select = () => {
10 | const router = useRouter();
11 | const [option, setOption] = useState("");
12 | const [userId,setUserId] = useState("");
13 | useEffect(() => {
14 | const fetchUser = async() => {
15 | const token = await AsyncStorage.getItem("auth");
16 | const decodedToken = jwtDecode(token);
17 | const userId = decodedToken.userId;
18 | setUserId(userId)
19 | }
20 |
21 | fetchUser();
22 | },[])
23 | const updateUserGender = async () => {
24 | try{
25 | const response = await axios.put(`http://localhost:3000/users/${userId}/gender`,{
26 | gender:option
27 | });
28 |
29 | console.log(response.data);
30 |
31 | if(response.status == 200){
32 | router.replace("(tabs)/bio")
33 | }
34 | } catch(error){
35 | console.log("error",error)
36 | }
37 | }
38 | return (
39 |
40 | setOption("male")}
42 | style={{
43 | backgroundColor: "#F0F0F0",
44 | padding: 12,
45 | justifyContent: "space-between",
46 | flexDirection: "row",
47 | alignItems: "center",
48 | marginTop: 25,
49 | borderRadius: 5,
50 | borderColor: option == "male" ? "#D0D0D0" : "transparent",
51 | borderWidth: option == "male" ? 1 : 0,
52 | }}
53 | >
54 | I am a Man
55 |
61 |
62 |
63 | setOption("female")}
65 | style={{
66 | backgroundColor: "#F0F0F0",
67 | padding: 12,
68 | justifyContent: "space-between",
69 | flexDirection: "row",
70 | alignItems: "center",
71 | marginTop: 25,
72 | borderRadius: 5,
73 | borderColor: option == "female" ? "#D0D0D0" : "transparent",
74 | borderWidth: option == "female" ? 1 : 0,
75 | }}
76 | >
77 | I am a Woman
78 |
84 |
85 |
86 | setOption("nonbinary")}
88 | style={{
89 | backgroundColor: "#F0F0F0",
90 | padding: 12,
91 | justifyContent: "space-between",
92 | flexDirection: "row",
93 | alignItems: "center",
94 | marginTop: 25,
95 | borderRadius: 5,
96 | borderColor: option == "nonbinary" ? "#D0D0D0" : "transparent",
97 | borderWidth: option == "nonbinary" ? 1 : 0,
98 | }}
99 | >
100 | I am Non-Binary
101 |
107 |
108 |
109 | {option && (
110 |
119 |
122 | Done
123 |
124 |
125 | )}
126 |
127 | );
128 | };
129 |
130 | export default select;
131 |
132 | const styles = StyleSheet.create({});
133 |
--------------------------------------------------------------------------------
/data.js:
--------------------------------------------------------------------------------
1 | //login screen images
2 | <>
3 |
9 |
15 | select screen images
16 |
22 |
28 | >;
29 |
30 | const profileImages = [
31 | {
32 | image:
33 | "https://images.pexels.com/photos/1042140/pexels-photo-1042140.jpeg?auto=compress&cs=tinysrgb&w=800",
34 | },
35 | {
36 | image:
37 | "https://images.pexels.com/photos/1215695/pexels-photo-1215695.jpeg?auto=compress&cs=tinysrgb&w=800",
38 | },
39 | {
40 | image:
41 | "https://images.pexels.com/photos/7580971/pexels-photo-7580971.jpeg?auto=compress&cs=tinysrgb&w=800",
42 | },
43 | ];
44 | const turnons = [
45 | {
46 | id: "0",
47 | name: "Music",
48 | description: "Pop Rock-Indie pick our sound track",
49 | },
50 | {
51 | id: "10",
52 | name: "Kissing",
53 | description:
54 | " It's a feeling of closeness, where every touch of lips creates a symphony of emotions.",
55 | },
56 | {
57 | id: "1",
58 | name: "Fantasies",
59 | description:
60 | "Fantasies can be deeply personal, encompassing diverse elements such as romance",
61 | },
62 | {
63 | id: "2",
64 | name: "Nibbling",
65 | description:
66 | "playful form of biting or taking small, gentle bites, typically done with the teeth",
67 | },
68 | {
69 | id: "3",
70 | name: "Desire",
71 | description: "powerful emotion or attainment of a particular person.",
72 | },
73 | ];
74 | const data = [
75 | {
76 | id: "0",
77 | name: "Casual",
78 | description: "Let's keep it easy and see where it goes",
79 | },
80 | {
81 | id: "1",
82 | name: "Long Term",
83 | description: "How about a one life stand",
84 | },
85 | {
86 | id: "2",
87 | name: "Virtual",
88 | description: "Let's have some virtual fun",
89 | },
90 | {
91 | id: "3",
92 | name: "Open for Anything",
93 | description: "Let's Vibe and see where it goes",
94 | },
95 | ];
96 |
97 | const profiles = [
98 | {
99 | id: "0",
100 | name: "Shreya Rao",
101 | description:
102 | "Hello, I want to chat and if everything goes well, meet probably during the weekend,we can go to the cinema feed the birds and hangout sometime ",
103 | profileImages: [
104 | {
105 | id: "0",
106 | image:
107 | "https://images.pexels.com/photos/3236651/pexels-photo-3236651.jpeg?auto=compress&cs=tinysrgb&w=800",
108 | },
109 | ],
110 | },
111 | {
112 | id: "1",
113 | name: "Aditi K",
114 | description:
115 | "Hello! I'm all for engaging conversations and if vibes align, how about a weekend meet-up? We could do something fun like catching a movie, feeding the birds at the park, and just enjoying each other's company",
116 | profileImages: [
117 | {
118 | id: "0",
119 | image:
120 | "https://images.pexels.com/photos/1485031/pexels-photo-1485031.jpeg?auto=compress&cs=tinysrgb&w=800",
121 | },
122 | ],
123 | },
124 | {
125 | id: "10",
126 | name: "Rheaa Thakur",
127 | description:
128 | "Hi! I'm here for intriguing conversations and if we hit it off, why not plan a weekend adventure? I'm into outdoor photography, trying new coffee shops, or maybe even a spontaneous road trip. Any ideas?",
129 | profileImages: [
130 | {
131 | id: "0",
132 | image:
133 | "https://images.pexels.com/photos/1844012/pexels-photo-1844012.jpeg?auto=compress&cs=tinysrgb&w=800",
134 | },
135 | ],
136 | },
137 | {
138 | id: "3",
139 | name: "Manisha Singha",
140 | description:
141 | "Hello! I'm all about deep talks and discovering common passions. If we vibe, how about planning something unique—like attending a live music gig, exploring a farmer's market, or taking a dance class together?",
142 | profileImages: [
143 | {
144 | id: "0",
145 | image:
146 | "https://images.pexels.com/photos/1642228/pexels-photo-1642228.jpeg?auto=compress&cs=tinysrgb&w=800",
147 | },
148 | ],
149 | },
150 | {
151 | id: "4",
152 | name: "Nisha J",
153 | description:
154 | "Hey! I'm into meaningful connections and if it feels right, let's plan something exciting—like attending a book reading, going to a comedy show, or even trying out a new adventurous cuisine together. What do you think about that?",
155 | profileImages: [
156 | {
157 | id: "0",
158 | image:
159 | "https://images.pexels.com/photos/1152994/pexels-photo-1152994.jpeg?auto=compress&cs=tinysrgb&w=800",
160 | },
161 | ],
162 | },
163 | ];
164 |
165 | //chat - > select
166 |
167 | ;
173 |
174 | //bio tab top image
175 | ;
181 |
--------------------------------------------------------------------------------
/app/(tabs)/chat/chatroom.js:
--------------------------------------------------------------------------------
1 | import {
2 | StyleSheet,
3 | Text,
4 | View,
5 | Image,
6 | KeyboardAvoidingView,
7 | ScrollView,
8 | TextInput,
9 | Pressable,
10 | } from "react-native";
11 | import React, { useLayoutEffect, useState, useEffect } from "react";
12 | import { useNavigation } from "@react-navigation/native";
13 | import { Ionicons } from "@expo/vector-icons";
14 | import { useLocalSearchParams } from "expo-router";
15 | import { Entypo, Feather } from "@expo/vector-icons";
16 | import { MaterialCommunityIcons } from "@expo/vector-icons";
17 | import { io } from "socket.io-client";
18 | import axios from "axios";
19 |
20 | const chatroom = () => {
21 | const navigation = useNavigation();
22 | const [message, setMessage] = useState("");
23 | const params = useLocalSearchParams();
24 | const [messages, setMessages] = useState([]);
25 | const socket = io("http://localhost:8000");
26 | socket.on("connect", () => {
27 | console.log("Connected to the Socket.IO server");
28 | });
29 | socket.on("receiveMessage", (newMessage) => {
30 | console.log("new Message", newMessage);
31 |
32 | //update the state to include new message
33 | setMessages((prevMessages) => [...prevMessages, newMessage]);
34 | });
35 | const sendMessage = async (senderId, receiverId) => {
36 | socket.emit("sendMessage", { senderId, receiverId, message });
37 |
38 | setMessage("");
39 |
40 | // call the fetchMessages() function to see the UI update
41 | setTimeout(() => {
42 | fetchMessages();
43 | },200)
44 | };
45 | useLayoutEffect(() => {
46 | navigation.setOptions({
47 | headerTitle: "",
48 | headerLeft: () => (
49 |
50 |
51 |
52 |
61 |
62 | {params?.name}
63 |
64 |
65 |
66 | ),
67 | headerRight: () => (
68 |
69 |
74 |
75 |
76 | ),
77 | });
78 | }, []);
79 | const fetchMessages = async () => {
80 | try {
81 | const senderId = params?.senderId;
82 | const receiverId = params?.receiverId;
83 |
84 | const response = await axios.get("http://localhost:3000/messages", {
85 | params: { senderId, receiverId },
86 | });
87 |
88 | setMessages(response.data);
89 | } catch (error) {
90 | console.log("Error fetching the messages", error);
91 | }
92 | };
93 | useEffect(() => {
94 | fetchMessages();
95 | }, []);
96 | const formatTime = (time) => {
97 | const options = { hour: "numeric", minute: "numeric" };
98 | return new Date(time).toLocaleString("en-US", options);
99 | };
100 | return (
101 |
102 |
103 | {messages?.map((item, index) => (
104 |
125 |
126 | {item?.message}
127 |
128 | {formatTime(item?.timestamp)}
129 |
130 | ))}
131 |
132 |
133 |
144 |
150 | setMessage(text)}
153 | style={{
154 | flex: 1,
155 | height: 40,
156 | borderWidth: 1,
157 | borderColor: "#dddddd",
158 | borderRadius: 20,
159 | paddingHorizontal: 10,
160 | }}
161 | placeholder="Type your message..."
162 | />
163 |
164 |
172 |
173 |
174 |
175 |
176 |
177 | sendMessage(params?.senderId, params?.receiverId)}
179 | style={{
180 | backgroundColor: "#007bff",
181 | paddingHorizontal: 12,
182 | paddingVertical: 8,
183 | borderRadius: 20,
184 | }}
185 | >
186 | Send
187 |
188 |
189 |
190 | );
191 | };
192 |
193 | export default chatroom;
194 |
195 | const styles = StyleSheet.create({});
196 |
--------------------------------------------------------------------------------
/app/(authenticate)/login.js:
--------------------------------------------------------------------------------
1 | import {
2 | StyleSheet,
3 | Text,
4 | View,
5 | SafeAreaView,
6 | Image,
7 | KeyboardAvoidingView,
8 | TextInput,
9 | Pressable,
10 | } from "react-native";
11 | import React, { useState,useEffect } from "react";
12 | import { MaterialIcons } from "@expo/vector-icons";
13 | import { AntDesign } from "@expo/vector-icons";
14 | import { useRouter } from "expo-router";
15 | import axios from "axios";
16 | import AsyncStorage from "@react-native-async-storage/async-storage";
17 |
18 |
19 | const login = () => {
20 | const [email, setEmail] = useState("");
21 | const [password, setPassword] = useState("");
22 | const router = useRouter();
23 | useEffect(() => {
24 | const checkLoginStatus = async () => {
25 | try{
26 | const token = await AsyncStorage.getItem("auth");
27 | if(token){
28 | router.replace("/(tabs)/profile")
29 | }
30 | } catch(error){
31 | console.log("Error",error)
32 | }
33 | }
34 | checkLoginStatus()
35 | },[])
36 | const handleLogin = () => {
37 | const user = {
38 | email: email,
39 | password: password,
40 | };
41 | axios.post("http://localhost:3000/login",user).then((response) => {
42 | console.log(response);
43 | const token = response.data.token;
44 | AsyncStorage.setItem("auth",token);
45 | router.replace("/(authenticate)/select")
46 | })
47 | };
48 | return (
49 |
52 |
53 |
60 |
66 |
67 |
75 | Match Mate
76 |
77 |
78 |
79 |
80 |
81 |
89 | Log in to your Account
90 |
91 |
92 |
93 |
100 |
106 |
107 |
108 |
109 |
120 |
126 | setEmail(text)}
129 | placeholder="Enter your email"
130 | placeholderTextColor={"white"}
131 | style={{
132 | color: "white",
133 | marginVertical: 10,
134 | width: 300,
135 | fontSize: password ? 17 : 17,
136 | }}
137 | />
138 |
139 |
140 |
141 |
152 |
158 | setPassword(text)}
161 | secureTextEntry={true}
162 | placeholder="Enter your password"
163 | style={{
164 | color: "white",
165 | marginVertical: 10,
166 | width: 300,
167 | fontSize: password ? 17 : 17,
168 | }}
169 | placeholderTextColor="white"
170 | />
171 |
172 |
173 |
174 |
182 | Keep me logged in
183 |
184 |
185 | Forgot Password
186 |
187 |
188 |
189 |
190 |
191 |
202 |
210 | Login
211 |
212 |
213 |
214 | router.replace("/register")}
216 | style={{ marginTop: 12 }}
217 | >
218 |
219 | Don't have an account? Sign Up
220 |
221 |
222 |
223 |
224 |
225 | );
226 | };
227 |
228 | export default login;
229 |
230 | const styles = StyleSheet.create({});
231 |
--------------------------------------------------------------------------------
/app/(authenticate)/register.js:
--------------------------------------------------------------------------------
1 | import {
2 | StyleSheet,
3 | Text,
4 | View,
5 | SafeAreaView,
6 | Image,
7 | Pressable,
8 | TextInput,
9 | KeyboardAvoidingView,
10 | Alert,
11 | } from "react-native";
12 | import React, { useState } from "react";
13 | import { MaterialIcons, Ionicons } from "@expo/vector-icons";
14 | import { AntDesign } from "@expo/vector-icons";
15 | import { useRouter } from "expo-router";
16 | import axios from "axios";
17 |
18 | const register = () => {
19 | const [name, setName] = useState("");
20 | const [email, setEmail] = useState("");
21 | const [password, setPassword] = useState("");
22 | const router = useRouter();
23 | const handleRegister = () => {
24 | const user = {
25 | name: name,
26 | email: email,
27 | password: password,
28 | };
29 |
30 | // send a POST request to the backend API to register the user
31 | axios
32 | .post("http://localhost:3000/register", user)
33 | .then((response) => {
34 | console.log(response);
35 | Alert.alert(
36 | "Registration successful",
37 | "You have been registered Successfully"
38 | );
39 | setName("");
40 | setEmail("");
41 | setPassword("");
42 | })
43 | .catch((error) => {
44 | Alert.alert(
45 | "Registration Error",
46 | "An error occurred while registering"
47 | );
48 | console.log("registration failed", error);
49 | });
50 | };
51 | return (
52 |
55 |
56 |
63 |
69 |
70 |
78 | Match Mate
79 |
80 |
81 |
82 |
83 |
84 |
92 | Register to your Account
93 |
94 |
95 |
96 |
103 |
109 |
110 |
111 |
112 |
123 |
129 | setName(text)}
132 | placeholder="Enter your name"
133 | placeholderTextColor={"white"}
134 | style={{
135 | color: "white",
136 | marginVertical: 10,
137 | width: 300,
138 | fontSize: name ? 17 : 17,
139 | }}
140 | />
141 |
142 |
143 |
154 |
160 | setEmail(text)}
163 | placeholder="Enter your email"
164 | placeholderTextColor={"white"}
165 | style={{
166 | color: "white",
167 | marginVertical: 10,
168 | width: 300,
169 | fontSize: password ? 17 : 17,
170 | }}
171 | />
172 |
173 |
174 |
175 |
186 |
192 | setPassword(text)}
195 | secureTextEntry={true}
196 | placeholder="Enter your password"
197 | style={{
198 | color: "white",
199 | marginVertical: 10,
200 | width: 300,
201 | fontSize: password ? 17 : 17,
202 | }}
203 | placeholderTextColor="white"
204 | />
205 |
206 |
207 |
208 |
209 |
210 |
221 |
229 | Register
230 |
231 |
232 |
233 | router.replace("/login")}
235 | style={{ marginTop: 12 }}
236 | >
237 |
238 | Already have an account? Sign In
239 |
240 |
241 |
242 |
243 |
244 | );
245 | };
246 |
247 | export default register;
248 |
249 | const styles = StyleSheet.create({});
250 |
--------------------------------------------------------------------------------
/app/(tabs)/chat/select.js:
--------------------------------------------------------------------------------
1 | import {
2 | StyleSheet,
3 | Text,
4 | View,
5 | ScrollView,
6 | Image,
7 | Pressable,
8 | } from "react-native";
9 | import React from "react";
10 | import { useLocalSearchParams, useRouter } from "expo-router";
11 | import { AntDesign } from "@expo/vector-icons";
12 | import { FontAwesome, Entypo } from "@expo/vector-icons";
13 | import axios from "axios";
14 |
15 | const select = () => {
16 | const router = useRouter();
17 | const params = useLocalSearchParams();
18 | const profiles = JSON.parse(params?.profiles);
19 |
20 | const userId = params?.userId;
21 |
22 | const handleMatch = async (selectedUserId) => {
23 | try {
24 | await axios.post("http://localhost:3000/create-match", {
25 | currentUserId: userId,
26 | selectedUserId: selectedUserId,
27 | });
28 |
29 | setTimeout(() => {
30 | router.push("/chat");
31 | }, 500);
32 | } catch (error) {
33 | console.log("error", error);
34 | }
35 | };
36 | return (
37 |
38 |
39 |
42 |
43 | NearBy 🔥
44 |
45 |
46 |
49 |
50 | Looking for 💓
51 |
52 |
53 |
56 |
57 | Turn-Ons 💌
58 |
59 |
60 |
61 | {profiles?.length > 0 ? (
62 |
63 | {profiles?.map((item, index) => (
64 |
65 |
66 |
73 |
74 |
75 | {item?.name}
76 |
77 |
87 | {item?.description?.length > 160
88 | ? item?.description
89 | : item?.description.substr(0, 160)}
90 |
91 |
92 |
93 | {item?.profileImages?.slice(0, 1).map((item, index) => (
94 |
103 | ))}
104 |
105 |
106 |
107 |
108 |
116 |
117 |
124 |
134 |
135 |
136 |
137 | handleMatch(item._id)}
139 | style={{
140 | width: 50,
141 | height: 50,
142 | borderRadius: 25,
143 | backgroundColor: "#E0E0E0",
144 | justifyContent: "center",
145 | alignItems: "center",
146 | }}
147 | >
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | Turn Ons 💓
156 |
164 | {item?.turnOns?.map((item, index) => (
165 |
172 |
180 | {item}
181 |
182 |
183 | ))}
184 |
185 |
186 |
187 |
188 | Looking For 👀
189 |
197 | {item?.lookingFor?.map((item, index) => (
198 |
205 |
213 | {item}
214 |
215 |
216 | ))}
217 |
218 |
219 |
220 | ))}
221 |
222 | ) : (
223 |
231 |
237 |
238 |
239 |
246 | UH - OH{" "}
247 |
254 | No likes yet
255 |
256 |
257 |
258 |
259 | Improve your AD to get better likes
260 |
261 |
262 |
263 | )}
264 |
265 | );
266 | };
267 |
268 | export default select;
269 |
270 | const styles = StyleSheet.create({});
271 |
--------------------------------------------------------------------------------
/components/Profile.js:
--------------------------------------------------------------------------------
1 | import {
2 | ScrollView,
3 | StyleSheet,
4 | Text,
5 | View,
6 | Image,
7 | Pressable,
8 | } from "react-native";
9 | import React, { useState } from "react";
10 | import { Entypo } from "@expo/vector-icons";
11 | import { AntDesign } from "@expo/vector-icons";
12 | import { FontAwesome } from "@expo/vector-icons";
13 | import axios from "axios";
14 | import * as Animatable from "react-native-animatable";
15 |
16 | const Profile = ({ item, isEven, userId, setProfiles }) => {
17 | const colors = ["#F0F8FF", "#FFFFFF"];
18 | const [liked, setLiked] = useState(false);
19 | const [selected, setSelcted] = useState(false);
20 | const handleLike = async (selectedUserId) => {
21 | try {
22 | setLiked(true);
23 | await axios.post("http://localhost:3000/send-like", {
24 | currentUserId: userId,
25 | selectedUserId: selectedUserId,
26 | });
27 |
28 | setTimeout(() => {
29 | setProfiles((prevProfiles) =>
30 | prevProfiles.filter((profile) => profile._id !== selectedUserId)
31 | );
32 | setLiked(false);
33 | }, 200);
34 | } catch (error) {
35 | console.log("error liking", error);
36 | }
37 | };
38 | const handleLikeOther = async (selectedUserId) => {
39 | try {
40 | setSelcted(true);
41 | await axios.post("http://localhost:3000/send-like", {
42 | currentUserId: userId,
43 | selectedUserId: selectedUserId,
44 | });
45 |
46 | setTimeout(() => {
47 | setProfiles((prevProfiles) =>
48 | prevProfiles.filter((profile) => profile._id !== selectedUserId)
49 | );
50 | setSelcted(false);
51 | }, 200);
52 |
53 | // Handle success: Perform any UI updates or navigate to another screen
54 | } catch (error) {
55 | console.error("Error liking user:", error);
56 | // Handle error scenarios
57 | }
58 | };
59 | if (isEven) {
60 | return (
61 |
62 |
63 |
64 |
65 |
66 | {item?.name}
67 |
68 |
78 | {item?.description?.length > 160
79 | ? item?.description
80 | : item?.description.substr(0, 160)}
81 |
82 |
83 |
84 | {item?.profileImages?.slice(0, 1).map((item, index) => (
85 |
94 | ))}
95 |
96 |
97 |
98 |
99 |
107 |
108 |
111 |
121 |
122 |
123 |
124 | {liked ? (
125 |
135 |
140 |
141 |
142 |
143 | ) : (
144 | handleLike(item?._id)}
146 | style={{
147 | width: 50,
148 | height: 50,
149 | borderRadius: 25,
150 | backgroundColor: "#E0E0E0",
151 | justifyContent: "center",
152 | alignItems: "center",
153 | }}
154 | >
155 |
156 |
157 | )}
158 |
159 |
160 |
161 |
162 |
163 |
164 | );
165 | } else {
166 | return (
167 |
168 |
169 |
170 | {item?.profileImages?.slice(0, 1).map((item, index) => (
171 |
180 | ))}
181 |
182 |
183 | {item?.name}
184 |
185 |
196 | {item?.description}
197 |
198 |
199 |
200 |
201 |
202 |
210 |
211 |
214 |
224 |
225 |
226 |
227 | {selected ? (
228 |
238 |
243 |
244 |
245 |
246 | ) : (
247 | handleLikeOther(item._id)}
249 | style={{
250 | width: 50,
251 | height: 50,
252 | borderRadius: 25,
253 | backgroundColor: "#6699CC",
254 | justifyContent: "center",
255 | alignItems: "center",
256 | }}
257 | >
258 |
259 |
260 | )}
261 |
262 |
263 |
264 |
265 |
266 | );
267 | }
268 | };
269 |
270 | export default Profile;
271 |
272 | const styles = StyleSheet.create({});
273 |
--------------------------------------------------------------------------------
/api/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const bodyParser = require("body-parser");
3 | const mongoose = require("mongoose");
4 | const crypto = require("crypto");
5 | const nodemailer = require("nodemailer");
6 |
7 | const app = express();
8 | const port = 3000;
9 | const cors = require("cors");
10 |
11 | const http = require("http").createServer(app);
12 | const io = require("socket.io")(http);
13 |
14 | app.use(cors());
15 |
16 | app.use(bodyParser.urlencoded({ extended: false }));
17 | app.use(bodyParser.json());
18 |
19 | const jwt = require("jsonwebtoken");
20 | const User = require("./models/user");
21 | const Chat = require("./models/message");
22 |
23 | mongoose
24 | .connect("mongodb+srv://sujan:sujan@cluster0.ye1ucer.mongodb.net/")
25 | .then(() => {
26 | console.log("Connected to MongoDB");
27 | })
28 | .catch((error) => {
29 | console.log("Error connecting to MongoDB");
30 | });
31 |
32 | app.listen(port, () => {
33 | console.log("Server is running on 3000");
34 | });
35 |
36 | //endpoint to register a user to the backend
37 | app.post("/register", async (req, res) => {
38 | try {
39 | const { name, email, password } = req.body;
40 |
41 | //check if the email is already registered
42 | const existingUser = await User.findOne({ email });
43 | if (existingUser) {
44 | console.log("Email already registered");
45 | return res.status(400).json({ message: "Email already registered" });
46 | }
47 |
48 | //create a new User
49 | const newUser = new User({
50 | name,
51 | email,
52 | password,
53 | });
54 |
55 | //generate the verification token
56 | newUser.verificationToken = crypto.randomBytes(20).toString("hex");
57 |
58 | //save the user to the database
59 | await newUser.save();
60 |
61 | //send the verification email to the registered user
62 | sendVerificationEmail(newUser.email, newUser.verificationToken);
63 |
64 | res
65 | .status(200)
66 | .json({ message: "User registered successfully", userId: newUser._id });
67 | } catch (error) {
68 | console.log("Error registering user", error);
69 | res.status(500).json({ message: "Registration failed" });
70 | }
71 | });
72 | const sendVerificationEmail = async (email, verificationToken) => {
73 | const transpoter = nodemailer.createTransport({
74 | service: "gmail",
75 | auth: {
76 | user: "sujananand0@gmail.com",
77 | pass: "rnzcugnscqtqiefs",
78 | },
79 | });
80 |
81 | const mailOptions = {
82 | from: "matchmake.com",
83 | to: email,
84 | subject: "Email verification",
85 | text: `Please click on the following link to verify your email : http://localhost:3000/verify/${verificationToken}`,
86 | };
87 |
88 | //send the mail
89 | try {
90 | await transpoter.sendMail(mailOptions);
91 | } catch (error) {
92 | console.log("Error sending the verification email");
93 | }
94 | };
95 |
96 | //verify the user
97 | app.get("/verify/:token", async (req, res) => {
98 | try {
99 | const token = req.params.token;
100 |
101 | const user = await User.findOne({ verificationToken: token });
102 | if (!user) {
103 | return res.status(404).json({ message: "Invalid verification token" });
104 | }
105 |
106 | //mark the user as verified
107 | user.verified = true;
108 | user.verificationToken = undefined;
109 |
110 | await user.save();
111 |
112 | res.status(200).json({ message: "Email verified Sucesfully" });
113 | } catch (error) {
114 | console.log("errror", error);
115 | res.status(500).json({ message: "Email verification failed" });
116 | }
117 | });
118 |
119 | const generateSecretKey = () => {
120 | const secretKey = crypto.randomBytes(32).toString("hex");
121 |
122 | return secretKey;
123 | };
124 |
125 | const secretKey = generateSecretKey();
126 |
127 | //endpoint to login
128 | app.post("/login", async (req, res) => {
129 | try {
130 | const { email, password } = req.body;
131 |
132 | //check if the user exists already
133 | const user = await User.findOne({ email });
134 | if (!user) {
135 | return res.status(401).json({ message: "Invalid email or password" });
136 | }
137 |
138 | //check in password is correct
139 | if (user.password !== password) {
140 | return res.status(401).json({ message: "Invalide password" });
141 | }
142 |
143 | const token = jwt.sign({ userId: user._id }, secretKey);
144 |
145 | res.status(200).json({ token });
146 | } catch (error) {
147 | res.status(500).json({ message: "login failed" });
148 | }
149 | });
150 |
151 | //endpoint to change or select the gender for a particular user profile
152 | app.put("/users/:userId/gender", async (req, res) => {
153 | try {
154 | const { userId } = req.params;
155 | const { gender } = req.body;
156 |
157 | const user = await User.findByIdAndUpdate(
158 | userId,
159 | { gender: gender },
160 | { new: true }
161 | );
162 |
163 | if (!user) {
164 | return res.status(404).json({ message: "User not found" });
165 | }
166 |
167 | return res.status(200).json({ message: "User gender updated Succesfully" });
168 | } catch (error) {
169 | res.status(500).json({ message: "Error updating user gender", error });
170 | }
171 | });
172 |
173 | //endpoint to update the user description
174 | app.put("/users/:userId/description", async (req, res) => {
175 | try {
176 | const { userId } = req.params;
177 | const { description } = req.body;
178 |
179 | const user = await User.findByIdAndUpdate(
180 | userId,
181 | {
182 | description: description,
183 | },
184 | { new: true }
185 | );
186 |
187 | if (!user) {
188 | return res.status(404).json({ message: "User not found" });
189 | }
190 |
191 | return res
192 | .status(200)
193 | .json({ message: "User description updated succesfully" });
194 | } catch (error) {
195 | res.status(500).json({ message: "Error updating user description" });
196 | }
197 | });
198 |
199 | //fetch users data
200 | app.get("/users/:userId", async (req, res) => {
201 | try {
202 | const { userId } = req.params;
203 |
204 | const user = await User.findById(userId);
205 |
206 | if (!user) {
207 | return res.status(500).json({ message: "User not found" });
208 | }
209 |
210 | return res.status(200).json({ user });
211 | } catch (error) {
212 | res.status(500).json({ message: "Error fetching the user details" });
213 | }
214 | });
215 |
216 | //end point to add a turnon for a user in the backend
217 | app.put("/users/:userId/turn-ons/add", async (req, res) => {
218 | try {
219 | const { userId } = req.params;
220 | const { turnOn } = req.body;
221 |
222 | const user = await User.findByIdAndUpdate(
223 | userId,
224 | { $addToSet: { turnOns: turnOn } },
225 | { new: true }
226 | );
227 |
228 | if (!user) {
229 | return res.status(404).json({ message: "User not found" });
230 | }
231 |
232 | return res
233 | .status(200)
234 | .json({ message: "Turn on updated succesfully", user });
235 | } catch (error) {
236 | res.status(500).json({ message: "Error adding the turn on" });
237 | }
238 | });
239 |
240 | //endpoint to remove a particular turn on for the user
241 | app.put("/users/:userId/turn-ons/remove", async (req, res) => {
242 | try {
243 | const { userId } = req.params;
244 |
245 | const { turnOn } = req.body;
246 |
247 | const user = await User.findByIdAndUpdate(
248 | userId,
249 | { $pull: { turnOns: turnOn } },
250 | { new: true }
251 | );
252 |
253 | if (!user) {
254 | return res.status(404).json({ message: "User not found" });
255 | }
256 |
257 | return res
258 | .status(200)
259 | .json({ message: "Turn on removed succesfully", user });
260 | } catch (error) {
261 | return res.status(500).json({ message: "Error removing turn on" });
262 | }
263 | });
264 |
265 | //end point to add a lookingFor for a user in the backend
266 | app.put("/users/:userId/looking-for", async (req, res) => {
267 | try {
268 | const { userId } = req.params;
269 | const { lookingFor } = req.body;
270 |
271 | const user = await User.findByIdAndUpdate(
272 | userId,
273 | {
274 | $addToSet: { lookingFor: lookingFor },
275 | },
276 | { new: true }
277 | );
278 |
279 | if (!user) {
280 | return res.status(404).json({ message: "No user" });
281 | }
282 |
283 | return res
284 | .status(200)
285 | .json({ message: "Looking for updated succesfully".user });
286 | } catch (error) {
287 | res.status(500).json({ message: "Error updating looking for", error });
288 | }
289 | });
290 |
291 | //endpoint to remove looking for in the backend
292 | app.put("/users/:userId/looking-for/remove", async (req, res) => {
293 | try {
294 | const { userId } = req.params;
295 | const { lookingFor } = req.body;
296 |
297 | const user = await User.findByIdAndUpdate(
298 | userId,
299 | {
300 | $pull: { lookingFor: lookingFor },
301 | },
302 | { new: true }
303 | );
304 |
305 | if (!user) {
306 | return res.status(404).json({ message: "No user" });
307 | }
308 |
309 | return res
310 | .status(200)
311 | .json({ message: "Looking for updated succesfully".user });
312 | } catch (error) {
313 | res.status(500).json({ message: "Error removing looking for", error });
314 | }
315 | });
316 |
317 | app.post("/users/:userId/profile-images", async (req, res) => {
318 | try {
319 | const { userId } = req.params;
320 | const { imageUrl } = req.body;
321 |
322 | const user = await User.findById(userId);
323 |
324 | if (!user) {
325 | return res.status(404).json({ message: "User not found" });
326 | }
327 |
328 | user.profileImages.push(imageUrl);
329 |
330 | await user.save();
331 |
332 | return res.status(200).json({ message: "Image has been added", user });
333 | } catch (error) {
334 | res.status(500).json({ message: "Error addding the profile images" });
335 | }
336 | });
337 |
338 | //endpoint to fetch all the profiles for a particular user
339 | app.get("/profiles", async (req, res) => {
340 | const { userId, gender, turnOns, lookingFor } = req.query;
341 |
342 | try {
343 | let filter = { gender: gender === "male" ? "female" : "male" }; // For gender filtering
344 |
345 | // Add filtering based on turnOns and lookingFor arrays
346 | if (turnOns) {
347 | filter.turnOns = { $in: turnOns };
348 | }
349 |
350 | if (lookingFor) {
351 | filter.lookingFor = { $in: lookingFor };
352 | }
353 |
354 | const currentUser = await User.findById(userId)
355 | .populate("matches", "_id")
356 | .populate("crushes", "_id");
357 |
358 | // Extract IDs of friends
359 | const friendIds = currentUser.matches.map((friend) => friend._id);
360 |
361 | // Extract IDs of crushes
362 | const crushIds = currentUser.crushes.map((crush) => crush._id);
363 |
364 | const profiles = await User.find(filter)
365 | .where("_id")
366 | .nin([userId, ...friendIds, ...crushIds]);
367 |
368 | return res.status(200).json({ profiles });
369 | } catch (error) {
370 | return res.status(500).json({ message: "Error fetching profiles", error });
371 | }
372 | });
373 |
374 | app.post("/send-like", async (req, res) => {
375 | const { currentUserId, selectedUserId } = req.body;
376 |
377 | try {
378 | //update the recepient's friendRequestsArray!
379 | await User.findByIdAndUpdate(selectedUserId, {
380 | $push: { recievedLikes: currentUserId },
381 | });
382 | //update the sender's sentFriendRequests array
383 | await User.findByIdAndUpdate(currentUserId, {
384 | $push: { crushes: selectedUserId },
385 | });
386 |
387 | res.sendStatus(200);
388 | } catch (error) {
389 | res.sendStatus(500);
390 | }
391 | });
392 |
393 | //ednpoint to get the details of the received Likes
394 | app.get("/received-likes/:userId/details", async (req, res) => {
395 | const { userId } = req.params;
396 |
397 | try {
398 | // Find the user by ID
399 | const user = await User.findById(userId);
400 |
401 | if (!user) {
402 | return res.status(404).json({ message: "User not found" });
403 | }
404 |
405 | // Fetch details of users who liked the current user
406 | const receivedLikesDetails = [];
407 | for (const likedUserId of user.recievedLikes) {
408 | const likedUser = await User.findById(likedUserId);
409 | if (likedUser) {
410 | receivedLikesDetails.push(likedUser);
411 | }
412 | }
413 |
414 | res.status(200).json({ receivedLikesDetails });
415 | } catch (error) {
416 | res.status(500).json({
417 | message: "Error fetching received likes details",
418 | error: error.message,
419 | });
420 | }
421 | });
422 |
423 | //endpoint to create a match betweeen two people
424 | app.post("/create-match", async (req, res) => {
425 | try {
426 | const { currentUserId, selectedUserId } = req.body;
427 |
428 | //update the selected user's crushes array and the matches array
429 | await User.findByIdAndUpdate(selectedUserId, {
430 | $push: { matches: currentUserId },
431 | $pull: { crushes: currentUserId },
432 | });
433 |
434 | //update the current user's matches array recievedlikes array
435 | await User.findByIdAndUpdate(currentUserId, {
436 | $push: { matches: selectedUserId },
437 | $pull: { recievedLikes: selectedUserId },
438 | });
439 |
440 | res.sendStatus(200);
441 | } catch (error) {
442 | res.status(500).json({ message: "Error creating a match", error });
443 | }
444 | });
445 |
446 | //endpoint to get all the matches of the particular user
447 | app.get("/users/:userId/matches", async (req, res) => {
448 | try {
449 | const { userId } = req.params;
450 |
451 | const user = await User.findById(userId);
452 |
453 | if (!user) {
454 | return res.status(404).json({ message: "User not found" });
455 | }
456 |
457 | const matchIds = user.matches;
458 |
459 | const matches = await User.find({ _id: { $in: matchIds } });
460 |
461 | res.status(200).json({ matches });
462 | } catch (error) {
463 | res.status(500).json({ message: "Error retrieving the matches", error });
464 | }
465 | });
466 |
467 | io.on("connection", (socket) => {
468 | console.log("a user is connected");
469 |
470 | socket.on("sendMessage", async (data) => {
471 | try {
472 | const { senderId, receiverId, message } = data;
473 |
474 | console.log("data", data);
475 |
476 | const newMessage = new Chat({ senderId, receiverId, message });
477 | await newMessage.save();
478 |
479 | //emit the message to the receiver
480 | io.to(receiverId).emit("receiveMessage", newMessage);
481 | } catch (error) {
482 | console.log("Error handling the messages");
483 | }
484 | socket.on("disconnet", () => {
485 | console.log("user disconnected");
486 | });
487 | });
488 | });
489 |
490 | http.listen(8000, () => {
491 | console.log("Socket.IO server running on port 8000");
492 | });
493 |
494 | app.get("/messages", async (req, res) => {
495 | try {
496 | const { senderId, receiverId } = req.query;
497 |
498 | console.log(senderId);
499 | console.log(receiverId);
500 |
501 | const messages = await Chat.find({
502 | $or: [
503 | { senderId: senderId, receiverId: receiverId },
504 | { senderId: receiverId, receiverId: senderId },
505 | ],
506 | }).populate("senderId", "_id name");
507 |
508 | res.status(200).json(messages);
509 | } catch (error) {
510 | res.status(500).json({ message: "Error in getting messages", error });
511 | }
512 | });
513 |
514 |
515 | //endpoint to delete the messages;
516 |
517 | app.post("/delete",async(req,res) => {
518 | try{
519 | const {messages} = req.body;
520 |
521 | if(!Array.isArray(messages) || messages.length == 0){
522 | return res.status(400).json({message:"Invalid request body"})
523 | };
524 |
525 | for(const messageId of messages){
526 | await Chat.findByIdAndDelete(messageId);
527 | }
528 |
529 | res.status(200).json({message:"Messages delted successfully!"})
530 | } catch(error){
531 | res.status(500).json({message:"Internal server error",error})
532 | }
533 | })
--------------------------------------------------------------------------------
/app/(tabs)/bio/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | StyleSheet,
3 | Text,
4 | View,
5 | ScrollView,
6 | Image,
7 | Pressable,
8 | TextInput,
9 | Button,
10 | FlatList,
11 | Alert,
12 | } from "react-native";
13 | import React, { useState, useEffect } from "react";
14 | import { Entypo, AntDesign } from "@expo/vector-icons";
15 | import Carousel from "react-native-snap-carousel";
16 | import axios from "axios";
17 | import "core-js/stable/atob";
18 | import { jwtDecode } from "jwt-decode";
19 | import AsyncStorage from "@react-native-async-storage/async-storage";
20 |
21 | const index = () => {
22 | const [option, setOption] = useState("AD");
23 | const [description, setDescription] = useState("");
24 | const [activeSlide, setActiveSlide] = React.useState(0);
25 | const [userId, setUserId] = useState("");
26 | const [selectedTurnOns, setSelectedTurnOns] = useState([]);
27 | const [lookingOptions, setLookingOptions] = useState([]);
28 | const [imageUrl, setImageUrl] = useState("");
29 | const [images, setImages] = useState([]);
30 | const profileImages = [
31 | {
32 | image:
33 | "https://images.pexels.com/photos/1042140/pexels-photo-1042140.jpeg?auto=compress&cs=tinysrgb&w=800",
34 | },
35 | {
36 | image:
37 | "https://images.pexels.com/photos/1215695/pexels-photo-1215695.jpeg?auto=compress&cs=tinysrgb&w=800",
38 | },
39 | {
40 | image:
41 | "https://images.pexels.com/photos/7580971/pexels-photo-7580971.jpeg?auto=compress&cs=tinysrgb&w=800",
42 | },
43 | ];
44 | const turnons = [
45 | {
46 | id: "0",
47 | name: "Music",
48 | description: "Pop Rock-Indie pick our sound track",
49 | },
50 | {
51 | id: "10",
52 | name: "Kissing",
53 | description:
54 | " It's a feeling of closeness, where every touch of lips creates a symphony of emotions.",
55 | },
56 | {
57 | id: "1",
58 | name: "Fantasies",
59 | description:
60 | "Fantasies can be deeply personal, encompassing diverse elements such as romance",
61 | },
62 | {
63 | id: "2",
64 | name: "Nibbling",
65 | description:
66 | "playful form of biting or taking small, gentle bites, typically done with the teeth",
67 | },
68 | {
69 | id: "3",
70 | name: "Desire",
71 | description: "powerful emotion or attainment of a particular person.",
72 | },
73 | ];
74 | const data = [
75 | {
76 | id: "0",
77 | name: "Casual",
78 | description: "Let's keep it easy and see where it goes",
79 | },
80 | {
81 | id: "1",
82 | name: "Long Term",
83 | description: "How about a one life stand",
84 | },
85 | {
86 | id: "2",
87 | name: "Virtual",
88 | description: "Let's have some virtual fun",
89 | },
90 | {
91 | id: "3",
92 | name: "Open for Anything",
93 | description: "Let's Vibe and see where it goes",
94 | },
95 | ];
96 | useEffect(() => {
97 | const fetchUser = async () => {
98 | const token = await AsyncStorage.getItem("auth");
99 | const decodedToken = jwtDecode(token);
100 | const userId = decodedToken.userId;
101 | setUserId(userId);
102 | };
103 |
104 | fetchUser();
105 | }, []);
106 | const fetchUserDescription = async () => {
107 | try {
108 | const response = await axios.get(`http://localhost:3000/users/${userId}`);
109 | console.log(response);
110 | const user = response.data;
111 |
112 | setDescription(user?.user?.description);
113 | setSelectedTurnOns(user.user?.turnOns);
114 | setImages(user?.user.profileImages);
115 | setLookingOptions(user?.user.lookingFor)
116 | } catch (error) {
117 | console.log("Error fetching user description", error);
118 | }
119 | };
120 | useEffect(() => {
121 | if (userId) {
122 | fetchUserDescription();
123 | }
124 | }, [userId]);
125 | const updateUserDescription = async () => {
126 | try {
127 | const response = await axios.put(
128 | `http://localhost:3000/users/${userId}/description`,
129 | {
130 | description: description,
131 | }
132 | );
133 |
134 | console.log(response.data);
135 |
136 | if (response.status === 200) {
137 | Alert.alert("Success", "Description updated successfully");
138 | }
139 | } catch (error) {
140 | console.log("Error updating the user Description");
141 | }
142 | };
143 | const handleToggleTurnOn = (turnOn) => {
144 | if (selectedTurnOns.includes(turnOn)) {
145 | removeTurnOn(turnOn);
146 | } else {
147 | addTurnOn(turnOn);
148 | }
149 | };
150 | const handleOption = (lookingFor) => {
151 | if (lookingOptions.includes(lookingFor)) {
152 | removeLookingFor(lookingFor);
153 | } else {
154 | addLookingFor(lookingFor);
155 | }
156 | };
157 | const addLookingFor = async (lookingFor) => {
158 | try {
159 | const response = await axios.put(
160 | `http://localhost:3000/users/${userId}/looking-for`,
161 | {
162 | lookingFor: lookingFor,
163 | }
164 | );
165 |
166 | console.log(response.data);
167 |
168 | if (response.status == 200) {
169 | setLookingOptions([...lookingOptions, lookingFor]);
170 | }
171 | } catch (error) {
172 | console.log("Error addding looking for", error);
173 | }
174 | };
175 | const removeLookingFor = async (lookingFor) => {
176 | try {
177 | const response = await axios.put(
178 | `http://localhost:3000/users/${userId}/looking-for/remove`,
179 | {
180 | lookingFor: lookingFor,
181 | }
182 | );
183 |
184 | console.log(response.data); // Log the response for confirmation
185 |
186 | // Handle success or update your app state accordingly
187 | if (response.status === 200) {
188 | setLookingOptions(lookingOptions.filter((item) => item !== lookingFor));
189 | }
190 | } catch (error) {
191 | console.error("Error removing looking for:", error);
192 | // Handle error scenarios
193 | }
194 | };
195 |
196 | const addTurnOn = async (turnOn) => {
197 | try {
198 | const response = await axios.put(
199 | `http://localhost:3000/users/${userId}/turn-ons/add`,
200 | {
201 | turnOn: turnOn,
202 | }
203 | );
204 |
205 | console.log(response.data);
206 |
207 | if (response.status == 200) {
208 | setSelectedTurnOns([...selectedTurnOns, turnOn]);
209 | }
210 | } catch (error) {
211 | console.log("Error adding turn on", error);
212 | }
213 | };
214 | const removeTurnOn = async (turnOn) => {
215 | try {
216 | const response = await axios.put(
217 | `http://localhost:3000/users/${userId}/turn-ons/remove`,
218 | {
219 | turnOn: turnOn,
220 | }
221 | );
222 |
223 | console.log(response.data);
224 |
225 | if (response.status == 200) {
226 | setSelectedTurnOns(selectedTurnOns.filter((item) => item !== turnOn));
227 | }
228 | } catch (error) {
229 | console.log("error removing turn on", error);
230 | }
231 | };
232 | const renderImageCarousel = ({ item }) => (
233 |
236 |
246 |
249 | {activeSlide + 1}/{images.length}
250 |
251 |
252 | );
253 | const handleAddImage = async () =>{
254 | try{
255 | const response = await axios.post(`http://localhost:3000/users/${userId}/profile-images`,{
256 | imageUrl:imageUrl
257 | });
258 |
259 | console.log(response);
260 |
261 | setImageUrl("");
262 | } catch(error){
263 | console.log("error",error)
264 | }
265 | }
266 | const getRandomImage = () => {
267 | const randomIndex = Math.floor(Math.random() * images.length);
268 | return images[randomIndex]
269 | }
270 | const randomImage = getRandomImage()
271 | return (
272 |
273 |
274 |
280 |
281 |
282 |
298 |
309 |
310 | Bangalore
311 |
312 |
313 | 22 years 110 days
314 |
315 |
316 |
317 |
318 |
319 |
320 |
330 | setOption("AD")}>
331 |
338 | AD
339 |
340 |
341 | setOption("Photos")}>
342 |
349 | Photos
350 |
351 |
352 | setOption("Turn-ons")}>
353 |
360 | Turn-ons
361 |
362 |
363 | setOption("Looking For")}>
364 |
371 | Looking For
372 |
373 |
374 |
375 |
376 |
377 | {option == "AD" && (
378 |
387 | setDescription(text)}
391 | style={{
392 | fontFamily: "Helvetica",
393 | fontSize: description ? 17 : 17,
394 | }}
395 | placeholder="Write your AD for people to like you"
396 | // placeholderTextColor={"black"}
397 | />
398 |
411 |
419 | Publish in feed
420 |
421 |
422 |
423 |
424 | )}
425 |
426 |
427 |
428 | {option == "Photos" && (
429 |
430 | setActiveSlide(index)}
436 | />
437 |
438 |
439 | Add a picture of yourself
440 |
451 |
457 | setImageUrl(text)}
460 | style={{ color: "gray", marginVertical: 10, width: 300 }}
461 | placeholder="enter your image url"
462 | />
463 |
464 |
465 |
466 |
467 | )}
468 |
469 |
470 |
471 | {option == "Turn-ons" && (
472 |
473 | {turnons?.map((item, index) => (
474 | handleToggleTurnOn(item?.name)}
476 | style={{
477 | backgroundColor: "#FFFDD0",
478 | padding: 10,
479 | marginVertical: 10,
480 | }}
481 | key={index}
482 | >
483 |
490 |
498 | {item?.name}
499 |
500 | {selectedTurnOns.includes(item?.name) && (
501 |
502 | )}
503 |
504 |
512 | {item?.description}
513 |
514 |
515 | ))}
516 |
517 | )}
518 |
519 |
520 |
521 | {option == "Looking For" && (
522 | <>
523 |
524 | (
529 | handleOption(item?.name)}
531 | style={{
532 | backgroundColor: lookingOptions.includes(item?.name)
533 | ? "#fd5c63"
534 | : "white",
535 | padding: 16,
536 | justifyContent: "center",
537 | alignItems: "center",
538 | width: 150,
539 | margin: 10,
540 | borderRadius: 5,
541 | borderColor: "#fd5c63",
542 | borderWidth: lookingOptions.includes(item?.name)
543 | ? "transparent"
544 | : 0.7,
545 | }}
546 | >
547 |
557 | {item?.name}
558 |
559 |
570 | {item?.description}
571 |
572 |
573 | )}
574 | />
575 |
576 | >
577 | )}
578 |
579 |
580 | );
581 | };
582 |
583 | export default index;
584 |
585 | const styles = StyleSheet.create({});
586 |
--------------------------------------------------------------------------------
/api/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@mongodb-js/saslprep@^1.1.0":
6 | version "1.1.1"
7 | resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz#9a6c2516bc9188672c4d953ec99760ba49970da7"
8 | integrity sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==
9 | dependencies:
10 | sparse-bitfield "^3.0.3"
11 |
12 | "@socket.io/component-emitter@~3.1.0":
13 | version "3.1.0"
14 | resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
15 | integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
16 |
17 | "@types/cookie@^0.4.1":
18 | version "0.4.1"
19 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d"
20 | integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==
21 |
22 | "@types/cors@^2.8.12":
23 | version "2.8.17"
24 | resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b"
25 | integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==
26 | dependencies:
27 | "@types/node" "*"
28 |
29 | "@types/node@*", "@types/node@>=10.0.0":
30 | version "20.10.6"
31 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.6.tgz#a3ec84c22965802bf763da55b2394424f22bfbb5"
32 | integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==
33 | dependencies:
34 | undici-types "~5.26.4"
35 |
36 | "@types/webidl-conversions@*":
37 | version "7.0.3"
38 | resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz#1306dbfa53768bcbcfc95a1c8cde367975581859"
39 | integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==
40 |
41 | "@types/whatwg-url@^8.2.1":
42 | version "8.2.2"
43 | resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.2.tgz#749d5b3873e845897ada99be4448041d4cc39e63"
44 | integrity sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==
45 | dependencies:
46 | "@types/node" "*"
47 | "@types/webidl-conversions" "*"
48 |
49 | abbrev@1:
50 | version "1.1.1"
51 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
52 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
53 |
54 | accepts@~1.3.4, accepts@~1.3.8:
55 | version "1.3.8"
56 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
57 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
58 | dependencies:
59 | mime-types "~2.1.34"
60 | negotiator "0.6.3"
61 |
62 | anymatch@~3.1.2:
63 | version "3.1.3"
64 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
65 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
66 | dependencies:
67 | normalize-path "^3.0.0"
68 | picomatch "^2.0.4"
69 |
70 | array-flatten@1.1.1:
71 | version "1.1.1"
72 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
73 | integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
74 |
75 | balanced-match@^1.0.0:
76 | version "1.0.2"
77 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
78 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
79 |
80 | base64id@2.0.0, base64id@~2.0.0:
81 | version "2.0.0"
82 | resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
83 | integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
84 |
85 | binary-extensions@^2.0.0:
86 | version "2.2.0"
87 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
88 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
89 |
90 | body-parser@1.20.1:
91 | version "1.20.1"
92 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
93 | integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
94 | dependencies:
95 | bytes "3.1.2"
96 | content-type "~1.0.4"
97 | debug "2.6.9"
98 | depd "2.0.0"
99 | destroy "1.2.0"
100 | http-errors "2.0.0"
101 | iconv-lite "0.4.24"
102 | on-finished "2.4.1"
103 | qs "6.11.0"
104 | raw-body "2.5.1"
105 | type-is "~1.6.18"
106 | unpipe "1.0.0"
107 |
108 | body-parser@^1.20.2:
109 | version "1.20.2"
110 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
111 | integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
112 | dependencies:
113 | bytes "3.1.2"
114 | content-type "~1.0.5"
115 | debug "2.6.9"
116 | depd "2.0.0"
117 | destroy "1.2.0"
118 | http-errors "2.0.0"
119 | iconv-lite "0.4.24"
120 | on-finished "2.4.1"
121 | qs "6.11.0"
122 | raw-body "2.5.2"
123 | type-is "~1.6.18"
124 | unpipe "1.0.0"
125 |
126 | brace-expansion@^1.1.7:
127 | version "1.1.11"
128 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
129 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
130 | dependencies:
131 | balanced-match "^1.0.0"
132 | concat-map "0.0.1"
133 |
134 | braces@~3.0.2:
135 | version "3.0.2"
136 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
137 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
138 | dependencies:
139 | fill-range "^7.0.1"
140 |
141 | bson@^6.2.0:
142 | version "6.2.0"
143 | resolved "https://registry.yarnpkg.com/bson/-/bson-6.2.0.tgz#4b6acafc266ba18eeee111373c2699304a9ba0a3"
144 | integrity sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==
145 |
146 | buffer-equal-constant-time@1.0.1:
147 | version "1.0.1"
148 | resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
149 | integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
150 |
151 | bytes@3.1.2:
152 | version "3.1.2"
153 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
154 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
155 |
156 | call-bind@^1.0.0:
157 | version "1.0.5"
158 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513"
159 | integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==
160 | dependencies:
161 | function-bind "^1.1.2"
162 | get-intrinsic "^1.2.1"
163 | set-function-length "^1.1.1"
164 |
165 | chokidar@^3.5.2:
166 | version "3.5.3"
167 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
168 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
169 | dependencies:
170 | anymatch "~3.1.2"
171 | braces "~3.0.2"
172 | glob-parent "~5.1.2"
173 | is-binary-path "~2.1.0"
174 | is-glob "~4.0.1"
175 | normalize-path "~3.0.0"
176 | readdirp "~3.6.0"
177 | optionalDependencies:
178 | fsevents "~2.3.2"
179 |
180 | concat-map@0.0.1:
181 | version "0.0.1"
182 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
183 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
184 |
185 | content-disposition@0.5.4:
186 | version "0.5.4"
187 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
188 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
189 | dependencies:
190 | safe-buffer "5.2.1"
191 |
192 | content-type@~1.0.4, content-type@~1.0.5:
193 | version "1.0.5"
194 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
195 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
196 |
197 | cookie-signature@1.0.6:
198 | version "1.0.6"
199 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
200 | integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
201 |
202 | cookie@0.5.0:
203 | version "0.5.0"
204 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
205 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
206 |
207 | cookie@~0.4.1:
208 | version "0.4.2"
209 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
210 | integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
211 |
212 | cors@^2.8.5, cors@~2.8.5:
213 | version "2.8.5"
214 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
215 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
216 | dependencies:
217 | object-assign "^4"
218 | vary "^1"
219 |
220 | debug@2.6.9:
221 | version "2.6.9"
222 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
223 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
224 | dependencies:
225 | ms "2.0.0"
226 |
227 | debug@4.x, debug@^4, debug@~4.3.1, debug@~4.3.2:
228 | version "4.3.4"
229 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
230 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
231 | dependencies:
232 | ms "2.1.2"
233 |
234 | define-data-property@^1.1.1:
235 | version "1.1.1"
236 | resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3"
237 | integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==
238 | dependencies:
239 | get-intrinsic "^1.2.1"
240 | gopd "^1.0.1"
241 | has-property-descriptors "^1.0.0"
242 |
243 | depd@2.0.0:
244 | version "2.0.0"
245 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
246 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
247 |
248 | destroy@1.2.0:
249 | version "1.2.0"
250 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
251 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
252 |
253 | ecdsa-sig-formatter@1.0.11:
254 | version "1.0.11"
255 | resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
256 | integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
257 | dependencies:
258 | safe-buffer "^5.0.1"
259 |
260 | ee-first@1.1.1:
261 | version "1.1.1"
262 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
263 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
264 |
265 | encodeurl@~1.0.2:
266 | version "1.0.2"
267 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
268 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
269 |
270 | engine.io-parser@~5.2.1:
271 | version "5.2.1"
272 | resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.1.tgz#9f213c77512ff1a6cc0c7a86108a7ffceb16fcfb"
273 | integrity sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==
274 |
275 | engine.io@~6.5.2:
276 | version "6.5.4"
277 | resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.5.4.tgz#6822debf324e781add2254e912f8568508850cdc"
278 | integrity sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==
279 | dependencies:
280 | "@types/cookie" "^0.4.1"
281 | "@types/cors" "^2.8.12"
282 | "@types/node" ">=10.0.0"
283 | accepts "~1.3.4"
284 | base64id "2.0.0"
285 | cookie "~0.4.1"
286 | cors "~2.8.5"
287 | debug "~4.3.1"
288 | engine.io-parser "~5.2.1"
289 | ws "~8.11.0"
290 |
291 | escape-html@~1.0.3:
292 | version "1.0.3"
293 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
294 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
295 |
296 | etag@~1.8.1:
297 | version "1.8.1"
298 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
299 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
300 |
301 | express@^4.18.2:
302 | version "4.18.2"
303 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
304 | integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
305 | dependencies:
306 | accepts "~1.3.8"
307 | array-flatten "1.1.1"
308 | body-parser "1.20.1"
309 | content-disposition "0.5.4"
310 | content-type "~1.0.4"
311 | cookie "0.5.0"
312 | cookie-signature "1.0.6"
313 | debug "2.6.9"
314 | depd "2.0.0"
315 | encodeurl "~1.0.2"
316 | escape-html "~1.0.3"
317 | etag "~1.8.1"
318 | finalhandler "1.2.0"
319 | fresh "0.5.2"
320 | http-errors "2.0.0"
321 | merge-descriptors "1.0.1"
322 | methods "~1.1.2"
323 | on-finished "2.4.1"
324 | parseurl "~1.3.3"
325 | path-to-regexp "0.1.7"
326 | proxy-addr "~2.0.7"
327 | qs "6.11.0"
328 | range-parser "~1.2.1"
329 | safe-buffer "5.2.1"
330 | send "0.18.0"
331 | serve-static "1.15.0"
332 | setprototypeof "1.2.0"
333 | statuses "2.0.1"
334 | type-is "~1.6.18"
335 | utils-merge "1.0.1"
336 | vary "~1.1.2"
337 |
338 | fill-range@^7.0.1:
339 | version "7.0.1"
340 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
341 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
342 | dependencies:
343 | to-regex-range "^5.0.1"
344 |
345 | finalhandler@1.2.0:
346 | version "1.2.0"
347 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
348 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
349 | dependencies:
350 | debug "2.6.9"
351 | encodeurl "~1.0.2"
352 | escape-html "~1.0.3"
353 | on-finished "2.4.1"
354 | parseurl "~1.3.3"
355 | statuses "2.0.1"
356 | unpipe "~1.0.0"
357 |
358 | forwarded@0.2.0:
359 | version "0.2.0"
360 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
361 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
362 |
363 | fresh@0.5.2:
364 | version "0.5.2"
365 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
366 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
367 |
368 | fsevents@~2.3.2:
369 | version "2.3.3"
370 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
371 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
372 |
373 | function-bind@^1.1.2:
374 | version "1.1.2"
375 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
376 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
377 |
378 | get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2:
379 | version "1.2.2"
380 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b"
381 | integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==
382 | dependencies:
383 | function-bind "^1.1.2"
384 | has-proto "^1.0.1"
385 | has-symbols "^1.0.3"
386 | hasown "^2.0.0"
387 |
388 | glob-parent@~5.1.2:
389 | version "5.1.2"
390 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
391 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
392 | dependencies:
393 | is-glob "^4.0.1"
394 |
395 | gopd@^1.0.1:
396 | version "1.0.1"
397 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
398 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
399 | dependencies:
400 | get-intrinsic "^1.1.3"
401 |
402 | has-flag@^3.0.0:
403 | version "3.0.0"
404 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
405 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
406 |
407 | has-property-descriptors@^1.0.0:
408 | version "1.0.1"
409 | resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340"
410 | integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==
411 | dependencies:
412 | get-intrinsic "^1.2.2"
413 |
414 | has-proto@^1.0.1:
415 | version "1.0.1"
416 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
417 | integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
418 |
419 | has-symbols@^1.0.3:
420 | version "1.0.3"
421 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
422 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
423 |
424 | hasown@^2.0.0:
425 | version "2.0.0"
426 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
427 | integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
428 | dependencies:
429 | function-bind "^1.1.2"
430 |
431 | http-errors@2.0.0:
432 | version "2.0.0"
433 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
434 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
435 | dependencies:
436 | depd "2.0.0"
437 | inherits "2.0.4"
438 | setprototypeof "1.2.0"
439 | statuses "2.0.1"
440 | toidentifier "1.0.1"
441 |
442 | iconv-lite@0.4.24:
443 | version "0.4.24"
444 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
445 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
446 | dependencies:
447 | safer-buffer ">= 2.1.2 < 3"
448 |
449 | ignore-by-default@^1.0.1:
450 | version "1.0.1"
451 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
452 | integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
453 |
454 | inherits@2.0.4:
455 | version "2.0.4"
456 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
457 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
458 |
459 | ipaddr.js@1.9.1:
460 | version "1.9.1"
461 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
462 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
463 |
464 | is-binary-path@~2.1.0:
465 | version "2.1.0"
466 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
467 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
468 | dependencies:
469 | binary-extensions "^2.0.0"
470 |
471 | is-extglob@^2.1.1:
472 | version "2.1.1"
473 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
474 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
475 |
476 | is-glob@^4.0.1, is-glob@~4.0.1:
477 | version "4.0.3"
478 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
479 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
480 | dependencies:
481 | is-extglob "^2.1.1"
482 |
483 | is-number@^7.0.0:
484 | version "7.0.0"
485 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
486 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
487 |
488 | jsonwebtoken@^9.0.2:
489 | version "9.0.2"
490 | resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3"
491 | integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==
492 | dependencies:
493 | jws "^3.2.2"
494 | lodash.includes "^4.3.0"
495 | lodash.isboolean "^3.0.3"
496 | lodash.isinteger "^4.0.4"
497 | lodash.isnumber "^3.0.3"
498 | lodash.isplainobject "^4.0.6"
499 | lodash.isstring "^4.0.1"
500 | lodash.once "^4.0.0"
501 | ms "^2.1.1"
502 | semver "^7.5.4"
503 |
504 | jwa@^1.4.1:
505 | version "1.4.1"
506 | resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
507 | integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
508 | dependencies:
509 | buffer-equal-constant-time "1.0.1"
510 | ecdsa-sig-formatter "1.0.11"
511 | safe-buffer "^5.0.1"
512 |
513 | jws@^3.2.2:
514 | version "3.2.2"
515 | resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
516 | integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
517 | dependencies:
518 | jwa "^1.4.1"
519 | safe-buffer "^5.0.1"
520 |
521 | kareem@2.5.1:
522 | version "2.5.1"
523 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d"
524 | integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==
525 |
526 | lodash.includes@^4.3.0:
527 | version "4.3.0"
528 | resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
529 | integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==
530 |
531 | lodash.isboolean@^3.0.3:
532 | version "3.0.3"
533 | resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
534 | integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==
535 |
536 | lodash.isinteger@^4.0.4:
537 | version "4.0.4"
538 | resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
539 | integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==
540 |
541 | lodash.isnumber@^3.0.3:
542 | version "3.0.3"
543 | resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
544 | integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==
545 |
546 | lodash.isplainobject@^4.0.6:
547 | version "4.0.6"
548 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
549 | integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
550 |
551 | lodash.isstring@^4.0.1:
552 | version "4.0.1"
553 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
554 | integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
555 |
556 | lodash.once@^4.0.0:
557 | version "4.1.1"
558 | resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
559 | integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
560 |
561 | lru-cache@^6.0.0:
562 | version "6.0.0"
563 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
564 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
565 | dependencies:
566 | yallist "^4.0.0"
567 |
568 | media-typer@0.3.0:
569 | version "0.3.0"
570 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
571 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
572 |
573 | memory-pager@^1.0.2:
574 | version "1.5.0"
575 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
576 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==
577 |
578 | merge-descriptors@1.0.1:
579 | version "1.0.1"
580 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
581 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
582 |
583 | methods@~1.1.2:
584 | version "1.1.2"
585 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
586 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
587 |
588 | mime-db@1.52.0:
589 | version "1.52.0"
590 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
591 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
592 |
593 | mime-types@~2.1.24, mime-types@~2.1.34:
594 | version "2.1.35"
595 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
596 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
597 | dependencies:
598 | mime-db "1.52.0"
599 |
600 | mime@1.6.0:
601 | version "1.6.0"
602 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
603 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
604 |
605 | minimatch@^3.1.2:
606 | version "3.1.2"
607 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
608 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
609 | dependencies:
610 | brace-expansion "^1.1.7"
611 |
612 | mongodb-connection-string-url@^2.6.0:
613 | version "2.6.0"
614 | resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz#57901bf352372abdde812c81be47b75c6b2ec5cf"
615 | integrity sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==
616 | dependencies:
617 | "@types/whatwg-url" "^8.2.1"
618 | whatwg-url "^11.0.0"
619 |
620 | mongodb@6.2.0:
621 | version "6.2.0"
622 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.2.0.tgz#2c9dcb3eeaf528ed850e94b3df392de6c6b0d7ab"
623 | integrity sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==
624 | dependencies:
625 | "@mongodb-js/saslprep" "^1.1.0"
626 | bson "^6.2.0"
627 | mongodb-connection-string-url "^2.6.0"
628 |
629 | mongoose@^8.0.3:
630 | version "8.0.3"
631 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.0.3.tgz#f3708ba0f40b6dec8f5f1a5d40abd69a80207114"
632 | integrity sha512-LJRT0yP4TW14HT4r2RkxqyvoTylMSzWpl5QOeVHTnRggCLQSpkoBdgbUtORFq/mSL2o9cLCPJz+6uzFj25qbHw==
633 | dependencies:
634 | bson "^6.2.0"
635 | kareem "2.5.1"
636 | mongodb "6.2.0"
637 | mpath "0.9.0"
638 | mquery "5.0.0"
639 | ms "2.1.3"
640 | sift "16.0.1"
641 |
642 | mpath@0.9.0:
643 | version "0.9.0"
644 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904"
645 | integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==
646 |
647 | mquery@5.0.0:
648 | version "5.0.0"
649 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-5.0.0.tgz#a95be5dfc610b23862df34a47d3e5d60e110695d"
650 | integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==
651 | dependencies:
652 | debug "4.x"
653 |
654 | ms@2.0.0:
655 | version "2.0.0"
656 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
657 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
658 |
659 | ms@2.1.2:
660 | version "2.1.2"
661 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
662 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
663 |
664 | ms@2.1.3, ms@^2.1.1:
665 | version "2.1.3"
666 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
667 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
668 |
669 | negotiator@0.6.3:
670 | version "0.6.3"
671 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
672 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
673 |
674 | nodemailer@^6.9.8:
675 | version "6.9.8"
676 | resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.8.tgz#29601e80440f2af7aa62b32758fdac7c6b784143"
677 | integrity sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==
678 |
679 | nodemon@^3.0.2:
680 | version "3.0.2"
681 | resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.2.tgz#222dd0de79fc7b7b3eedba422d2b9e5fc678621e"
682 | integrity sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==
683 | dependencies:
684 | chokidar "^3.5.2"
685 | debug "^4"
686 | ignore-by-default "^1.0.1"
687 | minimatch "^3.1.2"
688 | pstree.remy "^1.1.8"
689 | semver "^7.5.3"
690 | simple-update-notifier "^2.0.0"
691 | supports-color "^5.5.0"
692 | touch "^3.1.0"
693 | undefsafe "^2.0.5"
694 |
695 | nopt@~1.0.10:
696 | version "1.0.10"
697 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
698 | integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==
699 | dependencies:
700 | abbrev "1"
701 |
702 | normalize-path@^3.0.0, normalize-path@~3.0.0:
703 | version "3.0.0"
704 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
705 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
706 |
707 | object-assign@^4:
708 | version "4.1.1"
709 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
710 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
711 |
712 | object-inspect@^1.9.0:
713 | version "1.13.1"
714 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
715 | integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
716 |
717 | on-finished@2.4.1:
718 | version "2.4.1"
719 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
720 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
721 | dependencies:
722 | ee-first "1.1.1"
723 |
724 | parseurl@~1.3.3:
725 | version "1.3.3"
726 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
727 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
728 |
729 | path-to-regexp@0.1.7:
730 | version "0.1.7"
731 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
732 | integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
733 |
734 | picomatch@^2.0.4, picomatch@^2.2.1:
735 | version "2.3.1"
736 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
737 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
738 |
739 | proxy-addr@~2.0.7:
740 | version "2.0.7"
741 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
742 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
743 | dependencies:
744 | forwarded "0.2.0"
745 | ipaddr.js "1.9.1"
746 |
747 | pstree.remy@^1.1.8:
748 | version "1.1.8"
749 | resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
750 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
751 |
752 | punycode@^2.1.1:
753 | version "2.3.1"
754 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
755 | integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
756 |
757 | qs@6.11.0:
758 | version "6.11.0"
759 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
760 | integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
761 | dependencies:
762 | side-channel "^1.0.4"
763 |
764 | range-parser@~1.2.1:
765 | version "1.2.1"
766 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
767 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
768 |
769 | raw-body@2.5.1:
770 | version "2.5.1"
771 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
772 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
773 | dependencies:
774 | bytes "3.1.2"
775 | http-errors "2.0.0"
776 | iconv-lite "0.4.24"
777 | unpipe "1.0.0"
778 |
779 | raw-body@2.5.2:
780 | version "2.5.2"
781 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
782 | integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
783 | dependencies:
784 | bytes "3.1.2"
785 | http-errors "2.0.0"
786 | iconv-lite "0.4.24"
787 | unpipe "1.0.0"
788 |
789 | readdirp@~3.6.0:
790 | version "3.6.0"
791 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
792 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
793 | dependencies:
794 | picomatch "^2.2.1"
795 |
796 | safe-buffer@5.2.1, safe-buffer@^5.0.1:
797 | version "5.2.1"
798 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
799 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
800 |
801 | "safer-buffer@>= 2.1.2 < 3":
802 | version "2.1.2"
803 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
804 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
805 |
806 | semver@^7.5.3, semver@^7.5.4:
807 | version "7.5.4"
808 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
809 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
810 | dependencies:
811 | lru-cache "^6.0.0"
812 |
813 | send@0.18.0:
814 | version "0.18.0"
815 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
816 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
817 | dependencies:
818 | debug "2.6.9"
819 | depd "2.0.0"
820 | destroy "1.2.0"
821 | encodeurl "~1.0.2"
822 | escape-html "~1.0.3"
823 | etag "~1.8.1"
824 | fresh "0.5.2"
825 | http-errors "2.0.0"
826 | mime "1.6.0"
827 | ms "2.1.3"
828 | on-finished "2.4.1"
829 | range-parser "~1.2.1"
830 | statuses "2.0.1"
831 |
832 | serve-static@1.15.0:
833 | version "1.15.0"
834 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
835 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
836 | dependencies:
837 | encodeurl "~1.0.2"
838 | escape-html "~1.0.3"
839 | parseurl "~1.3.3"
840 | send "0.18.0"
841 |
842 | set-function-length@^1.1.1:
843 | version "1.1.1"
844 | resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed"
845 | integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==
846 | dependencies:
847 | define-data-property "^1.1.1"
848 | get-intrinsic "^1.2.1"
849 | gopd "^1.0.1"
850 | has-property-descriptors "^1.0.0"
851 |
852 | setprototypeof@1.2.0:
853 | version "1.2.0"
854 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
855 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
856 |
857 | side-channel@^1.0.4:
858 | version "1.0.4"
859 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
860 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
861 | dependencies:
862 | call-bind "^1.0.0"
863 | get-intrinsic "^1.0.2"
864 | object-inspect "^1.9.0"
865 |
866 | sift@16.0.1:
867 | version "16.0.1"
868 | resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.1.tgz#e9c2ccc72191585008cf3e36fc447b2d2633a053"
869 | integrity sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==
870 |
871 | simple-update-notifier@^2.0.0:
872 | version "2.0.0"
873 | resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb"
874 | integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==
875 | dependencies:
876 | semver "^7.5.3"
877 |
878 | socket.io-adapter@~2.5.2:
879 | version "2.5.2"
880 | resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz#5de9477c9182fdc171cd8c8364b9a8894ec75d12"
881 | integrity sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==
882 | dependencies:
883 | ws "~8.11.0"
884 |
885 | socket.io-parser@~4.2.4:
886 | version "4.2.4"
887 | resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83"
888 | integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==
889 | dependencies:
890 | "@socket.io/component-emitter" "~3.1.0"
891 | debug "~4.3.1"
892 |
893 | socket.io@^4.7.3:
894 | version "4.7.3"
895 | resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.7.3.tgz#a0f1a4511eb23fe182ae3a018875a31501be3ffc"
896 | integrity sha512-SE+UIQXBQE+GPG2oszWMlsEmWtHVqw/h1VrYJGK5/MC7CH5p58N448HwIrtREcvR4jfdOJAY4ieQfxMr55qbbw==
897 | dependencies:
898 | accepts "~1.3.4"
899 | base64id "~2.0.0"
900 | cors "~2.8.5"
901 | debug "~4.3.2"
902 | engine.io "~6.5.2"
903 | socket.io-adapter "~2.5.2"
904 | socket.io-parser "~4.2.4"
905 |
906 | sparse-bitfield@^3.0.3:
907 | version "3.0.3"
908 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
909 | integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==
910 | dependencies:
911 | memory-pager "^1.0.2"
912 |
913 | statuses@2.0.1:
914 | version "2.0.1"
915 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
916 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
917 |
918 | supports-color@^5.5.0:
919 | version "5.5.0"
920 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
921 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
922 | dependencies:
923 | has-flag "^3.0.0"
924 |
925 | to-regex-range@^5.0.1:
926 | version "5.0.1"
927 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
928 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
929 | dependencies:
930 | is-number "^7.0.0"
931 |
932 | toidentifier@1.0.1:
933 | version "1.0.1"
934 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
935 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
936 |
937 | touch@^3.1.0:
938 | version "3.1.0"
939 | resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
940 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==
941 | dependencies:
942 | nopt "~1.0.10"
943 |
944 | tr46@^3.0.0:
945 | version "3.0.0"
946 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
947 | integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
948 | dependencies:
949 | punycode "^2.1.1"
950 |
951 | type-is@~1.6.18:
952 | version "1.6.18"
953 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
954 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
955 | dependencies:
956 | media-typer "0.3.0"
957 | mime-types "~2.1.24"
958 |
959 | undefsafe@^2.0.5:
960 | version "2.0.5"
961 | resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
962 | integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
963 |
964 | undici-types@~5.26.4:
965 | version "5.26.5"
966 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
967 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
968 |
969 | unpipe@1.0.0, unpipe@~1.0.0:
970 | version "1.0.0"
971 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
972 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
973 |
974 | utils-merge@1.0.1:
975 | version "1.0.1"
976 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
977 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
978 |
979 | vary@^1, vary@~1.1.2:
980 | version "1.1.2"
981 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
982 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
983 |
984 | webidl-conversions@^7.0.0:
985 | version "7.0.0"
986 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
987 | integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
988 |
989 | whatwg-url@^11.0.0:
990 | version "11.0.0"
991 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018"
992 | integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==
993 | dependencies:
994 | tr46 "^3.0.0"
995 | webidl-conversions "^7.0.0"
996 |
997 | ws@~8.11.0:
998 | version "8.11.0"
999 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
1000 | integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
1001 |
1002 | yallist@^4.0.0:
1003 | version "4.0.0"
1004 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
1005 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
1006 |
--------------------------------------------------------------------------------