├── .gitignore ├── networking ├── graphql │ ├── client │ │ └── index.html │ └── server │ │ ├── package-lock.json │ │ ├── package.json │ │ └── server.js ├── grpc │ ├── client.js │ ├── package-lock.json │ ├── package.json │ ├── problems.proto │ └── server.js ├── long-polling │ ├── client │ │ └── index.html │ └── server │ │ ├── package-lock.json │ │ ├── package.json │ │ └── server.js ├── rest │ ├── package-lock.json │ ├── package.json │ └── server.js ├── short-polling │ ├── client │ │ └── index.html │ └── server │ │ ├── package-lock.json │ │ ├── package.json │ │ └── server.js ├── trpc │ ├── client │ │ ├── .gitignore │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── counter.ts │ │ │ ├── main.ts │ │ │ ├── style.css │ │ │ ├── typescript.svg │ │ │ └── vite-env.d.ts │ │ └── tsconfig.json │ └── server │ │ ├── index.ts │ │ ├── package-lock.json │ │ ├── package.json │ │ └── tsconfig.json └── websockets │ ├── client │ └── index.html │ └── server │ ├── package-lock.json │ ├── package.json │ └── server.js └── performance ├── CLS ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.jsx │ ├── assets │ │ └── react.svg │ ├── index.css │ └── main.jsx └── vite.config.js ├── INP ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.jsx │ ├── assets │ │ └── react.svg │ ├── index.css │ └── main.jsx └── vite.config.js ├── LCP └── index.html ├── code-splitting ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.jsx │ ├── assets │ │ └── react.svg │ ├── components │ │ └── NavBar.jsx │ ├── index.css │ ├── main.jsx │ └── pages │ │ ├── About.jsx │ │ ├── Contact.jsx │ │ ├── FAQs.jsx │ │ ├── Login.jsx │ │ ├── Profile.jsx │ │ └── index.js └── vite.config.js ├── compression ├── dist │ ├── index.html │ ├── index.html.gz │ ├── main.js │ ├── main.js.LICENSE.txt │ ├── main.js.LICENSE.txt.gz │ └── main.js.gz ├── package-lock.json ├── package.json ├── src │ ├── index.html │ └── index.js └── webpack.config.js ├── import-on-interaction ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.jsx │ ├── Emoji.jsx │ ├── Message.jsx │ ├── assets │ │ └── react.svg │ ├── index.css │ └── main.jsx └── vite.config.js ├── import-on-visibility ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.jsx │ ├── Emoji.jsx │ ├── Message.jsx │ ├── assets │ │ └── react.svg │ ├── index.css │ └── main.jsx └── vite.config.js ├── prefetch ├── package-lock.json ├── package.json ├── src │ ├── App.js │ ├── Emoji.js │ ├── index.html │ └── index.js └── webpack.config.js ├── preload ├── package-lock.json ├── package.json ├── src │ ├── App.js │ ├── Emoji.js │ ├── index.html │ └── index.js └── webpack.config.js ├── tree-shaking ├── dist │ ├── index.html │ └── main.js ├── package-lock.json ├── package.json ├── src │ ├── index.html │ ├── index.js │ └── math.js └── webpack.config.js └── virtualization ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public └── vite.svg ├── src ├── App.css ├── App.jsx ├── assets │ └── react.svg ├── index.css └── main.jsx └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /networking/graphql/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

GraphQL Example

10 | 11 | 23 | 24 | -------------------------------------------------------------------------------- /networking/graphql/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "apollo-server": "^3.13.0", 14 | "nodemon": "^3.1.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /networking/graphql/server/server.js: -------------------------------------------------------------------------------- 1 | const { gql, ApolloServer } = require("apollo-server"); 2 | 3 | const users = [ 4 | { 5 | id: 0, 6 | name: "JS Cafe", 7 | problems: [0, 1], 8 | }, 9 | { 10 | id: 1, 11 | name: "Roadside Coder", 12 | problems: [1, 2], 13 | }, 14 | ]; 15 | 16 | const problems = [ 17 | { 18 | id: 0, 19 | title: "Two Sum", 20 | solvers: [0], 21 | }, 22 | { 23 | id: 1, 24 | title: "Three Sum", 25 | solvers: [0, 1], 26 | }, 27 | { 28 | id: 2, 29 | title: "Four Sum", 30 | solvers: [1], 31 | }, 32 | ]; 33 | 34 | const typeDefs = gql(` 35 | type User { 36 | id: ID, 37 | name: String, 38 | problems: [Problem] 39 | } 40 | 41 | type Problem { 42 | id: ID, 43 | title: String, 44 | solvers: [User] 45 | } 46 | 47 | type Query { 48 | users: [User], 49 | problems: [Problem] 50 | } 51 | `); 52 | 53 | const resolvers = { 54 | Query: { 55 | users: () => { 56 | return users; 57 | }, 58 | problems: () => { 59 | return problems; 60 | }, 61 | }, 62 | User: { 63 | problems: (user) => { 64 | return problems.filter((problem) => problem.solvers.includes(user.id)); 65 | }, 66 | }, 67 | Problem: { 68 | solvers: (problem) => { 69 | return users.filter((user) => user.problems.includes(problem.id)); 70 | }, 71 | }, 72 | }; 73 | 74 | const server = new ApolloServer({ typeDefs, resolvers }); 75 | server.listen(4000).then(({ url }) => { 76 | console.log(`GraphQL started on ${url}`); 77 | }); 78 | -------------------------------------------------------------------------------- /networking/grpc/client.js: -------------------------------------------------------------------------------- 1 | const grpc = require("@grpc/grpc-js"); 2 | const protoLoader = require("@grpc/proto-loader"); 3 | const PROTO_PATh = "./problems.proto"; 4 | 5 | const express = require("express"); 6 | const app = express(); 7 | app.use(express.json()); 8 | 9 | const options = { 10 | keepCase: true, 11 | longs: String, 12 | enums: String, 13 | defaults: true, 14 | oneofs: true, 15 | }; 16 | const packagegeDefinition = protoLoader.loadSync(PROTO_PATh, options); 17 | const ProblemService = 18 | grpc.loadPackageDefinition(packagegeDefinition).ProblemService; 19 | 20 | const client = new ProblemService( 21 | "localhost:50051", 22 | grpc.credentials.createInsecure() 23 | ); 24 | 25 | app.get("/getAllProblems", (req, res) => { 26 | client.getAllProblems({}, (error, problems) => { 27 | if (error) { 28 | throw error; 29 | } 30 | res.json(problems); 31 | }); 32 | }); 33 | 34 | app.post("/updateProblem/:id", (req, res) => { 35 | const id = req.params.id; 36 | const body = req.body; 37 | client.updateProblem({ id, ...body }, (error, problem) => { 38 | if (error) { 39 | throw error; 40 | } 41 | res.json(problem); 42 | }); 43 | }); 44 | 45 | app.listen("3000", () => { 46 | console.log("client is running"); 47 | }); 48 | -------------------------------------------------------------------------------- /networking/grpc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "client.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@grpc/grpc-js": "^1.11.2", 14 | "@grpc/proto-loader": "^0.7.13", 15 | "express": "^4.21.0", 16 | "nodemon": "^3.1.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /networking/grpc/problems.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Problem { 4 | string id = 1; 5 | string title = 2; 6 | string description = 3; 7 | } 8 | 9 | service ProblemService { 10 | rpc GetAllProblems (Empty) returns (ProblemList) {} 11 | rpc UpdateProblem (Problem) returns (Problem) {} 12 | } 13 | 14 | message Empty {} 15 | 16 | message ProblemList { 17 | repeated Problem problems = 1; 18 | } 19 | -------------------------------------------------------------------------------- /networking/grpc/server.js: -------------------------------------------------------------------------------- 1 | const grpc = require("@grpc/grpc-js"); 2 | const protoLoader = require("@grpc/proto-loader"); 3 | const PROTO_PATh = "./problems.proto"; 4 | 5 | const options = { 6 | keepCase: true, 7 | longs: String, 8 | enums: String, 9 | defaults: true, 10 | oneofs: true, 11 | }; 12 | 13 | const packagegeDefinition = protoLoader.loadSync(PROTO_PATh, options); 14 | const problemsProto = grpc.loadPackageDefinition(packagegeDefinition); 15 | 16 | const server = new grpc.Server(); 17 | let problems = [ 18 | { 19 | id: "0", 20 | title: "Polyfill of Array.map", 21 | description: "Some description", 22 | }, 23 | { 24 | id: "1", 25 | title: "Polyfill of Promise.all()", 26 | description: "Some description", 27 | }, 28 | ]; 29 | 30 | server.addService(problemsProto.ProblemService.service, { 31 | getAllProblems: (_, callback) => { 32 | callback(null, { problems: problems }); 33 | }, 34 | updateProblem: (call, callback) => { 35 | const id = call.request.id; 36 | console.log(call.request); 37 | problems = problems.map((p) => { 38 | if (id === p.id) { 39 | return { ...p, ...call.request }; 40 | } 41 | return p; 42 | }); 43 | const updatedProblem = problems.find((p) => p.id === id); 44 | callback(null, { ...updatedProblem }); 45 | }, 46 | }); 47 | 48 | server.bindAsync( 49 | "127.0.0.1:50051", 50 | grpc.ServerCredentials.createInsecure(), 51 | (error, port) => { 52 | console.log("grpc is up and running"); 53 | server.start(); 54 | } 55 | ); 56 | -------------------------------------------------------------------------------- /networking/long-polling/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

Long Polling

10 | 11 | 25 | 26 | -------------------------------------------------------------------------------- /networking/long-polling/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "type": "module", 13 | "dependencies": { 14 | "cors": "^2.8.5", 15 | "events": "^3.3.0", 16 | "express": "^4.21.0", 17 | "nodemon": "^3.1.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /networking/long-polling/server/server.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import cors from "cors"; 3 | import events from "events"; 4 | 5 | const app = express(); 6 | app.use(express.json()); 7 | app.use(cors()); 8 | const PORT = 3000; 9 | 10 | const messageEventEmitter = new events.EventEmitter(); 11 | 12 | app.get("/messages", (req, res) => { 13 | messageEventEmitter.once("newMessage", (from, message) => { 14 | res.json({ from, message }); 15 | }); 16 | }); 17 | 18 | app.post("/new-message", (req, res) => { 19 | const { from, message } = req.body; 20 | messageEventEmitter.emit("newMessage", from, message); 21 | res.json({ message: "success" }); 22 | }); 23 | 24 | app.listen(PORT, () => { 25 | console.log("long polling server started"); 26 | }); 27 | -------------------------------------------------------------------------------- /networking/rest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "type": "module", 12 | "license": "ISC", 13 | "dependencies": { 14 | "express": "^4.20.0", 15 | "nodemon": "^3.1.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /networking/rest/server.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | const app = express(); 4 | app.use(express.json()); 5 | const PORT = 3000; 6 | 7 | let problems = [ 8 | { 9 | id: 0, 10 | title: "Polyfill of Array.map", 11 | description: "Some description", 12 | }, 13 | { 14 | id: 1, 15 | title: "Polyfill of Promise.all()", 16 | description: "Some description", 17 | }, 18 | ]; 19 | 20 | app.get("/api/problems", (req, res) => { 21 | res.json(problems); 22 | }); 23 | 24 | app.post("/api/problems", (req, res) => { 25 | const body = req.body; 26 | problems = [...problems, body]; 27 | res.json(problems); 28 | }); 29 | 30 | app.put("/api/problems/:id", (req, res) => { 31 | const body = req.body; 32 | const id = req.params.id; 33 | problems = problems.map((p) => { 34 | if (p.id == id) { 35 | return { 36 | id, 37 | ...body, 38 | }; 39 | } 40 | return p; 41 | }); 42 | res.json(problems); 43 | }); 44 | 45 | app.delete("/api/problems/:id", (req, res) => { 46 | const id = req.params.id; 47 | problems = problems.filter((p) => p.id != id); 48 | res.json(problems); 49 | }); 50 | 51 | app.patch("/api/problems/:id", (req, res) => { 52 | const body = req.body; 53 | const id = req.params.id; 54 | const problem = problems.find((p) => p.id == id); 55 | problems = problems.map((p) => { 56 | if (p.id == id) { 57 | return { 58 | ...problem, 59 | ...body, 60 | }; 61 | } 62 | return p; 63 | }); 64 | res.json(problems); 65 | }); 66 | 67 | app.listen(PORT, () => { 68 | console.log(`server up and running on ${PORT}`); 69 | }); 70 | -------------------------------------------------------------------------------- /networking/short-polling/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

Short Polling

10 | 11 | 24 | 25 | -------------------------------------------------------------------------------- /networking/short-polling/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "type": "module", 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "cors": "^2.8.5", 15 | "express": "^4.21.0", 16 | "nodemon": "^3.1.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /networking/short-polling/server/server.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import cors from "cors"; 3 | const app = express(); 4 | app.use(express.json()); 5 | app.use(cors()); 6 | const PORT = 3000; 7 | 8 | let problems = [ 9 | { 10 | id: 0, 11 | title: "Polyfill of Array.map", 12 | description: "Some description", 13 | }, 14 | { 15 | id: 1, 16 | title: "Polyfill of Promise.all()", 17 | description: "Some description", 18 | }, 19 | ]; 20 | 21 | app.get("/api/problems", (req, res) => { 22 | res.json(problems); 23 | }); 24 | 25 | app.post("/api/problems", (req, res) => { 26 | const body = req.body; 27 | problems = [...problems, body]; 28 | res.json(problems); 29 | }); 30 | 31 | app.patch("/api/problems/:id", (req, res) => { 32 | const body = req.body; 33 | const id = req.params.id; 34 | const problem = problems.find((p) => p.id == id); 35 | problems = problems.map((p) => { 36 | if (p.id == id) { 37 | return { 38 | ...problem, 39 | ...body, 40 | }; 41 | } 42 | return p; 43 | }); 44 | res.json(problems); 45 | }); 46 | 47 | app.listen(PORT, () => { 48 | console.log(`server up and running on ${PORT}`); 49 | }); 50 | -------------------------------------------------------------------------------- /networking/trpc/client/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /networking/trpc/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /networking/trpc/client/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "client", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "@trpc/client": "^11.0.0-rc.522", 12 | "@trpc/server": "^11.0.0-rc.522" 13 | }, 14 | "devDependencies": { 15 | "typescript": "^5.5.3", 16 | "vite": "^5.4.1" 17 | } 18 | }, 19 | "node_modules/@esbuild/aix-ppc64": { 20 | "version": "0.21.5", 21 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 22 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 23 | "cpu": [ 24 | "ppc64" 25 | ], 26 | "dev": true, 27 | "optional": true, 28 | "os": [ 29 | "aix" 30 | ], 31 | "engines": { 32 | "node": ">=12" 33 | } 34 | }, 35 | "node_modules/@esbuild/android-arm": { 36 | "version": "0.21.5", 37 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 38 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 39 | "cpu": [ 40 | "arm" 41 | ], 42 | "dev": true, 43 | "optional": true, 44 | "os": [ 45 | "android" 46 | ], 47 | "engines": { 48 | "node": ">=12" 49 | } 50 | }, 51 | "node_modules/@esbuild/android-arm64": { 52 | "version": "0.21.5", 53 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 54 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 55 | "cpu": [ 56 | "arm64" 57 | ], 58 | "dev": true, 59 | "optional": true, 60 | "os": [ 61 | "android" 62 | ], 63 | "engines": { 64 | "node": ">=12" 65 | } 66 | }, 67 | "node_modules/@esbuild/android-x64": { 68 | "version": "0.21.5", 69 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 70 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 71 | "cpu": [ 72 | "x64" 73 | ], 74 | "dev": true, 75 | "optional": true, 76 | "os": [ 77 | "android" 78 | ], 79 | "engines": { 80 | "node": ">=12" 81 | } 82 | }, 83 | "node_modules/@esbuild/darwin-arm64": { 84 | "version": "0.21.5", 85 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 86 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 87 | "cpu": [ 88 | "arm64" 89 | ], 90 | "dev": true, 91 | "optional": true, 92 | "os": [ 93 | "darwin" 94 | ], 95 | "engines": { 96 | "node": ">=12" 97 | } 98 | }, 99 | "node_modules/@esbuild/darwin-x64": { 100 | "version": "0.21.5", 101 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 102 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 103 | "cpu": [ 104 | "x64" 105 | ], 106 | "dev": true, 107 | "optional": true, 108 | "os": [ 109 | "darwin" 110 | ], 111 | "engines": { 112 | "node": ">=12" 113 | } 114 | }, 115 | "node_modules/@esbuild/freebsd-arm64": { 116 | "version": "0.21.5", 117 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 118 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 119 | "cpu": [ 120 | "arm64" 121 | ], 122 | "dev": true, 123 | "optional": true, 124 | "os": [ 125 | "freebsd" 126 | ], 127 | "engines": { 128 | "node": ">=12" 129 | } 130 | }, 131 | "node_modules/@esbuild/freebsd-x64": { 132 | "version": "0.21.5", 133 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 134 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 135 | "cpu": [ 136 | "x64" 137 | ], 138 | "dev": true, 139 | "optional": true, 140 | "os": [ 141 | "freebsd" 142 | ], 143 | "engines": { 144 | "node": ">=12" 145 | } 146 | }, 147 | "node_modules/@esbuild/linux-arm": { 148 | "version": "0.21.5", 149 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 150 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 151 | "cpu": [ 152 | "arm" 153 | ], 154 | "dev": true, 155 | "optional": true, 156 | "os": [ 157 | "linux" 158 | ], 159 | "engines": { 160 | "node": ">=12" 161 | } 162 | }, 163 | "node_modules/@esbuild/linux-arm64": { 164 | "version": "0.21.5", 165 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 166 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 167 | "cpu": [ 168 | "arm64" 169 | ], 170 | "dev": true, 171 | "optional": true, 172 | "os": [ 173 | "linux" 174 | ], 175 | "engines": { 176 | "node": ">=12" 177 | } 178 | }, 179 | "node_modules/@esbuild/linux-ia32": { 180 | "version": "0.21.5", 181 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 182 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 183 | "cpu": [ 184 | "ia32" 185 | ], 186 | "dev": true, 187 | "optional": true, 188 | "os": [ 189 | "linux" 190 | ], 191 | "engines": { 192 | "node": ">=12" 193 | } 194 | }, 195 | "node_modules/@esbuild/linux-loong64": { 196 | "version": "0.21.5", 197 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 198 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 199 | "cpu": [ 200 | "loong64" 201 | ], 202 | "dev": true, 203 | "optional": true, 204 | "os": [ 205 | "linux" 206 | ], 207 | "engines": { 208 | "node": ">=12" 209 | } 210 | }, 211 | "node_modules/@esbuild/linux-mips64el": { 212 | "version": "0.21.5", 213 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 214 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 215 | "cpu": [ 216 | "mips64el" 217 | ], 218 | "dev": true, 219 | "optional": true, 220 | "os": [ 221 | "linux" 222 | ], 223 | "engines": { 224 | "node": ">=12" 225 | } 226 | }, 227 | "node_modules/@esbuild/linux-ppc64": { 228 | "version": "0.21.5", 229 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 230 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 231 | "cpu": [ 232 | "ppc64" 233 | ], 234 | "dev": true, 235 | "optional": true, 236 | "os": [ 237 | "linux" 238 | ], 239 | "engines": { 240 | "node": ">=12" 241 | } 242 | }, 243 | "node_modules/@esbuild/linux-riscv64": { 244 | "version": "0.21.5", 245 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 246 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 247 | "cpu": [ 248 | "riscv64" 249 | ], 250 | "dev": true, 251 | "optional": true, 252 | "os": [ 253 | "linux" 254 | ], 255 | "engines": { 256 | "node": ">=12" 257 | } 258 | }, 259 | "node_modules/@esbuild/linux-s390x": { 260 | "version": "0.21.5", 261 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 262 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 263 | "cpu": [ 264 | "s390x" 265 | ], 266 | "dev": true, 267 | "optional": true, 268 | "os": [ 269 | "linux" 270 | ], 271 | "engines": { 272 | "node": ">=12" 273 | } 274 | }, 275 | "node_modules/@esbuild/linux-x64": { 276 | "version": "0.21.5", 277 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 278 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 279 | "cpu": [ 280 | "x64" 281 | ], 282 | "dev": true, 283 | "optional": true, 284 | "os": [ 285 | "linux" 286 | ], 287 | "engines": { 288 | "node": ">=12" 289 | } 290 | }, 291 | "node_modules/@esbuild/netbsd-x64": { 292 | "version": "0.21.5", 293 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 294 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 295 | "cpu": [ 296 | "x64" 297 | ], 298 | "dev": true, 299 | "optional": true, 300 | "os": [ 301 | "netbsd" 302 | ], 303 | "engines": { 304 | "node": ">=12" 305 | } 306 | }, 307 | "node_modules/@esbuild/openbsd-x64": { 308 | "version": "0.21.5", 309 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 310 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 311 | "cpu": [ 312 | "x64" 313 | ], 314 | "dev": true, 315 | "optional": true, 316 | "os": [ 317 | "openbsd" 318 | ], 319 | "engines": { 320 | "node": ">=12" 321 | } 322 | }, 323 | "node_modules/@esbuild/sunos-x64": { 324 | "version": "0.21.5", 325 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 326 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 327 | "cpu": [ 328 | "x64" 329 | ], 330 | "dev": true, 331 | "optional": true, 332 | "os": [ 333 | "sunos" 334 | ], 335 | "engines": { 336 | "node": ">=12" 337 | } 338 | }, 339 | "node_modules/@esbuild/win32-arm64": { 340 | "version": "0.21.5", 341 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 342 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 343 | "cpu": [ 344 | "arm64" 345 | ], 346 | "dev": true, 347 | "optional": true, 348 | "os": [ 349 | "win32" 350 | ], 351 | "engines": { 352 | "node": ">=12" 353 | } 354 | }, 355 | "node_modules/@esbuild/win32-ia32": { 356 | "version": "0.21.5", 357 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 358 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 359 | "cpu": [ 360 | "ia32" 361 | ], 362 | "dev": true, 363 | "optional": true, 364 | "os": [ 365 | "win32" 366 | ], 367 | "engines": { 368 | "node": ">=12" 369 | } 370 | }, 371 | "node_modules/@esbuild/win32-x64": { 372 | "version": "0.21.5", 373 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 374 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 375 | "cpu": [ 376 | "x64" 377 | ], 378 | "dev": true, 379 | "optional": true, 380 | "os": [ 381 | "win32" 382 | ], 383 | "engines": { 384 | "node": ">=12" 385 | } 386 | }, 387 | "node_modules/@rollup/rollup-android-arm-eabi": { 388 | "version": "4.22.3", 389 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.3.tgz", 390 | "integrity": "sha512-Po+UujLih7BSLvAWcPWTKgtmaFdzkzgPXoJ2w4vNPbIgUJEjhzdNgei/2X6RyWExXuhr1c68kHPySdXH8F+EWA==", 391 | "cpu": [ 392 | "arm" 393 | ], 394 | "dev": true, 395 | "optional": true, 396 | "os": [ 397 | "android" 398 | ] 399 | }, 400 | "node_modules/@rollup/rollup-android-arm64": { 401 | "version": "4.22.3", 402 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.3.tgz", 403 | "integrity": "sha512-52cRgrMaz2JxX0a/wfnnrkToHGzMWrI18X5n+e73Hz/BFPEV4QhglW5z8cOs6kyYHB9tQPo7kjMjFhxwj72SXg==", 404 | "cpu": [ 405 | "arm64" 406 | ], 407 | "dev": true, 408 | "optional": true, 409 | "os": [ 410 | "android" 411 | ] 412 | }, 413 | "node_modules/@rollup/rollup-darwin-arm64": { 414 | "version": "4.22.3", 415 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.3.tgz", 416 | "integrity": "sha512-3o4PxCB4dQyFXanB/rfaLk37mX/ZKo8tIwULy37H8NLmcQOoH8reWSG2qVuyEKjLqAo14hVPTsRIXxjqciuMgQ==", 417 | "cpu": [ 418 | "arm64" 419 | ], 420 | "dev": true, 421 | "optional": true, 422 | "os": [ 423 | "darwin" 424 | ] 425 | }, 426 | "node_modules/@rollup/rollup-darwin-x64": { 427 | "version": "4.22.3", 428 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.3.tgz", 429 | "integrity": "sha512-6MvaCC++JZcKWZ/BdgugJSnt03DMFwoKhAb4QADDkV+iQR/utqPrEgisAdleTb21MrgBi5XcgMPiUtrhNlNSTw==", 430 | "cpu": [ 431 | "x64" 432 | ], 433 | "dev": true, 434 | "optional": true, 435 | "os": [ 436 | "darwin" 437 | ] 438 | }, 439 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 440 | "version": "4.22.3", 441 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.3.tgz", 442 | "integrity": "sha512-tY4B/12eysJZ9gdOAKQbTsWC+3YVpopcxNvXxXUg6+OMSlVh0raMwlWqQNIxfGPqanuiR5JOes3dAVckt/NMow==", 443 | "cpu": [ 444 | "arm" 445 | ], 446 | "dev": true, 447 | "optional": true, 448 | "os": [ 449 | "linux" 450 | ] 451 | }, 452 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 453 | "version": "4.22.3", 454 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.3.tgz", 455 | "integrity": "sha512-nxBawr7RUK3SelngWI0y136bSCVLt2HkPuNiNEek25PDgmh/mdTJRVgxMmr76mmJesewImOGQBWhw3kpZ5Jv7Q==", 456 | "cpu": [ 457 | "arm" 458 | ], 459 | "dev": true, 460 | "optional": true, 461 | "os": [ 462 | "linux" 463 | ] 464 | }, 465 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 466 | "version": "4.22.3", 467 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.3.tgz", 468 | "integrity": "sha512-kVrJmt7kSQBptiuKccz+QVHTkRz7UhQuKhmXtCFbG8RukSfvbrFDfanYe5jaCUc0hDUE4T40sVPsyrwbnhlf+Q==", 469 | "cpu": [ 470 | "arm64" 471 | ], 472 | "dev": true, 473 | "optional": true, 474 | "os": [ 475 | "linux" 476 | ] 477 | }, 478 | "node_modules/@rollup/rollup-linux-arm64-musl": { 479 | "version": "4.22.3", 480 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.3.tgz", 481 | "integrity": "sha512-yx7Xei61efYQ1JZMZ0WOA3vRwEHFU0LlzaEER2cVejr5EplBmOykBeHSeWnngeVNRASgiHS36tA8jlo6AJ9Shg==", 482 | "cpu": [ 483 | "arm64" 484 | ], 485 | "dev": true, 486 | "optional": true, 487 | "os": [ 488 | "linux" 489 | ] 490 | }, 491 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 492 | "version": "4.22.3", 493 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.3.tgz", 494 | "integrity": "sha512-QJTk7pEUN1T1OGIkHbfeQd/+wthw+kmXrmNZUrDvDznKxgpgS+Uqbi+egux6UdEXuuaxhavm5L+aotbTuWqqaQ==", 495 | "cpu": [ 496 | "ppc64" 497 | ], 498 | "dev": true, 499 | "optional": true, 500 | "os": [ 501 | "linux" 502 | ] 503 | }, 504 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 505 | "version": "4.22.3", 506 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.3.tgz", 507 | "integrity": "sha512-aXFDDzVq2HTT7GsV5s8rpsH1Mk6WlZOxxsd2H/4LP4gJ8Fu9+C+O5k2ccmXjSh7IPc8R0u1YdeGETARcJvgoPg==", 508 | "cpu": [ 509 | "riscv64" 510 | ], 511 | "dev": true, 512 | "optional": true, 513 | "os": [ 514 | "linux" 515 | ] 516 | }, 517 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 518 | "version": "4.22.3", 519 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.3.tgz", 520 | "integrity": "sha512-pesLBj+872ZyL43ALKua0syvFLYY/Z5cVsB5xdBGkYaRYjxwIDze1QN9Cxi8tlAhJGblz41D4507DEraITDvkw==", 521 | "cpu": [ 522 | "s390x" 523 | ], 524 | "dev": true, 525 | "optional": true, 526 | "os": [ 527 | "linux" 528 | ] 529 | }, 530 | "node_modules/@rollup/rollup-linux-x64-gnu": { 531 | "version": "4.22.3", 532 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.3.tgz", 533 | "integrity": "sha512-QWAgO5V7E6n3w4a1H7qrqA7k4IDqGYjT/P/wTV1b5o3wifLB1sYmuXw1urw4HWP3KmZxIKb5uEwZPW6Ec4l9DA==", 534 | "cpu": [ 535 | "x64" 536 | ], 537 | "dev": true, 538 | "optional": true, 539 | "os": [ 540 | "linux" 541 | ] 542 | }, 543 | "node_modules/@rollup/rollup-linux-x64-musl": { 544 | "version": "4.22.3", 545 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.3.tgz", 546 | "integrity": "sha512-fUL9CVfu2DLycemee7QoYHpABaLUJh5QM3naBUGlZoysaSFVvAbFju0wBHcY73IGdUb2MI2Yh8sSjIPAiUs+Kg==", 547 | "cpu": [ 548 | "x64" 549 | ], 550 | "dev": true, 551 | "optional": true, 552 | "os": [ 553 | "linux" 554 | ] 555 | }, 556 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 557 | "version": "4.22.3", 558 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.3.tgz", 559 | "integrity": "sha512-IWxGO/k2gysJPXDmUAqmpcayaX6P+RB10JXJrV4QjcN7ipKWFcHYfTDG1EGyXLEZhHMQe3Ed0OjvPe4JYZvINA==", 560 | "cpu": [ 561 | "arm64" 562 | ], 563 | "dev": true, 564 | "optional": true, 565 | "os": [ 566 | "win32" 567 | ] 568 | }, 569 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 570 | "version": "4.22.3", 571 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.3.tgz", 572 | "integrity": "sha512-liDr0/niP4/7bhiZwrjl2nAARj7gwden3G2DdOJImMbYrjp2C2cYKxEPViOIs4ci6ugcan6TcakxfqJfcb9SJQ==", 573 | "cpu": [ 574 | "ia32" 575 | ], 576 | "dev": true, 577 | "optional": true, 578 | "os": [ 579 | "win32" 580 | ] 581 | }, 582 | "node_modules/@rollup/rollup-win32-x64-msvc": { 583 | "version": "4.22.3", 584 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.3.tgz", 585 | "integrity": "sha512-4fEwOjO95h0RuNrAYKXIAd1ZWTKUNN+PZwVBHGGdekfeHldP7l2V/iqKPGinMKv5g+KJjcJe9BD6ooBpS/EUJQ==", 586 | "cpu": [ 587 | "x64" 588 | ], 589 | "dev": true, 590 | "optional": true, 591 | "os": [ 592 | "win32" 593 | ] 594 | }, 595 | "node_modules/@trpc/client": { 596 | "version": "11.0.0-rc.522", 597 | "resolved": "https://registry.npmjs.org/@trpc/client/-/client-11.0.0-rc.522.tgz", 598 | "integrity": "sha512-MvlsLF5nVRSPRRLyqu0CUJr+yk6CNY8f1YoPHy25CDX0a/dtGohXd8UAj5pBfQTRcoRB91rGpKpxTg6qw23fVg==", 599 | "funding": [ 600 | "https://trpc.io/sponsor" 601 | ], 602 | "peerDependencies": { 603 | "@trpc/server": "11.0.0-rc.522+b99c8b036" 604 | } 605 | }, 606 | "node_modules/@trpc/server": { 607 | "version": "11.0.0-rc.522", 608 | "resolved": "https://registry.npmjs.org/@trpc/server/-/server-11.0.0-rc.522.tgz", 609 | "integrity": "sha512-a0Cei94zJM/cYFBdsPEd1QPHhSsJljz7d2NI4n2jDow9xclZfEEp71hhth+i8vrddPjadexn++tzXcdEkeMbgg==", 610 | "funding": [ 611 | "https://trpc.io/sponsor" 612 | ] 613 | }, 614 | "node_modules/@types/estree": { 615 | "version": "1.0.5", 616 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 617 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 618 | "dev": true 619 | }, 620 | "node_modules/esbuild": { 621 | "version": "0.21.5", 622 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 623 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 624 | "dev": true, 625 | "hasInstallScript": true, 626 | "bin": { 627 | "esbuild": "bin/esbuild" 628 | }, 629 | "engines": { 630 | "node": ">=12" 631 | }, 632 | "optionalDependencies": { 633 | "@esbuild/aix-ppc64": "0.21.5", 634 | "@esbuild/android-arm": "0.21.5", 635 | "@esbuild/android-arm64": "0.21.5", 636 | "@esbuild/android-x64": "0.21.5", 637 | "@esbuild/darwin-arm64": "0.21.5", 638 | "@esbuild/darwin-x64": "0.21.5", 639 | "@esbuild/freebsd-arm64": "0.21.5", 640 | "@esbuild/freebsd-x64": "0.21.5", 641 | "@esbuild/linux-arm": "0.21.5", 642 | "@esbuild/linux-arm64": "0.21.5", 643 | "@esbuild/linux-ia32": "0.21.5", 644 | "@esbuild/linux-loong64": "0.21.5", 645 | "@esbuild/linux-mips64el": "0.21.5", 646 | "@esbuild/linux-ppc64": "0.21.5", 647 | "@esbuild/linux-riscv64": "0.21.5", 648 | "@esbuild/linux-s390x": "0.21.5", 649 | "@esbuild/linux-x64": "0.21.5", 650 | "@esbuild/netbsd-x64": "0.21.5", 651 | "@esbuild/openbsd-x64": "0.21.5", 652 | "@esbuild/sunos-x64": "0.21.5", 653 | "@esbuild/win32-arm64": "0.21.5", 654 | "@esbuild/win32-ia32": "0.21.5", 655 | "@esbuild/win32-x64": "0.21.5" 656 | } 657 | }, 658 | "node_modules/fsevents": { 659 | "version": "2.3.3", 660 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 661 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 662 | "dev": true, 663 | "hasInstallScript": true, 664 | "optional": true, 665 | "os": [ 666 | "darwin" 667 | ], 668 | "engines": { 669 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 670 | } 671 | }, 672 | "node_modules/nanoid": { 673 | "version": "3.3.7", 674 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 675 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 676 | "dev": true, 677 | "funding": [ 678 | { 679 | "type": "github", 680 | "url": "https://github.com/sponsors/ai" 681 | } 682 | ], 683 | "bin": { 684 | "nanoid": "bin/nanoid.cjs" 685 | }, 686 | "engines": { 687 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 688 | } 689 | }, 690 | "node_modules/picocolors": { 691 | "version": "1.1.0", 692 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", 693 | "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", 694 | "dev": true 695 | }, 696 | "node_modules/postcss": { 697 | "version": "8.4.47", 698 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", 699 | "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", 700 | "dev": true, 701 | "funding": [ 702 | { 703 | "type": "opencollective", 704 | "url": "https://opencollective.com/postcss/" 705 | }, 706 | { 707 | "type": "tidelift", 708 | "url": "https://tidelift.com/funding/github/npm/postcss" 709 | }, 710 | { 711 | "type": "github", 712 | "url": "https://github.com/sponsors/ai" 713 | } 714 | ], 715 | "dependencies": { 716 | "nanoid": "^3.3.7", 717 | "picocolors": "^1.1.0", 718 | "source-map-js": "^1.2.1" 719 | }, 720 | "engines": { 721 | "node": "^10 || ^12 || >=14" 722 | } 723 | }, 724 | "node_modules/rollup": { 725 | "version": "4.22.3", 726 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.3.tgz", 727 | "integrity": "sha512-RCKDv63O5cc4G/erEqWsi9U0DHbVlQ+5ww5BawleRHcSB4Ozqwf7eBE8lIywUtZtBebGxed3XydVDaQoBnsk5Q==", 728 | "dev": true, 729 | "dependencies": { 730 | "@types/estree": "1.0.5" 731 | }, 732 | "bin": { 733 | "rollup": "dist/bin/rollup" 734 | }, 735 | "engines": { 736 | "node": ">=18.0.0", 737 | "npm": ">=8.0.0" 738 | }, 739 | "optionalDependencies": { 740 | "@rollup/rollup-android-arm-eabi": "4.22.3", 741 | "@rollup/rollup-android-arm64": "4.22.3", 742 | "@rollup/rollup-darwin-arm64": "4.22.3", 743 | "@rollup/rollup-darwin-x64": "4.22.3", 744 | "@rollup/rollup-linux-arm-gnueabihf": "4.22.3", 745 | "@rollup/rollup-linux-arm-musleabihf": "4.22.3", 746 | "@rollup/rollup-linux-arm64-gnu": "4.22.3", 747 | "@rollup/rollup-linux-arm64-musl": "4.22.3", 748 | "@rollup/rollup-linux-powerpc64le-gnu": "4.22.3", 749 | "@rollup/rollup-linux-riscv64-gnu": "4.22.3", 750 | "@rollup/rollup-linux-s390x-gnu": "4.22.3", 751 | "@rollup/rollup-linux-x64-gnu": "4.22.3", 752 | "@rollup/rollup-linux-x64-musl": "4.22.3", 753 | "@rollup/rollup-win32-arm64-msvc": "4.22.3", 754 | "@rollup/rollup-win32-ia32-msvc": "4.22.3", 755 | "@rollup/rollup-win32-x64-msvc": "4.22.3", 756 | "fsevents": "~2.3.2" 757 | } 758 | }, 759 | "node_modules/source-map-js": { 760 | "version": "1.2.1", 761 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 762 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 763 | "dev": true, 764 | "engines": { 765 | "node": ">=0.10.0" 766 | } 767 | }, 768 | "node_modules/typescript": { 769 | "version": "5.6.2", 770 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", 771 | "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", 772 | "dev": true, 773 | "bin": { 774 | "tsc": "bin/tsc", 775 | "tsserver": "bin/tsserver" 776 | }, 777 | "engines": { 778 | "node": ">=14.17" 779 | } 780 | }, 781 | "node_modules/vite": { 782 | "version": "5.4.7", 783 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", 784 | "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==", 785 | "dev": true, 786 | "dependencies": { 787 | "esbuild": "^0.21.3", 788 | "postcss": "^8.4.43", 789 | "rollup": "^4.20.0" 790 | }, 791 | "bin": { 792 | "vite": "bin/vite.js" 793 | }, 794 | "engines": { 795 | "node": "^18.0.0 || >=20.0.0" 796 | }, 797 | "funding": { 798 | "url": "https://github.com/vitejs/vite?sponsor=1" 799 | }, 800 | "optionalDependencies": { 801 | "fsevents": "~2.3.3" 802 | }, 803 | "peerDependencies": { 804 | "@types/node": "^18.0.0 || >=20.0.0", 805 | "less": "*", 806 | "lightningcss": "^1.21.0", 807 | "sass": "*", 808 | "sass-embedded": "*", 809 | "stylus": "*", 810 | "sugarss": "*", 811 | "terser": "^5.4.0" 812 | }, 813 | "peerDependenciesMeta": { 814 | "@types/node": { 815 | "optional": true 816 | }, 817 | "less": { 818 | "optional": true 819 | }, 820 | "lightningcss": { 821 | "optional": true 822 | }, 823 | "sass": { 824 | "optional": true 825 | }, 826 | "sass-embedded": { 827 | "optional": true 828 | }, 829 | "stylus": { 830 | "optional": true 831 | }, 832 | "sugarss": { 833 | "optional": true 834 | }, 835 | "terser": { 836 | "optional": true 837 | } 838 | } 839 | } 840 | } 841 | } 842 | -------------------------------------------------------------------------------- /networking/trpc/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^5.5.3", 13 | "vite": "^5.4.1" 14 | }, 15 | "dependencies": { 16 | "@trpc/client": "^11.0.0-rc.522", 17 | "@trpc/server": "^11.0.0-rc.522" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /networking/trpc/client/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /networking/trpc/client/src/counter.ts: -------------------------------------------------------------------------------- 1 | export function setupCounter(element: HTMLButtonElement) { 2 | let counter = 0 3 | const setCounter = (count: number) => { 4 | counter = count 5 | element.innerHTML = `count is ${counter}` 6 | } 7 | element.addEventListener('click', () => setCounter(counter + 1)) 8 | setCounter(0) 9 | } 10 | -------------------------------------------------------------------------------- /networking/trpc/client/src/main.ts: -------------------------------------------------------------------------------- 1 | import type { AppRouter } from "../../server/index"; 2 | import { createTRPCClient, httpBatchLink } from "@trpc/client"; 3 | 4 | const client = createTRPCClient({ 5 | links: [ 6 | httpBatchLink({ 7 | url: "http://localhost:3000/trpc", 8 | }), 9 | ], 10 | }); 11 | 12 | async function main() { 13 | client.greeting.query(); 14 | client.getAllProblems.query(); 15 | client.updateProblems.mutate({ id: 0, title: "new problem" }); 16 | } 17 | 18 | main(); 19 | -------------------------------------------------------------------------------- /networking/trpc/client/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: #646cff; 19 | text-decoration: inherit; 20 | } 21 | a:hover { 22 | color: #535bf2; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | display: flex; 28 | place-items: center; 29 | min-width: 320px; 30 | min-height: 100vh; 31 | } 32 | 33 | h1 { 34 | font-size: 3.2em; 35 | line-height: 1.1; 36 | } 37 | 38 | #app { 39 | max-width: 1280px; 40 | margin: 0 auto; 41 | padding: 2rem; 42 | text-align: center; 43 | } 44 | 45 | .logo { 46 | height: 6em; 47 | padding: 1.5em; 48 | will-change: filter; 49 | transition: filter 300ms; 50 | } 51 | .logo:hover { 52 | filter: drop-shadow(0 0 2em #646cffaa); 53 | } 54 | .logo.vanilla:hover { 55 | filter: drop-shadow(0 0 2em #3178c6aa); 56 | } 57 | 58 | .card { 59 | padding: 2em; 60 | } 61 | 62 | .read-the-docs { 63 | color: #888; 64 | } 65 | 66 | button { 67 | border-radius: 8px; 68 | border: 1px solid transparent; 69 | padding: 0.6em 1.2em; 70 | font-size: 1em; 71 | font-weight: 500; 72 | font-family: inherit; 73 | background-color: #1a1a1a; 74 | cursor: pointer; 75 | transition: border-color 0.25s; 76 | } 77 | button:hover { 78 | border-color: #646cff; 79 | } 80 | button:focus, 81 | button:focus-visible { 82 | outline: 4px auto -webkit-focus-ring-color; 83 | } 84 | 85 | @media (prefers-color-scheme: light) { 86 | :root { 87 | color: #213547; 88 | background-color: #ffffff; 89 | } 90 | a:hover { 91 | color: #747bff; 92 | } 93 | button { 94 | background-color: #f9f9f9; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /networking/trpc/client/src/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /networking/trpc/client/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /networking/trpc/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /networking/trpc/server/index.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { initTRPC } from "@trpc/server"; 3 | import { createExpressMiddleware } from "@trpc/server/adapters/express"; 4 | import cors from "cors"; 5 | 6 | const app = express(); 7 | const port = process.env.PORT || 3000; 8 | const t = initTRPC.create(); 9 | 10 | export const router = t.router; 11 | export const publicProcedure = t.procedure; 12 | 13 | let problems = [ 14 | { 15 | id: 0, 16 | title: "Polyfill of Array.map", 17 | description: "Some description", 18 | }, 19 | { 20 | id: 1, 21 | title: "Polyfill of Promise.all()", 22 | description: "Some description", 23 | }, 24 | ]; 25 | 26 | type Problem = { 27 | id: number; 28 | title: string; 29 | description: string; 30 | }; 31 | 32 | const appRouter = router({ 33 | greeting: publicProcedure.query(() => "hello tRPC v10!"), 34 | getAllProblems: publicProcedure.query(() => problems), 35 | updateProblems: publicProcedure 36 | .input((v) => { 37 | if (typeof v !== "object") 38 | throw new Error(`Object expected received ${typeof v}`); 39 | return v; 40 | }) 41 | .mutation(async (opts) => { 42 | const data = opts.input as unknown as Problem; 43 | problems = problems.map((p) => { 44 | if (p.id == data.id) { 45 | return { ...p, ...data }; 46 | } 47 | return p; 48 | }); 49 | }), 50 | }); 51 | app.use(cors()); 52 | app.use( 53 | "/trpc", 54 | createExpressMiddleware({ 55 | router: appRouter, 56 | }) 57 | ); 58 | 59 | app.listen(port, () => { 60 | console.log(`Server running at http://localhost:${port}`); 61 | }); 62 | 63 | export type AppRouter = typeof appRouter; 64 | -------------------------------------------------------------------------------- /networking/trpc/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node index.ts", 8 | "build": "tsc", 9 | "serve": "node dist/index.js", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@types/express": "^4.17.21", 16 | "@types/node": "^22.5.5", 17 | "express": "^4.21.0", 18 | "ts-node": "^10.9.2", 19 | "typescript": "^5.6.2" 20 | }, 21 | "dependencies": { 22 | "@trpc/server": "^10.45.2", 23 | "@types/cors": "^2.8.17", 24 | "cors": "^2.8.5" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /networking/trpc/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "outDir": "./dist", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true 10 | }, 11 | "include": ["src/**/*.ts"], 12 | "exclude": ["node_modules"] 13 | } 14 | -------------------------------------------------------------------------------- /networking/websockets/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

WebSocket

10 |
11 |
12 | 13 |
14 | 15 | 16 | 37 | 38 | -------------------------------------------------------------------------------- /networking/websockets/server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "server", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.21.0", 13 | "nodemon": "^3.1.4", 14 | "ws": "^8.18.0" 15 | } 16 | }, 17 | "node_modules/accepts": { 18 | "version": "1.3.8", 19 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 20 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 21 | "dependencies": { 22 | "mime-types": "~2.1.34", 23 | "negotiator": "0.6.3" 24 | }, 25 | "engines": { 26 | "node": ">= 0.6" 27 | } 28 | }, 29 | "node_modules/anymatch": { 30 | "version": "3.1.3", 31 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 32 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 33 | "dependencies": { 34 | "normalize-path": "^3.0.0", 35 | "picomatch": "^2.0.4" 36 | }, 37 | "engines": { 38 | "node": ">= 8" 39 | } 40 | }, 41 | "node_modules/array-flatten": { 42 | "version": "1.1.1", 43 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 44 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 45 | }, 46 | "node_modules/balanced-match": { 47 | "version": "1.0.2", 48 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 49 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 50 | }, 51 | "node_modules/binary-extensions": { 52 | "version": "2.3.0", 53 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 54 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 55 | "engines": { 56 | "node": ">=8" 57 | }, 58 | "funding": { 59 | "url": "https://github.com/sponsors/sindresorhus" 60 | } 61 | }, 62 | "node_modules/body-parser": { 63 | "version": "1.20.3", 64 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", 65 | "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", 66 | "dependencies": { 67 | "bytes": "3.1.2", 68 | "content-type": "~1.0.5", 69 | "debug": "2.6.9", 70 | "depd": "2.0.0", 71 | "destroy": "1.2.0", 72 | "http-errors": "2.0.0", 73 | "iconv-lite": "0.4.24", 74 | "on-finished": "2.4.1", 75 | "qs": "6.13.0", 76 | "raw-body": "2.5.2", 77 | "type-is": "~1.6.18", 78 | "unpipe": "1.0.0" 79 | }, 80 | "engines": { 81 | "node": ">= 0.8", 82 | "npm": "1.2.8000 || >= 1.4.16" 83 | } 84 | }, 85 | "node_modules/brace-expansion": { 86 | "version": "1.1.11", 87 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 88 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 89 | "dependencies": { 90 | "balanced-match": "^1.0.0", 91 | "concat-map": "0.0.1" 92 | } 93 | }, 94 | "node_modules/braces": { 95 | "version": "3.0.3", 96 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 97 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 98 | "dependencies": { 99 | "fill-range": "^7.1.1" 100 | }, 101 | "engines": { 102 | "node": ">=8" 103 | } 104 | }, 105 | "node_modules/bytes": { 106 | "version": "3.1.2", 107 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 108 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 109 | "engines": { 110 | "node": ">= 0.8" 111 | } 112 | }, 113 | "node_modules/call-bind": { 114 | "version": "1.0.7", 115 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 116 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 117 | "dependencies": { 118 | "es-define-property": "^1.0.0", 119 | "es-errors": "^1.3.0", 120 | "function-bind": "^1.1.2", 121 | "get-intrinsic": "^1.2.4", 122 | "set-function-length": "^1.2.1" 123 | }, 124 | "engines": { 125 | "node": ">= 0.4" 126 | }, 127 | "funding": { 128 | "url": "https://github.com/sponsors/ljharb" 129 | } 130 | }, 131 | "node_modules/chokidar": { 132 | "version": "3.6.0", 133 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 134 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 135 | "dependencies": { 136 | "anymatch": "~3.1.2", 137 | "braces": "~3.0.2", 138 | "glob-parent": "~5.1.2", 139 | "is-binary-path": "~2.1.0", 140 | "is-glob": "~4.0.1", 141 | "normalize-path": "~3.0.0", 142 | "readdirp": "~3.6.0" 143 | }, 144 | "engines": { 145 | "node": ">= 8.10.0" 146 | }, 147 | "funding": { 148 | "url": "https://paulmillr.com/funding/" 149 | }, 150 | "optionalDependencies": { 151 | "fsevents": "~2.3.2" 152 | } 153 | }, 154 | "node_modules/concat-map": { 155 | "version": "0.0.1", 156 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 157 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 158 | }, 159 | "node_modules/content-disposition": { 160 | "version": "0.5.4", 161 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 162 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 163 | "dependencies": { 164 | "safe-buffer": "5.2.1" 165 | }, 166 | "engines": { 167 | "node": ">= 0.6" 168 | } 169 | }, 170 | "node_modules/content-type": { 171 | "version": "1.0.5", 172 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 173 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 174 | "engines": { 175 | "node": ">= 0.6" 176 | } 177 | }, 178 | "node_modules/cookie": { 179 | "version": "0.6.0", 180 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", 181 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", 182 | "engines": { 183 | "node": ">= 0.6" 184 | } 185 | }, 186 | "node_modules/cookie-signature": { 187 | "version": "1.0.6", 188 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 189 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 190 | }, 191 | "node_modules/debug": { 192 | "version": "2.6.9", 193 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 194 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 195 | "dependencies": { 196 | "ms": "2.0.0" 197 | } 198 | }, 199 | "node_modules/define-data-property": { 200 | "version": "1.1.4", 201 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 202 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 203 | "dependencies": { 204 | "es-define-property": "^1.0.0", 205 | "es-errors": "^1.3.0", 206 | "gopd": "^1.0.1" 207 | }, 208 | "engines": { 209 | "node": ">= 0.4" 210 | }, 211 | "funding": { 212 | "url": "https://github.com/sponsors/ljharb" 213 | } 214 | }, 215 | "node_modules/depd": { 216 | "version": "2.0.0", 217 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 218 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 219 | "engines": { 220 | "node": ">= 0.8" 221 | } 222 | }, 223 | "node_modules/destroy": { 224 | "version": "1.2.0", 225 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 226 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 227 | "engines": { 228 | "node": ">= 0.8", 229 | "npm": "1.2.8000 || >= 1.4.16" 230 | } 231 | }, 232 | "node_modules/ee-first": { 233 | "version": "1.1.1", 234 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 235 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 236 | }, 237 | "node_modules/encodeurl": { 238 | "version": "2.0.0", 239 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 240 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 241 | "engines": { 242 | "node": ">= 0.8" 243 | } 244 | }, 245 | "node_modules/es-define-property": { 246 | "version": "1.0.0", 247 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 248 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 249 | "dependencies": { 250 | "get-intrinsic": "^1.2.4" 251 | }, 252 | "engines": { 253 | "node": ">= 0.4" 254 | } 255 | }, 256 | "node_modules/es-errors": { 257 | "version": "1.3.0", 258 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 259 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 260 | "engines": { 261 | "node": ">= 0.4" 262 | } 263 | }, 264 | "node_modules/escape-html": { 265 | "version": "1.0.3", 266 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 267 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 268 | }, 269 | "node_modules/etag": { 270 | "version": "1.8.1", 271 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 272 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 273 | "engines": { 274 | "node": ">= 0.6" 275 | } 276 | }, 277 | "node_modules/express": { 278 | "version": "4.21.0", 279 | "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", 280 | "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", 281 | "dependencies": { 282 | "accepts": "~1.3.8", 283 | "array-flatten": "1.1.1", 284 | "body-parser": "1.20.3", 285 | "content-disposition": "0.5.4", 286 | "content-type": "~1.0.4", 287 | "cookie": "0.6.0", 288 | "cookie-signature": "1.0.6", 289 | "debug": "2.6.9", 290 | "depd": "2.0.0", 291 | "encodeurl": "~2.0.0", 292 | "escape-html": "~1.0.3", 293 | "etag": "~1.8.1", 294 | "finalhandler": "1.3.1", 295 | "fresh": "0.5.2", 296 | "http-errors": "2.0.0", 297 | "merge-descriptors": "1.0.3", 298 | "methods": "~1.1.2", 299 | "on-finished": "2.4.1", 300 | "parseurl": "~1.3.3", 301 | "path-to-regexp": "0.1.10", 302 | "proxy-addr": "~2.0.7", 303 | "qs": "6.13.0", 304 | "range-parser": "~1.2.1", 305 | "safe-buffer": "5.2.1", 306 | "send": "0.19.0", 307 | "serve-static": "1.16.2", 308 | "setprototypeof": "1.2.0", 309 | "statuses": "2.0.1", 310 | "type-is": "~1.6.18", 311 | "utils-merge": "1.0.1", 312 | "vary": "~1.1.2" 313 | }, 314 | "engines": { 315 | "node": ">= 0.10.0" 316 | } 317 | }, 318 | "node_modules/fill-range": { 319 | "version": "7.1.1", 320 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 321 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 322 | "dependencies": { 323 | "to-regex-range": "^5.0.1" 324 | }, 325 | "engines": { 326 | "node": ">=8" 327 | } 328 | }, 329 | "node_modules/finalhandler": { 330 | "version": "1.3.1", 331 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", 332 | "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", 333 | "dependencies": { 334 | "debug": "2.6.9", 335 | "encodeurl": "~2.0.0", 336 | "escape-html": "~1.0.3", 337 | "on-finished": "2.4.1", 338 | "parseurl": "~1.3.3", 339 | "statuses": "2.0.1", 340 | "unpipe": "~1.0.0" 341 | }, 342 | "engines": { 343 | "node": ">= 0.8" 344 | } 345 | }, 346 | "node_modules/forwarded": { 347 | "version": "0.2.0", 348 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 349 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 350 | "engines": { 351 | "node": ">= 0.6" 352 | } 353 | }, 354 | "node_modules/fresh": { 355 | "version": "0.5.2", 356 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 357 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 358 | "engines": { 359 | "node": ">= 0.6" 360 | } 361 | }, 362 | "node_modules/fsevents": { 363 | "version": "2.3.3", 364 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 365 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 366 | "hasInstallScript": true, 367 | "optional": true, 368 | "os": [ 369 | "darwin" 370 | ], 371 | "engines": { 372 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 373 | } 374 | }, 375 | "node_modules/function-bind": { 376 | "version": "1.1.2", 377 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 378 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 379 | "funding": { 380 | "url": "https://github.com/sponsors/ljharb" 381 | } 382 | }, 383 | "node_modules/get-intrinsic": { 384 | "version": "1.2.4", 385 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 386 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 387 | "dependencies": { 388 | "es-errors": "^1.3.0", 389 | "function-bind": "^1.1.2", 390 | "has-proto": "^1.0.1", 391 | "has-symbols": "^1.0.3", 392 | "hasown": "^2.0.0" 393 | }, 394 | "engines": { 395 | "node": ">= 0.4" 396 | }, 397 | "funding": { 398 | "url": "https://github.com/sponsors/ljharb" 399 | } 400 | }, 401 | "node_modules/glob-parent": { 402 | "version": "5.1.2", 403 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 404 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 405 | "dependencies": { 406 | "is-glob": "^4.0.1" 407 | }, 408 | "engines": { 409 | "node": ">= 6" 410 | } 411 | }, 412 | "node_modules/gopd": { 413 | "version": "1.0.1", 414 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 415 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 416 | "dependencies": { 417 | "get-intrinsic": "^1.1.3" 418 | }, 419 | "funding": { 420 | "url": "https://github.com/sponsors/ljharb" 421 | } 422 | }, 423 | "node_modules/has-flag": { 424 | "version": "3.0.0", 425 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 426 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 427 | "engines": { 428 | "node": ">=4" 429 | } 430 | }, 431 | "node_modules/has-property-descriptors": { 432 | "version": "1.0.2", 433 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 434 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 435 | "dependencies": { 436 | "es-define-property": "^1.0.0" 437 | }, 438 | "funding": { 439 | "url": "https://github.com/sponsors/ljharb" 440 | } 441 | }, 442 | "node_modules/has-proto": { 443 | "version": "1.0.3", 444 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 445 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 446 | "engines": { 447 | "node": ">= 0.4" 448 | }, 449 | "funding": { 450 | "url": "https://github.com/sponsors/ljharb" 451 | } 452 | }, 453 | "node_modules/has-symbols": { 454 | "version": "1.0.3", 455 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 456 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 457 | "engines": { 458 | "node": ">= 0.4" 459 | }, 460 | "funding": { 461 | "url": "https://github.com/sponsors/ljharb" 462 | } 463 | }, 464 | "node_modules/hasown": { 465 | "version": "2.0.2", 466 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 467 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 468 | "dependencies": { 469 | "function-bind": "^1.1.2" 470 | }, 471 | "engines": { 472 | "node": ">= 0.4" 473 | } 474 | }, 475 | "node_modules/http-errors": { 476 | "version": "2.0.0", 477 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 478 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 479 | "dependencies": { 480 | "depd": "2.0.0", 481 | "inherits": "2.0.4", 482 | "setprototypeof": "1.2.0", 483 | "statuses": "2.0.1", 484 | "toidentifier": "1.0.1" 485 | }, 486 | "engines": { 487 | "node": ">= 0.8" 488 | } 489 | }, 490 | "node_modules/iconv-lite": { 491 | "version": "0.4.24", 492 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 493 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 494 | "dependencies": { 495 | "safer-buffer": ">= 2.1.2 < 3" 496 | }, 497 | "engines": { 498 | "node": ">=0.10.0" 499 | } 500 | }, 501 | "node_modules/ignore-by-default": { 502 | "version": "1.0.1", 503 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 504 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" 505 | }, 506 | "node_modules/inherits": { 507 | "version": "2.0.4", 508 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 509 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 510 | }, 511 | "node_modules/ipaddr.js": { 512 | "version": "1.9.1", 513 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 514 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 515 | "engines": { 516 | "node": ">= 0.10" 517 | } 518 | }, 519 | "node_modules/is-binary-path": { 520 | "version": "2.1.0", 521 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 522 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 523 | "dependencies": { 524 | "binary-extensions": "^2.0.0" 525 | }, 526 | "engines": { 527 | "node": ">=8" 528 | } 529 | }, 530 | "node_modules/is-extglob": { 531 | "version": "2.1.1", 532 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 533 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 534 | "engines": { 535 | "node": ">=0.10.0" 536 | } 537 | }, 538 | "node_modules/is-glob": { 539 | "version": "4.0.3", 540 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 541 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 542 | "dependencies": { 543 | "is-extglob": "^2.1.1" 544 | }, 545 | "engines": { 546 | "node": ">=0.10.0" 547 | } 548 | }, 549 | "node_modules/is-number": { 550 | "version": "7.0.0", 551 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 552 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 553 | "engines": { 554 | "node": ">=0.12.0" 555 | } 556 | }, 557 | "node_modules/media-typer": { 558 | "version": "0.3.0", 559 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 560 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 561 | "engines": { 562 | "node": ">= 0.6" 563 | } 564 | }, 565 | "node_modules/merge-descriptors": { 566 | "version": "1.0.3", 567 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", 568 | "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", 569 | "funding": { 570 | "url": "https://github.com/sponsors/sindresorhus" 571 | } 572 | }, 573 | "node_modules/methods": { 574 | "version": "1.1.2", 575 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 576 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 577 | "engines": { 578 | "node": ">= 0.6" 579 | } 580 | }, 581 | "node_modules/mime": { 582 | "version": "1.6.0", 583 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 584 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 585 | "bin": { 586 | "mime": "cli.js" 587 | }, 588 | "engines": { 589 | "node": ">=4" 590 | } 591 | }, 592 | "node_modules/mime-db": { 593 | "version": "1.52.0", 594 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 595 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 596 | "engines": { 597 | "node": ">= 0.6" 598 | } 599 | }, 600 | "node_modules/mime-types": { 601 | "version": "2.1.35", 602 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 603 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 604 | "dependencies": { 605 | "mime-db": "1.52.0" 606 | }, 607 | "engines": { 608 | "node": ">= 0.6" 609 | } 610 | }, 611 | "node_modules/minimatch": { 612 | "version": "3.1.2", 613 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 614 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 615 | "dependencies": { 616 | "brace-expansion": "^1.1.7" 617 | }, 618 | "engines": { 619 | "node": "*" 620 | } 621 | }, 622 | "node_modules/ms": { 623 | "version": "2.0.0", 624 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 625 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 626 | }, 627 | "node_modules/negotiator": { 628 | "version": "0.6.3", 629 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 630 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 631 | "engines": { 632 | "node": ">= 0.6" 633 | } 634 | }, 635 | "node_modules/nodemon": { 636 | "version": "3.1.4", 637 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", 638 | "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", 639 | "dependencies": { 640 | "chokidar": "^3.5.2", 641 | "debug": "^4", 642 | "ignore-by-default": "^1.0.1", 643 | "minimatch": "^3.1.2", 644 | "pstree.remy": "^1.1.8", 645 | "semver": "^7.5.3", 646 | "simple-update-notifier": "^2.0.0", 647 | "supports-color": "^5.5.0", 648 | "touch": "^3.1.0", 649 | "undefsafe": "^2.0.5" 650 | }, 651 | "bin": { 652 | "nodemon": "bin/nodemon.js" 653 | }, 654 | "engines": { 655 | "node": ">=10" 656 | }, 657 | "funding": { 658 | "type": "opencollective", 659 | "url": "https://opencollective.com/nodemon" 660 | } 661 | }, 662 | "node_modules/nodemon/node_modules/debug": { 663 | "version": "4.3.7", 664 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 665 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 666 | "dependencies": { 667 | "ms": "^2.1.3" 668 | }, 669 | "engines": { 670 | "node": ">=6.0" 671 | }, 672 | "peerDependenciesMeta": { 673 | "supports-color": { 674 | "optional": true 675 | } 676 | } 677 | }, 678 | "node_modules/nodemon/node_modules/ms": { 679 | "version": "2.1.3", 680 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 681 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 682 | }, 683 | "node_modules/normalize-path": { 684 | "version": "3.0.0", 685 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 686 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 687 | "engines": { 688 | "node": ">=0.10.0" 689 | } 690 | }, 691 | "node_modules/object-inspect": { 692 | "version": "1.13.2", 693 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", 694 | "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", 695 | "engines": { 696 | "node": ">= 0.4" 697 | }, 698 | "funding": { 699 | "url": "https://github.com/sponsors/ljharb" 700 | } 701 | }, 702 | "node_modules/on-finished": { 703 | "version": "2.4.1", 704 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 705 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 706 | "dependencies": { 707 | "ee-first": "1.1.1" 708 | }, 709 | "engines": { 710 | "node": ">= 0.8" 711 | } 712 | }, 713 | "node_modules/parseurl": { 714 | "version": "1.3.3", 715 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 716 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 717 | "engines": { 718 | "node": ">= 0.8" 719 | } 720 | }, 721 | "node_modules/path-to-regexp": { 722 | "version": "0.1.10", 723 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", 724 | "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" 725 | }, 726 | "node_modules/picomatch": { 727 | "version": "2.3.1", 728 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 729 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 730 | "engines": { 731 | "node": ">=8.6" 732 | }, 733 | "funding": { 734 | "url": "https://github.com/sponsors/jonschlinkert" 735 | } 736 | }, 737 | "node_modules/proxy-addr": { 738 | "version": "2.0.7", 739 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 740 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 741 | "dependencies": { 742 | "forwarded": "0.2.0", 743 | "ipaddr.js": "1.9.1" 744 | }, 745 | "engines": { 746 | "node": ">= 0.10" 747 | } 748 | }, 749 | "node_modules/pstree.remy": { 750 | "version": "1.1.8", 751 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", 752 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" 753 | }, 754 | "node_modules/qs": { 755 | "version": "6.13.0", 756 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", 757 | "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 758 | "dependencies": { 759 | "side-channel": "^1.0.6" 760 | }, 761 | "engines": { 762 | "node": ">=0.6" 763 | }, 764 | "funding": { 765 | "url": "https://github.com/sponsors/ljharb" 766 | } 767 | }, 768 | "node_modules/range-parser": { 769 | "version": "1.2.1", 770 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 771 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 772 | "engines": { 773 | "node": ">= 0.6" 774 | } 775 | }, 776 | "node_modules/raw-body": { 777 | "version": "2.5.2", 778 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 779 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 780 | "dependencies": { 781 | "bytes": "3.1.2", 782 | "http-errors": "2.0.0", 783 | "iconv-lite": "0.4.24", 784 | "unpipe": "1.0.0" 785 | }, 786 | "engines": { 787 | "node": ">= 0.8" 788 | } 789 | }, 790 | "node_modules/readdirp": { 791 | "version": "3.6.0", 792 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 793 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 794 | "dependencies": { 795 | "picomatch": "^2.2.1" 796 | }, 797 | "engines": { 798 | "node": ">=8.10.0" 799 | } 800 | }, 801 | "node_modules/safe-buffer": { 802 | "version": "5.2.1", 803 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 804 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 805 | "funding": [ 806 | { 807 | "type": "github", 808 | "url": "https://github.com/sponsors/feross" 809 | }, 810 | { 811 | "type": "patreon", 812 | "url": "https://www.patreon.com/feross" 813 | }, 814 | { 815 | "type": "consulting", 816 | "url": "https://feross.org/support" 817 | } 818 | ] 819 | }, 820 | "node_modules/safer-buffer": { 821 | "version": "2.1.2", 822 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 823 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 824 | }, 825 | "node_modules/semver": { 826 | "version": "7.6.3", 827 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 828 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 829 | "bin": { 830 | "semver": "bin/semver.js" 831 | }, 832 | "engines": { 833 | "node": ">=10" 834 | } 835 | }, 836 | "node_modules/send": { 837 | "version": "0.19.0", 838 | "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", 839 | "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", 840 | "dependencies": { 841 | "debug": "2.6.9", 842 | "depd": "2.0.0", 843 | "destroy": "1.2.0", 844 | "encodeurl": "~1.0.2", 845 | "escape-html": "~1.0.3", 846 | "etag": "~1.8.1", 847 | "fresh": "0.5.2", 848 | "http-errors": "2.0.0", 849 | "mime": "1.6.0", 850 | "ms": "2.1.3", 851 | "on-finished": "2.4.1", 852 | "range-parser": "~1.2.1", 853 | "statuses": "2.0.1" 854 | }, 855 | "engines": { 856 | "node": ">= 0.8.0" 857 | } 858 | }, 859 | "node_modules/send/node_modules/encodeurl": { 860 | "version": "1.0.2", 861 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 862 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 863 | "engines": { 864 | "node": ">= 0.8" 865 | } 866 | }, 867 | "node_modules/send/node_modules/ms": { 868 | "version": "2.1.3", 869 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 870 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 871 | }, 872 | "node_modules/serve-static": { 873 | "version": "1.16.2", 874 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", 875 | "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", 876 | "dependencies": { 877 | "encodeurl": "~2.0.0", 878 | "escape-html": "~1.0.3", 879 | "parseurl": "~1.3.3", 880 | "send": "0.19.0" 881 | }, 882 | "engines": { 883 | "node": ">= 0.8.0" 884 | } 885 | }, 886 | "node_modules/set-function-length": { 887 | "version": "1.2.2", 888 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 889 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 890 | "dependencies": { 891 | "define-data-property": "^1.1.4", 892 | "es-errors": "^1.3.0", 893 | "function-bind": "^1.1.2", 894 | "get-intrinsic": "^1.2.4", 895 | "gopd": "^1.0.1", 896 | "has-property-descriptors": "^1.0.2" 897 | }, 898 | "engines": { 899 | "node": ">= 0.4" 900 | } 901 | }, 902 | "node_modules/setprototypeof": { 903 | "version": "1.2.0", 904 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 905 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 906 | }, 907 | "node_modules/side-channel": { 908 | "version": "1.0.6", 909 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", 910 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", 911 | "dependencies": { 912 | "call-bind": "^1.0.7", 913 | "es-errors": "^1.3.0", 914 | "get-intrinsic": "^1.2.4", 915 | "object-inspect": "^1.13.1" 916 | }, 917 | "engines": { 918 | "node": ">= 0.4" 919 | }, 920 | "funding": { 921 | "url": "https://github.com/sponsors/ljharb" 922 | } 923 | }, 924 | "node_modules/simple-update-notifier": { 925 | "version": "2.0.0", 926 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", 927 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", 928 | "dependencies": { 929 | "semver": "^7.5.3" 930 | }, 931 | "engines": { 932 | "node": ">=10" 933 | } 934 | }, 935 | "node_modules/statuses": { 936 | "version": "2.0.1", 937 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 938 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 939 | "engines": { 940 | "node": ">= 0.8" 941 | } 942 | }, 943 | "node_modules/supports-color": { 944 | "version": "5.5.0", 945 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 946 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 947 | "dependencies": { 948 | "has-flag": "^3.0.0" 949 | }, 950 | "engines": { 951 | "node": ">=4" 952 | } 953 | }, 954 | "node_modules/to-regex-range": { 955 | "version": "5.0.1", 956 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 957 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 958 | "dependencies": { 959 | "is-number": "^7.0.0" 960 | }, 961 | "engines": { 962 | "node": ">=8.0" 963 | } 964 | }, 965 | "node_modules/toidentifier": { 966 | "version": "1.0.1", 967 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 968 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 969 | "engines": { 970 | "node": ">=0.6" 971 | } 972 | }, 973 | "node_modules/touch": { 974 | "version": "3.1.1", 975 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", 976 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", 977 | "bin": { 978 | "nodetouch": "bin/nodetouch.js" 979 | } 980 | }, 981 | "node_modules/type-is": { 982 | "version": "1.6.18", 983 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 984 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 985 | "dependencies": { 986 | "media-typer": "0.3.0", 987 | "mime-types": "~2.1.24" 988 | }, 989 | "engines": { 990 | "node": ">= 0.6" 991 | } 992 | }, 993 | "node_modules/undefsafe": { 994 | "version": "2.0.5", 995 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", 996 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" 997 | }, 998 | "node_modules/unpipe": { 999 | "version": "1.0.0", 1000 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1001 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1002 | "engines": { 1003 | "node": ">= 0.8" 1004 | } 1005 | }, 1006 | "node_modules/utils-merge": { 1007 | "version": "1.0.1", 1008 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1009 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1010 | "engines": { 1011 | "node": ">= 0.4.0" 1012 | } 1013 | }, 1014 | "node_modules/vary": { 1015 | "version": "1.1.2", 1016 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1017 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1018 | "engines": { 1019 | "node": ">= 0.8" 1020 | } 1021 | }, 1022 | "node_modules/ws": { 1023 | "version": "8.18.0", 1024 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", 1025 | "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", 1026 | "engines": { 1027 | "node": ">=10.0.0" 1028 | }, 1029 | "peerDependencies": { 1030 | "bufferutil": "^4.0.1", 1031 | "utf-8-validate": ">=5.0.2" 1032 | }, 1033 | "peerDependenciesMeta": { 1034 | "bufferutil": { 1035 | "optional": true 1036 | }, 1037 | "utf-8-validate": { 1038 | "optional": true 1039 | } 1040 | } 1041 | } 1042 | } 1043 | } 1044 | -------------------------------------------------------------------------------- /networking/websockets/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.21.0", 14 | "nodemon": "^3.1.4", 15 | "ws": "^8.18.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /networking/websockets/server/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const WebSocket = require("ws"); 3 | 4 | const app = express(); 5 | 6 | // Initialize WebSocket server 7 | const wss = new WebSocket.Server({ port: 8080 }); 8 | 9 | // WebSocket event handling 10 | wss.on("connection", (ws) => { 11 | console.log("A new client connected."); 12 | 13 | // Event listener for incoming messages 14 | ws.on("message", (message) => { 15 | console.log("Received message:", message.toString()); 16 | 17 | // Broadcast the message to all connected clients 18 | wss.clients.forEach((client) => { 19 | if (client.readyState === WebSocket.OPEN) { 20 | client.send(message.toString()); 21 | } 22 | }); 23 | }); 24 | 25 | // Event listener for client disconnection 26 | ws.on("close", () => { 27 | console.log("A client disconnected."); 28 | }); 29 | }); 30 | 31 | // Start the server 32 | const port = 3000; 33 | app.listen(port, () => { 34 | console.log(`Server started on http://localhost:${port}`); 35 | }); 36 | -------------------------------------------------------------------------------- /performance/CLS/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /performance/CLS/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /performance/CLS/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /performance/CLS/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /performance/CLS/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cls", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1" 15 | }, 16 | "devDependencies": { 17 | "@eslint/js": "^9.11.1", 18 | "@types/react": "^18.3.10", 19 | "@types/react-dom": "^18.3.0", 20 | "@vitejs/plugin-react": "^4.3.2", 21 | "eslint": "^9.11.1", 22 | "eslint-plugin-react": "^7.37.0", 23 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 24 | "eslint-plugin-react-refresh": "^0.4.12", 25 | "globals": "^15.9.0", 26 | "vite": "^5.4.8" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /performance/CLS/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/CLS/src/App.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/CLS/src/App.css -------------------------------------------------------------------------------- /performance/CLS/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | 3 | function App() { 4 | const [showAds, toggleAds] = useState(false); 5 | useEffect(() => { 6 | setTimeout(() => { 7 | toggleAds(true); 8 | }, 100); 9 | }, []); 10 | return ( 11 | <> 12 |

CLS

13 | 14 |
15 | {showAds && ( 16 | 17 | )} 18 |
19 | 20 |

21 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 22 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim 23 | veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 24 | commodo consequat. Duis aute irure dolor in reprehenderit in voluptate 25 | velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint 26 | occaecat cupidatat non proident, sunt in culpa qui officia deserunt 27 | mollit anim id est laborum." 28 |

29 | 30 | ); 31 | } 32 | 33 | export default App; 34 | -------------------------------------------------------------------------------- /performance/CLS/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/CLS/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/CLS/src/index.css -------------------------------------------------------------------------------- /performance/CLS/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /performance/CLS/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /performance/INP/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /performance/INP/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /performance/INP/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /performance/INP/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /performance/INP/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inp", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1" 15 | }, 16 | "devDependencies": { 17 | "@eslint/js": "^9.11.1", 18 | "@types/react": "^18.3.10", 19 | "@types/react-dom": "^18.3.0", 20 | "@vitejs/plugin-react": "^4.3.2", 21 | "eslint": "^9.11.1", 22 | "eslint-plugin-react": "^7.37.0", 23 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 24 | "eslint-plugin-react-refresh": "^0.4.12", 25 | "globals": "^15.9.0", 26 | "vite": "^5.4.8" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /performance/INP/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/INP/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /performance/INP/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | function App() { 4 | const [showModal, toggleModal] = useState(false); 5 | const handleClick = () => { 6 | for (let i = 0; i < 10000000; i++) { 7 | // empty 8 | } 9 | toggleModal((prev) => !prev); 10 | }; 11 | return ( 12 | <> 13 |

INP

14 | 15 | {showModal &&
I am modal
} 16 | 17 | ); 18 | } 19 | 20 | export default App; 21 | -------------------------------------------------------------------------------- /performance/INP/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/INP/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/INP/src/index.css -------------------------------------------------------------------------------- /performance/INP/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /performance/INP/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /performance/LCP/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

LCP

10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /performance/code-splitting/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /performance/code-splitting/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /performance/code-splitting/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /performance/code-splitting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /performance/code-splitting/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "code-splitting", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1", 15 | "react-router-dom": "^6.26.2" 16 | }, 17 | "devDependencies": { 18 | "@eslint/js": "^9.11.1", 19 | "@types/react": "^18.3.10", 20 | "@types/react-dom": "^18.3.0", 21 | "@vitejs/plugin-react": "^4.3.2", 22 | "eslint": "^9.11.1", 23 | "eslint-plugin-react": "^7.37.0", 24 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 25 | "eslint-plugin-react-refresh": "^0.4.12", 26 | "globals": "^15.9.0", 27 | "vite": "^5.4.8" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /performance/code-splitting/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/code-splitting/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /performance/code-splitting/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { lazy, Suspense } from "react"; 2 | import { BrowserRouter, Navigate, Routes, Route } from "react-router-dom"; 3 | import { NavBar } from "./components/NavBar"; 4 | // import { About, Contact, FAQs, Profile, Login } from "./pages"; 5 | 6 | const Profile = lazy(() => import("./pages/Profile")); 7 | const About = lazy(() => import("./pages/About")); 8 | const Contact = lazy(() => import("./pages/Contact")); 9 | const FAQs = lazy(() => import("./pages/FAQs")); 10 | const Login = lazy(() => import("./pages/Login")); 11 | 12 | const isAuthenticated = true; 13 | export const PrivateRoutes = () => { 14 | return ( 15 | <> 16 | 17 | 18 | ...}> 22 | {" "} 23 | 24 | 25 | } 26 | /> 27 | ...}> 31 | {" "} 32 | 33 | 34 | } 35 | /> 36 | ...}> 40 | {" "} 41 | 42 | 43 | } 44 | /> 45 | ...}> 49 | {" "} 50 | 51 | 52 | } 53 | /> 54 | 55 | } /> 56 | 57 | 58 | ); 59 | }; 60 | 61 | export const PublicRoutes = () => { 62 | return ( 63 | 64 | ...}> 68 | {" "} 69 | 70 | 71 | } 72 | /> 73 | 74 | } /> 75 | 76 | ); 77 | }; 78 | 79 | const App = () => { 80 | return ( 81 | 82 | 83 | {isAuthenticated ? ( 84 | } /> 85 | ) : ( 86 | } /> 87 | )} 88 | 89 | 90 | ); 91 | }; 92 | export default App; 93 | -------------------------------------------------------------------------------- /performance/code-splitting/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/code-splitting/src/components/NavBar.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | export const NavBar = () => { 4 | return ( 5 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /performance/code-splitting/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/code-splitting/src/index.css -------------------------------------------------------------------------------- /performance/code-splitting/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /performance/code-splitting/src/pages/About.jsx: -------------------------------------------------------------------------------- 1 | const About = () => { 2 | return
About
; 3 | }; 4 | 5 | export default About; 6 | -------------------------------------------------------------------------------- /performance/code-splitting/src/pages/Contact.jsx: -------------------------------------------------------------------------------- 1 | const Contact = () => { 2 | return
Contact
; 3 | }; 4 | 5 | export default Contact; 6 | -------------------------------------------------------------------------------- /performance/code-splitting/src/pages/FAQs.jsx: -------------------------------------------------------------------------------- 1 | const FAQs = () => { 2 | return
FAQs
; 3 | }; 4 | 5 | export default FAQs; 6 | -------------------------------------------------------------------------------- /performance/code-splitting/src/pages/Login.jsx: -------------------------------------------------------------------------------- 1 | const Login = () => { 2 | return
Login
; 3 | }; 4 | 5 | export default Login; 6 | -------------------------------------------------------------------------------- /performance/code-splitting/src/pages/Profile.jsx: -------------------------------------------------------------------------------- 1 | const Profile = () => { 2 | return
Profile
; 3 | }; 4 | 5 | export default Profile; 6 | -------------------------------------------------------------------------------- /performance/code-splitting/src/pages/index.js: -------------------------------------------------------------------------------- 1 | export * from "./About"; 2 | export * from "./Contact"; 3 | export * from "./FAQs"; 4 | export * from "./Login"; 5 | export * from "./Profile"; 6 | -------------------------------------------------------------------------------- /performance/code-splitting/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /performance/compression/dist/index.html: -------------------------------------------------------------------------------- 1 | React App
-------------------------------------------------------------------------------- /performance/compression/dist/index.html.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/compression/dist/index.html.gz -------------------------------------------------------------------------------- /performance/compression/dist/main.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * @license React 3 | * react-dom.production.min.js 4 | * 5 | * Copyright (c) Facebook, Inc. and its affiliates. 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | /** 12 | * @license React 13 | * react-jsx-runtime.production.min.js 14 | * 15 | * Copyright (c) Facebook, Inc. and its affiliates. 16 | * 17 | * This source code is licensed under the MIT license found in the 18 | * LICENSE file in the root directory of this source tree. 19 | */ 20 | 21 | /** 22 | * @license React 23 | * react.production.min.js 24 | * 25 | * Copyright (c) Facebook, Inc. and its affiliates. 26 | * 27 | * This source code is licensed under the MIT license found in the 28 | * LICENSE file in the root directory of this source tree. 29 | */ 30 | 31 | /** 32 | * @license React 33 | * scheduler.production.min.js 34 | * 35 | * Copyright (c) Facebook, Inc. and its affiliates. 36 | * 37 | * This source code is licensed under the MIT license found in the 38 | * LICENSE file in the root directory of this source tree. 39 | */ 40 | -------------------------------------------------------------------------------- /performance/compression/dist/main.js.LICENSE.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/compression/dist/main.js.LICENSE.txt.gz -------------------------------------------------------------------------------- /performance/compression/dist/main.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/compression/dist/main.js.gz -------------------------------------------------------------------------------- /performance/compression/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compression", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack serve", 8 | "build": "webpack", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "compression-webpack-plugin": "^11.1.0", 15 | "react": "^18.3.1", 16 | "react-dom": "^18.3.1" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.25.7", 20 | "@babel/preset-env": "^7.25.7", 21 | "@babel/preset-react": "^7.25.7", 22 | "babel-loader": "^9.2.1", 23 | "html-webpack-plugin": "^5.6.0", 24 | "webpack": "^5.95.0", 25 | "webpack-cli": "^5.1.4", 26 | "webpack-dev-server": "^5.1.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /performance/compression/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React App 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /performance/compression/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | 4 | ReactDOM.render(

Hello World

, document.getElementById("root")); 5 | -------------------------------------------------------------------------------- /performance/compression/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 3 | const CompressionPlugin = require("compression-webpack-plugin"); 4 | 5 | module.exports = { 6 | entry: path.join(__dirname, "src", "index.js"), 7 | output: { 8 | path: path.resolve(__dirname, "dist"), 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.?js$/, 14 | exclude: /node_modules/, 15 | use: { 16 | loader: "babel-loader", 17 | options: { 18 | presets: [ 19 | "@babel/preset-env", 20 | [ 21 | "@babel/preset-react", 22 | { 23 | runtime: "automatic", 24 | }, 25 | ], 26 | ], 27 | }, 28 | }, 29 | }, 30 | ], 31 | }, 32 | plugins: [ 33 | new CompressionPlugin({ algorithm: "gzip" }), 34 | new HtmlWebpackPlugin({ 35 | template: path.join(__dirname, "src", "index.html"), 36 | }), 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /performance/import-on-interaction/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /performance/import-on-interaction/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /performance/import-on-interaction/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /performance/import-on-interaction/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /performance/import-on-interaction/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "import-on-interaction", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1" 15 | }, 16 | "devDependencies": { 17 | "@eslint/js": "^9.11.1", 18 | "@types/react": "^18.3.10", 19 | "@types/react-dom": "^18.3.0", 20 | "@vitejs/plugin-react": "^4.3.2", 21 | "eslint": "^9.11.1", 22 | "eslint-plugin-react": "^7.37.0", 23 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 24 | "eslint-plugin-react-refresh": "^0.4.12", 25 | "globals": "^15.9.0", 26 | "vite": "^5.4.8" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /performance/import-on-interaction/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/import-on-interaction/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /performance/import-on-interaction/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState, lazy, Suspense } from "react"; 2 | // import Emoji from "./Emoji"; 3 | import Message from "./Message"; 4 | 5 | const Emoji = lazy(() => import("./Emoji")); 6 | 7 | function App() { 8 | const [showEmoji, toggleEmoji] = useState(false); 9 | 10 | return ( 11 | <> 12 | 13 | 14 | {showEmoji && ( 15 | 16 | 17 | 18 | )} 19 | 20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /performance/import-on-interaction/src/Emoji.jsx: -------------------------------------------------------------------------------- 1 | const Emoji = () => { 2 | return
Emoji
; 3 | }; 4 | 5 | export default Emoji; 6 | -------------------------------------------------------------------------------- /performance/import-on-interaction/src/Message.jsx: -------------------------------------------------------------------------------- 1 | const Message = () => { 2 | return
Message
; 3 | }; 4 | 5 | export default Message; 6 | -------------------------------------------------------------------------------- /performance/import-on-interaction/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/import-on-interaction/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/import-on-interaction/src/index.css -------------------------------------------------------------------------------- /performance/import-on-interaction/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /performance/import-on-interaction/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /performance/import-on-visibility/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /performance/import-on-visibility/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /performance/import-on-visibility/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /performance/import-on-visibility/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /performance/import-on-visibility/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "import-on-visibility", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1", 15 | "react-intersection-observer": "^9.13.1" 16 | }, 17 | "devDependencies": { 18 | "@eslint/js": "^9.11.1", 19 | "@types/react": "^18.3.10", 20 | "@types/react-dom": "^18.3.0", 21 | "@vitejs/plugin-react": "^4.3.2", 22 | "eslint": "^9.11.1", 23 | "eslint-plugin-react": "^7.37.0", 24 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 25 | "eslint-plugin-react-refresh": "^0.4.12", 26 | "globals": "^15.9.0", 27 | "vite": "^5.4.8" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /performance/import-on-visibility/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/import-on-visibility/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /performance/import-on-visibility/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { Suspense, lazy, useEffect } from "react"; 2 | import { useInView } from "react-intersection-observer"; 3 | import Message from "./Message"; 4 | const Emoji = lazy(() => import("./Emoji")); 5 | 6 | function App() { 7 | const { ref, inView } = useInView(); 8 | 9 | useEffect(() => { 10 | console.log("inView", inView); 11 | }, [inView]); 12 | return ( 13 | <> 14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | {inView && } 81 |
82 | 83 | ); 84 | } 85 | 86 | export default App; 87 | -------------------------------------------------------------------------------- /performance/import-on-visibility/src/Emoji.jsx: -------------------------------------------------------------------------------- 1 | const Emoji = () => { 2 | return
Emoji
; 3 | }; 4 | 5 | export default Emoji; 6 | -------------------------------------------------------------------------------- /performance/import-on-visibility/src/Message.jsx: -------------------------------------------------------------------------------- 1 | const Message = () => { 2 | return
Message
; 3 | }; 4 | 5 | export default Message; 6 | -------------------------------------------------------------------------------- /performance/import-on-visibility/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/import-on-visibility/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/import-on-visibility/src/index.css -------------------------------------------------------------------------------- /performance/import-on-visibility/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /performance/import-on-visibility/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /performance/prefetch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compression", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack serve", 8 | "build": "webpack", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^18.3.1", 15 | "react-dom": "^18.3.1" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.25.7", 19 | "@babel/preset-env": "^7.25.7", 20 | "@babel/preset-react": "^7.25.7", 21 | "babel-loader": "^9.2.1", 22 | "html-webpack-plugin": "^5.6.0", 23 | "webpack": "^5.95.0", 24 | "webpack-cli": "^5.1.4", 25 | "webpack-dev-server": "^5.1.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /performance/prefetch/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const App = () => { 4 | const [showEmoji, toggleEmoji] = useState(false); 5 | const [emojiEle, setEmojiPickerEl] = useState(); 6 | const handleClick = () => { 7 | import(/* webpackPrefetch: true, webpackChunkName: "emoji" */ "./Emoji") 8 | .then((module) => module.default) 9 | .then((emojiPicker) => { 10 | setEmojiPickerEl(emojiPicker); 11 | toggleEmoji(true); 12 | }); 13 | }; 14 | return ( 15 |
16 |

Webpack Prefetch

17 | 18 | {showEmoji && emojiEle} 19 |
20 | ); 21 | }; 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /performance/prefetch/src/Emoji.js: -------------------------------------------------------------------------------- 1 | const Emoji = () => { 2 | return
Emoji
; 3 | }; 4 | 5 | export default Emoji; 6 | -------------------------------------------------------------------------------- /performance/prefetch/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React App 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /performance/prefetch/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | ReactDOM.render(, document.getElementById("root")); 5 | -------------------------------------------------------------------------------- /performance/prefetch/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 3 | 4 | module.exports = { 5 | entry: path.join(__dirname, "src", "index.js"), 6 | output: { 7 | path: path.resolve(__dirname, "dist"), 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.?js$/, 13 | exclude: /node_modules/, 14 | use: { 15 | loader: "babel-loader", 16 | options: { 17 | presets: [ 18 | "@babel/preset-env", 19 | [ 20 | "@babel/preset-react", 21 | { 22 | runtime: "automatic", 23 | }, 24 | ], 25 | ], 26 | }, 27 | }, 28 | }, 29 | ], 30 | }, 31 | plugins: [ 32 | new HtmlWebpackPlugin({ 33 | template: path.join(__dirname, "src", "index.html"), 34 | }), 35 | ], 36 | }; 37 | -------------------------------------------------------------------------------- /performance/preload/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compression", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack serve", 8 | "build": "webpack", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^18.3.1", 15 | "react-dom": "^18.3.1" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.25.7", 19 | "@babel/preset-env": "^7.25.7", 20 | "@babel/preset-react": "^7.25.7", 21 | "@vue/preload-webpack-plugin": "^2.0.0", 22 | "babel-loader": "^9.2.1", 23 | "html-webpack-plugin": "^5.6.0", 24 | "webpack": "^5.95.0", 25 | "webpack-cli": "^5.1.4", 26 | "webpack-dev-server": "^5.1.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /performance/preload/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const App = () => { 4 | const [showEmoji, toggleEmoji] = useState(false); 5 | const [emojiEle, setEmojiPickerEl] = useState(); 6 | const handleClick = () => { 7 | import(/* webpackChunkName: "emoji" */ "./Emoji") 8 | .then((module) => module.default) 9 | .then((emojiPicker) => { 10 | setEmojiPickerEl(emojiPicker); 11 | toggleEmoji(true); 12 | }); 13 | }; 14 | return ( 15 |
16 |

Webpack Preload

17 | 18 | {showEmoji && emojiEle} 19 |
20 | ); 21 | }; 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /performance/preload/src/Emoji.js: -------------------------------------------------------------------------------- 1 | const Emoji = () => { 2 | return
Emoji
; 3 | }; 4 | 5 | export default Emoji; 6 | -------------------------------------------------------------------------------- /performance/preload/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React App 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /performance/preload/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | ReactDOM.render(, document.getElementById("root")); 5 | -------------------------------------------------------------------------------- /performance/preload/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 3 | const PreloadWebpackPlugin = require("@vue/preload-webpack-plugin"); 4 | module.exports = { 5 | entry: path.join(__dirname, "src", "index.js"), 6 | output: { 7 | path: path.resolve(__dirname, "dist"), 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.?js$/, 13 | exclude: /node_modules/, 14 | use: { 15 | loader: "babel-loader", 16 | options: { 17 | presets: [ 18 | "@babel/preset-env", 19 | [ 20 | "@babel/preset-react", 21 | { 22 | runtime: "automatic", 23 | }, 24 | ], 25 | ], 26 | }, 27 | }, 28 | }, 29 | ], 30 | }, 31 | plugins: [ 32 | new HtmlWebpackPlugin({ 33 | template: path.join(__dirname, "src", "index.html"), 34 | }), 35 | new PreloadWebpackPlugin(), 36 | ], 37 | }; 38 | -------------------------------------------------------------------------------- /performance/tree-shaking/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React App 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /performance/tree-shaking/dist/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 3 | * This devtool is neither made for production nor for readable output files. 4 | * It uses "eval()" calls to create a separate source file in the browser devtools. 5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 6 | * or disable the default devtool with "devtool: false". 7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 8 | */ 9 | /******/ (() => { // webpackBootstrap 10 | /******/ "use strict"; 11 | /******/ var __webpack_modules__ = ({ 12 | 13 | /***/ "./src/index.js": 14 | /*!**********************!*\ 15 | !*** ./src/index.js ***! 16 | \**********************/ 17 | /***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => { 18 | 19 | eval("/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math */ \"./src/math.js\");\n\nconsole.log((0,_math__WEBPACK_IMPORTED_MODULE_0__.multiply)(2, 3));\n\n//# sourceURL=webpack://compression/./src/index.js?"); 20 | 21 | /***/ }), 22 | 23 | /***/ "./src/math.js": 24 | /*!*********************!*\ 25 | !*** ./src/math.js ***! 26 | \*********************/ 27 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 28 | 29 | eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ multiply: () => (/* binding */ multiply)\n/* harmony export */ });\n/* unused harmony export sum */\nfunction sum(a, b) {\n return a + b;\n}\nfunction multiply(a, b) {\n return a * b;\n}\n\n\n//# sourceURL=webpack://compression/./src/math.js?"); 30 | 31 | /***/ }) 32 | 33 | /******/ }); 34 | /************************************************************************/ 35 | /******/ // The module cache 36 | /******/ var __webpack_module_cache__ = {}; 37 | /******/ 38 | /******/ // The require function 39 | /******/ function __webpack_require__(moduleId) { 40 | /******/ // Check if module is in cache 41 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 42 | /******/ if (cachedModule !== undefined) { 43 | /******/ return cachedModule.exports; 44 | /******/ } 45 | /******/ // Create a new module (and put it into the cache) 46 | /******/ var module = __webpack_module_cache__[moduleId] = { 47 | /******/ // no module.id needed 48 | /******/ // no module.loaded needed 49 | /******/ exports: {} 50 | /******/ }; 51 | /******/ 52 | /******/ // Execute the module function 53 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 54 | /******/ 55 | /******/ // Return the exports of the module 56 | /******/ return module.exports; 57 | /******/ } 58 | /******/ 59 | /************************************************************************/ 60 | /******/ /* webpack/runtime/define property getters */ 61 | /******/ (() => { 62 | /******/ // define getter functions for harmony exports 63 | /******/ __webpack_require__.d = (exports, definition) => { 64 | /******/ for(var key in definition) { 65 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 66 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 67 | /******/ } 68 | /******/ } 69 | /******/ }; 70 | /******/ })(); 71 | /******/ 72 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 73 | /******/ (() => { 74 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 75 | /******/ })(); 76 | /******/ 77 | /************************************************************************/ 78 | /******/ 79 | /******/ // startup 80 | /******/ // Load entry module and return exports 81 | /******/ // This entry module can't be inlined because the eval devtool is used. 82 | /******/ var __webpack_exports__ = __webpack_require__("./src/index.js"); 83 | /******/ 84 | /******/ })() 85 | ; -------------------------------------------------------------------------------- /performance/tree-shaking/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compression", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack serve", 8 | "build": "webpack", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@babel/core": "^7.25.7", 15 | "@babel/preset-env": "^7.25.7", 16 | "babel-loader": "^9.2.1", 17 | "html-webpack-plugin": "^5.6.0", 18 | "webpack": "^5.95.0", 19 | "webpack-cli": "^5.1.4", 20 | "webpack-dev-server": "^5.1.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /performance/tree-shaking/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React App 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /performance/tree-shaking/src/index.js: -------------------------------------------------------------------------------- 1 | import { multiply } from "./math"; 2 | 3 | console.log(multiply(2, 3)); 4 | -------------------------------------------------------------------------------- /performance/tree-shaking/src/math.js: -------------------------------------------------------------------------------- 1 | function sum(a, b) { 2 | return a + b; 3 | } 4 | 5 | function multiply(a, b) { 6 | return a * b; 7 | } 8 | 9 | export { sum, multiply }; 10 | -------------------------------------------------------------------------------- /performance/tree-shaking/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 3 | 4 | module.exports = { 5 | entry: path.join(__dirname, "src", "index.js"), 6 | mode: "development", 7 | output: { 8 | path: path.resolve(__dirname, "dist"), 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.?js$/, 14 | exclude: /node_modules/, 15 | use: { 16 | loader: "babel-loader", 17 | options: { 18 | presets: ["@babel/preset-env"], 19 | }, 20 | }, 21 | }, 22 | ], 23 | }, 24 | optimization: { 25 | usedExports: true, 26 | }, 27 | plugins: [ 28 | new HtmlWebpackPlugin({ 29 | template: path.join(__dirname, "src", "index.html"), 30 | }), 31 | ], 32 | }; 33 | -------------------------------------------------------------------------------- /performance/virtualization/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /performance/virtualization/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /performance/virtualization/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /performance/virtualization/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /performance/virtualization/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "virtualization", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1", 15 | "react-window": "^1.8.10" 16 | }, 17 | "devDependencies": { 18 | "@eslint/js": "^9.11.1", 19 | "@types/react": "^18.3.10", 20 | "@types/react-dom": "^18.3.0", 21 | "@vitejs/plugin-react": "^4.3.2", 22 | "eslint": "^9.11.1", 23 | "eslint-plugin-react": "^7.37.0", 24 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 25 | "eslint-plugin-react-refresh": "^0.4.12", 26 | "globals": "^15.9.0", 27 | "vite": "^5.4.8" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /performance/virtualization/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/virtualization/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /performance/virtualization/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { FixedSizeList as List } from "react-window"; 2 | const Row = ({ index, style }) =>
Row {index}
; 3 | 4 | function App() { 5 | return ( 6 | <> 7 | 8 | {Row} 9 | 10 | 11 | ); 12 | } 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /performance/virtualization/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /performance/virtualization/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jscafe-dev/frontend-system-design-yatra/e9071ba1d7d69d4032ed56a526b8b9c83b6e6bb6/performance/virtualization/src/index.css -------------------------------------------------------------------------------- /performance/virtualization/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /performance/virtualization/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | --------------------------------------------------------------------------------